为什么要使用类alisases?

Dar*_*ill 20 php alias

我们为什么要使用这个class_alias功能?例如:

Class Test {
 public function __construct(){
   echo "Class initialized"; 
 }
}

class_alias("Test", "AnotherName"); 

$instance = new AnotherName();   # equivalent to $instance = new Test();
Run Code Online (Sandbox Code Playgroud)

根据手册,"别名类与原始类完全相同."

这对什么有用?

Eli*_*gem 34

令人惊讶的是,没有人提到为什么会这样做的明显原因: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)
    {}
}
Run Code Online (Sandbox Code Playgroud)

这不起作用:尽管use语句在最外层,但正如我之前所说,这些导入是在编译时执行的,而不是在运行时执行的.作为结果,这段代码表现得像是这样写的:

namespace Foo;
use Images\GdImage as Image;
use Images\MagicImage as Image;
Run Code Online (Sandbox Code Playgroud)

哪个会产生错误(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)
    {}
}
Run Code Online (Sandbox Code Playgroud)

除此之外,我怀疑主要的好处class_alias是在PHP 5.3(引入名称空间)之前编写的所有代码都允许你避免编写类似的东西:

$foo = new My_Lib_With_Pseudo_Name_Spaces_Class();
Run Code Online (Sandbox Code Playgroud)

而不是必须重构整个代码库并创建命名空间,添加几个更容易:

class_alias('My_Lib_With_Pseudo_Name_Spaces_Class', 'MyClass');
Run Code Online (Sandbox Code Playgroud)

在脚本的顶部,以及一些//TODO: switch to Namespaces注释.

另一个用例可能是在实际将这些类转移到它们的命名空间对应物时:只需class_alias在重构一个类后更改调用,其他类可以保持不变.
在重构代码时,你很可能想要重新考虑一些事情,所以像aichingm建议的用例可能不会太过分.

我能想到的最后一件事,但我还没有看到这个,当你想用模拟对象测试一些代码时,你可能会使用class_alias一切顺利运行.但是,如果你必须这样做,你可能还会考虑测试失败,因为这表明编写错误的代码,即IMO.

很明显,就在今天,我遇到了另一个用例class_alias.我正在研究一种实现lib的方法,这种方法是从CLI工具中提炼出来的,用于基于MVC的web-app.一些类依赖于要传递的被调用命令的实例,从中获得了一些其他的位和螺栓.
我没有经历重构的麻烦,而是决定更换:

use Application\Commands\SomeCommand as Invoker;
Run Code Online (Sandbox Code Playgroud)

声明:

if (\PHP_SAPI === 'cli')
{
    class_alias('\\Application\\Commands\\SomeCommand', 'Invoker');
}
else
{
    class_alias('\\Web\\Models\\Services\\SomeService', 'Invoker');
}
Run Code Online (Sandbox Code Playgroud)

在快速:%s/SomeCommand/Invoker/g进入vim后,我很高兴(或多或少)


aic*_*ngm 7

从另一个角度考虑这个问题.有一个库,它包含一个名为MySq的类,当库继续开发时,他们认为" 哦,也许我们应该创建一个数据库类 ",所以重写类并称之为'DatabaseConnection',它具有与之相同的功能. MySql类但它也可以处理Sql和MsSql.随着时间的推移,他们发布新版本'PHPLib2'.开发人员现在有两个选择:1,告诉用户从MySql更改为DatabaseConnection或2,开发人员使用

class_alias("DatabaseConnection","MySql"); 
Run Code Online (Sandbox Code Playgroud)

并且只是将MySql类标记为已弃用.

tltr;

保持版本兼容性!