2012-08-06 91 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()方法之後,它表明,它現在是一個實例,並且成員函數錯誤的致命呼叫消失。

相關問題