2013-07-11 64 views
0

我試圖通過基於class_exists返回來保護類被重新聲明。在Wordpress中創建插件時這很常見,因爲可能有多個使用相同類的插件。使用下面的簡單的例子:PHP:返回後無法重新聲明類錯誤

您可以在http://www.youtube.com/watch?v=llVTvh6ffmw

以下鏈接說明了問題,根源在Youtube上觀看這一http://www.youtube.com/watch?v=VcNLoDvRLDc

的index.php

<?php 
include_once('debug1.php'); 
include_once('debug2.php'); 

$test = new SomeClass(); 
echo $test->someVar; 

debug1.php & debug2.php是重複的文件...

<?php 
if(class_exists('SomeClass')) return; 
class SomeClass { 
    var $someVar = "test"; 
} 

儘管有一個return語句,我們仍然獲得了致命錯誤「不能重新聲明類」。

附註:通過在debug2中簡單地添加/刪除空白,這段代碼工作的時間有80% - 我的意思是它運行一次然後中斷。

我正在運行PHP版本5.4.4。

所以我的問題是。這是預期的行爲?如果是,我錯過了什麼。如果不是,那麼令人擔憂,因爲我在幾個WordPress插件中看到了這一點。

請注意:我能得到它的工作與其他包裝每一次,但這是更多的代碼...:

<?php 
if(class_exists('SomeClass')) return; 
else { 
    class SomeClass { 
     var $someVar = "test"; 
    } 
} 
+0

這個問題最好用自動加載來解決,所以除非你事先給出具體的限制(並解釋爲什麼它們不能被解除),否則建議替代方法沒有任何意義。 – Jon

+0

感謝Jon - 您的正確自動加載可以繞過這個問題,但對這種預期行爲更感興趣,尤其是當其他衆所周知的插件使用它時。 [Wordpres Github插件更新程序](https://github.com/jkudish/WordPress-GitHub-Plugin-Updater/blob/master/updater.php) – afxdesign

+0

這是預期的行爲,是的。再說一次,除非你在特定的限制條件下操作,否則做這種事情是沒有意義的。 – Jon

回答

2

我可以確認這與xcache編譯/安裝代碼的方式不同。 默認情況下,PHP在編譯期間安裝類,然後刪除類代碼,以便在執行時不會再次安裝類代碼。這被稱爲早期綁定。在此過程中,第二個類的安裝將失敗,因爲「類存在」並且代碼將保持不變以供執行。

一旦執行,PHP將有第二次安裝任何剩餘的類與代碼相同的順序,這就是所謂的後期綁定。在執行過程中沒有達到的任何類(如debug2)都未安裝,因此不會導致錯誤。這提供了一定程度的靈活性,允許在聲明之前實例化類的不良實踐。或者在這種情況下,通過檢查類是否存在而避免重複包括,而不是更加勤勉地使用自己的包含或通過使用自動載入使您的生活更輕鬆。

雖然PHP允許這種做法xcache已經證實,他們只執行早期綁定,這反過來又強制類重新聲明錯誤。(請參閱:http://xcache.lighttpd.net/ticket/314

由於xcache在現場環境中使用很多,我建議不要使用return語句而不使用else語句。然而,正如喬恩所說,自動加載是一種方式,否則將其包裝在一個else語句中。

該視頻顯示了XCache和PHP之間的矛盾:http://www.youtube.com/watch?v=VcNLoDvRLDc

附: Jon的答案與PHP解析頁面的方式是一致的,但是我已經創建了這個更詳細的答案,因爲xcache也對結果產生了影響。

+0

你應該接受這個答案,因爲它是結果,並且很好地解釋了你所遇到的問題。 ^^ – Jon

0

類結構可以在文檔的任何地方被定義,然後在其他地方使用。這就是爲什麼你可以在頁面末尾聲明類,並在開始時使用它們。這不是一個建議的做法,但確實有效。這是由於PHP解析頁面的原因。如果您將類聲明包裝在if/else語句中,那麼只有在滿足條件(或之前未滿足)時纔會執行該聲明 - 因此您會否定嘗試重新聲明現有類的錯誤。

+0

只是爲了澄清你的答案。在我的示例代碼中,如果滿足if條件,if語句中的任何內容都將不會達到 - 與它是否包含在其他內容中無關。但是,在此之前,PHP正在解析整個文件,因此即使該類不會被滿足,也會觸發類重新聲明錯誤。爲什麼你認爲PHP在使用空格時有時會成功執行此操作? – afxdesign

+0

取決於您對空白處理的操作。這可能是因爲它沒有被正確解析(當你這樣做時它會崩潰)。但是,如果沒有看到你如何使用_just_修改空格,我不能確定給你一個體面的答案。 – Jon

+0

嗨喬恩 - 我已經上傳了一個小視頻,應該清楚地表明我正在經歷什麼。由於PHP處理這個問題的零星特性,我不確信你的答案。 – afxdesign

相關問題