如何捕获反序列化异常?

时间:2012-10-02 05:12:59

标签: php serialization try-catch

如果在unserialize生成错误时如何捕获PHP上的异常?

5 个答案:

答案 0 :(得分:12)

一个简单的方法是:

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

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

如前所述,最好的方法是拥有自定义错误/异常处理程序(不仅适用于此情况)。但是,根据你正在做的事情,这可能是过度的。

答案 1 :(得分:11)

不,你无法抓住它,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");

答案 2 :(得分:4)

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

<?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

答案 3 :(得分:3)

将所有PHP错误(警告通知等)转换为异常。示例是here

答案 4 :(得分:1)

正如Mihai Iorga所说,unserialize不会抛出任何东西。您可以通过将返回值与false进行比较来检查错误,但是如果序列化的值为布尔值false,它将失败。下面的解决方案无需使用缓慢而麻烦的技术(例如设置自定义错误处理程序)即可解决此问题。

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

要特别注意区分:

  • unserialize()返回false表示无效的序列化值
  • 原始值实际上是布尔值false
$x = @unserialize ($v);
if ($x === false && $v != 'b:0;')
  throw new InvalidArgumentException;