2012-11-05 126 views
2

我正在使用神奇方法_call_callStatic來爲我自己實現類似於ORM/Activerow的東西。它們主要用於捕獲某些函數調用:__call負責獲取方和設置方法,__callStatic方法(例如findById)。__call捕獲靜態方法調用

要映射外鍵,我試圖將呼叫轉換爲例如getArticle返回Article::findById()的值。要做到這一點,我使用的這種情況下,我的__call內:

if (strstr($property, "_id")) { 
return $foreignClass::findById($this->getId()); 
} 

其中$property是後設置__call得到子串,並$foreignClass字符串的其餘部分。因此,在電話getArticle的情況下,$ property將被獲得並且$foreignClass將是Article

我已經放置了一些回聲以確保值是正確的。但是,我的__call方法被調用而不是我的__callStatic。如果我使用隱式靜態方法findById,它確實會被調用(所以它會將其識別爲靜態調用)。如果我專門撥打Article::findById()__call也會捕獲它。

這是相對較新的__callStatic錯誤,還是我做錯了什麼?

編輯: 這個問題似乎居住在這一部分:

_call()在對象範圍內調用方法不可訪問時被觸發。
__callStatic()在調用靜態上下文中不可訪問的方法時被觸發。

雖然我稱它在一個類中,我從一個對象上下文調用它。在這種情況下是否有辦法進入靜態環境?

+0

我有可怕的感覺,這裏有遺漏的重要信息。在哪個類中定義了魔術方法?他們被稱爲哪個類?前面提到的類是否是同一繼承樹的成員?如果是這樣,他們的關係是什麼? – Jon

+0

這裏的繼承樹是DBObject(我在其中展示了代碼) - > Article-> Activity。文章和活動覆蓋沒有相關的代碼,所有這些邏輯發生在DBObject中。我現在改變了我的代碼,使用__get和__set代替__call,現在它似乎正在觸發__callStatic。 –

+0

所以'$ foreignClass'就是'Article',並且該方法在'Activity'的上下文中被調用。這使得「文章」成爲祖先階級。有問題。 – Jon

回答

2

由於代碼你給運行在一個Activity對象的上下文並且由於$foreignClas值爲Article,這是Activity的祖先,PHP假定您打算的方法的to call an ancestor's implementation

爲了擺脫對象上下文有AFAIK沒有比這絕對可怕的技術,另一種選擇:

$id = $this->getById(); 
return call_user_func(
    function() use($foreignClass, $id) { 
     return call_user_func("$foreignClass::findById", $id); 
    } 
); 
+0

嗯,這很有趣。我之前閱讀過它,但不知何故又回到了假設::只是稱爲靜態方法。我會進一步探討一下,但這至少是一個很好的來源:它實際上做了什麼:) –

0

__callStatic魔法僅在PHP 5.3中引入。在此之前,我認爲靜態調用通過__call,就像正常的方法調用一樣。我的猜測是你正在使用的PHP版本是< 5.3。命令行上的php -v的輸出是什麼?

+0

我剛剛升級到5.4才能夠使用__callStatic ...我會測試一下,看看它是否可以工作。 –

+0

編輯我的帖子。 –