Поэтому я создал эти два класса
//Quarter.php namespace Resources; class Quarter { ... } //Epoch.php namespace Resources; class Epoch { public static function initFromType($value, $type) { $class = "Quarter"; return new $class($value, $type); } }
Теперь это очень упрощенная версия обоих, но этого достаточно, чтобы проиллюстрировать мой вопрос. Классы, как они показаны здесь, не будут работать, поскольку он не найдет класс Quarter. Чтобы он работал, я мог бы изменить переменную $ class на
$class = "\Resources\Quarter";
Поэтому мой вопрос: зачем мне использовать пространство имен здесь, когда оба класса уже являются членами одного и того же пространства имен. Пространство имен требуется только тогда, когда я помещаю имя класса в переменную так:
public static function initFromType($value, $type) { return new Quarter($value, $type); }
будет работать без проблем. Почему это и есть какие-то потенциальные ловушки здесь, мне нужно избегать?
Поскольку строки могут передаваться из одного пространства имен в другое. Это делает разрешение имен неоднозначным в лучшем случае и легко вводит странные проблемы.
namespace Foo; $class = 'Baz'; namespace Bar; new $class; // what class will be instantiated?
Литерал в определенном пространстве имен не имеет этой проблемы:
namespace Foo; new Baz; // can't be moved, it's unequivocally \Foo\Baz
Поэтому все «имена классов строк» всегда являются абсолютными и должны быть записаны как FQN:
$class = 'Foo\Baz';
(Примечание: нет ведущих \
.)
Вы можете использовать это как стенографию, эквивалентную самореферентному self
в классах:
$class = __NAMESPACE__ . '\Baz';