2010-04-09 49 views
8

所以,如果你嘗試做一個嵌套類是這樣的:PHP嵌套類工作...排序?

//nestedtest.php 

class nestedTest{ 
    function test(){ 
     class E extends Exception{} 
     throw new E; 
    } 
} 

你會得到一個錯誤Fatal error: Class declarations may not be nested in [...]

,但如果你有一個類在一個單獨的文件,像這樣:

//nestedtest2.php 

class nestedTest2{ 
    function test(){ 
     include('e.php'); 
     throw new E; 
    } 
} 

//e.php 
class E Extends Exception{} 

那麼,爲什麼做這件事的第二種方法很有效,但這種做法並不行之有效?

回答

18

從手冊(http://php.net/manual/en/function.include.php):

當包括一個文件,它 包含代碼繼承線的可變範圍 在其上包括 發生。 在調用文件中可用的任何變量將爲 ,該值來自 指向的文件。 但是, 包含文件中定義的所有 函數和類都具有全局範圍。

+1

+1不知道那 – soulmerge 2010-04-09 15:01:54

+0

因此,他們有一個全球範圍,我可以打電話給所有的私人和受保護的職能,該類擁有... – SeanJA 2010-04-09 15:09:59

+0

@ SeanJA:因爲他們有全球範圍,你將不能夠調用那些包含include() – 2010-04-09 15:53:47

1

第二種方法不是嵌套類。你只需要將你的兩個聲明放在一個文件中,這與你的第一個例子不同。在PHP中,您可以在一個文件中有多個類聲明,這是組織決策而非需求。

+1

儘管如此,他還是有一個觀點:他將代碼包含在函數中。 – 2010-04-09 14:55:53

+1

@Pekka這是因爲如何包含作品:*包含文件時,其包含的代碼繼承包含所在行的變量範圍。從調用文件的那一行可用的任何變量將在被調用的文件中可用,從這一點開始。但是,包含文件中定義的所有函數和類都具有全局範圍。*請參見http://de3.php.net/manual/en/function.include.php – Gordon 2010-04-09 15:01:07

+1

無關緊要,因爲它們位於同一個文件中。他可以將Exception類放入另一個文件幷包含它或使用__autoload來獲得相同的效果。 – 2010-04-09 15:01:18

1

在方法中定義類沒有什麼好的理由。第二種方法「起作用」的意義在於它不會拋出錯誤 - 該類仍然存在於與其他所有定義的類相同的作用域/名稱空間中。所以,在這種情況下,你實際上並不是「嵌套」一個班級。

順便說一句,它的工作原因是因爲一個類只是一個定義 - 沒有涉及定義類的執行。因此,只要包含該文件(e.php),就會對其進行解析,然後其類將變爲可用於當前的執行上下文。只有代碼的可執行部分(即throw new E;)實際上屬於調用者的範圍。

+0

這實際上是因爲我擔心第二種方式行不通,因爲第一種方式不行......當它發生時,我有點困惑。 – SeanJA 2010-04-09 15:18:54