2012-08-06 128 views
4

我遇到了PHP问题,因为它一直在标题中抛出异常提及。 它失败以下行:PHP:致命错误调用成员函数...在非对象上

$item->getDescription(); 

我明白了什么错误应该是指($item为空)。但是,$ item不为null。

该场景如下: 这是一个脚本,可以将供应商的产品同步到商店。为此,我创建了自己的类(SimpleProduct)。这个类有一个getDescription()函数。

问题是我收到的数据往往会有很多垃圾,比如尚未填充的项目。该脚本应该跳过这些项目并继续遍历其余产品。 这个致命错误会杀死整个脚本。

我已经尝试过实施保护措施,以防止这种情况发生,但它仍然不断发生。这里是当前的代码(由于它们与currect情况不相关,所以删除了一些代码段)。

//This is part of a class that performs the sync 

public function syncProduct($item) { 

    if(empty($item)) { return "Not a product"; } 
     else { var_dump($item) } 

    $foo = $item->getDescription(); 
} 

在检查的var_dump结果,我得到填充。看到一些值的对象,因为它是正确的类型(SimpleProduct)的,它不是空/空,我会怀疑这个错误停止发生,但它仍然如此。

另请注意,在弹出一个产品之前,几个产品同步已经没有任何错误发生,所以我知道该代码是有效的。不知何故,这个特定的情况滑过我的空检查。

我的空检查有问题吗? 有问题的对象存在时,如何引发非对象错误?

+2

你可以发布var_dump输出吗? – cegfault 2012-08-06 09:32:09

+0

如果你在if()之前做了一个var_dump(),对于所有的$ items,你会看到有问题的$ item类型吗? – periklis 2012-08-06 09:32:30

+0

在这种情况下,我可以看到的唯一原因是getDescription()方法throeing该错误..你可以请代码为getDescription()方法 – 2012-08-06 09:34:37

回答

8

不是检查变量是否为空,为什么不检查它是否是SimpleProduct的实例?

if ($item instanceof SimpleProduct) 
{ 

} 

http://php.net/manual/en/language.operators.type.php

+0

该检查实际上是在上面的代码中执行的,上面的函数只有在它针对SimpleProduct类型进行验证时才会被调用。 – Flater 2012-08-06 09:36:26

+0

嗯,我会....我添加了再次检查功能,现在它成功了。我不知道为什么它只是在相同的函数中起作用,而不是在调用它之前,但它起作用(好吧,我现在得到其他错误,但它们与这种情况无关)。 – Flater 2012-08-06 10:00:08

+2

在这种情况下,我会在'if(!instanceof)'分支中添加一个debug_backtrace(),并检查是否有另一个调用者。 – VolkerK 2012-08-06 10:13:35

0

即使它的 为空,您的空检查也不会阻止使用该对象 包含非对象。

使用此:

public function syncProduct($item) { 
    var_dump($item); 

    if($item InstanceOf SimpleProduct) { 
     $foo = $item->getDescription(); 
    } 

    return "Not a product"; 
} 

我认错!我没有注意到退货声明。另一种情况是,如果$item的值非空,但不是产品 - 很可能是标量或数组,因为将对象用作其他类型的对象会发出与找不到方法有关的不同错误。

+3

如果它是空的,函数返回字符串'Not a product',为什么它应该执行返回语句后遇到的代码?该代码是一个更大的迭代的一部分,我实际上已经7-8层的代码嵌套深,所以我宁愿不添加额外的层(为了可读性)。不应该这个解决方案是相同的,因为if-block中有return语句吗? – Flater 2012-08-06 09:30:39

+0

@Flater是对的,它不会发生 – 2012-08-06 09:31:29

+0

是的,我触发了快乐,我道歉,并立场纠正。 – 2012-08-06 09:36:25

0

当然,该对象在函数syncProduct的上下文中仍然不可用。

尝试做一个var_dump($ item)来确认它并在代码的其他部分执行它以确保它不为空。

+0

检查代码,它执行var_dump。这是奇怪的部分。发生var_dump(因此该对象不是空的,请参阅if语句)。另外,var_dump返回一个有效的对象,但是我得到一个错误,那个对象是null。 – Flater 2012-08-06 09:34:28

0

要检查是否$项目是一个对象,你可以使用is_object()

+0

这并不完全关注错误。如果变量是一个对象,但没有实现'getDescription'方法呢? – 2012-08-06 09:37:29

+0

是的,我意识到,当我看到你的解决方案。没有足够的声望点upvote它虽然:( – Tom 2012-08-06 09:54:20

0

我也碰到了类似的问题,在运行此之后:

$user = DB::getInstance()->action($action="SELECT * ", 'users'); 

然后检查是否$ user是DB的一个实例,我发现它不是。然后我决定分离,如下所示:

$user = DB::getInstance(); 
$user->action($action="SELECT * ", 'users'); 

这样做的,使用的instanceof()方法之后,它表明,它现在是一个实例,并且成员函数错误的致命呼叫消失。

相关问题