web-dev-qa-db-fra.com

Instanciation de classe par chaîne en utilisant PHP 5.3 espaces de noms

Je ne peux pas contourner un problème instanciant une nouvelle classe en utilisant une variable de chaîne et PHP 5.3. Namespaces. Par exemple, cela fonctionne;

$class = 'Reflection';
$object = new $class();

Cependant, ce n'est pas le cas;

$class = '\Application\Log\MyClass';
$object = new $class();

Une erreur fatale est levée indiquant que la classe est introuvable. Cependant, il peut évidemment être instancié si vous utilisez le FQN, c'est-à-dire;

$object = new \Application\Log\MyClass;

J'ai trouvé que c'était un partenaire sur PHP 5.3.2-1 mais pas dans les versions ultérieures. Y a-t-il un moyen de contourner cela?

36
Kevin
$class = 'Application\Log\MyClass';
$object = new $class();

Le départ \ introduit un identifiant d'espacement de noms (complet), mais il ne fait pas partie du nom de classe lui-même.

68
Artefacto

Une autre façon d'obtenir le même résultat mais avec des arguments dynamiques est la suivante. Veuillez considérer la classe ci-dessous comme la classe que vous souhaitez instancier.

<?php

// test.php

namespace Acme\Bundle\MyBundle;

class Test {
    public function __construct($arg1, $arg2) {
        var_dump(
            $arg1,
            $arg2
        );
    }
}

Puis:

<?php

require_once('test.php');

(new ReflectionClass('Acme\Bundle\MyBundle\Test'))->newInstanceArgs(['one', 'two']);

Si vous n'utilisez pas une version récente de PHP, veuillez utiliser le code suivant qui remplace la dernière ligne de l'exemple ci-dessus:

$r = new ReflectionClass('Acme\Bundle\MyBundle\Test');
$r->newInstanceArgs(array('one', 'two'));

Le code produira la sortie suivante:

string(3) "one"
string(3) "two"
5
Francesco Casula

J'ai eu le même problème et j'ai trouvé un moyen de contourner ce problème. Probablement pas très efficace, mais au moins fonctionne.

function getController($controller)
{
    return new $controller;
}

$object = getController('Application\Log\MyClass');
0
Przemek Kro