PHP - 错误处理问题

时间:2012-12-27 00:54:20

标签: php error-handling duck-typing

我有一些代码,用户可以通过数据库设置任意数量的数组元素。我是基于键名的鸭子打字函数,但并非所有的键名都是要调用的对象,我不能保证键可以是静态的顺序。代码类似于:

$arr = get_arr_from_db();

foreach($arr as $key => $val){
    if($obj = new $key){
        unset($arr[$key]);

        $obj->give_data($arr);

        break;
    }
}

$obj->quack();

上述代码不起作用,因为$obj = new $key将会死亡。在创建失败的对象时,有什么方法可以让上面的循环不受影响?

3 个答案:

答案 0 :(得分:1)

您可以在尝试实例化之前使用class_exists(),如果无法实例化,try / catch块也会捕获任何错误。

foreach($arr as $key => $val){
  if(class_exists($key)){
    try {
        if($obj = new $key){
            unset($arr[$key]);

            if(method_exists($obj, 'give_data'){
                $obj->give_data($arr);
            }

            break;
        }
    } catch(Exception $e) {
        // do something with the exception
    }
  }
}

答案 1 :(得分:1)

序列化

使用serializeunserialize会更直接,它将为您处理类初始化和类型检查。

E.g:

$person = new Person();
$person->firstname = 'Chuck';
$person->lastname = 'Jones';

$blob = serialize($person); // put blob in the database

序列化/反序列化接口

如果您想遵循give_data()方法(例如,您的类属性与数据库中的列名匹配),则应指定interface。接口可以保证您正在调用的类具有可用的unserialize方法,并且它的行为与您期望的一样(下面的示例使用工厂模式):

<?php
interface ArraySerializable
{
    public static function createFromArray($array);
}

class Person implements ArraySerializable
{
    public static function createFromArray($array)
    {
        $temp = new self();
        $temp->firstname = $array['first_name'];
        $temp->lastname = $array['last_name'];
        return $temp;
    }
}

然后你要测试class_implements()

$class_name = 'Person';

if (class_exists($class_name)
    && in_array('ArraySerializable', class_implements($class_name))
){
    $person = $class_name::createFromArray(array(
        'last_name' => 'Jones',
        'first_name' => 'Chuck'
    ));

    var_dump($person);
}

要在更多类中使用它,您只需为每个类实现ArraySerializable接口。

如果您不想从头开始滚动,可以使用功能齐全的ORM(如Doctrine)来完全抽象数据库。

答案 2 :(得分:0)

最好使用Reflector类:

foreach($arr as $key => $val){
    $reflection = new ReflectionClass($key);
    if ($reflection->IsInstantiable()) {
        unset($arr[$key]);

        $obj = $reflection->newInstance();
        $obj->give_data($arr);

        break;
    }
}