web-dev-qa-db-fra.com

Pourquoi est-ce que j'obtiens PHP Erreur fatale: Erreur non interceptée: Classe 'MyClass' introuvable?

Cela marche:

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;

salut

Mais lorsque j'essaie de le décomposer en fichiers individuels, j'obtiens une erreur.

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

C'est la ligne 9:

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

Ce qui est fou, c'est que je peux le coder en dur, et cela fonctionne, donc je sais que l'espace de noms est correct.

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

salut

Évidemment, je ne veux pas le coder en dur car j'ai besoin de valeurs dynamiques. J'ai aussi essayé:

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

Mais cela me donne cette erreur:

Erreur fatale PHP: les noms de classe dynamiques ne sont pas autorisés dans la compilation-time :: class fetch

Je suis à perte. Clonez ces fichiers pour les reproduire :

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

N'oubliez pas l'autochargeur.

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

Merci à @tkausl , j'ai pu contourner l'espace de noms relatif dynamique en passant le nom complet en tant que variable.

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

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

salut

10
Jeff Puckett