更好的方法来避免调用成员函数

时间:2017-12-17 00:03:56

标签: php

我需要知道是否有更好的方法可以避免在xxxx()上调用成员函数null

目前我编码如下,但很麻烦。

if($event->getForm()
                && $event->getForm()->getParent()
                && $event->getForm()->getParent()->getParent()
                && $event->getForm()->getParent()->getParent()->getData()
                && $event->getForm()->getParent()->getParent()->getData()->getComponente()
            ){
                $componente = $event->getForm()->getParent()->getParent()->getData()->getComponente();
                $formModifier($event->getForm(), $componente, $defaultComponente);
            }

4 个答案:

答案 0 :(得分:1)

没有办法,但至少你可以做一些性能提升

$form = $event->getForm();

if(!$form){
    //do error handling
    return;
}
$parent = $form->getParent();

if(!$parent){
    //do error handling
    return;
}

$p_parent = $parent->getParent();

if(!$p_parent){
    //do error handling
    return;
}

$data = $p_parent->getData();

if(!$data){
    //do error handling
    return;
}

$component = $data->getComponente();
...

这样你只需调用一次函数,就可以做更好的错误处理

答案 1 :(得分:1)

在PHP 7中,这实际上是一个可捕获的错误(如果您使用hhvm它是常规异常):

try {
    $componente = $event->getForm()->getParent()->getParent()->getData()->getComponente();
} catch (\Error $e) {
    $componente = null;
}

if ($componente !== null) {
    $formModifier($event->getForm(), $componente, $defaultComponente);
}

在PHP 5中,有一种使用中间变量和and关键字而不是&&的解决方法:

if (
    $f  = $event->getForm() and
    $p  = $f->getParent()   and
    $p2 = $p->getParent()   and
    $d  = $p2->getData()    and
    $componente = $d->getComponente()
) {
    $formModifier($f, $componente, $defaultComponente);
}

如果您使用&&代替and,那么您将获得"未定义的变量"通知和这种解决方法不起作用。

工作示例:https://3v4l.org/0S6ps

答案 2 :(得分:0)

我认为这是糟糕代码的一个很好的例子。通过拥有这样的代码,你可以打破几条规则,让你的生活更加艰难。 你的代码是僵化的,脆弱的,难以理解和维护等。

更简单总是更好。

如果你不能在没有这种丑陋的嵌套关系的情况下轻松访问你的$ xx-> getComponent()一个正确的对象,你至少应该将该方法封装到适当的地方并使用它,所以如果有任何改变,你不必全力以赴,并在整个地方改变它。

答案 3 :(得分:0)

这个类在它的创建中似乎很奇怪,但如果你不是使用__call()动态提取这些方法,你可以在函数内部的循环中使用method_exists(),类似于:

function getMethodChain($class,$arr = ['getForm','getParent','getParent','getData','getComponente'])
{
    # First check the object is set
    if(!is_object($class))
        return false;
    # Loop intended method chain
    foreach($arr as $method) {
        # Check if the method exists in the current class or passed already
        $useClass   =   (!isset($classPass))? $class : $classPass;
        # Check if the method exists in the current class
        if(is_object($useClass) && method_exists($useClass,$method)) {
            # Assign this class/method to use next in the loop
            $classPass  =   $useClass->{$method}();
        }
        else
            return false;
    }
    # Just send back
    return (isset($classPass))? $classPass : false;
}

使用方法如下:

# This will either be the data you expect or false
$componente = getMethodChain($event);