2012-01-09 54 views
0

我正在動態地更新config.php文件,並遇到了一個我無法解決的有趣故障。以下是我更新config.php文件的代碼: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 

缺乏單引號可以防止配置文件解析(破壞整個網站),並且我們丟失了數據以便引導!在閱讀the PHP preg_replace manual後,我嘗試在幾個位置使用大括號(修改「示例#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個例子,我原來的劇本。

希望有人解決這個問題之前或至少有一個新的想法。

+1

您首次嘗試使用'$ {3}'應該可以工作。 – Qtax 2012-01-09 15:53:43

+0

不幸的是我試過這個,它沒有工作。 – stevendesu 2012-01-09 16:57:06

回答

2

似乎雙引號插值是搞砸了事情。這種替換工作:

'config[\''.$key.'\']$1=$2${3}'.$value.'$4;' 

還要注意的是,你應該正確逃生以下(元字符):

  • 在與替換preg_quote
  • $key$value正則表達式$key,沒有內置功能做到這一點(preg_quote逃脫太多)

還可以使用正則表達式分隔符和引號分隔符(如果存在)。

+0

謝謝。完美工作。我意識到我需要在正則表達式中用'$ key'使用preg_quote,儘管我沒有考慮在替換中轉義任何東西。你認爲addslashes是足夠的嗎? – stevendesu 2012-01-09 16:30:54

+0

@steven_desu,'addslashes'不會轉義'$',所以這還不夠。另外,如果原始值是一個未加引號的數字,而您的新值是一些字符串呢?這種簡單的解析有很多漏洞。如果你想允許他們在你的服務器上運行任意代碼,只允許用戶訪問它。 :p – Qtax 2012-01-09 17:07:38

0

嘗試\g{1}爲組1(並且相應地爲其它基團)

參見php manual on backreferences

更新:

當然Qtax是正確的,這是反向引用的語法在的正則表達式中。 (+1爲Qtax)

+0

'\ g {N}'和朋友不在替換部​​分afaik中工作。 – Qtax 2012-01-09 15:51:41

+0

Qtax是對的。沒有工作。使用'\ g {3}'代替'$ 3',把下面的代碼放在'$ config_content'中:'$ config ['ls_key'] = \ g {3} 136609a7b4 ...'' – stevendesu 2012-01-09 16:00:31

相關問題