I was working on a dynamic way to update a config.php file and I ran into an interesting glitch that I can't quite solve. Below is my code for updating the config.php file:
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 );
}
The logic is fairly sound. It searches for any POST variables prefixed by "config-" then uses everything after "config-" as the name of the key in our config file to update. The config file takes the form:
$config['var1'] = 'value1';
$config['var2'] = 123;
$config['var3'] = '...';
In 90% of cases this works perfectly, however if $value begins with a numeral then $3 and the first numeral of $value are completely ignored during the replacement.
For instance, I have the following value in my config file:
$config['ls_key'] = '136609a7b4....'; // Rest of key has been truncated
If I don't change this value and leave the key untouched but submit my form then this line suddenly looks like so:
$config['ls_key'] = 36609a7b4...'; // Rest of key has been truncated
The lack of single quote prevents the config file from parsing (breaking the entire site) and we've lost data to boot! After reading the PHP preg_replace manual I have tried using braces in several locations (modifying "Example #1 Using backreferences followed by numeric literals"). None of the following worked:
"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};",
The first 3 lead to the exact same problem, having no effect on the replacement. The fourth doesn't work at all (syntax errors), and the fifth actually causes EVERY backreference to be ignored. I've also tried using single quotes and concatenation like so:
'config[\'$key\']$1=$2$3' . $value . '$4;',
Again, I had the same problem as the 3 prior examples and my original script.
Hoping someone has solved this before or at least has a new idea.
${3}should work afais.