21

unserialize()生成错误时是否可以在 PHP 上捕获异常?

4

5 回答 5

17

一个简单的方法是:

$ret = @unserialize($foo);
if($ret === null){
   //Error case
}

但这不是最现代的解决方案。

如前所述,最好的方法是拥有一个自定义错误/异常处理程序(不仅适用于这种情况)。但取决于你在做什么,这可能是矫枉过正。

于 2012-10-02T07:05:04.227 回答
17

不,你不能抓住它,unserialize()不会抛出异常。

如果传递的字符串不是不可序列化的,则返回 FALSE 并发出 E_NOTICE。

您可以设置自定义异常处理程序来处理所有错误:

function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
set_error_handler("exception_error_handler");
于 2012-10-02T05:15:05.590 回答
5

将所有 PHP 错误(警告通知等)转换为异常。例子在这里

于 2012-10-02T05:45:43.377 回答
5

完整的解决方案如下所示:

<?php
// As mentioned in the top answer, we need to set up 
// some general error handling
function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
set_error_handler("exception_error_handler");


// Note, there are two types of way it could fail, 
// the fail2 fail is when try to unserialise just 
// false, it should fail. Also note, what you 
// do when something fails is up to your app. 
// So replace var_dump("fail...") with your 
// own app logic for error handling
function unserializeSensible($value) {
    $caught = false;
    try {
        $unserialised = unserialize($value);
    } catch(ErrorException $e) {
        var_dump("fail");
        $caught = true;
    }
    // PHP doesn't have a try .. else block like Python
    if(!$caught) {
        if($unserialised === false && $value !== serialize(false)) {
            var_dump("fail2");
        } else {
            var_dump("pass");
            return $unserialised;
        }
    }
}

unserializeSensible('b:0;'); // Should pass
unserializeSensible('b:1;'); // Should pass
unserializeSensible('a:2:{s:1:"a";b:0;s:1:"b";s:3:"foo";}'); // Should pass
unserializeSensible('a:2:{s:1:"a";b:0;s:1:"b";s:3:1111111111111111;}'); // Should fail
unserializeSensible(123); // Should fail
unserializeSensible("Gday"); // Should fail
unserializeSensible(false); // Should fail2
unserializeSensible(true); // Should fail
于 2016-08-27T05:42:03.327 回答
3

正如 Mihai Iorga 解释的那样,unserialize不会扔任何东西。您可以通过将返回值与 进行比较来检查错误,但如果序列化值是布尔值false,它将失败。false下面的解决方案解决了这个问题,而无需借助缓慢而繁琐的技术(例如设置自定义错误处理程序)。

InvalidArgumentException如果序列化的值$v无效,以下代码将抛出 a ,否则$x将包含未序列化的值。

特别注意区分:

  • unserialize()返回false以表示无效的序列化值
  • 原始值实际上是一个 boolean false
$x = @unserialize ($v);
if ($x === false && $v != 'b:0;')
  throw new InvalidArgumentException;
于 2019-10-30T15:48:16.400 回答