PHP5转PHP7:批量替换类同名构造函数为__construct的正则方案求助
批量替换PHP5同名构造函数为__construct的方案
我刚好做过类似的PHP版本迁移工作,用sed配合简单的脚本就能高效完成这个任务,给你两种实用的方案,你可以根据自己的情况选择:
方案一:单条Sed命令(一次性处理)
这条命令利用Sed的**保持空间(Hold Space)**来存储捕获到的类名,自动匹配并替换对应的构造函数,还支持带缩进的类和函数定义:
sed -i.bak '/^[[:space:]]*class \([A-Za-z0-9_]*\)/{h;s/^[[:space:]]*class \(.*\)/\1/;x};/^[[:space:]]*function \([A-Za-z0-9_]*\)(/{G;s/^[[:space:]]*function \([A-Za-z0-9_]*\)(\n\(.*\))/function __construct(/;x}' your_php_files/*.php
命令拆解:
-i.bak:直接修改目标文件,同时生成.bak后缀的备份文件(处理完确认无误后,可批量删除这些备份)- 第一部分
/^[[:space:]]*class \([A-Za-z0-9_]*\)/{...}:- 匹配所有带缩进的类定义行,捕获类名到分组
h:把捕获到的类名存入保持空间暂存
- 第二部分
/^[[:space:]]*function \([A-Za-z0-9_]*\)(/{...}:- 匹配所有带缩进的函数定义行
G:把保持空间里的类名追加到当前行后方- 如果函数名和类名完全一致,就替换成
function __construct(
先测试再修改:
先去掉-i.bak参数运行,预览替换效果是否符合预期:
sed '/^[[:space:]]*class \([A-Za-z0-9_]*\)/{h;s/^[[:space:]]*class \(.*\)/\1/;x};/^[[:space:]]*function \([A-Za-z0-9_]*\)(/{G;s/^[[:space:]]*function \([A-Za-z0-9_]*\)(\n\(.*\))/function __construct(/;x}' test.php
方案二:Grep+循环脚本(更直观易调试)
如果觉得单条Sed命令太复杂,这个脚本逻辑更清晰:先找到所有类定义,再逐个替换对应文件里的同名构造函数:
grep -r "^[[:space:]]*class " your_php_files/ | while read -r line; do # 提取当前类所在的文件名 file=$(echo "$line" | cut -d: -f1) # 提取类名 class=$(echo "$line" | sed 's/^[[:space:]]*class \([A-Za-z0-9_]*\).*/\1/') # 替换当前文件里的同名构造函数 sed -i.bak "s/^[[:space:]]*function $class(/function __construct(/g" "$file" done
脚本优势:
- 逻辑清晰,每一步都能单独调试(比如先看
grep输出的类名是否正确) - 支持递归处理子目录里的PHP文件(
grep -r) - 如果一个文件里有多个类,会自动处理每个类的构造函数
重要注意事项
- 务必先备份:两个方案都用了
-i.bak生成备份,处理完一定要检查替换结果,确认无误后再删除备份(比如执行rm your_php_files/*.bak) - 兼容命名空间:如果你的代码有命名空间(比如
namespace App; class User {),上述正则依然能正确捕获类名,不用额外调整 - 特殊情况排查:PHP5中类内与类名同名的函数就是构造函数,所以替换是安全的;如果你的代码里有同名的普通函数(非常见情况),需要手动检查排除
内容的提问来源于stack exchange,提问作者Paul Allsopp
相关产品推荐
相关产品推荐

