我正在研究一种更新 config.php 文件的动态方法,但遇到了一个我无法完全解决的有趣故障。下面是我更新 config.php 文件的代码:
if( isset( $_POST['submitted'] ) ) {
$config_keys = array();
foreach( $_POST as $key => $value ) {
if( substr( $key, 0, 7 ) == 'config-' ) {
$config_keys[ substr( $key, 7 ) ] = $value;
}
}
$config_content = file_get_contents( dirname(__FILE__) . '/../../inc/config.php' );
foreach( $config_keys as $key => $value ) {
$config_content = preg_replace(
"/config\['$key'\](\s*)=(\s*)(['\"]?).*?(['\"]?);/",
"config['$key']$1=$2$3$value$4;",
$config_content
);
$config[$key] = $value;
}
file_put_contents( dirname(__FILE__) . '/../../inc/config.php', $config_content );
}
逻辑相当合理。它搜索以“config-”为前缀的任何 POST 变量,然后使用“config-”之后的所有内容作为我们配置文件中要更新的键的名称。配置文件采用以下形式:
$config['var1'] = 'value1';
$config['var2'] = 123;
$config['var3'] = '...';
在 90% 的情况下,这可以完美运行,但是如果$value
以数字开头,则替换过程中将完全忽略$3
第一个数字。$value
例如,我的配置文件中有以下值:
$config['ls_key'] = '136609a7b4....'; // Rest of key has been truncated
如果我不更改此值并保持键不变但提交我的表单,那么这一行突然看起来像这样:
$config['ls_key'] = 36609a7b4...'; // Rest of key has been truncated
缺少单引号会阻止配置文件解析(破坏整个站点),并且我们丢失了引导数据!阅读PHP preg_replace 手册后,我尝试在多个位置使用大括号(修改“示例 #1 使用反向引用后跟数字文字”)。以下方法均无效:
"config['$key']$1=$2${3}$value$4;",
"config['$key']$1=$2$3${value}$4;",
"config['$key']$1=$2$3{$value}$4;",
"config['$key']$1=$2{$3}$value$4;", // This one actually leads to syntax errors
"config['$key']${1}=${2}${3}$value${4};",
前 3 个导致完全相同的问题,对替换没有影响。第四个根本不起作用(语法错误),第五个实际上导致每个反向引用都被忽略。我也尝试过像这样使用单引号和连接:
'config[\'$key\']$1=$2$3' . $value . '$4;',
同样,我遇到了与之前的 3 个示例和我的原始脚本相同的问题。
希望有人以前解决过这个问题,或者至少有一个新的想法。