首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 依點分路徑字串動態建構多維陣列:eval 實作與替代方案

     編輯:PHP 綜合知識

將扁平的「路徑→值」對應 (如 'a.b.c' => 1) 轉換為巢狀陣列 (['a'=>['b'=>['c'=>1]]]) 是配置解析、表單處理常見需求。本文示範使用 eval 快速實作,並提供不依賴 eval 的迭代參考實作,討論安全性與效能權衡。

eval 版本(簡潔但有風險)

$config = array(
    'project|page|index' => 'content',
    'project|page|nav' => array(
        array('image'=>'1.jpg', 'name'=>'home'),
        array('image'=>'2.jpg', 'name'=>'about')
    ),
    'project|page|open' => true
);

$result = array();
foreach ($config as $path => $val) {
    $keys = explode('|', $path);
    $expr = '$result';
    foreach ($keys as $k) $expr .= "['$k']";
    if (is_array($val)) $expr .= ' = '.var_export($val, true).';';
    elseif (is_string($val)) $expr .= ' = \''.$val.'\';';
    else $expr .= ' = '.$val.';';
    eval($expr);
}
print_r($result);

輸出結果

Array
(
    [project] => Array
        (
            [page] => Array
                (
                    [index] => content
                    [nav] => Array
                        (
                            [0] => Array ( [image] => 1.jpg [name] => home )
                            [1] => Array ( [image] => 2.jpg [name] => about )
                        )
                    [open] => 1
                )
        )
)

安全風險與緩解

  • 程式碼注入:若 $path 來自使用者輸入,可能構造 ']; system('rm -rf /'); // 導致任意代碼執行。
  • 緩解:嚴格驗證鍵名 preg_match('/^[a-zA-Z0-9_|]+$/', $path),拒絕含引號、分號、括號等字元。
  • 禁用 eval:生產環境強烈建議使用非 eval 實作。

非 eval 迭代實作(推薦)

function buildNestedArray($flat, $delimiter='|') {
    $nested = array();
    foreach ($flat as $path => $value) {
        $keys = explode($delimiter, $path);
        $ref = &$nested;
        foreach ($keys as $key) {
            if (!isset($ref[$key]) || !is_array($ref[$key])) $ref[$key] = array();
            $ref = &$ref[$key];
        }
        $ref = $value; // 參考賦值
    }
    return $nested;
}

$result = buildNestedArray($config);
print_r($result); // 結果相同

進階:支援數值索引與混合路徑

$flat = array(
    'users|0|name' => 'Alice',
    'users|1|name' => 'Bob',
    'settings|theme' => 'dark'
);
// buildNestedArray 會正確產生 ['users'=>[['name'=>'Alice'],['name'=>'Bob']], 'settings'=>['theme'=>'dark']]

效能比較

方法時間複雜度記憶體安全性
evalO(n * k) + 編譯開銷較高低 (需嚴格過濾)
迭代參考O(n * k)低高
SPL RecursiveArrayIteratorO(n * k)低高

eval 適合一次性腳本、受信任資料來源;長期專案請使用迭代參考或封裝為工具類別。完整測試程式碼可至本站下載。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved