找不到具有 PHP 命名空间的类

2022-08-30 14:33:33

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

但是,当我尝试像这样在PHP中使用命名空间时,我遇到了错误。这是按原样运行以下代码时的第一个错误...

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

E:\控制器\测试.php文件

<?php
use \Controller;

include('testcontroller.php');

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

E:\Controller\testcontroller.php File

<?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:\库\注册表.class.php文件

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

如您所见,我试图使其尽可能简单,只是为了让命名空间部分正常工作。我尝试了不同的变体,似乎无法弄清楚。


答案 1

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

为了更好地理解它,我将向您描述它是如何工作的。在你的情况下,当你这样做时,整个命名空间变得可用,但不能用于此命名空间中的类。例如:use \ControllerController

<?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>';
    }
}
?>

测试.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();
?>

如果您希望完全导入该类,则需要这样做 - 那么该类将在您当前的作用域中可访问。Controlleruse Controller\Controller


答案 2

像类一样命名命名空间不是那么好主意,因为它令人困惑(我认为这就是这里发生的事情)。有一刻,您通过此定义别名会引用类或命名空间,但是您的类,因为它位于命名空间中,因此被命名为1use Controller\Controller\Controller\Controller\Controller

use Controller;
$class = new Controller\Controller;

$class = new \Controller\Controller;

use Controller\Controller;
$class = new Controller;

这个想法是,当您尝试访问具有相对名称的类时,它会尝试将“第一部分”映射到使用定义的任何别名(请记住与 相同)。后面的是别名)。useuse MyClassuse MyClass as MyClassas

namespace MyNamespace\MyPackage\SomeComponent\And\So\On {
  class MyClass {}
}
namespace Another {
  use MyNamespace\MyPackage\SomeComponent; // as SomeComponent
  $class =              new SomeComponent\An\So\On\MyClass;
}

如您所见,PHP 查找作为第一部分,并将其映射到上面行的 -alias。SomeComponentSomeComponent

您可以在有关命名空间的手册中阅读有关它的更多信息

1 它被称为“完全限定的类名”,如果你用它的全名命名一个类。


推荐