2012-01-09 4 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-"の後ろのすべてを使用して更新します。 $valueは、その後、数字で$3始まり、$valueの最初の数字が完全に交換中に無視されている場合ただし、これは完璧に動作例

$config['var1'] = 'value1'; 
$config['var2'] = 123; 
$config['var3'] = '...'; 

90では%:configファイルの形式をとります。例えば

、私は私の設定ファイルに次の値を持っている:私はこの値を変更し、キー手つかずのままに私のフォームを送信していない場合は

$config['ls_key'] = '136609a7b4....'; // Rest of key has been truncated 

この行は突然そうのようになります。

一重引用符がないと、設定ファイルが解析されず(サイト全体が破損する)、起動するためのデータが失われてしまいます。 the PHP preg_replace manualを読んだ後で、いくつかの場所で中括弧を使用しようとしました( "Example#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つは全く同じ問題を引き起こし、置換には影響しません。 4つ目は全く機能しません(構文エラー)、5つ目は実際にはすべての逆参照を無視します。また、私はそうのように単一引用符と連結を使用して試してみた:

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

繰り返しますが、私は3つの前の例と私の元のスクリプトと同じ問題を抱えていました。

誰かがこれを解決する前に、または少なくとも新しいアイデアがあることを願っています。

+1

'$ {3}'で最初に試してください。 – Qtax

+0

残念ながら私はこれを試しても機能しませんでした。 – stevendesu

答えて

2

二重引用補間が物事を混乱させているようです。この置換が機能:

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

はまた、あなたが適切に以下の(メタ文字)をエスケープする必要があることに注意してください:交換でpreg_quote

  • $key$valueと正規表現で

    • $key、なしありこれを行うための関数を組み込んでいます(preg_quoteエスケープが多すぎます)

    また、正規表現区切り文字と引用符区切り文字があればそれをエスケープします。

  • +0

    ありがとうございます。完璧に働いた。私は正規表現で '$ key'でpreg_quoteを使う必要があることを認識していますが、置き換えに何かエスケープすることは考えていませんでした。 addslashesで十分だろうと思いますか? – stevendesu

    +0

    @steven_desu、 'addslashes'は' $ 'をエスケープしないので、十分ではありません。元の値が引用符で囲まれておらず、新しい値が文字列の場合はどうなりますか?この単純な構文解析には多くの穴があります。サーバー上で任意のコードを実行できるようにする場合にのみ、ユーザーにこれにアクセスできるようにします。 :p – Qtax

    0

    グループ1 \g{1}を試してみてください(それに応じて他のグループのための)

    php manual on backreferences

    更新を参照してください:もちろんQtaxの

    が正しい、これは後方参照の構文ですの正規表現内にあります。 (Qtaxの+1)

    +0

    '\ g {N}'と友人はアフリカの交換部分で働かない。 – Qtax

    +0

    Qtaxが正しいです。うまくいきませんでした。 '$ 3 'の代わりに' \ g {3} 'を' $ config_content'に入れてください: '$ config [' ls_key '] = \ g {3} 136609a7b4 ...' ' – stevendesu

    関連する問題