2016-10-12 2 views
3

Это работает:Почему я получаю 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; 

hi

Но когда я пытаюсь разбить его на отдельные файлы, я получаю сообщение об ошибке.

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

Это строка 9:

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

Что с ума, что я могу жестко закодировать его, и он работает, так что я знаю, что пространство имен является правильным.

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

hi

Очевидно, что я не хочу жесткий код, потому что мне нужны динамические значения. Я также попытался:

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

Но это дает мне эту ошибку:

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

Я в недоумении. Clone these files to reproduce:

. 
├── 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'; 
} 
+0

'нового ClassName' ищет класс относительно текущего пространства имен,' нового $ classname' не делает. – tkausl

+0

@tkausl hmm, что имеет смысл, так что же такое решение? –

+0

Используйте полное имя класса в вашей переменной (например, '\ scratchers \ nstest \ MyClass') или лучше' MyClass :: class' (который дает полное имя класса) – tkausl

ответ

4

Thanks to @tkausl, мне удалось обойти динамическое относительное пространство имен путем передачи полного имени в качестве переменной.

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

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

hi

+0

Кроме того, убедитесь, что ваш капитал использования или небольшие буквы имеют значение. – prosti

+0

@prosti фактически имена классов не чувствительны к регистру в php https://stackoverflow.com/a/33273959/4233593 –

Смежные вопросы