Импорт классов и пространств имен в PHP: Какую разницу имеет начальная обратная косая черта? - PullRequest
43 голосов
/ 31 января 2011

В чем разница между этими двумя:

use Exception;
use \Exception;

Или теми:

use Foo\Bar;
use \Foo\Bar;

В руководстве написано:

Обратите внимание, что для имен с пространством имен (полностью определенных имен пространств имен, содержащих разделитель пространств имен, таких как Foo \ Bar, в отличие от глобальных имен, которые этого не делают, таких как FooBar), начальная обратная косая черта не нужна и недопустима, поскольку имена импорта должны быть полностью определеныи не обрабатываются относительно текущего пространства имен.

Но я не совсем понимаю это, так как все вышеперечисленные варианты работают, то есть он определенно не "не разрешен".

Изучение zend_do_use показало, что is_global (устанавливается при наличии обратной косой черты) используется только для предупреждения в следующем случае:

namespace {
    use Exception;
}

, который говорит мне: "Theоператор use с не составным именем «Exception» не имеет никакого эффекта ».(Хотя то же самое с use \Exception будет иметь такой же небольшой эффект, но не выдаст предупреждение.)

Итак: я что-то упустил?Есть ли какая-то разница?

Ответы [ 5 ]

33 голосов
/ 02 февраля 2011

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

Однако, есть еще кое-что, что беспокоит руководство. Они рекламируют это:

// importing a global class
use \ArrayObject;

Если верно, что имена импорта не обрабатываются относительно текущего пространства имен, тогда use \ArrayObject и use ArrayObject должны иметь одинаковое значение. На что еще может ссылаться use ArrayObject, кроме глобального? На практике движок будет импортировать глобальный.

Также с такими ошибками: http://bugs.php.net/bug.php?id=49143

Я полагаю, что существует путаница в отношении того, каким должен быть стандарт.

Чтобы ответить на ваш вопрос: разницы нет. Однако, если бы я был разработчиком движка, который также был сторонником стандарта «не ведущий слэш», то мне не пришлось бы рассматривать случай, когда кто-то писал use \Exception;. Я полагаю, что так и было.

12 голосов
/ 07 июля 2014

На самом деле в настоящее время нет никакой разницы в использовании обратной косой черты при импорте пространств имен, а также изменилась информация в руководстве по PHP :

Обратите внимание, что для имен с пространством имен (полные имена пространств имен содержащий разделитель пространства имен, такой как Foo \ Bar, а не глобальный имена, которые не, такие как FooBar), ведущая обратная косая черта не нужно и не рекомендуется , так как имена импорта должны быть полностью квалифицированы и не обрабатываются относительно текущего пространства имен.

Так что теперь есть достоверная информация о том, что использование начального обратного слеша не рекомендуется, но нет информации о том, что в прошлом это было запрещено.

Итак, на данный момент:

use Exception;
use \Exception;

эти две строки работают одинаково, но вам лучше использовать первую.

5 голосов
/ 02 февраля 2011

Обычно ведущий обратный слеш определяет, что идентификатор является абсолютным. Если он отсутствует, интерпретатор предполагает, что это относительный идентификатор.

Это абсолютный идентификатор:

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

Это относительный идентификатор из-за отсутствия начального слеша. Относительно текущего пространства имен:

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

Это также относительный идентификатор. В этом случае он разрешается в операторе use, поскольку последняя часть (псевдоним) такая же, как и в первом классе:

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

Однако, поскольку в операторах namespace и use разрешены только абсолютные идентификаторы (полные имена), здесь можно его опустить. В namespace даже запрещено устанавливать начальную обратную косую черту.

Для получения дополнительной информации о том, как PHP разрешает различные объявления пространства имен, см. Руководство по правилам пространства имен .

0 голосов
/ 08 февраля 2011

Обратная косая черта означает глобальное пространство имен. Если вы находитесь в области имен, вы должны использовать это для достижения глобального пространства имен. Например:

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();
}

С обратной косой чертой вы получаете абсолютный путь, а без него - относительный путь.

0 голосов
/ 31 января 2011

не говорите, что у нас есть

namespace MyNamespace
use Exception;
use \Exception;

тогда первое использование фактически импортирует класс MyNamespace \ Exception, а второе только основной класс \ Exception

так что вы можете иметь что-то вроде

namespace MyNamespace;
class Exception extends \Exception{ }

и тогда я смогу

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