为什么我们会使用class_alias
函数?例如:
Class Test {
public function __construct(){
echo "Class initialized";
}
}
class_alias("Test", "AnotherName");
$instance = new AnotherName(); # equivalent to $instance = new Test();
根据the manual,“别名类与原始类完全相同。”
这对什么有用?
答案 0 :(得分:33)
令人惊讶的是,没有人提到为什么会这样做的明显原因:use
关键字只能在最外层使用,并且在编译时处理,因此你不能{{1} }基于某些条件,也不能是块作用域:
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
哪会产生错误(2个别名具有相同的别名......)
namespace Foo;
use Images\GdImage as Image;
use Images\MagicImage as Image;
但是,作为在运行时调用的函数,因此可以是块作用域,可以用于条件导入:
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)
{}
}
的主要好处是,在PHP 5.3(引入名称空间)之前编写的所有代码都允许您避免编写类似的内容:
class_alias
不必重构整个代码库并创建命名空间,而是添加几个更容易:
$foo = new My_Lib_With_Pseudo_Name_Spaces_Class();
在脚本的顶部,以及一些class_alias('My_Lib_With_Pseudo_Name_Spaces_Class', 'MyClass');
条评论。
另一个用例可能是在将这些类实际转移到它们的命名空间对应物时:只需在重构一个类后更改//TODO: switch to Namespaces
调用,其他类可以保持不变。
在重构代码时,你很可能想要重新思考一些事情,所以像aichingm建议的用例可能不会太过分。
我能想到的最后一件事,但我还没有看到这个,当你想用模拟对象测试一些代码时,你可以使用class_alias
来使一切运行顺利。但是,如果你必须这样做,你可能还会考虑测试失败,因为这表明编写错误的代码,IMO。
很明显,就在今天,我遇到了class_alias
的另一个用例。我正在研究一种实现lib的方法,这种方法是从CLI工具中提炼出来的,用于基于MVC的web-app。一些类依赖于要传递的被调用命令的实例,从中获得了一些其他的点和螺栓
我没有经历重构的麻烦,而是决定更换:
class_alias
声明:
use Application\Commands\SomeCommand as Invoker;
并且,在vim快速if (\PHP_SAPI === 'cli')
{
class_alias('\\Application\\Commands\\SomeCommand', 'Invoker');
}
else
{
class_alias('\\Web\\Models\\Services\\SomeService', 'Invoker');
}
之后,我很乐意去(或多或少)
答案 1 :(得分:7)
从另一个角度考虑这个问题。有一个库,它包含一个名为MySq的类,当库继续开发时,他们认为'哦,也许我们应该只创建一个数据库类'所以重写类并将其称为'DatabaseConnection'它具有与MySql类相同的功能,但它也可以处理Sql和MsSql。随着时间的推移,他们发布新版本'PHPLib2'。开发人员现在有两个选择:1,告诉用户从MySql更改为DatabaseConnection或2,开发人员使用
class_alias("DatabaseConnection","MySql");
并将MySql类标记为已弃用。
<强> tltr; 强>
保持版本兼容性!
答案 2 :(得分:2)
它可用于: