Importation de classes et espaces de noms en PHP: Quelle différence fait l'un des principaux backslash faire?

StackOverflow https://stackoverflow.com/questions/4849279

Question

Quelle est la différence entre les deux:

use Exception;
use \Exception;

Ou ceux-ci:

use Foo\Bar;
use \Foo\Bar;

Le manuel dit:

Notez que pour les noms avec (entièrement espaces de noms qualifiés contenant séparateur d'espace de noms, tels que Foo \ Bar par opposition aux noms globaux qui font non, comme FooBar), le leader backslash est inutile et non a permis, en tant que noms d'importation doivent être pleinement qualifié, et ne sont pas traités par rapport à l'espace de noms courant.

Mais je ne comprends pas vraiment cela, comme toutes les variantes ci-dessus travail, à savoir qu'il est certainement pas « non autorisé ».

Un regard sur zend_do_use a montré que is_global (set, quand il y a une barre oblique inverse de premier plan) est utilisé uniquement pour un avertissement dans le cas suivant:

namespace {
    use Exception;
}

Ce qui me dit: « La déclaration d'utilisation avec le nom non-composé « Exception » n'a pas d'effet ». (Bien que faire la même chose avec use \Exception aurait tout aussi peu d'effet, mais ne jette pas un avertissement.)

: Am quelque chose que je manque? Y at-il vraiment une différence?

Était-ce utile?

La solution

Le manuel spécifie la barre oblique inverse comme inutiles , qui naturellement signifie que si vous utilisez encore que le sens est équivalent. Cependant, comme vous avez en pointe, le manuel dit qu'il est soi-disant pas permis, ce qui est faux.

Cependant, il y a quelque chose de troublant d'autre avec le manuel. Ils annoncent ceci:

// importing a global class
use \ArrayObject;

S'il est vrai que les noms d'importation ne sont pas traitées par rapport à l'espace de noms en cours, puis use \ArrayObject et use ArrayObject doivent avoir le même sens. Ce qui pourrait se référer à autre use ArrayObject autre que celui global? Dans la pratique, le moteur importera le global.

En outre, avec des bugs tels que celui-ci: http://bugs.php.net/bug.php?id=49143

Je crois qu'il ya confusion sur ce que la norme est censé être.

Pour répondre à votre question: il n'y a pas de différence. Cependant, si j'étais le développeur du moteur qui était aussi un croyant de la norme sans avant-slash, alors je pas besoin d'examiner un cas où quelqu'un a écrit use \Exception;. Je crois que ce fut probablement le cas.

Autres conseils

En fait il n'y a pas de différence dans l'utilisation de leader dans l'importation backslash namespaces au moment et aussi des informations manuel PHP a changé:

Notez que pour les noms avec (noms d'espace de noms pleinement qualifiés contenant séparateur d'espace de noms, tels que Foo \ Bar, par opposition au niveau mondial Les noms qui ne sont pas, comme FooBar), le leader est backslash inutile et pas recommandé , en tant que noms d'importation doivent être pleinement qualifié, et ne sont pas traitées par rapport à l'espace de noms en cours.

Alors maintenant, il est vrai que l'utilisation des informations conduisant backslash n'est pas recommandé, mais il n'y a pas d'information qu'il n'a pas le droit à c'était dans le passé.

Donc pour le moment:

use Exception;
use \Exception;

ces 2 lignes fonctionnent de la même chose, mais vous devriez plutôt utiliser le premier.

Habituellement, les principaux définit barre oblique inverse, que l'identifiant est absolue. Si son manque, l'interprète suppose, qu'il est un identificateur relatif.

Ceci est un identificateur absolu:

$x = new \Name\Space\To\Class();

Ceci est un identificateur relatif, à cause de la barre oblique premier pas. Il est par rapport à l'espace de noms courant:

namespace Name\Space;
$x = new To\Class;

Ceci est également un identificateur relatif. Dans ce cas, sa résolu par le compte de use, parce que la dernière partie (alias) est le même, que la première de la classe:

namespace Other\Name\Space;
use Name\Space;
$x = new Space\To\Class;

Cependant, comme dans les déclarations de namespace et use seulement des identificateurs absolus (noms qualifiés) sont autorisés, il est autorisé à omettre ici. En namespace, il est même pas permis de mettre le premier backslash.

Pour plus informations sur la façon dont PHP résout les différentes déclarations d'espace de noms, voir namespace règles manuel.

le't dire que nous avons

namespace MyNamespace
use Exception;
use \Exception;

alors la première utilisation des importations classe MyNamespace fait \ Exception et la seconde juste la classe principale \ Exception

vous pouvez donc avoir quelque chose comme

namespace MyNamespace;
class Exception extends \Exception{ }

et alors je peux

throw new \Exception('Exception from global namespace');
throw new \MyNamespace\Exception('Exception from MyNamespace');

La barre oblique inverse signifie l'espace de noms leader mondial. Si vous êtes dans un champ d'application de l'espace de noms, vous devez l'utiliser pour atteindre l'espace de noms global. Par exemple:

namespace A
{
    class A
    {
        public function __construct()
        {
            echo('namespace: A<br />');
        }
    }
}

namespace B\A
{
    class A
    {
        public function __construct()
        {
            echo('namespace: B\\A<br />');
        }
    }
}

namespace B
{
    class B
    {
        public function __construct()
        {
            new \A\A(); // namespace: A
            new A\A(); // namespace: B\A
        }
    }
    new B();
}

Avec leader backslash vous avez le chemin absolu, et sans elle, vous avez le chemin relatif.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top