我正在尝试从PHP类集合中自动删除命名空间,以使它们与PHP 5.2兼容。 (共享主机提供商并不喜欢流氓PHP 5.3安装。不知道为什么。此外,有问题的代码不使用任何5.3功能添加,只是语法。自动转换似乎比手动或重新实现代码库更容易。)
为了重写* .php脚本,我基本上是在tokenizer列表上运行。标识符搜索+合并已经完成。但是我现在有点困惑如何完成实际的重写。
function rewrite($name, $namespace, $use) {
global $identifiers2; // list of known/existing classes
/*
bounty on missing code here
*/
return strtr($name, "\\", "_"); // goal: backslash to underscore
}
将在每个找到的标识符(无论是类,函数还是常量)上调用该函数。它将接收一些上下文信息,以将本地标识符转换为绝对/全局$ name:
$name =
rewrite(
"classfuncconst", # <-- foreach ($names as $name)
"current\name\space",
array(
'namespc' => 'use\this\namespc',
'alias' => 'from\name\too',
...
)
);
在这个阶段,我已经准备了$identifiers2
列表。它包含所有已知类,函数和常量名称的列表(为简单起见,此处合并)。
$identifiers2 = array( // Alternative suggestions welcome.
"name\space\Class" => "Class", // - list structure usable for task?
"other\ns\func1" => "func1", // - local name aliases helpful?
"blip\CONST" => "CONST", // - (ignore case-insensitivity)
$name
功能收到的rewrite()
参数可以是本地,不合格, \ absolute 或名称\间距标识符(但只是标识符,没有表达式)。 $identifiers2
列表对于解析非限定标识符至关重要,这些标识符可以引用当前命名空间中的内容,或者如果没有在那里找到全局内容。
除了命名空间解析和优先级规则之外,还必须考虑各种use namespace
别名并添加一些复杂性。
那么,您将在何处/以何种顺序尝试转换类/函数名称的变体?
精神懒惰赏金。
为了使这个问题变得不那么明显:一个解释性指令列表或伪代码答案也是合格的。如果另一种方法更适合这项任务,请详细说明。 (但不是,升级PHP或更改主机不是一种选择。)
我想我已经明白了,但问题仍然是答案/实施建议。 (否则赏金显然会转向nikic。)
答案 0 :(得分:18)
在existing question on migration of namespaces to pseudo namespaced code我已经introduced a conversion tool我已经写了一个大项目的一部分。从那时起我就不再维护这个项目,但据我记得,命名空间替换确实有效。 (我可能会在某个时候使用proper parser重新实现这个项目。使用普通令牌已经证明是一项相当繁琐的工作。)
你会发现我的命名空间实现 - &gt; namespace.php中的伪命名空间解析。我的实施基于namespace resolution rules,这也可能对你有所帮助。
为了使这个不那么明显的readmycodez答案,这里是代码的基本步骤:
self
和parent
类,也不会解析true
,false
和null
常量。use
列表):
class
,请检查标识符是否为别名,如果是,请将其替换为别名类。class
,则前置当前命名空间,将所有NS分隔符替换为下划线并结束此算法。assumeGlobal
标志,我也不会这样做。相反,我总是插入动态调度代码。)附加说明:不要忘记也可以写namespace\some\ns
。我在the NS
function中解析这些结构(它也负责查找名称空间声明)。