78

I want to catch this error:

$a[1] = 'jfksjfks';
try {
      $b = $a[0];
} catch (\Exception $e) {
      echo "jsdlkjflsjfkjl";
}

Edit: in fact, I got this error on the following line: $parse = $xml->children[0]->children[0]->toArray();

David Ferenczy Rogožan
  • 23,966
  • 9
  • 79
  • 68
meotimdihia
  • 4,191
  • 15
  • 49
  • 69

7 Answers7

116

You need to define your custom error handler like:

<?php

set_error_handler('exceptions_error_handler');

function exceptions_error_handler($severity, $message, $filename, $lineno) {
  if (error_reporting() == 0) {
    return;
  }
  if (error_reporting() & $severity) {
    throw new ErrorException($message, 0, $severity, $filename, $lineno);
  }
}

$a[1] = 'jfksjfks';
try {
      $b = $a[0];
} catch (Exception $e) {
      echo "jsdlkjflsjfkjl";
}
zerkms
  • 249,484
  • 69
  • 436
  • 539
  • 3
    This won't work if you have error reporting turned off, as you probably would in production. – Mark Fisher Mar 08 '18 at 17:16
  • This might break an application. Exceptions will be thrown in all the parts of the code that get executed after the handler has been set. And this is obvious to have certain libraries or piece of code that produce non-critical warnings. – Rehmat Mar 01 '20 at 14:27
  • 4
    @Rehmat there is no such thing as "non-critical warning": if a warning is emitted - the current code is broken already. It may work accidentally most of the times or this very moment, but it cannot be guaranteed. – zerkms Mar 01 '20 at 19:54
  • i think it's better that `set_error_handler(...)` should place after `function exceptions_error_handler...`, anyway tnx – TechDogLover OR kiaNasirzadeh Oct 22 '20 at 04:40
27

You can't with a try/catch block, as this is an error, not an exception.

Always tries offsets before using them:

if( isset( $a[ 0 ] ) { $b = $a[ 0 ]; }
Macmade
  • 52,708
  • 13
  • 106
  • 123
  • 19
    1. It is not a error, but a notice 2. We can convert notices/warnings/errors into exceptions – zerkms Mar 21 '11 at 04:33
  • There must be a range of solutions for this notice in PHP, is there a best practice? Personally, I often use `empty()` instead of `isset()` because it compares a little differently: https://www.php.net/manual/en/types.comparisons.php – Abraham Brookes Jul 03 '19 at 03:51
14

I know it's 2016 but in case someone gets to this post.

You could use the array_key_exists($index, $array) method in order to avoid the exception to happen.

$index = 99999;
$array = [1,2,3,4,5,6];

if(!array_key_exists($index, $array))
{
    //Throw myCustomException;
}
Community
  • 1
  • 1
Luis Deras
  • 1,239
  • 2
  • 19
  • 48
10
$a[1] = 'jfksjfks';
try {
  $offset = 0;
  if(isset($a[$offset]))
    $b = $a[$offset];
  else
    throw new Exception("Notice: Undefined offset: ".$offset);
} catch (Exception $e) {
  echo $e->getMessage();
}

Or, without the inefficiency of creating a very temporary exception:

$a[1] = 'jfksjfks';
$offset = 0;
if(isset($a[$offset]))
  $b = $a[$offset];
else
  echo "Notice: Undefined offset: ".$offset;
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
Prisoner
  • 27,391
  • 11
  • 73
  • 102
  • 10
    I should mention that it's horribly inefficient to create an exception just so you can catch it and use it immediately, especially when it's easier to just put that `echo` in the `else` clause. That doesn't detract from your answer but I thought it needed pointing out. – paxdiablo Mar 21 '11 at 04:31
  • 3
    That is very true, I didnt enjoy writing it but it suffices his original question! – Prisoner Mar 21 '11 at 04:34
  • I'd be interested in knowing the rationale behind the downvote, bods. This seems perfectly okay to me. – paxdiablo Mar 21 '11 at 04:37
  • 1
    Horribly efficient though it may be, it will soon be necessary to keep code behavior congruent to PHP 7. PHP 7 throws exceptions almost exclusively. – Michael Morris Jul 30 '15 at 17:03
  • 3
    It's appropriate if it's truly an Exception, efficiency doesn't really matter if this is never expected to happen. – chim Jan 29 '16 at 09:24
  • Would a RunTimeException be more appropriate for this use case maybe http://php.net/manual/en/class.unexpectedvalueexception.php – chim Jan 29 '16 at 09:24
  • @paxdiablo this little inefficiency **is insignificant in 2021** and there's only a slight difference only **when the exception is actually thrown** (which should not be the most cases since it should be only when something unexpected comes). Unless you're throwing thousands of exceptions, there should not be much performance cost. (if you would really want to ultra optimize - you should look for PHP-similar lower languages like C++/C) **or look for other bottlenecks first**. – jave.web Apr 28 '21 at 21:33
0

Important: Prefer not using this method, use others. While it works, it is ugly and has its own pitfalls, like falling into the trap of converting real and meaningful output into exceptions.

Normally, you can't catch notices with a simple try-catch block. But there's a hacky and ugly way to do it:

function convert_notice_to_exception($output)
{
    if (($noticeStartPoint = \strpos($output, "<b>Notice</b>:")) !== false) {
        $position = $noticeStartPoint;
        for ($i = 0; $i < 3; $i++)
            $position = strpos($output, "</b>", $position) + 1;
        $noticeEndPoint = $position;
        $noticeLength = $noticeEndPoint + 3 - $noticeStartPoint;
        $noticeMessage = \substr($output, $noticeStartPoint, $noticeLength);

        throw new \Exception($noticeMessage);
    } else
        echo $output;
}

try {
    ob_start();
    // Codes here
    $codeOutput = ob_get_clean();

    convert_notice_to_exception($codeOutput);
} catch (\Exception $exception) {

}

Also, you can use this function for to catch warnings. Just change function name to convert_warning_to_exception and change "<b>Notice</b>:" to "<b>Warning</b>:".

Note: The function will catch normal output that contains:

<b>Notice</b>:

To escape from this problem, simply, change it to:

<b>Notice:</b>
MAChitgarha
  • 3,728
  • 2
  • 33
  • 40
0

For the people who are getting the error

PHP Notice: unserialize(): Error at offset 191 of 285 bytes in ...

and are getting the data from a database, Make sure that you have the database set the the correct encoding, I had the database set as latin1_swedish_ci and all of the data looked perfect, Infact when i copied it into a online unserialize it worked fine. I changed the collation to utf8mb4_unicode_ci and all worked fine.

Source User Contributed Notes: https://www.php.net/manual/pt_BR/function.unserialize.php

I tried to utf8_decode before unserialize, and it's works fine.

Piece of code where I applied utf8_decode()

Caique Andrade
  • 1,025
  • 7
  • 9
-6

Im sure why the Error Throw but i fix some..

in html2pdf.class.php

on Lines 2132:

//FIX:
$ctop=$corr[$y][$x][2]<=count($sw)?$corr[$y][$x][2]:count($sw);
$s = 0; for ($i=0; $i<$ctop; $i++) {$s+= array_key_exists($x+$i, $sw)? $sw[$x+$i]:0;}

SAME On line 2138:

//FIX:

$ctop=$corr[$y][$x][2]<=count($sw)?$corr[$y][$x][2]:count($sw);
 for ($i=0; $i<$ctop; $i++) {

the problem the array $sw not have a key of $corr[$y][$x][2] so i fix the loop for to max count($sw) to fix .. I dont know if that create an another consecuense but i resolve my problem y dont have any more errors..

So i hope works to you ..!!! Beats Reguards

carlos
  • 1