我可以使用 PHP 8.1 函数(例如类别名)创建命名空间别名吗?
我们将公司中的默认命名空间模块命名为“Subcompany”,并希望它现在成为“Company”,因为它的用途已经扩大了。
一个完美的答案是尽可能少的开销,并且允许透明地自动加载。一个问题是 Intelephense 等工具会理解此别名。
该项目还使用 Composer,因此使用它重写命名空间的答案也可以。
是的,并且思考:class_alias 是随 PHP 5.3 引入的,并且它的新命名空间语言功能。它的创建是为了更容易地从全局命名空间迁移到命名空间 - 实际上是在命名空间之间。
class_alias
但是,您需要首先为每个旧类/接口/特征/枚举注册一个类别名到新的对应项。
My\Old\Lib\Name\Module\Submodule\Interface My\Tiger\Lib\Name\Module\Submodule\Interface
旧的库已经消失,现在有了全新的 Tiger 库。它们的所有类等都可以通过交换命名空间前缀来映射('My\Old\Lib\Name\' -> 'My\Tiger\Lib\Name')。
'My\Old\Lib\Name\' -> 'My\Tiger\Lib\Name'
这可以在运行时完成,因为 PHP 会为您完成大部分工作。
注册一个自动加载器,它基于旧的命名空间前缀作为新的命名空间前缀加载,并预先将类别名为旧名称。
示例:
spl_autoload_register( static function (string $class_name) { static $old = 'My\Old\Lib\Name\'; static $new = 'My\Tiger\Lib\Name\'; // only operate on the old namespace if (0 !== strpos($class_name, $old)) { return; } $new_name = substr_replace($class_name, $new, 0, strlen($old)); class_alias($new_name, $class_name); $exists = class_exists($new_name); }, $throw = true, /* throw when registering fails */ $prepend = false /* only alias at fall-through */ );
这段代码很简单,只需对注册参数做两点说明:
$throw = true
$prepend = false
也许值得注意的是 class_exists() 部分:
class_exists()
$exists = class_exists($new_name);
如果新类尚未加载,它会触发自动加载。
注册自动加载器后,旧代码将自动加载旧别名下的新类。
use My\Old\Lib\Name\Module\Boring; $boring = new Boring(); assert($boring instanceof My\Old\Lib\Name\Module\Boring); var_dump(get_class($boring)); # string(31) "My\Tiger\Lib\Name\Module\Boring"
是的,并且思考:
class_alias
是随 PHP 5.3 引入的,并且它的新命名空间语言功能。它的创建是为了更容易地从全局命名空间迁移到命名空间 - 实际上是在命名空间之间。但是,您需要首先为每个旧类/接口/特征/枚举注册一个类别名到新的对应项。
旧的库已经消失,现在有了全新的 Tiger 库。它们的所有类等都可以通过交换命名空间前缀来映射(
'My\Old\Lib\Name\' -> 'My\Tiger\Lib\Name'
)。这可以在运行时完成,因为 PHP 会为您完成大部分工作。
注册一个自动加载器,它基于旧的命名空间前缀作为新的命名空间前缀加载,并预先将类别名为旧名称。
示例:
这段代码很简单,只需对注册参数做两点说明:
$throw = true
:当别名自动加载器无法注册时,您希望立即停止应用程序,否则您会在很久以后收到奇怪的“未找到类”错误。$prepend = false
:仅当仍有代码使用旧类名时,才应调用回调。因此,现在使用新命名空间和标准自动加载的标准代码是第一位的。也许值得注意的是
class_exists()
部分:如果新类尚未加载,它会触发自动加载。
注册自动加载器后,旧代码将自动加载旧别名下的新类。