Ответ 1
Удивительно, но никто не упомянул очевидную причину, по которой это можно было бы сделать: ключевое слово use
может использоваться только в самой внешней области и обрабатывается во время компиляции, поэтому вы не можете use Some\Class
на основе некоторых условие, а также не может быть блочным:
namespace Foo;
if (!extension_loaded('gd'))
{
use Images\MagicImage as Image;
}
else
{
use Images\GdImage as Image;
}
class ImageRenderer
{
public function __construct(Image $img)
{}
}
Это не сработает: хотя операторы use
находятся в самой верхней области видимости, эти импорты, как я уже говорил, выполняются во время компиляции, а не во время выполнения. В результате этот код ведет себя так, как если бы он был написан так:
namespace Foo;
use Images\GdImage as Image;
use Images\MagicImage as Image;
Что приведет к ошибке (2 класса с тем же псевдонимом...) class_alias
однако, являясь функцией, которая вызывается во время выполнения, поэтому она может быть заблокирована блоком и может использоваться для условного импорта:
namespace Foo;
if (!extension_loaded('gd'))
{
class_alias('Images\\MagicImage', 'Image');
}
else
{
class_alias('Images\\GdImage','Image');
}
class ImageRenderer
{
public function __construct(Image $img)
{}
}
Кроме того, я подозреваю, что основным преимуществом class_alias
является то, что весь написанный код до PHP 5.3 (который вводил пространства имен) позволял вам не писать такие вещи, как:
$foo = new My_Lib_With_Pseudo_Name_Spaces_Class();
Вместо того, чтобы рефакторировать всю базу кода и создать пространства имен, просто добавить несколько папок:
class_alias('My_Lib_With_Pseudo_Name_Spaces_Class', 'MyClass');
В начало script, а также некоторые комментарии //TODO: switch to Namespaces
.
Другим вариантом использования может быть передача этих классов в их сопоставленные именами: просто измените вызовы class_alias
после рефакторинга класса, остальные классы могут остаться нетронутыми.
Когда вы реорганизуете свой код, скорее всего, вам захочется переосмыслить пару вещей, поэтому предложенный вариант использования, например, предложенный aichingm, может быть не слишком завышенным.
Последнее, что я могу придумать, но я еще не видел этого, это когда вы хотите протестировать некоторый код с помощью макетного объекта, вы можете использовать class_alias
, чтобы все работало плавно. Однако, если вам нужно это сделать, вы можете также рассмотреть тест на провал, потому что это свидетельствует о плохо написанном коде, IMO.
Кстати, только сегодня я наткнулся на другой прецедент для class_alias
. Я работал над тем, чтобы реализовать lib, перегоняемый из инструмента CLI для использования в веб-приложении на основе MVC. Некоторые из классов зависели от экземпляра вызываемой команды, которая должна быть передана, из которой они получили некоторые другие бит и болты.
Вместо того, чтобы решить проблему рефакторинга, я решил заменить:
use Application\Commands\SomeCommand as Invoker;
Заявления с:
if (\PHP_SAPI === 'cli')
{
class_alias('\\Application\\Commands\\SomeCommand', 'Invoker');
}
else
{
class_alias('\\Web\\Models\\Services\\SomeService', 'Invoker');
}
и, после быстрого :%s/SomeCommand/Invoker/g
в vim, мне было хорошо идти (более или менее)