PHP正则提取赋值给变量的Lambda函数体返回NULL如何解决
PHP匿名函数体提取正则匹配失败修复
问题背景
现有可正常工作的具名函数体提取函数extractBody(),实现代码如下:
$data = ' <?php function my_function($param){ if($param === true){ // This is true }else if($param === false){ // This is false }else{ // This is not } } ?> '; function extractBody($functionName, $data) { $c = preg_match_all("/function\s+".$functionName."\s*\((?<param>[^\)]*)\)\s*(?<body>\{(?:[^{}]+|(?&body))*\})/", $data, $matches); return $c > 0 ? $matches['body'] : null; } $body = extractBody("my_function", $data); var_dump($body);
运行后$body可正确获取函数主体内容:
if($param === true){ // This is true }else if($param === false){ // This is false }else{ // This is not }
现在需要开发提取赋值给变量的Lambda匿名函数体的函数extractBody2(),测试代码如下:
$data2 = ' <?php $my_function = function($param){ if($param === true){ // This is true }else if($param === false){ // This is false }else{ // This is not } } ?> '; function extractBody2($functionName, $data) { $c = preg_match_all("/".$functionName."\s+=\s+function\s+\s*\((?<param>[^\)]*)\)\s*(?<body>\{(?:[^{}]+|(?&body))*\})/", $data, $matches); return $c > 0 ? $matches['body'] : null; } $body2 = extractBody2("my_function", $data2); var_dump($body2);
运行后返回结果为NULL,无法正确提取函数体。
故障原因
正则逻辑存在三个问题:
- 未匹配PHP变量前缀的
$符号:传入的函数名参数是my_function,但代码中实际变量写为$my_function,正则开头直接拼接函数名,完全跳过了前缀$的匹配,无法命中目标片段 - 未转义正则元字符:
$是正则中的特殊元字符,默认代表行/字符串结尾位置,就算手动在正则中补上$,不做转义也会导致正则匹配逻辑完全失效,无法匹配字面意义的$符号 - 匹配规则兼容性差:原正则用
\s+要求等号、function关键字前后必须存在至少1个空白字符,遇到$f=function(){}这类无空格的写法会匹配失败,且function\s+\s*属于冗余的重复空白匹配,没有实际意义
修正方案
调整正则逻辑:
- 正则开头增加转义后的
\$匹配PHP变量前缀 - 用
preg_quote()处理传入的函数名,避免函数名中存在其他正则特殊字符导致匹配异常 - 将冗余/严格的
\s+改为\s*,兼容0个或多个空白的写法,提升适配性
修正后的函数代码:
function extractBody2($functionName, $data) { // 拼接正则:转义$符号,转义函数名特殊字符,调整空白匹配规则 $pattern = "/\\\$" . preg_quote($functionName, '/') . "\s*=\s*function\s*\((?<param>[^\)]*)\)\s*(?<body>\{(?:[^{}]+|(?&body))*\})/"; $c = preg_match_all($pattern, $data, $matches); return $c > 0 ? $matches['body'] : null; }
运行测试代码后,$body2可正确返回匿名函数的主体内容,和具名函数提取结果一致。
内容的提问来源于stack exchange,提问作者smolo
相关产品推荐
相关产品推荐

