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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8610729/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 05:04:55  来源:igfitidea点击:

Cannot find Class with PHP Namespace

phpnamespaces

提问by JasonDavis

I posted some questions previously regarding the use of Namespaces in PHP and from what I got, this example code I have below should be working.

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

However I am getting errors when I try to use Namespace in PHP like this. Here is the first error when running the code below as is...

但是,当我尝试像这样在 PHP 中使用 Namespace 时出现错误。这是按原样运行以下代码时的第一个错误...

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

E:\Controller\testing.php File

E:\Controller\testing.php 文件

<?php
use \Controller;

include('testcontroller.php');

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

E:\Controller\testcontroller.php File

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 File

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

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

As you can see I tried to make it as simple as possible just to get the Namespace part working. I have tried different variations and cannot seem to figure it out.

正如你所看到的,我试图让它尽可能简单,只是为了让 Namespace 部分工作。我尝试了不同的变体,但似乎无法弄清楚。

回答by Timur

Even when using usestatement, you need to specify the namespace of the class you are trying to instantiate. There are a lot of examples here: http://www.php.net/manual/en/language.namespaces.importing.php

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

To understand it better, I will describe to you how it works. In your case, when you do use \Controller, the whole Controllernamespace becomes available to you, but not the classes that are in this namespace. So, for example:

为了更好地理解它,我将向您描述它是如何工作的。在你的情况下,当你这样做时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();
?>

Another example:

另一个例子:

testcontoller.php:

测试控制器.php:

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

class Controller
{
    function __construct()
    {

    }

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

testing.php:

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

If you wish to import exactly the Controllerclass, you need to do use Controller\Controller- then this class will be accessible in your current scope.

如果您希望准确地导入Controllerclass,则需要这样做use Controller\Controller- 然后可以在您当前的范围内访问该类。

回答by KingCrunch

Its not that good idea to name the namespace, like the class, because it is confusing (and I think this is what happens here). There moment you define the alias via use Controllerthis referenes to either a class \Controller, or the namespace \Controller, but your class, because it is within the namespace, is named \Controller\Controller1

像类一样命名命名空间并不是一个好主意,因为它令人困惑(我认为这就是这里发生的事情)。在那一刻,您通过use Controller此引用将别名定义为 class\Controller或 namespace \Controller,但是您的类,因为它在命名空间内,被命名为\Controller\Controller1

use Controller;
$class = new Controller\Controller;

or

或者

$class = new \Controller\Controller;

or

或者

use Controller\Controller;
$class = new Controller;

The idea is, that the moment you try to access a class with its relative name it tries to map the "first part" against any alias defined using use(remeber use MyClassis the same as use MyClass as MyClass. The thing after asis the alias).

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

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

As you can see PHP finds SomeComponentas the first part and maps it against the SomeComponent-alias the line above.

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

You can read more about it in the manual about namespaces.

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

1Its called "Full-qualified classname", if you name a class with its complete name.

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

回答by Dan Soap

When you put a class Controllerin the namespace Controller, then you have to reference it that way:

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

$controller = new Controller\Controller();

\Controllerwould be a class in the global (default) namespace, i.e. as if you used no namespace at all.

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

回答by JasonDavis

Strangely I have found that in my example code from the Question above, if I change all the Namespace'sthat are defined to something like MyLibraryso it would be like this code below...

奇怪的是,我发现在我上面问题的示例代码中,如果我将所有Namespace's定义的更改为类似的内容MyLibrary,它就会像下面的代码一样......

E:\Library\Registry.class.php File

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

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

Then when I use use MyLibrary\Registry;in another file, I am able to access it how I had planned...

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

$this->registry = new Registry;

The reason this is very strange to me is this now makes a class name appear to be a Namespaceas well. So I would not need to set a Namespace to 'MyLibrary\Library' to access the Registryinstead I would do it like I showed in this answer to be able to access it with just calling the name of the class.

这对我来说很奇怪的原因是这现在使类名看起来也是 a Namespace。因此,我不需要将命名空间设置为 'MyLibrary\Library' 来访问它,Registry而是像我在此答案中显示的那样进行操作,只需调用类的名称即可访问它。

I hope this makes sense and helps someone else. I will not accept this as the answer as I am hoping someone with more know-how will come in and post a better Answer with explanation

我希望这是有道理的,并帮助别人。我不会接受这个作为答案,因为我希望有更多专业知识的人进来并发布更好的答案和解释

回答by Ascherer

try

尝试

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

and

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