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

PHP 操作 INI 設定檔完整指南:讀寫封裝與跨語言相容

     編輯:PHP 綜合知識

INI 格式因結構簡單、人類可讀、多語言支援良好,常用於應用程式設定。PHP 內建 parse_ini_file() 讀取,但缺乏寫入功能。本文提供完整的讀寫封裝函式,支援區段、陣列值、空值處理,並說明跨語言(Python)互操作注意事項。

寫入 INI 檔案:write_ini_file()

<?php
/**
 * 將關聯陣列寫入 INI 檔案
 * @param array  $assocArr  資料陣列,支援多層區段
 * @param string $path      檔案路徑
 * @param bool   $hasSections 是否包含區段(section)
 * @return bool 成功與否
 */
function write_ini_file(array $assocArr, string $path, bool $hasSections = false): bool
{
    $content = '';

    if ($hasSections) {
        foreach ($assocArr as $section => $keys) {
            $content .= "[$section]\n";
            foreach ($keys as $key => $val) {
                $content .= writeIniValue($key, $val);
            }
        }
    } else {
        foreach ($assocArr as $key => $val) {
            $content .= writeIniValue($key, $val);
        }
    }

    $handle = @fopen($path, 'w');
    if (!$handle) return false;
    $result = fwrite($handle, $content);
    fclose($handle);
    return $result !== false;
}

/** 統一處理值的輸出格式:字串加雙引號、陣列展開、空值處理 */
function writeIniValue(string $key, $val): string
{
    if (is_array($val)) {
        $lines = '';
        foreach ($val as $item) {
            $lines .= "$key[] = \"$item\"\n";
        }
        return $lines;
    }
    if ($val === '') {
        return "$key = \n";
    }
    return "$key = \"$val\"\n";
}
?>

使用範例

<?php
$sampleData = [
    'database' => [
        'host' => 'localhost',
        'port' => 3306,
        'name' => 'myapp',
        'user' => 'root',
        'pass' => 'secret',
    ],
    'cache' => [
        'driver' => 'redis',
        'servers' => ['127.0.0.1:6379', '127.0.0.1:6380'], // 陣列值
    ],
    'debug' => true,
];

write_ini_file($sampleData, __DIR__ . '/config.ini', true); // true = 有區段
?>

產出的 config.ini 內容

[database]
host = "localhost"
port = "3306"
name = "myapp"
user = "root"
pass = "secret"

[cache]
driver = "redis"
servers[] = "127.0.0.1:6379"
servers[] = "127.0.0.1:6380"

debug = "1"

讀取 INI 檔案:parse_ini_file() 封裝

<?php
/**
 * 讀取 INI 並回傳關聯陣列
 * @param string $name 檔案名稱(相對路徑)
 * @return array|false
 */
public function readIni(string $name)
{
    $path = SEM_PATH . 'init/' . $name; // 專案常數路徑
    if (!is_file($path)) return false;

    // 第二參數 true = 解析區段為多維陣列
    $data = parse_ini_file($path, true);
    return $data ?: false;
}
?>

跨語言互操作:PHP ↔ Python 陷阱與對策

PHP write_ini_file 產出的值一律雙引號包裹(如 port = "3306")。Python 標準庫 configparser 預設不處理引號,會將引號視為值一部分,導致讀取到 "3306" 而非 3306。

解決方案二選一

  1. PHP 端調整:寫入時不加雙引號(數值、布林、無空格字串可不加),但需自行處理含空格/特殊字元的字串加引號邏輯。
  2. Python 端後處理(推薦,不改動 PHP 既有格式):
    import configparser, re
    
    config = configparser.ConfigParser()
    config.read('config.ini')
    
    def strip_quotes(v):
        return re.sub(r'^"(.*)"$', r'\1', v)  # 移除首尾雙引號
    
    for section in config.sections():
        for key, val in config[section].items():
            config[section][key] = strip_quotes(val)
    

最佳實踐總結

面向建議
編碼檔案存 UTF-8 無 BOM,PHP parse_ini_file 預期 UTF-8
安全設定檔放在 public/ 以外目錄,Nginx/Apache 禁止直接存取 *.ini
版本控制config.ini.example 納入 Git,實際 config.ini 加入 .gitignore
環境區隔採 config.local.ini 覆蓋機制,或用環境變數注入敏感值
效能啟動時一次性讀取快取至 APCu/Redis,避免每請求解析

替代方案參考

  • YAML:symfony/yaml,結構更豐富、支援錨點參考,適合複雜設定。
  • JSON:json_decode(file_get_contents(...), true),極速解析、原生支援巢狀陣列,但無註解。
  • PHP 陣列回傳:return [ ... ]; 純 PHP 檔案,include 即得陣列,效能最強、支援邏輯運算,但非通用格式。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved