如何捕获这个错误:"Notice: Undefined offset: 0"

78

我想捕获这个错误:

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

编辑:事实上,我在下面这行代码中遇到了错误: $parse = $xml->children[0]->children[0]->toArray();

7个回答

116

你需要定义自己的错误处理程序,例如:

<?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";
}

3
如果你在生产环境中关闭了错误报告,那么这个方法将无效。 - Mark Fisher
这可能会破坏应用程序。在处理程序设置后执行的所有代码部分都将抛出异常。显然,某些库或代码片段会产生非关键性警告。 - Rehmat
4
@Rehmat,"非关键性警告"这种说法是不存在的:如果发出警告,当前的代码已经出现问题了。它可能在大多数情况下或此时此刻偶然工作,但无法保证。 - zerkms
我认为最好将 set_error_handler(...) 放在 function exceptions_error_handler... 之后,无论如何感谢。 - TechDogLover OR kiaNasirzadeh

27

使用try/catch块无法捕获这个错误,因为这是一个错误而不是异常。

在使用偏移量之前,始终先检查它们:

if( isset( $a[ 0 ] ) { $b = $a[ 0 ]; }

19
  1. 这不是错误,而是提示。
  2. 我们可以将提示/警告/错误转换为异常。
- zerkms
这个 PHP 的提示信息可能有多种解决方案,是否有最佳实践?就我个人而言,我经常使用 empty() 而不是 isset(),因为它们的比较略有不同:https://www.php.net/manual/en/types.comparisons.php - Abraham Brookes

14

我知道现在已经是2016年,但以防万一有人看到了这篇文章。

你可以使用array_key_exists($index, $array)方法来避免出现异常。

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

if(!array_key_exists($index, $array))
{
    //Throw myCustomException;
}

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();
}

或者,不需要创建一个非常临时的异常导致低效率:

$a[1] = 'jfksjfks';
$offset = 0;
if(isset($a[$offset]))
  $b = $a[$offset];
else
  echo "Notice: Undefined offset: ".$offset;

10
我应该提到,仅仅为了立即捕获和使用异常而创建异常是非常低效的,特别是当你可以更容易地将那个 echo 放在 else 子句中时。这并不会削弱你的答案,但我认为需要指出来。 - paxdiablo
3
非常正确,我写这篇文章并不是很愉快,但它足以回答他最初的问题! - Prisoner
1
虽然它可能效率低下,但很快将需要确保代码行为与PHP 7一致。PHP 7几乎只会抛出异常。 - Michael Morris
3
如果确实是异常情况,那么这样做就是合适的,即使效率不高也无所谓,因为这种情况本来就不应该发生。 - chim
也许对于这种用例,RunTimeException 更合适,可以参考 http://php.net/manual/zh/class.unexpectedvalueexception.php - chim
显示剩余2条评论

0

重要提示:尽量不要使用此方法,使用其他方法更好。虽然它可以工作,但它很丑陋,并且有自己的缺陷,比如将真实和有意义的输出转换为异常。

通常情况下,你无法通过简单的 try-catch 块捕获通知。但是有一种 hacky 和丑陋的方法可以做到:

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) {

}

此外,您还可以使用此函数来捕获警告。只需将函数名称更改为convert_warning_to_exception,并将"<b>Notice</b>:"更改为"<b>Warning</b>:"

注意:该函数将捕获包含以下内容的正常输出:

<b>Notice</b>:

为了避免这个问题,简单地将其更改为:
<b>Notice:</b>

0
对于那些遇到以下错误的人:
PHP提示:unserialize():在...的285字节中的第191个偏移处出现错误
并且从数据库获取数据,请确保你已经将数据库设置为正确的编码。我之前将数据库设置为latin1_swedish_ci,所有的数据看起来都很完美。实际上,当我将数据复制到一个在线的反序列化工具中时,它也能正常工作。但是当我将排序规则更改为utf8mb4_unicode_ci后,一切都正常了。
来源用户提交的注释:https://www.php.net/manual/pt_BR/function.unserialize.php 我尝试在反序列化之前使用utf8_decode,结果也很好。

Piece of code where I applied utf8_decode()


-6

我不确定为什么会出现错误,但我已经修复了一些问题。

在html2pdf.class.php文件中

第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;}

在第2138行的SAME:

//FIX:

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

问题是数组$sw没有$corr[$y][$x][2]的键,所以我修复了循环,将其修复到max count($sw)。

我不知道这是否会产生其他后果,但我解决了我的问题,不再有任何错误。

所以我希望它对你也有用..!!! 最好的问候


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接