我想为现有的CMS编写一个小插件。为此,我需要从CMS的代码扩展一个类。
我的代码将写在自己的命名空间内,而CMS的代码不使用命名空间,这基本上意味着它存在于全局命名空间内。
在我的代码中,我创建了一个新的stdClass
:
$var = new stdClass();
如果该代码存在,它总是会产生致命错误:
Fatal error: Class 'MyNamespace\something\StdClass' not found in /some/rather/long/path/to/class.php on line 123
像这样创建stdClass
解决了这个问题:
$var = new \stdClass();
由于我仍然是命名空间的新手,我不确定这里的问题是什么?
我的猜测是,在第一个例子中,stdClass
将在我的类的命名空间中创建。这实际上意味着将调用我的名称空间中存在的名为stdClass
的类的构造函数,但由于该类不存在,因此会引发错误。
在第二个例子中,我发信号通知我想从全局命名空间中实例化名为stdClass
的类,这在某种程度上突然变得有意义。
如果有人能详细说明这里发生的事情,我会非常高兴。
答案 0 :(得分:4)
您似乎理解名称空间背后的概念,并且您正在朝着正在发生的事情的分析方向前进。
当您在命名空间内工作时,您可以将名称称为不合格,合格和完全限定。
当你创建命名空间时,你告诉PHP组织(和解决)你的类,函数,方法等的名称,远离内置PHP代码所在的同一范围以及其后面的任何其他代码。拥有名称空间它可以组织您的代码并避免命名库和内置PHP函数之间的冲突。
以下是关于如何解析名称的简要说明:
如果您尝试在同一命名空间中解析名称,则可以使用非限定名称。因此,对于课程\Foo\Bar\Baz
,只要您在命名空间new Baz();
中,就可以使用\Foo\Bar
。
如果您尝试解析同一父命名空间中较低的名称,则可以使用限定名称。因此,对于课程\Foo\Bar\Baz
,如果您在命名空间new Bar\Baz();
中,则需要使用\Foo
。
如果您尝试解析的名称不在您的命名空间中或位于全局命名空间(内置PHP内容)中,那么您必须使用完全限定名称。如果您在命名空间\Foo\Bar
中并且想要使用mysqli
类之类的东西,则需要通过其完全限定名称来调用它。例如new \mysqli()
上面的问题就是一个很好的例子来说明这一点。同样,如果您需要访问完全不同的名称空间中的类,您还需要完全限定的名称:new \Third\Party\AppClass();
总而言之,您是对的,您的命名空间中不存在内置stdClass
,因此您需要通过完全限定名称访问它。你必须以这种方式做事的原因与符合PHP解析名称时使用的规则有关。
如果您需要找出您所在的命名空间,它将位于__NAMESPACE__
常量。
如果您还没有阅读过,请参阅以下是PHP中名称解析的文档:http://php.net/manual/en/language.namespaces.rules.php
答案 1 :(得分:1)
代码在您的命名空间中进行评估,而stdClass并不存在。你的猜测是在回答你自己的问题。
答案 2 :(得分:1)
你的猜测是正确的。请查看此页面上示例#1的“类引用”部分中的注释。