2010-10-22 60 views
3

嘿PHP大師。我遇到了一些奇怪的類問題,這些問題顯然與php中的一些怪癖有關。誰能告訴我什麼出的最普通的情況下,可能會提供以下錯誤......PHP5類範圍怪癖

致命錯誤:當無級範圍是活躍在MyClass.php第5行無法訪問自己::

現在,很明顯,如果我在課堂外使用self ::,我會得到錯誤...但我不是。這裏是一個簡化版本的情況...

//file1 
class MyClass{ 
    public static function search($args=array()){ 
     $results = MyDbObject::getQueryResults("some query"); 
     $ordered_results = self::stack($results); //Error occurs here 

     return $ordered_results; 
    } 
    public static function stack($args){ 
     //Sort the results 
     return $ordered_results; 
    } 
} 

//file 2 
include_once("MyClass.php"); 
$args = array('search_term'=>"Jimmy Hoffa"); 
$results = MyClass::search($args); 

給出這個設置我怎麼能得到上面的錯誤?這是我迄今爲止發現的...

MyClass::search($args) //does not give the error (usually) 
call_user_func("MyClass::search"); // this gives the error! 

任何其他情況?

+0

彈出問題的另一種情況是當您在類函數中有函數時。但我不明白爲什麼這應該是一個問題,因爲內部功能仍然應該在班級的範圍內,對嗎?顯然內函數不能在封閉函數之外訪問。但是,你似乎應該能夠在內部函數中使用self。 – Brooks 2010-10-22 16:55:58

+0

如果將「self ::」更改爲「MyClass ::」,會發生什麼情況? – thetaiko 2010-10-22 16:59:56

+0

然後它可以正常工作,但代碼的可重用性大大降低 – Brooks 2010-10-22 17:01:01

回答

1

如果我理解正確,那麼您正在尋找Late Static Binding。該功能至少需要PHP 5.3版本。

+0

問題在於,似乎有些情況下可以在不加載類的範圍的情況下調用類方法。這不是繼承問題,可以通過延遲靜態綁定來解決。 – Brooks 2010-10-22 18:41:11

1

你沒有傳遞任何參數,但你的方法正在尋找它們。嘗試

call_user_func("MyClass::search", $args); 

這工作在PHP 5.3.1,但call_user_func("MyClass::search");沒有

+0

這是正確的,我只是在PHP 5.3.x中試過它,它工作正常,你只需要參數,<5.2.x它會給你那個錯誤。代碼我使用了class MyClass公共靜態函數搜索($ args){results}「some query」; $ ordered_results = self :: stack($ results); return $ ordered_results; } public static function stack($ args){ //對結果排序 return'query some'; } } $ args = array('search_term'=>「Jimmy Hoffa」); print call_user_func(「MyClass :: search」,$ args); – 2010-10-22 19:32:40

+0

你完全錯過了這個問題的關鍵。閱讀問題而不是代碼。我並沒有試圖找到一些工作,我試圖找出一些限制。 – Brooks 2010-10-25 15:26:02

0

試試這個:

call_user_func(array('MyClass', 'search')); 

參見例如#4 http://php.net/call_user_func

+0

您可以傳遞靜態對象方法作爲第一個參數 – 2010-10-22 18:05:56

+0

但是這不需要PHP 5.3.0嗎? – 2010-10-22 18:13:40

+0

我們已經在最初的討論中進行了討論。 – Brooks 2010-10-25 15:26:48

0

您的代碼似乎罰款。如果它有什麼問題,我一定會錯過這個問題。看來你對self ::的調用完全在一個類的範圍內!和一個靜態範圍,具體來說,這是自我::是。

從PHP的第三版對象模式與實踐(一真棒書):

爲同一類 內(而不是從孩子)訪問靜態方法或屬性,我會用self關鍵字。自己是 類的$這個僞變量是對象。所以從外面 的StaticExample類,我訪問使用它的類 名$ ANUM屬性:

StaticExample::$aNum; 

從StaticExample類中我可以使用自拍關鍵字:

class StaticExample {` 
    static public $aNum = 0; 

    static public function sayHello() { 
     self::$aNum++; 
     print "hello (".self::$aNum.")\n"; 
    } 
} 

所以,我不確定爲什麼這段代碼失敗了。也許是一個PHP的錯誤?我來到這個錯誤時,實際上是試圖用自我::一個分類 - 我的誤差範圍之外是這樣的:

public static function get_names() { 
    $machine_names = self::get_machine_names(); 

    return array_map(function ($machine_name) { 
     $service_settings = self::get_settings_by_machine_name($machine_name); 
     return $service_settings . $machine_name; 
     }, 
     $machine_names 
    ); 
} 

所以,我得到的錯誤,因爲我用自己::範圍之內的封閉。爲了解決這個錯誤,我可以在關閉之前調用self :: get_settings_by_machine_name(),並將結果傳遞給use的閉包範圍。

不確定你的代碼中發生了什麼。