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

PHP 多格式設定檔讀取器:支援 INI、YAML、XML、PHP 陣列的統一介面設計

     編輯:PHP 綜合知識

專案背景

專案常需支援多種設定檔格式(INI、YAML、XML、PHP 陣列)。本文實作一個基底 Settings 類別與四個具體實作類別,提供統一的 load() 與 get() 介面,實現設定檔格式的無縫切換。

核心架構設計

基底抽象類別:Settings

abstract class Settings {
    protected $_settings = [];
    
    public function get($var) {
        $keys = explode('.', $var);
        $result = $this->_settings;
        foreach ($keys as $key) {
            if (!isset($result[$key])) {
                return false;
            }
            $result = $result[$key];
        }
        return $result;
    }
    
    abstract public function load($file);
}

四大具體實作

1. Settings_PHP - PHP 陣列格式

class Settings_PHP extends Settings {
    public function load($file) {
        if (!file_exists($file)) return false;
        include($file);
        $vars = get_defined_vars();
        foreach ($vars as $key => $val) {
            if ($key === 'this') continue;
            $this->_settings[$key] = $val;
        }
    }
}

設定檔範例 (config.php):

<?php
$db = [];
$db['name'] = 'test';
$db['host'] = 'localhost';
$db['user'] = 'root';
$db['pass'] = 'password';
?>

2. Settings_INI - INI 格式

class Settings_INI extends Settings {
    public function load($file) {
        if (!file_exists($file)) return false;
        $this->_settings = parse_ini_file($file, true);
    }
}

設定檔範例 (config.ini):

[db]
name = test
host = localhost
user = root
pass = password

3. Settings_XML - XML 格式

class Settings_XML extends Settings {
    public function load($file) {
        if (!file_exists($file)) return false;
        include('xmllib.php'); // 需第三方 XML 解析庫
        $xml = file_get_contents($file);
        $data = XML_unserialize($xml);
        $this->_settings = $data['settings'];
    }
}

設定檔範例 (config.xml):

<?xml version="1.0" encoding="UTF-8"?>
<settings>
  <db>
    <name>test</name>
    <host>localhost</host>
    <user>root</user>
    <pass>password</pass>
  </db>
</settings>

4. Settings_YAML - YAML 格式

class Settings_YAML extends Settings {
    public function load($file) {
        if (!file_exists($file)) return false;
        include('spyc.php'); // 需 Spyc 庫
        $this->_settings = Spyc::YAMLLoad($file);
    }
}

設定檔範例 (config.yaml):

db:
  name: test
  host: localhost
  user: root
  pass: password

統一使用介面

// PHP 格式
$settings = new Settings_PHP();
$settings->load('config.php');
echo 'PHP: ' . $settings->get('db.host');

// INI 格式
$settings = new Settings_INI();
$settings->load('config.ini');
echo 'INI: ' . $settings->get('db.host');

// XML 格式
$settings = new Settings_XML();
$settings->load('config.xml');
echo 'XML: ' . $settings->get('db.host');

// YAML 格式
$settings = new Settings_YAML();
$settings->load('config.yaml');
echo 'YAML: ' . $settings->get('db.host');

各格式優缺點深度分析

格式優點缺點適用場景
PHP 陣列原生支援、效能最好、可包含邏輯/常數安全性風險(可執行程式碼)、非標準格式、難以跨語言共用內部專用、高效能需求、動態設定
INI簡單易讀、PHP 內建解析、輕量功能有限(無巢狀深度、無型別)、標準化不一、逐漸過時簡單設定、舊專案維護、PHP 專用
XML標準化程度高、跨語言、支援屬性/命名空間/驗證、工具鏈豐富冗長、解析效能較差、複雜度高企業級應用、跨系統整合、需嚴格結構驗證
YAML人類可讀性最佳、支援複雜資料結構、錨點/參考、廣泛採用(Docker、K8s、CI/CD)解析複雜、標準化歷程曲折、對縮排敏感、需第三方庫現代化專案、設定檔由人維護、DevOps 工具鏈
JSON原生 JS 支援、解析快、標準化、無註解無註解、無尾隨逗號、嚴格語法易出錯API 回應、前後端共用、靜態設定

現代化改進建議

1. 使用成熟庫替代手工實作

// 推薦:symfony/config + symfony/yaml
use Symfony\Component\Config\Loader\LoaderResolver;
use Symfony\Component\Config\Loader\DelegatingLoader;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Yaml\Yaml;

$locator = new FileLocator([__DIR__.'/config']);
$loader = new DelegatingLoader([
    new YamlFileLoader($locator),
    new PhpFileLoader($locator),
    new IniFileLoader($locator),
    new XmlFileLoader($locator),
], new LoaderResolver([
    new YamlFileLoader($locator),
    new PhpFileLoader($locator),
    new IniFileLoader($locator),
    new XmlFileLoader($locator),
]));
$config = $loader->load('config.yaml'); // 自動偵測格式

2. 加入快取機制

class CachedSettings extends Settings {
    private $cacheDir;
    private $ttl;
    
    public function load($file) {
        $cacheFile = $this->cacheDir . '/' . md5($file) . '.php';
        if (file_exists($cacheFile) && (time() - filemtime($cacheFile)) < $this->ttl) {
            $this->_settings = include $cacheFile;
            return;
        }
        parent::load($file);
        file_put_contents($cacheFile, '

3. 環境變數覆蓋支援

public function load($file) {
    parent::load($file);
    // 環境變數優先:DB_HOST 覆蓋 db.host
    foreach ($this->_settings as $key => $value) {
        if (is_array($value)) {
            $this->_settings[$key] = $this->applyEnvOverrides($value, strtoupper($key));
        }
    }
}

private function applyEnvOverrides(array $arr, string $prefix) {
    foreach ($arr as $k => $v) {
        $envKey = $prefix . '_' . strtoupper($k);
        if (isset($_ENV[$envKey])) {
            $arr[$k] = $_ENV[$envKey];
        } elseif (is_array($v)) {
            $arr[$k] = $this->applyEnvOverrides($v, $envKey);
        }
    }
    return $arr;
}

總結

統一設定檔介面設計體現了「依賴抽象而非具體實作」的 SOLID 原則。雖然本文的手工實作具教學意義,但生產環境強烈建議使用 Symfony Config Component、Laravel Config 或 vlucas/phpdotenv 等成熟方案。選擇格式時,現代專案首推 YAML(人類可讀)或 PHP 陣列(效能最佳),配合環境變數覆蓋實現十二因子應用規範。

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