web-dev-qa-db-ja.com

なぜPHP致命的なエラー:キャッチされないエラー:クラス 'MyClass'が見つかりませんか?

これは動作します:

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;

こんにちは

しかし、個々のファイルに分割しようとすると、エラーが発生します。

PHP致命的エラー:キャッチされないエラー:/nstest/src/Container.php:9にクラス 'MyClass'が見つかりません

これは9行目です。

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

クレイジーなのは、それをハードコーディングできることです。そして、それが機能するので、名前空間が正しいことを知っています。

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

こんにちは

動的な値が必要なので、明らかにハードコーディングしたくありません。私も試しました:

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

しかし、それは私にこのエラーを与えます:

PHP致命的エラー:コンパイル時:: class fetchでは動的クラス名は許可されません

私は迷っています。 これらのファイルを複製して複製

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

オートローダーを忘れないでください。

composer dumpautoload

composer.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

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

namespace scratchers\nstest;

class MyClass {
    public $prop = 'hi';
}
6
Jeff Puckett

@ tkauslのおかげ 、完全修飾名を変数として渡すことで、動的な相対名前空間を回避することができました。

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

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

こんにちは

10
Jeff Puckett