命名空间的 PHP 使用语句
Posted
技术标签:
【中文标题】命名空间的 PHP 使用语句【英文标题】:PHP use statement for namespace 【发布时间】:2014-10-29 16:41:50 【问题描述】:也许这是一个奇怪的问题,但我无法弄清楚当您编写时 php 内部发生了什么:
use garcha\path\class;
我不是在问命名空间的用途,而是关于该语句本身,即使它没有分配任何内存,我的意思是,当你甚至为某个类提供别名时:
use garcha\path\class as withNewName;
它存储在哪里?或者它是如何记住名字的?它只是在编译时发生吗?而不是运行时间?就像只是描述函数一样。
【问题讨论】:
如果您熟悉 C,请查看实现:lxr.php.net/xref/PHP_TRUNK/Zend/zend_compile.c#zend_compile_use。它通过将名称存储在哈希表中来记住它们(另请参见 zend_get_import_ht)。是的,别名解析是完全编译时的。 VM 不知道命名空间别名。 您可以通过制作像namespace Test class MyClass namespace use Test\MyClass;
这样的简单脚本然后使用phpdbg
转储操作码来亲眼看到这是编译时间。您只会得到 ZEND_NOP,因为那里没有运行时代码。
lxr 已关闭(2017 年 5 月)。使用 github github.com/php/php-src/blob/master/Zend/zend_compile.c#L6408 或启动 docker 容器 hub.docker.com/r/itszero/opengrok
【参考方案1】:
这不是一个非常复杂的算法(对于 5.5,在 5.6 中描述的类名部分是相同的)。
-
如有必要,将创建 HashTable 实例。它保持导入(使用的命名空间类)。
在使用
as
关键字的情况下,此名称用作别名。否则使用导入类名的最后一个组件(对于 XXX\YYY\ZZZ,名称将是 ZZZ)。将其转换为小写。
检查self
/parent
,它不能用作别名。
检查该名称是否已存在于 class_table 中(使用当前命名空间,如果已声明)。
将此别名添加到特殊的 HashTable(第 1 页中提到)。
这个表用在什么地方?
就在编译期间解析类名。
关于别名还有一件更有趣的事情——它的作用域是命名空间块:
<?php
namespace nsC
class classC
namespace nsA
use nsC\classC as importC;
new importC();
namespace nsB
// ERROR!
new importC(); // or \nsA\importC()
【讨论】:
以上是关于命名空间的 PHP 使用语句的主要内容,如果未能解决你的问题,请参考以下文章