找不到带有PHP命名空间的Class

时间:2011-12-22 23:10:07

标签: php namespaces

我之前发过一些关于在PHP中使用命名空间的问题,以及我得到的,我在下面的示例代码应该正常工作。

但是当我尝试在PHP中使用Namespace时,我遇到了错误。以下是运行下面的代码时出现的第一个错误...

Fatal error: Class 'Controller' not found in E:\Controllers\testing.php on line 6

E:\ Controller \ testing.php文件

<?php
use \Controller;

include('testcontroller.php');

$controller = new Controller;
$controller->show();
?>

E:\ Controller \ testcontroller.php文件

<?php
use \Library\Registry;

namespace Controller
{
    class Controller
    {
        public $registry;

        function __construct()
        {
            include('E:\Library\Registry.class.php');
            $this->registry = new Registry;
        }

        function show()
        {
            echo $this->registry;
            echo '<br>Registry was ran inside testcontroller.php<br>';
        }
    }
}
?>

E:\ Library \ Registry.class.php文件

<?php
namespace Library\Registry
{
    class Registry
    {
        function __construct()
        {
            return 'Registry.class.php Constructor was ran';
        }
    }
}
?>

正如您所看到的,我试图让它变得尽可能简单,只是为了让Namespace部分工作。我尝试了不同的变化,似乎无法弄明白。

5 个答案:

答案 0 :(得分:33)

即使使用use语句,您也需要指定要尝试实例化的类的命名空间。这里有很多例子:http://www.php.net/manual/en/language.namespaces.importing.php

为了更好地理解它,我将向您描述它是如何工作的。在您的情况下,执行use \Controller时,您可以使用整个Controller命名空间,但不能使用此命名空间中的类。所以,例如:

<?php
include('testcontroller.php');

use \Controller;

// Desired class is in namespace!
$controller = new Controller\Controller();

// Error, because in current scope there is no such class
$controller = new Controller();

$controller->show();
?>

另一个例子:

testcontoller.php:

<?php
namespace Some\Path\To\Controller;

class Controller
{
    function __construct()
    {

    }

    function show()
    {
        echo '<br>Was run inside testcontroller.php<br>';
    }
}
?>

testing.php:

<?php
include('testcontroller.php');

use \Some\Path\To\Controller;

// We now can access Controller using only Controller namespace,
// not Some\Path\To\Controller
$controller = new Controller\Controller();

// Error, because, again, in current scope there is no such class
$controller = new Controller();

$controller->show();
?>

如果您希望完全导入Controller ,则需要执行use Controller\Controller - 然后可以在当前范围内访问此类。

答案 1 :(得分:8)

命名命名空间并不是一个好主意,比如类,因为它令人困惑(我认为这就是这里发生的事情)。您可以通过use Controller定义别名,这可以引用类\Controller或命名空间\Controller,但是您的类因为它位于命名空间内而被命名为{{1} } 1

\Controller\Controller

use Controller;
$class = new Controller\Controller;

$class = new \Controller\Controller;

我们的想法是,当您尝试使用其相对名称访问某个类时,它会尝试映射&#34;第一部分&#34;针对使用use Controller\Controller; $class = new Controller; 定义的任何别名(记住useuse MyClass相同。use MyClass as MyClass之后的内容是别名)。

as

正如您所看到的,PHP找到namespace MyNamespace\MyPackage\SomeComponent\And\So\On { class MyClass {} } namespace Another { use MyNamespace\MyPackage\SomeComponent; // as SomeComponent $class = new SomeComponent\An\So\On\MyClass; } 作为第一部分并将其映射到SomeComponent - 别名上面的行。

您可以在manual about namespaces中了解更多相关信息。

1如果你用一个完整的名字来命名一个类,那就叫它&#34;完全限定的类名&#34;

答案 2 :(得分:5)

当您将一个类Controller放入名称空间Controller时,您必须以这种方式引用它:

$controller = new Controller\Controller();

\Controller将是全局(默认)命名空间中的一个类,即好像根本没有使用任何命名空间。

答案 3 :(得分:2)

奇怪的是,我发现在上面问题的示例代码中,如果我将所有定义为Namespace's的{​​{1}}更改为MyLibrary,那么它就像下面的代码... < / p>

E:\ Library \ Registry.class.php文件

<?php
namespace MyLibrary
{
    class Registry
    {
        function __construct()
        {
            echo 'Registry.class.php Constructor was ran';
        }
    }
}
?>

然后当我在另一个文件中使用use MyLibrary\Registry;时,我能够按照我的计划来访问它...

$this->registry = new Registry;

这对我来说很奇怪的原因是现在这个类名也显示为Namespace。所以我不需要将命名空间设置为“MyLibrary \ Library&#39;访问Registry而不是像我在这个答案中所展示的那样只需要调用类的名称就可以访问它。

我希望这有意义并帮助别人。我不会接受这个作为答案,因为我希望有更多技术诀窍的人进来并发布一个更好的答案和解释

答案 4 :(得分:0)

<?php
use \Library\Registry;

namespace Controller;
class Controller
{
    public $registry;
    function __construct()
    {
        include('E:\Library\Registry.class.php');
        $this->registry = new Registry;
    }
    function show()
    {
        echo $this->registry;
        echo '<br>Registry was ran inside testcontroller.php<br>';
    }
}
?>

<?php
namespace Library\Registry;
class Registry
{
    function __construct()
    {
        return 'Registry.class.php Constructor was ran';
    }
}
?>