在我的命名空间中实例化一个PHP stdClass - 致命错误

时间:2014-10-10 19:23:41

标签: php namespaces

我想为现有的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的类,这在某种程度上突然变得有意义。

如果有人能详细说明这里发生的事情,我会非常高兴。

3 个答案:

答案 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的“类引用”部分中的注释。

http://php.net/manual/en/language.namespaces.rules.php