2010-04-09 35 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