Подтвердить что ты не робот

Импорт классов и пространств имен в PHP: Какая разница делает лидирующую обратную косую черту?

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

use Exception;
use \Exception;

Или те:

use Foo\Bar;
use \Foo\Bar;

manual говорит:

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

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

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

namespace {
    use Exception;
}

Что говорит мне: "Инструкция использования с не-составным именем" Исключение "не имеет никакого эффекта". (Хотя делать то же самое с use \Exception было бы так же мало, но не предупреждало.)

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

4b9b3361

Ответ 1

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

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

// importing a global class
use \ArrayObject;

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

Кроме того, с ошибками, такими как: http://bugs.php.net/bug.php?id=49143

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

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

Ответ 2

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

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

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

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

use Exception;
use \Exception;

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

Ответ 3

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

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

$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 разрешает различные объявления пространств имен, см. руководство по правилам пространства имен.

Ответ 4

Скажем, мы имеем

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');

Ответ 5

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

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

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