Импорт классов и пространств имен в 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
было бы так же мало, но не предупреждало.)
Итак: я что-то упустил? Есть ли какая-то разница?
Ответы
Ответ 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();
}
С ведущей обратной косой чертой вы получите абсолютный путь, и без него вы получите относительный путь.