web-dev-qa-db-fra.com

Comment vérifier si la classe existe dans un espace de noms?

J'ai ça:

    use XXX\Driver\Driver;

...

var_dump(class_exists('Driver')); // false
        $driver = new Driver(); // prints 123123123 since I put an echo in the constructor of this class
        exit;

Eh bien ... ce comportement est assez irrationnel (créer des objets de classes correspondant à PHP n'existe pas). Existe-t-il un moyen de vérifier si une classe existe sous un espace de noms donné?

60
Taruo Gene

Afin de vérifier la classe, vous devez le spécifier avec un espace de noms, chemin complet:

namespace Foo;
class Bar
{
}

et

var_dump(class_exists('Bar'), class_exists('\Foo\Bar')); //false, true

-c'est à dire. vous devez spécifier le chemin complet de la classe. Vous l'avez défini dans votre espace de noms et non dans un contexte global.

Toutefois, si vous importez la classe dans l’espace de noms comme vous le faites dans votre exemple, vous pouvez la référencer via un nom importé et sans espace de noms, mais cela ne vous permet pas de le faire dans des constructions dynamiques et en particulier dans des chaînes en ligne qui nom de classe de formulaires. Par exemple, tout ce qui suit va échouer:

namespace Foo;
class Bar {
    public static function baz() {} 
}

use Foo\Bar;

var_dump(class_exists('Bar')); //false
var_dump(method_exists('Bar', 'baz')); //false

$ref = "Bar";
$obj = new $ref(); //fatal

etc. Le problème réside dans les mécanismes de travail pour les alias importés. Ainsi, lorsque vous travaillez avec de telles constructions, vous devez spécifier le chemin complet:

var_dump(class_exists('\Foo\Bar')); //true
var_dump(method_exists('\Foo\Bar', 'baz')); //true

$ref = 'Foo\Bar';
$obj = new $ref(); //ok
97
Alma Do

Le problème (comme mentionné dans les class_exists() notes d'utilisateur de la page de manuel) est que les alias ne sont pas pris en compte lorsqu'un nom de classe est donné sous forme de chaîne. Cela affecte également d'autres fonctions prenant un nom de classe, telles que is_a(). Par conséquent, si vous indiquez le nom de la classe dans une chaîne, vous devez inclure l’espace de nom complet (par exemple, '\XXX\Driver\Driver', 'XXX\\Driver\\Driver').

PHP 5.5 a introduit la constante class uniquement dans ce but:

use XXX\Driver\Driver;
...
if (class_exists(Driver::class)) {
    ...
}
27
outis