我打算将我的脚本(成千上万)从PHP 5迁移到PHP 7,并且试图找出一种“智能”的方式来处理正则表达式以自动(如果可能)替换任何while/each
带有foreach
的语句。
可能要处理的案件是
while(list($key,$value)=each($varname0)) {
while ( list ( $k , $v ) = each( $varname1 ) ) {
while (list(, $v) = each($varname2)) {
while (list($k) = each($varname3)) {
和相关的可能组合组合。我的目标是找到一个“ preg_match”字符串,将3个不同的示例转换为符合PHP 7的语句。
foreach ($varname0 as $key => $value) {
foreach ($varname1 as $k => $v) {
foreach ($varname2 as $v) {
foreach ($varname3 as $k => null) {
有人有同样的需求吗? 如果您认为上述方法可能会破坏php本机脚本的风险,是否有一些工具可以从PHP 5迁移到PHP 7,显然可以保留本机脚本的功能?
2019年7月17日,已解决。可以肯定的是,这不是一个好的方法,但是它可以帮助某人花些时间将此半自动脚本应用于成千上万的脚本和页面,这些脚本和页面将“ while / each”语句转换为“ foreach”(与PHP7兼容): / p>
import("fx.readline","class.log");
$log = new Log();
$filename = $argv[1];
if (!$filename) die();
if (!file_exists($filename)) die();
unset($filelist);
if (is_dir($filename)) exec("/bin/find " . $filename . " -type f | grep -v 'php7_syntax_check'", $filelist);
else $filelist = array($fname);
$whoami = exec("whoami");
foreach($filelist as $filename) {
$changeflag = false;
$log->Separator("-");
$log->Show("", "{s:104}FILE : " . $filename . "{s:0}");
$script = array_map("rtrim", file($filename));
/*********************************************************************************************************************
*
* Replace [ while-list-each ] with [ foreach ]
*
*********************************************************************************************************************/
$scanstr = preg_grep("/\beach\(/", $script);
foreach($scanstr as $k => $str) {
unset($m);
$log->Show("", "ROW : " . ($k + 1));
$log->Show("", "CHANGE FROM : {s:93}" . $str . "{s:0}");
preg_match("/(\s*)(while)?\s*\(\s*list\s*\(\s*(.*?)\s*\)\s*=\s*each\s*\(\s*(.*?)\s*\)\s*\)\s*(\{{0,1})(.*)/", $str, $m);
$m = array_combine(
array("complete","space","while","key_variable","list","bracket","other"),
$m
);
list($m['key'] , $m['variable']) = explode(",", $m['key_variable']);
$replace_str = $m['space'];
if ($m['while']) {
if ($m['key'] && $m['variable']) $replace_str .= "foreach (" . trim($m['list']) . " as " . trim($m['key']) . " => " . trim($m['variable']) . ")";
elseif ($m['variable']) $replace_str .= "foreach (" . trim($m['list']) . " as " . trim($m['variable']) . ")";
elseif ($m['key']) $replace_str .= "foreach (array_keys(" . trim($m['list']) . ") as " . trim($m['key']) . ")";
if ($m['bracket']) $replace_str .= " {";
if ($m['other']) $replace_str .= $m['other'];
$log->Show("", " TO : {s:92}" . $replace_str . "{s:0}");
$script[$k] = $replace_str;
$changeflag = true;
} else {
$log->Show("", "{s:95}ERROR : Unable to handle Row #". ($k + 1) . " [ " . $filename . " ]. Please modify it manually{s:0}");
$log->Show("", "{s:95}TIP : if 'each()' statement is not part of 'while' loop, most of times it can be replaced with 'array_values()' function{s:0}");
die();
}
$log->Separator();
}
if (!$changeflag) {
$log->Show("", "No changed detected");
$log->Separator();
continue;
}
/*********************************************************************************************************************
*
* Override
*
*********************************************************************************************************************/
$fileowner = posix_getpwuid(fileowner($filename));
if ($whoami != "root" && $fileowner['name'] != $whoami) {
$log->Show("", "ERROR: User [ " . $whoami . " ] does not have priviledges to change a file owned by [ " . $fileowner['name'] . " ]");
$log->Separator();
continue;
}
$answer = ReadLine("Do you want to override " . $filename . "? ('Y/y' to confirm) ");
if ($answer == "Y" or $answer == "y") {
$backup = $filename . ".php7_syntax_check.backup." . date("YmdHis");
$log->Show("", "Backup created on [ " . $backup . " ]");
copy($filename, $backup);
file_put_contents($filename, implode("\n", $script));
system("/usr/bin/php -l ". $filename . " > /dev/null", $return);
if ($return != 0) {
$log->Show("", "{s:95}Syntax error detected on " . $filename . ". Please check as soon as possible");
die();
}
}
$log->Separator();
}
例如,这些是对在命令行中作为输入传递的脚本提出的修改:
ROW : 45
CHANGE FROM : while (list($rows,$v) = each($segment)) {
TO : foreach ($segment as $rows => $v) {
ROW : 70
CHANGE FROM : while(list(,$cols) = each($whole)) {
TO : foreach ($whole as $cols) {
ROW : 109
CHANGE FROM : while (list($r) = each($testable)) {
TO : foreach (array_keys($testable) as $r) {
ROW : 111
CHANGE FROM : while (list($c) = each($testable[$r])) { $dielist[] = "$r,$c"; }
TO : foreach (array_keys($testable[$r]) as $c) { $dielist[] = "$r,$c"; }
ROW : 133
CHANGE FROM : while (list(,$coord) = each($site0)) {
TO : foreach ($site0 as $coord) {