84669 人学习
152542 人学习
20005 人学习
5487 人学习
7821 人学习
359900 人学习
3350 人学习
180660 人学习
48569 人学习
18603 人学习
40936 人学习
1549 人学习
1183 人学习
32909 人学习
我可以使用 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()
部分:如果新类尚未加载,它会触发自动加载。
注册自动加载器后,旧代码将自动加载旧别名下的新类。