DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> XML學習教程 >> XML詳解 >> 使用 PHP 處理 XML 配置文件
使用 PHP 處理 XML 配置文件
編輯:XML詳解     

簡介

作為一條通用規則,開發任何稍微復雜的軟件時,最好花點時間確定產品的重要配置變量,並將其從標准變量名稱空間中取出來放到單獨的位置。這樣處理後就能形成集中的應用程序配置信息存儲庫,從而簡化在不同環境中工作時對產品的修改。還有助於開發人員熟悉和理解產品成功運行所需要的重要信息。

傳統上,配置變量存儲在一個(或多個)配置文件中。這些變量常常用 XML 表示,XML 提供了一個靈活的框架允許文檔作者使用自定義的標簽和標記描述內容。多數情況下,開發人員還需要建立與這些 XML 配置文件交互的用戶接口,讀取和使用包含的配置數據。

XJConf for PHP 可幫助 PHP 開發人員完成這項任務。這個開源的包提供了一種 API,從配置文件中提取 XML 編碼的信息,轉化成原生數據結構直接在應用程序中使用。同樣地,它也為所有的 PHP 應用程序提供了一種健壯的、易用的部件。


安裝需要的軟件

XJConf 包由 Frank Kleine 和 Stephan Schmidt 維護,按照 GNU LGPL 協議在 PHP 社區發布。它需要 PHP 5.0(或更高版本),最簡單的安裝方法是使用 PEAR 自動安裝程序,後者默認情況下包含在 PHP 中。安裝只需在 shell 提示符下輸入下列命令即可:

shell> pear channel-discover pear.PHP-tools.Net

shell> pear install pat/XJConfForPHP-alpha

PEAR 安裝程序將連接到新的通道,下載這個程序包並安裝到系統中適當的位置。本文使用的是 XJConf for PHP V. 0.2.0。

手動安裝需要訪問主頁,下載源代碼壓縮包,手動解壓到目標位置。可以在本文的 參考資料 部分找到該程序包的主頁以及正在開發版本的鏈接。需要注意的是手工安裝之前必須對 PEAR 程序包的組織結構有所了解。

最後一點要求:XJConf for PHP 需要啟用 PHP 的 XMLreader 擴展。PHP 5.1.0 或以上版本默認啟用該擴展。老版本 PHP 用戶可從 PHP 手冊(鏈接見 參考資料)的適當章節獲取詳細信息和激活方法。

本文假設您使用過 PHP 和 XML,熟悉 PHP 的簡單和復雜數據類型。假設對一般 OOP 概念和 PHP 5 的類模型有一定的了解,對 PHP 文檔對象模型(DOM)擴展生成 XML 樹也有所了解。


理解基本用法

XJConf 為 PHP 應用程序開發人員提供了一個 API,可以讀取 XML 格式配置文件並轉化成原生 PHP 數據類型或自定義對象。然後即可按照通常的方式在 PHP 腳本中使用這些類型或對象。任何基於 XJConf 的程序都包括三部分:

  • XML 格式的配置文件
  • 解析和提取配置文件數據的 PHP 腳本
  • 將配置文件中的元素映射到原生 PHP 結構的定義文件

最好用一個例子來說明三者之間的聯系。清單 1 顯示了關於寵物貓的配置文件:


清單 1. XML 配置文件(cat.XML)
                        
<?XML version='1.0'?>
<cat>
 <name>Martha</name>
 <age>4</age>
 <breed>Siamese</breed>
</cat>
 

假設需要將這些配置值讀入 PHP 應用程序。首先要創建一個定義文件,將 清單 1 中的每個元素映到一種 PHP 原生數據類型。清單 2 給出了一個例子:


清單 2. XJConf 定義文件(defs.XML)
                        
<defines>
 <tag name="name" type="string"/>
 <tag name="breed" type="string"/>
 <tag name="age" type="integer"/>
</defines>
 

先研究一下定義文件的結構,因為理解該文件對後面所有的例子至關重要。外層的 <defines> 元素包含一系列 <tag> 元素,分別代表 XML 配置文件中的一個元素。每個 <tag> 必須至少具有 nametype 屬性。name 屬性指定配置文件中的元素名,type 屬性則指定對應的 PHP 數據類型。常見的基本類型有 stringintegerboolean,不過,後面將看到還能將元素映射為數組或自定義類。

最後還需要一個 PHP 腳本初始化 XJConf 實例,並使用 清單 2 中的定義檢索配置數據。清單 3 顯示了需要的 PHP 代碼:


清單 3. 讀取 XML 配置數據的 PHP 腳本
                        
<?php
// include XJConf class file
include_once 'XJConf/XJConfLoader.PHP';

// load facade
XJConfLoader::load('XJConfFacade');
$conf = new XJConfFacade();

// attach definitions to parser
$conf->addDefinition('defs.xml');

// parse XML
$conf->parse('cat.xml');

// Access XML element values
echo $conf->getConfigValue('name') . " is " . $conf->getConfigValue('breed') 
. " and " . $conf->getConfigValue('age') . " year(s) old.";
?>
 

腳本的輸出結果如 清單 4 所示:


清單 4. 清單 3 的輸出結果
                        
Martha is Siamese and 4 year(s) old.
 

仔細看看 清單 3,很容易理解其作用。清單 3 首先讀入需要的類定義文件,然後加載和初始化 XJConf facade 對象。在 XJConf 中,該對象為 DefinitionParser 方法和 XMLParser 方法提供了通用接口,前者處理 清單 2 中的定義文件,後者處理 清單 1 中的 XML 格式配置文件。

首先,腳本調用 XJConfFacade 對象的 addDefinition() 方法從 清單 2 中讀取各種標簽定義並將這些定義添加到對象中。然後,該對象的 parse() 方法解析 清單 1 中的配置數據文件。解析過程中,配置文件中的元素和數據轉化成類似 PHP 關聯數組的鍵-值對。

解析一旦完成(如果 XML 文件定義有錯誤則終止並報告錯誤),就可以用 XJConfFacade 對象的 getConfigValue() 方法訪問鍵和值了,該方法接收鍵名作為參數返回對應的值。因此,在 清單 4 中,對 getConfigValue('name') 的調用將返回配置文件 cat.XML清單 1)中 <name> 元素的值,即 Martha

現在修改配置文件(清單 1)中的值,如 清單 5 所示:


清單 5. 修改後的配置文件
                        
<?XML version='1.0'?>
<cat>
 <name>Tom</name>
 <age>1</age>
 <breed>Norwegian</breed>
</cat>
 

現在重新運行 清單 4 中的 PHP 腳本,結果如 清單 6 所示:


清單 6. 修改後的輸出結果
                        
Tom is Norwegian and 1 year(s) old.
 

注意,訪問修改後的配置數據不需要改變 清單 4 中的代碼。因而,在單獨的文件中存儲配置變量並使用 XJConf 這樣的工具對其進行訪問的優點就很清楚了:全局性的修改只需變動一個文件,修改會立即反映到整個應用程序。


配置數組

簡單的數據類型僅僅是冰山一角 — XJConf 還能夠定義相關配置變量的集合,並將其轉化成原生 PHP 數組。XJConf 同時支持數字索引數組和關聯數組。

為說明其原理,清單 7 創建了一個包含一組值的配置文件。


清單 7. 包含一組相關項的數據文件(collection.XML)
                        
<?XML version='1.0'?>
<root>
 <collection>
 <item letter="a">apples</item>
 <item letter="p">pears</item>
 <item letter="o">oranges</item>
 </collection>
</root>
 

清單 8 是對應的定義文件:


清單 8. 定義文件(defs.XML)
                        
<defines>
 <tag name="collection" type="array" />
 <tag name="item" type="string" keyAttribute="letter" />
</defines>
 

注意定義文件中 type 屬性的值:<collection> 元素映射到一個數組,嵌套的 <item> 映射為簡單字符串值。清單中還引入了一個新屬性:keyAttribute 屬性,它告訴 XJConf 設置輸出關聯數組的鍵時使用哪個元素屬性。

清單 9 中的 PHP 代碼解析和顯示上述配置數據:


清單 9. 將 XML 配置數據讀入 PHP 數組的 PHP 腳本
                        
<?php
// include XJConf class file
include_once 'XJConf/XJConfLoader.PHP';

// load facade
XJConfLoader::load('XJConfFacade');
$xml = new XJConfFacade();

// attach definitions to parser
$xml->addDefinition('defs.xml');

// parse XML
$xml->parse('collection.xml');

// Access XML element values
print_r($XML->getConfigValue('collection'));
?>
 

清單 10 顯示了輸出結果:


清單 10. 清單 9 的輸出結果
                        
Array
(
 [a] => apples
 [p] => pears
 [o] => oranges
)
 

通過把 keyAttribute 設置為 letter,XJConf 自動將每個 <item> 元素的 letter 屬性的值賦給輸出關聯數組對應的鍵。

喜歡用一般的數字索引數組嗎?只需要修改定義文件並將 keyAttribute 值設為特殊符號 __none


清單 11. 修改後的定義文件(defs.XML)
                        
<defines>
 <tag name="collection" type="array" />
 <tag name="item" type="string" keyAttribute="__none" />
</defines>
 

輸出結果如 清單 12 所示:


清單 12. 清單 9 的輸出結果
                        
Array
(
 [0] => apples
 [1] => pears
 [2] => oranges
)
 

現在看一個實際的應用:根據 XML 配置文件中的變量配置數據庫連接。假設配置文件如 清單 13 所示:


清單 13. XML 數據庫配置文件(conf.XML)
                        
<?XML version='1.0'?>
<conf>
 <database>
 <user>root</user>
 <pass>MySQL123</pass>
 <host>localhost</host>
 <db>test</db>
 </database>
</conf>

並且,假設目標是將這些配置值讀入一個數組,使用這個數組連接到一個 MySQL 數據庫服務器。首先要使用定義文件將 XML 映射到數組,如 清單 14 所示:


清單 14. 定義文件(defs.XML)
                        
<defines>
 <tag name="database" type="array">
 <tag name="user" type="string" />
 <tag name="pass" type="string" />
 <tag name="host" type="string" />
 <tag name="db" type="string" />
 </tag>
</defines>
 

清單 15 中的 PHP 腳本嘗試使用這些數據連接到 MySQL 數據庫:


清單 15. 從 XML 文件讀取數據庫配置數據的 PHP 腳本
                        
<?php
// include XJConf class file
include_once 'XJConf/XJConfLoader.PHP';

// load facade
XJConfLoader::load('XJConfFacade');
$xml = new XJConfFacade();

// attach definitions to parser
$xml->addDefinition('defs.xml');

// parse XML
$xml->parse('conf.xml');

// Access database configuration array
$db = $XML->getConfigValue('database');

// test MySQL connection
$conn = mysql_connect($db['host'], $db['user'], $db['pass']) 
or die('Connection error!');
mysql_select_db($db['db'], $conn) or dIE('Database selection error!');
MySQL_close($conn);
echo 'Database test successful';
?>
 

清單 15 使用 XJConf 創建數組 $db,並使用配置文件 conf.XML 中的數據填充該數組。然後使用該數組打開到 MySQL 數據庫服務器的連接,並選擇要使用的數據庫。如前面的例子所說明的那樣,腳本的關鍵在於定義文件 defs.XML,它告訴 XJConf 如何將配置文件中的元素映射到 PHP 數組。


配置類和對象

然而,XJConf 的強大功能在於對 PHP 類和對象的支持。使用 XJConf,從 XML 配置文件實例化自定義對象非常簡單,甚至可使用配置文件中的數據表示配置對象的屬性。

作為一個例子,首先定義簡單的 RectangularObject 類,它向配置 API 公開了三個主要屬性:長、寬和高。該類還公開了一個 getVolume() 方法,可根據這些屬性計算對象的體積。代碼如 清單 16 所示:


清單 16. PHP 類定義(RectangularObject.PHP)
                                
<?PHP
class RectangularObject {

 // declare propertIEs
 private $length;
 private $height;
 private $width;
 
 // declare constructor
 function __construct() {
 return true; 
 }
 
 // declare setter methods
 function setLength($l) {
 $this->length = $l;
 }
 
 function setHeight($h) {
 $this->height = $h;
 }
 
 function setWidth($w) {
 $this->width = $w;
 }
 
 // declare other methods
 function getVolume() {
 return ($this->length * $this->width * $this->height);
 }
}
?>
 

清單 17 包含 RectangularObject 類對應的 XML 格式的配置數據:


清單 17. XML 配置文件(data.XML)
                                
<?XML version='1.0'?>
<conf>
 <rectangularobject>
 <height>20</height>
 <width>15</width>
 <length>10</length>
 </rectangularobject>
</conf>
 

將數據映射到對象實例很簡單。只需將 type 屬性設置為需要實例化的類名。清單 18 顯示了對應的定義:


清單 18. XJConf 定義文件(defs.XML)
                                
<defines>
 <tag name="rectangularobject" type="RectangularObject">
 <tag name="length" type="integer"/>
 <tag name="width" type="integer"/>
 <tag name="height" type="integer"/> 
 </tag>
</defines>
 

只要正確命名了 setter 方法,XJConf 將做兩件事:

  1. 實例化該類的一個對象。
  2. 對嵌套的每個元素調用 setter 方法自動配置對象的特性。

因此,對 <length> 元素自動調用 setLength() 方法,對 <height> 元素自動調用 setHeight() 方法,依此類推。

清單 1920 分別顯示了 PHP 代碼和輸出結果:


清單 19. 根據 XML 數據實例化和配置對象的 PHP 腳本
                                
<?php
// include XJConf class file
include_once 'XJConf/XJConfLoader.php';

// load class definition
include_once 'RectangularObject.PHP';

// load facade
XJConfLoader::load('XJConfFacade');
$xml = new XJConfFacade();

// attach definitions to parser
$xml->addDefinition('defs.xml');

// parse XML
$xml->parse('data.xml');

// Access object instance
$instance = $XML->getConfigValue('rectangularobject');
print 'The volume of the object is: ' . $instance->getVolume() . ' units';
?>
 

清單 20 顯示了輸出結果:


清單 20. 清單 19 的輸出結果
                                
The volume of the object is: 3000 units
 


配置默認值和強制值

也可用屬性代替嵌套標記編寫 XML 配置文件,用這些屬性配置對象實例。要查看實際效果,首先修改 清單 17 以使用屬性代替嵌套元素:


清單 21. 修改後的 XML 配置文件(data.XML)
                                
<?XML version='1.0'?>
<conf>
 <rectangularobject height="20" width="15" length="10" />
</conf>
 

顯然,還必須修改定義文件:


清單 22. 修改後的 XJConf 定義文件(defs.XML)
                                
<defines>
 <tag name="rectangularobject" type="RectangularObject">
 <attribute name="length" type="integer"/>
 <attribute name="width" type="integer"/>
 <attribute name="height" type="integer"/> 
 </tag>
</defines>
 

所做的修改包括:使用 <attribute> 元素替換 <tag> 元素,以通知 XJConf 在設置對象特性時考慮指定標記的屬性,而非其子元素的 CDATA 內容。

您還可以為特定的配置變量設置默認值,或將某個配置變量標記為強制值,這可通過在定義文件中使用 defaultrequired 屬性實現。看一下 清單 23,它將 lengthwidth 配置變量設置為強制值,而將 height 設置為默認值:


清單 23. 包含 ‘默認’ 和 ‘強制’ 限制的 XJConf 定義文件
                                
<defines>
    <tag name="rectangularobject" type="RectangularObject">
        <attribute name="length" type="integer" required="true" />
        <attribute name="width" type="integer" required="true" />
        <attribute name="height" type="integer" default="10" />    
    </tag>
</defines>
        

如果您現在嘗試讀取一個缺少強制值的配置文件,XJConf 將拋出 MissingAttributeException 異常(參見圖 1):


圖 1. 缺少強制值時將拋出一個 XJConf 異常
缺少強制值時將拋出一個 XJConf 異常

在前面的示例中,您了解了 XJConf 可以自動調用合適的 setter 方法來配置對象實例。setter 方法的自動調用主要取決於對 setter 方法的正確命名,從而能夠輕易地進行識別並映射到元素/屬性名。如果您不喜歡使用這種方法,那麼還可以通過定義文件中的 setter 屬性,顯式地為每個元素/屬性定義 setter 方法。清單 24 演示了對 lengthwidth 屬性使用定制的 setter 方法:


清單 24. XJConf 定義文件使用了定制的 setter 方法
                                
<defines>
    <tag name="rectangularobject" type="RectangularObject">
        <attribute name="length" setter="setL" />
        <attribute name="width" setter="setW" />
        <attribute name="height" />    
    </tag>
</defines>
        

您可能已經了解到,PHP 5 的一個新特性就是引入了特殊的 __set()__get() 重載方法。即使沒有為某個對象特性顯式定義 setter 或 getter 方法,您也可以使用這兩種重載方法設置對象特性。清單 25清單 16 中的類定義進行了修改,演示了這種方法的功能:


清單 25. 使用了 __set() 和 __get() 的 PHP 類定義
                                
<?PHP
class RectangularObject {

    // declare propertIEs
    public $length;
    public $height;
    public $width;
    
    // declare constructor
    function __construct() {
        return true;    
    }
    
    // declare generic setter method
    public function __set($property, $value) {
        $this->$property = $value;
    }
    
    // declare generic getter method
    public function __get($property) {
        return $this->property;
    }
    
    // declare other methods
    function getVolume() {
        return ($this->length * $this->width * $this->height);
    }
}
?>
        

假設數據和定義文件分別與 清單 17清單 18 相同,並運行 清單 26 中的 PHP 腳本:


清單 26. 使用 XJConf 配置文件配置對象的 PHP 腳本
                                
<?php
// include XJConf class file
include_once 'XJConf/XJConfLoader.php';

// load class definition
include_once 'RectangularObject.PHP';

// load facade
XJConfLoader::load('XJConfFacade');
$xml = new XJConfFacade();

// attach definitions to parser
$xml->addDefinition('defs.xml');

// parse XML
$xml->parse('data.xml');

// Access object instance
$instance = $XML->getConfigValue('rectangularobject');
print 'The volume of the object is: ' . $instance->getVolume() . ' units';
?>
        

將得到如下輸出:


清單 27. 清單 26 的輸出
                                
The volume of the object is: 3000 units
        

您將注意到,盡管類定義中缺少顯式定義的 setter 方法,XJConf 仍然能夠通過 __set() 方法配置對象的特性。同樣,這個特性可以顯著減少類定義的長度,並使您的應用程序代碼更容易維護和讀取。

在 V. 0.2.0 版本以前,XJConf for PHP 並不支持這些特殊的重載方法,並且嘗試使用這些方法將使 PHP 腳本出現致命錯誤。

最後,您將看到,在解析 XML 定義和數據之前,上文中的所有清單都可以顯式地加載類定義文件。通過其獨有的類加載器,XJConf 可為您自動完成這一任務;可從 XJConf for PHP 包獲得這些特性的使用示例(參見 參考資料)。如果您的應用程序中包含了大量類的話,那麼您一定要查看這些示例用法。


項目:配置復雜的類樹

如上文中的清單所示,XJConf 可以使用屬性或子元素正確配置實例化的對象。因此,除了一種情況以外,使用這兩種技巧可以很方便地定義方法。然而,當將復雜樹的一個或多個對象鏈接到另一對象時,這種情況下使用子元素要勝於使用屬性。

為進一步解釋,請看 清單 28,它定義了一些類:


清單 28. 一些 PHP 類定義(App.PHP)
                                
<?PHP
// configuration class
class Config {
    // declare properties
    private $host;
    private $port;
    private $user;
    private $pass;
    
    // declare methods
    function setConfig($confArray) {
        if (isset($confArray['host'])) {
            $this->host = $confArray['host'];
        }    
        if (isset($confArray['port'])) {
            $this->port = $confArray['port'];
        }    
        if (isset($confArray['user'])) {
            $this->user = $confArray['user'];
        }    
        if (isset($confArray['pass'])) {
            $this->pass = $confArray['pass'];
        }    
    }    
}

// these inherit from the Config class
class DBConfig extends Config {
}

class SMTPConfig extends Config {
}

// application class
class App {
    // declare propertIEs
    public $DBConfig;
    public $SMTPConfig;
    
    // declare constructor
    public function __construct() {
        return true;    
    }
    
    // declare setter methods
    function setDBConfig($db) {
        $this->DBConfig = $db;    
    }    
    function setSMTPConfig($smtp) {
        $this->SMTPConfig = $smtp;    
    }    
    
    // declare getter methods
    function getDBConfig() {
        return $this->DBConfig;    
    }    
    function getSMTPConfig() {
        return $this->SMTPConfig;    
    }    
}
?>
        

清單 28 首先定義了 Config 類,它公開了一個通用 API 來接收一組有關的服務器訪問參數。DBConfigSMTPConfig 類是 Config 類的子類,分別用來保存一個數據庫服務器和一個 SMTP 服務器的訪問參數。DBConfigSMTPConfig 對象用於 App class,後者表示一個應用程序。這個 App 類公開 setter 和 getter 方法,以在需要時設置和檢索對應的 Config 類。

這些類的配置通過一個 XML 配置文件完成,如 清單 29 所示:


清單 29. 一個 XML 配置文件(conf.XML)
                                
<?XML version='1.0'?>
<configuration>
  <app>
    <db>
      <array>
        <host>localhost</host>
        <user>guest</user>
        <pass>MySQL123</pass>
      </array>
    </db>
    
    <smtp>
      <array>
        <host>mail.domain.com</host>
        <user>sluggo</user>
        <pass>mypass</pass>
        <port>25</port>
      </array>
    </smtp>
  </app>
</configuration>
        

清單 29 中的 XML 數據轉換為完整配置的 App 對象所需的膠合代碼(glue)位於定義文件(清單 30)和對應的 PHP 腳本(清單 31)中。首先查看定義文件:


清單 30. 一個 XJConf 定義文件(defs.XML)
                                
<defines>
  <tag name="app" type="App">  
    <tag name="db" type="DBConfig" setter="setDBConfig">
        <tag name="array" type="array" keyAttribute="name" setter="setConfig">
            <tag name="host" type="string" />
            <tag name="user" type="string" />
            <tag name="pass" type="string" />
        </tag>
    </tag>
    <tag name="smtp" type="SMTPConfig" setter="setSMTPConfig">
        <tag name="array" type="array" keyAttribute="name" setter="setConfig">
            <tag name="host" type="string" />
            <tag name="port" type="integer" />
            <tag name="user" type="string" />
            <tag name="pass" type="string" />
        </tag>
    </tag>
  </tag>
</defines>
        

它是如何工作的呢?實際上沒有看上去那麼復雜:

  1. 當 XJConf 遇到配置文件中的 <app> 元素時,它將對 App 對象實例進行實例化。從 清單 28 中的類定義可以看出,App 對象公開了 setDBConfig()setSMTPConfig() 方法。
  2. 當 XJConf 接下來遇到 <db><smtp> 元素時,它將對 DBConfigSMTPConfig 對象進行實例化,並調用該對象的 setConfig() setter 方法。這個 setter 方法的輸入為一個配置參數數組,由 <array> 元素及其子元素生成。
  3. 然後將 步驟 2 創建的 DBConfigSMTPConfig 對象通過 setter 方法 setDBConfig()setSMTPConfig() 連接回 App 對象。您將注意到,定義文件通過 setter 屬性也對這些方法進行了命名。

    然後,通過調用 getConfigValue() 從 PHP 腳本檢索生成的 App 對象實例。在類似的結構中,通過調用 App::getDBConfig()App::getSMTPConfig() 也可以檢索經過實例化和配置的 DBConfigSMTPConfig 對象。如 清單 31 所示:


清單 31. 配置復雜類樹的 PHP 腳本
                                
<?php
// include XJConf class file
include_once 'XJConf/XJConfLoader.php';

// include class file
include_once 'App.PHP';

// load facade
XJConfLoader::load('XJConfFacade');
$xml = new XJConfFacade();

// attach definitions to parser
$xml->addDefinition('defs.xml');

// parse XML
$xml->parse('conf.xml');

// Access objects
$app = $XML->getConfigValue('app');
$db = $app->getDBConfig();
$smtp = $app->getSMTPConfig();

// display App object
print_r($app);
?>
        

清單 32 顯示了輸出:


清單 32. 清單 31 的輸出
                                
App Object
(
    [DBConfig] => DBConfig Object
        (
            [host:private] => localhost
            [port:private] => 
            [user:private] => guest
            [pass:private] => MySQL123
        )

    [SMTPConfig] => SMTPConfig Object
        (
            [host:private] => mail.domain.com
            [port:private] => 25
            [user:private] => sluggo
            [pass:private] => mypass
        )

)
        


項目:構建一個基於 web 的配置接口

對於很多項目來說,另一個常見的實際需求就是基於 Web 的配置工具,它允許用戶通過一個 Web 表單輸入配置數據並將數據以 XML 格式保存到文件。XJConf 在此方面功能有限。雖然它提供了一個功能強大的 API 將 XML 格式的配置數據讀取到 PHP 數據結構,它並沒有提供任何方法將數據寫回文件中。因此,在這些情形下,需要在 PHP 中為 XJConf 補充 DOM 擴展,這個擴展可以提供 API 動態構建 XML 樹並將它寫入文件。

清單 33 演示了這兩種工具的使用:


清單 33. 編輯並將數據保存到文件的 PHP 腳本
                                
<?php
// include XJConf class file
include_once 'XJConf/XJConfLoader.php';

$dataFile = 'config.xml';
$defsFile = 'defs.xml';
    
// if form is not submitted
if (!isset($_POST['submit'])) {
    
    // check to see if config file exists
    if (file_exists($dataFile)) {

        // load facade
        XJConfLoader::load('XJConfFacade');
        $xml = new XJConfFacade();

        // attach definitions to parser
        $xml->addDefinition($defsFile);

        // parse XML
        $xml->parse($dataFile);
    } 
?>
<html>
 <head><basefont face="Arial"></head>
 <body>
  <h2>Configuration</h2>
  <table border="0" cellspacing="5" cellpadding="5">
   <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
    <tr>
     <td>POP3 host name</td>
     <td><input type="text" name="pop3_host" 
     value="<?php echo (isset($xml)) ? $xml->getConfigValue('host') : null; ?>"
     ></td>
    </tr>
    <tr>
     <td>POP3 port</td>
     <td><input type="text" name="pop3_port" 
     value="<?php echo (isset($xml)) ? $xml->getConfigValue('port') : null; ?>"
     ></td>
    </tr>
    <tr>
     <td>POP3 user name</td>
     <td><input type="text" name="pop3_user" 
     value="<?php echo (isset($xml)) ? $XML->getConfigValue('user') : null; ?>"
     ></td>
    </tr>
    <tr>
     <td>POP3 user passWord</td>
     <td><input type="text" name="pop3_pass" 
     value="<?PHP echo (isset($xml)) ? $XML->getConfigValue('pass') : null; ?>"
     ></td>
    </tr>
    <tr>
     <td colspan="2" align="center"><input type="submit" name="submit" 
     value="Save Configuration"></td>
    </tr>
   </form>
  </table>           
 </body>
</Html>
<?PHP
} else {
    // do some input validation here
    
    // write the submitted values to a configuration file
    // generate DOM tree and root node
    $dom = new DOMDocument('1.0', 'iso-8859-1');
    $conf = $dom->createElement('conf');
    $dom->appendChild($conf);    
    
    // attach child nodes
    $host = new DOMElement('host', $_POST['pop3_host']);
    $port = new DOMElement('port', $_POST['pop3_port']);
    $user = new DOMElement('user', $_POST['pop3_user']);
    $pass = new DOMElement('pass', $_POST['pop3_pass']);
    $conf->appendChild($host);
    $conf->appendChild($port);
    $conf->appendChild($user);
    $conf->appendChild($pass);
    
    // save to configuration file
    $dom->formatOutput = true;
    if ($dom->save($dataFile)) {
        echo 'Configuration successfully saved!';
    }
}
?>
        

清單 33 分為兩大部分:用一個表單顯示當前配置(如果存在)並允許用戶進行編輯,用一個表單處理程序接受新配置並保存為文件。腳本的前半部分使用 XJConf 解析 XML 配置數據並將其內容檢索到 PHP 變量中;然後使用這些變量預填充 Web 表單的字段。

清單 34 包含了 清單 33 所使用的簡單定義文件:


清單 34. 一個 XJConf 定義文件(defs.XML)
                                
<defines>
  <tag name="host" type="string"/>  
  <tag name="port" type="integer"/>  
  <tag name="user" type="string"/>  
  <tag name="pass" type="string"/>  
</defines>
        

提交表單後,將由 PHP 中的 DOM 擴展處理。將創建一個 DOMDocument 實例,然後將子元素連接到其上以保存用戶輸入的配置數據。當完成整個 DOM 樹的構建後,將使用 DOMDocument::save() 方法將它寫回到配置文件。

圖 2 演示了表單的外觀:


圖 2. 用來編輯和保存配置數據的 Web 表單
用來編輯和保存配置數據的 Web 表單

清單 35 演示了由這個腳本編寫的配置文件:


清單 35. 清單 34 創建的示例文件
                                
<?XML version="1.0" encoding="iso-8859-1"?>
<conf>
  <host>localhost</host>
  <port>110</port>
  <user>joelle</user>
  <pass>guessme</pass>
</conf>
            

如前面的清單所示,XJConf 包提供了易於使用的靈活的 API,它可以讀取 XML 格式的配置文件並將其中的值轉換為 PHP 數據結構。除了簡單的字符串和數字值外,它還支持使用數組和對象,並提供了內置的智能,可以使用 setter 方法自動配置最新實例化的對象。綜上所述,任何 PHP 開發人員都值得將其集成到工具包中。如果您需要在 PHP 應用程序和 XML 配置文件之間建立一個接口,那麼請親自嘗試使用它吧!


XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved