为什么我会收到 PHP 致命错误:未捕获的错误:找不到类“MyClass”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39989977/
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 02:04:08  来源:igfitidea点击:

Why am I getting PHP Fatal error: Uncaught Error: Class 'MyClass' not found?

phpoopdependency-injectionnamespacesautoloader

提问by Jeff Puckett

This works:

这有效:

class MyClass {
    public $prop = 'hi';
}

class Container {
    static protected $registry = [];
    public static function get($key){
        if(!array_key_exists($key, static::$registry)){
            static::$registry[$key] = new $key;
        }
        return static::$registry[$key];
    }
}

$obj = Container::get('MyClass');
echo $obj->prop;

hi

你好

But when I try to break it out into individual files, I get an error.

但是当我尝试将其分解为单个文件时,出现错误。

PHP Fatal error: Uncaught Error: Class 'MyClass' not found in /nstest/src/Container.php:9

PHP 致命错误:未捕获的错误:在 /nstest/src/Container.php:9 中找不到类“MyClass”

This is line 9:

这是第 9 行:

static::$registry[$key] = new $key;

What's crazy is that I can hard code it, and it works, so I know the namespace is correct.

疯狂的是,我可以对其进行硬编码,并且它可以工作,所以我知道命名空间是正确的。

static::$registry[$key] = new MyClass;

hi

你好

Obviously I don't want to hard code it because I need dynamic values. I've also tried:

显然我不想硬编码它,因为我需要动态值。我也试过:

$key = $key::class;
static::$registry[$key] = new $key;

But that gives me this error:

但这给了我这个错误:

PHP Fatal error: Dynamic class names are not allowed in compile-time ::class fetch

PHP 致命错误:编译时不允许动态类名::class fetch

I'm at a loss. Clone these files to reproduce:

我不知所措。克隆这些文件以重现

.
├── composer.json
├── main.php
├── src
│?? ├── Container.php
│?? └── MyClass.php
├── vendor
│?? └── ...
└── works.php

Don't forget the autoloader.

不要忘记自动加载器。

composer dumpautoload

composer.json

作曲家.json

{
    "autoload": {
        "psr-4": {
            "scratchers\nstest\": "src/"
        }
    }
}

main.php

主文件

require __DIR__.'/vendor/autoload.php';
use scratchers\nstest\Container;

$obj = Container::get('MyClass');
echo $obj->prop;

src/Container.php

src/Container.php

namespace scratchers\nstest;

class Container {
    static protected $registry = [];
    public static function get($key){
        if(!array_key_exists($key, static::$registry)){
            static::$registry[$key] = new $key;
        }
        return static::$registry[$key];
    }
}

src/MyClass.php

源代码/MyClass.php

namespace scratchers\nstest;

class MyClass {
    public $prop = 'hi';
}

回答by Jeff Puckett

Thanks to @tkausl, I was able to get around dynamic relative namespacing by passing the fully qualified name in as the variable.

感谢 @tkausl,我能够通过将完全限定的名称作为变量传递来绕过动态相对命名空间。

require __DIR__.'/vendor/autoload.php';
use scratchers\nstest\Container;
use scratchers\nstest\MyClass;

$obj = Container::get(MyClass::class);
echo $obj->prop;

hi

你好