Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Try catch not catching 1

Status
Not open for further replies.

PeDa

Technical User
Oct 10, 2002
227
0
0
NL
I read dates from a table and show a thumbnail and link for each date. The thumbnails are in folder /impressie/yyyymmdd/ . The following script works fine if the folders do exist. I want, however, to catch the case that the folder does not exist (that is to say: wrong date in table)

Code:
$result = $q->fetchAll(PDO::FETCH_ASSOC);
$numberOfEvents=count($result);
$numberOfRows=ceil($numberOfEvents/4);
$event=0;
for ($row = 0; $row < $numberOfRows; $rij++) 
  {
  echo "<div class='w3-row'>\n";
  for ($col = 0; $col < 4; $col++)
    {
    if ($event<$numberOfEvents)
      {
      $id=$result[$event]["id"];
      $datum=$result[$event]["datum"];
      $titel=$result[$event]["titel"];
      try { 
	$thumbnail=glob(__DIR__ . "/impressie/".  date_format(date_create($datum),"Ymd") . "/" . "*a.*")[0]; // <<================line 61
	$thumbnail=str_replace(__DIR__,"",$thumbnail); <<================line 62
	echo "<div class='w3-row w3-quarter plaatje'>\n";
	echo "<a href='impressie.php?id=" . $id . "'>\n";
	echo "<img src='" . $thumbnail . "' style='max-width:100%;' alt='".htmlspecialchars($titel)."'></a>";
	$maandNr=date_format(date_create($datum),"m");
	$maand=" ". substr("janfebmaraprmeijunjulaugsepoktnovdec", (($maandNr) * 3)-3,3)." ";
	echo "<br>" . date_format(date_create($datum),"d").$maand.date_format(date_create($datum),"Y") . " - " . $titel . "<br><br>\n";
	echo "</div>\n";
	}
      catch (PDOException $e) 
        {
        echo "Exception caught";
        }
    } 
    $event++;
    } 
  echo "</div>\n";
  }

As can be seen here, no exception is caught and the following message is shown
Code:
Warning: Undefined array key 0 in xxxxxxx/phptest/impressies2.php on line 61
Deprecated: str_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /srv/customers/12250601/amsterdamhv.nl/phptest/impressies2.php on line 62

N.B. I am aware that all this code might not be great php-practice (too many years writing VBA!)
 
The error message seems accurate. That is not an array in line 61. What is the intent of "[0]"?
 
Line 61 must give an array of filesnames of the form /impressie/yyyymmdd.*a.* and load the first one into $thumbnail (and this is what indeeed happens if such files exist, the normal condition). If no such files exist the error message is indeed correct; however my question is: why is this not caught by the try-catch construction?
 
Hi

PeDa said:
why is this not caught by the try-catch construction?
Because it is a warning, not an exception.

Yepp, that may be quite confusing, but unfortunately PHP has 2 completely different problem signaling mechanisms : errors and exceptions.

Code:
[silver]# once a notice[/silver]
[blue]master #[/blue] php7.3 -r '[][0];'
PHP Notice:  Undefined offset: 0 in Command line code on line 1

[silver]# later its level was raised to warning[/silver]
[blue]master #[/blue] php8.1 -r '[][0];'
PHP Warning:  Undefined array key 0 in Command line code on line 1

[silver]# but level does not matter if you only want to silence it[/silver]
[blue]master #[/blue] php7.3 -r '@[][0];'

[blue]master #[/blue] php8.1 -r '@[][0];'

[silver]# even silenced, you can find out what happened[/silver]
[blue]master #[/blue] php7.3 -r '[][0]; print_r(error_get_last());'
PHP Notice:  Undefined offset: 0 in Command line code on line 1
Array
(
    [type] => 8
    [message] => Undefined offset: 0
    [file] => Command line code
    [line] => 1
)

[blue]master #[/blue] php8.1 -r '[][0]; print_r(error_get_last());'
PHP Warning:  Undefined array key 0 in Command line code on line 1
Array
(
    [type] => 2
    [message] => Undefined array key 0
    [file] => Command line code
    [line] => 1
)

[silver]# instead of silencing one by one, you can filter out entire levels[/silver]
[blue]master #[/blue] php7.3 -d error_reporting='E_ALL & ~E_NOTICE' -r '[][0];'

[blue]master #[/blue] php8.1 -d error_reporting='E_ALL & ~E_WARNING' -r '[][0];'

[silver]# alternatively you can set up an error handler which to actually do nothing[/silver]
[blue]master #[/blue] php7.3 -r 'set_error_handler(function() {}); [][0];'

[blue]master #[/blue] php8.1 -r 'set_error_handler(function() {}); [][0];'

And this later possibility is actually the base to convert errors to exceptions so you can catch them :
PHP:
[COLOR=orange]set_error_handler[/color][teal]([/teal][b]function[/b][teal]([/teal][navy]$errno[/navy][teal],[/teal] [navy]$errstr[/navy][teal],[/teal] [navy]$errfile[/navy][teal],[/teal] [navy]$errline[/navy][teal],[/teal] [navy]$errcontext[/navy][teal]) {[/teal]
    [b]if[/b] [teal]([/teal][COLOR=orange]error_reporting[/color][teal]() &[/teal] [navy]$errno[/navy][teal])[/teal]
        [b]throw new[/b] [COLOR=orange]ErrorException[/color][teal]([/teal][navy]$errstr[/navy][teal],[/teal] [purple]0[/purple][teal],[/teal] [navy]$errno[/navy][teal],[/teal] [navy]$errfile[/navy][teal],[/teal] [navy]$errline[/navy][teal]);[/teal]
[teal]});[/teal]

[b]try[/b] [teal]{[/teal]
    [teal][][[/teal][purple]0[/purple][teal]];[/teal]
[teal]}[/teal] [b]catch[/b] [teal]([/teal]ErrorException [navy]$e[/navy][teal]) {[/teal]
    [b]echo[/b] [i][green]'Bad thing happened : '[/green][/i][teal],[/teal] [navy]$e[/navy][teal]->[/teal][COLOR=orange]getMessage[/color][teal]();[/teal]
[teal]}[/teal]

[COLOR=orange]restore_error_handler[/color][teal]();[/teal]


Feherke.
feherke.github.io
 
Thank you for this, which I understand. I now have the following code (now with original Dutch text)

Code:
	$result = $q->fetchAll(PDO::FETCH_ASSOC);
	$aantalEvenementen=count($result);
	$aantalRijen=ceil($aantalEvenementen/4);
	$evenement=0;
	
	set_error_handler(function($errno, $errstr, $errfile, $errline, $errcontext) { // <========== 51
    if (error_reporting() & $errno)
        throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
	});

	for ($rij = 0; $rij < $aantalRijen; $rij++) 
		{
		echo "<div class='w3-row'>\n";
		for ($col = 0; $col < 4; $col++)
			{
			if ($evenement<$aantalEvenementen)
				{
				$id=$result[$evenement]["id"];
				$datum=$result[$evenement]["datum"];
				$titel=$result[$evenement]["titel"];
				try {
					//volgende regel geeft een waarschuwing (geen exceptie) indien geen bestand gevonden
					$thumbnail=glob(__DIR__ . "/impressie/".  date_format(date_create($datum),"Ymd") . "/" . "*a.*")[0]; // <================ 68
					$thumbnail=str_replace(__DIR__,"",$thumbnail); //en hier hebben wij juist een relatief pad nodig
					echo "<div class='w3-row w3-quarter plaatje'>\n";
					echo "<a href='impressie.php?id=" . $id . "'>\n";
					echo "<img src='" . $thumbnail . "' style='max-width:100%;' alt='".htmlspecialchars($titel)."'></a>";
					$maandNr=date_format(date_create($datum),"m");
					$maand=" ". substr("janfebmaraprmeijunjulaugsepoktnovdec", (($maandNr) * 3)-3,3)." ";
					echo "<br>" . date_format(date_create($datum),"d").$maand.date_format(date_create($datum),"Y") . " - " . $titel . "<br><br>\n";
					echo "</div>\n";
					}
				catch(PDOException $e) {echo "Bad thing happened";}
				} 
		  	$evenement++;
			} 
		echo "</div>\n";
		}
	restore_error_handler(); // afhandeling van waarschuwingen weer normaal

Unfortunately I now get the following:
Code:
Fatal error: Uncaught ArgumentCountError: Too few arguments to function {closure}(), 4 passed in xxxxxxxxxxx/phptest/impressies3.php on line 68 and 
exactly 5 expected in xxxxxxxxx/phptest/impressies3.php:51 Stack trace: #0 /xxxxxxxx/phptest/impressies3.php(68): 
{closure}(2, 'Undefined array...', '/srv/customers/...', 68) #1 {main} thrown in xxxxxxxxx/phptest/impressies3.php on line 51

See here
 
Hi

Sorry, as mentioned earlier, I am still on PHP 7.3 so again posted code incompatible with PHP 8.0. :-(
PHP documentation said:
Warning

This parameter has been DEPRECATED as of PHP 7.2.0, and REMOVED as of PHP 8.0.0. If your function defines this parameter without a default, an error of "too few arguments" will be raised when it is called.
( [tt]set_error_handler()[/tt]'s callback parameter [tt]$errcontext[/tt] )

Just remove the unused [tt]$errcontext[/tt] parameter :
Code:
[COLOR=orange]set_error_handler[/color][teal]([/teal][b]function[/b][teal]([/teal][navy]$errno[/navy][teal],[/teal] [navy]$errstr[/navy][teal],[/teal] [navy]$errfile[/navy][teal],[/teal] [navy]$errline[/navy][teal]) {[/teal]
    [b]if[/b] [teal]([/teal][COLOR=orange]error_reporting[/color][teal]() &[/teal] [navy]$errno[/navy][teal])[/teal]
        [b]throw new[/b] [COLOR=orange]ErrorException[/color][teal]([/teal][navy]$errstr[/navy][teal],[/teal] [purple]0[/purple][teal],[/teal] [navy]$errno[/navy][teal],[/teal] [navy]$errfile[/navy][teal],[/teal] [navy]$errline[/navy][teal]);[/teal]
[teal]});[/teal]

[b]try[/b] [teal]{[/teal]
    [teal][][[/teal][purple]0[/purple][teal]];[/teal]
[teal]}[/teal] [b]catch[/b] [teal]([/teal]ErrorException [navy]$e[/navy][teal]) {[/teal]
    [b]echo[/b] [i][green]'Bad thing happened : '[/green][/i][teal],[/teal] [navy]$e[/navy][teal]->[/teal][COLOR=orange]getMessage[/color][teal]();[/teal]
[teal]}[/teal]

[COLOR=orange]restore_error_handler[/color][teal]();[/teal]

BTW, there you are catching only [tt]PDOException[/tt] and its descendants, so [tt]ErrorException[/tt] will pass uncaught. You either include another [tt]catch[/tt] or change it catch [tt]Exception[/tt] instead, as that is those 2 exceptions closest ancestor.


Feherke.
feherke.github.io
 
Hello Feherke,
Yes, that did the trick. One again: many thanks,
Peter Da.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top