XML 配置文件
尽管文本文件易于阅读及编辑,但却不如 XML 文件流行。另外,XML 有众多适用的编辑器,这些编辑器能够理解标记、特殊符号转义等等。所以配置文件的 XML 版本会是什么样的呢?清单 11 显示了 XML 格式的配置文件。
清单 11. config.xml
<?xml version="1.0"?> <config> <Title>My App</Title> <TemplateDirectory>tempdir</TemplateDirectory> </config>
|
清单 12 显示了使用 XML 来装载配置设置的 Configuration 类的更新版。
清单 12. xml1.php
<?php class Configuration { private $configFile = 'config.xml'; private $items = array(); function __construct() { $this->parse(); } function __get($id) { return $this->items[ $id ]; } function parse() { $doc = new DOMDocument(); $doc->load( $this->configFile ); $cn = $doc->getElementsByTagName( "config" ); $nodes = $cn->item(0)->getElementsByTagName( "*" ); foreach( $nodes as $node ) $this->items[ $node->nodeName ] = $node->nodeValue; } } $c = new Configuration(); echo( $c->TemplateDirectory."\n" ); ?>
|
看起来 XML 还有另一个好处:代码比文本版的代码更为简洁、容易。为保存这个 XML,需要另一个版本的 save 函数,将结果保存为 XML 格式,而不是文本格式。
清单 13. xml2.php
... function save() { $doc = new DOMDocument(); $doc->formatOutput = true; $r = $doc->createElement( "config" ); $doc->appendChild( $r ); foreach( $this->items as $k => $v ) { $kn = $doc->createElement( $k ); $kn->appendChild( $doc->createTextNode( $v ) ); $r->appendChild( $kn ); } copy( $this->configFile, $this->configFile.'.bak' ); $doc->save( $this->configFile ); } ...
|
这段代码创建了一个新的 XML 文档对象模型(Document Object Model ,DOM),然后将 $items 数组中的所有数据都保存到这个模型中。完成这些以后,使用 save 方法将 XML 保存为一个文件。
使用数据库
最后的替代方式是使用一个数据库保存配置元素的值。那首先要用一个简单的模式来存储配置数据。下面是一个简单的模式。
清单 14. schema.sql
DROP TABLE IF EXISTS settings; CREATE TABLE settings ( id MEDIUMINT NOT NULL AUTO_INCREMENT, name TEXT, value TEXT, PRIMARY KEY ( id ) );
|
这要求进行一些基于应用程序需求的调整。例如,如果想让配置元素按照每个用户进行存储,就需要添加用户 ID 作为额外的一列。
为了读取及写入数据,我编写了如图 15 所示的更新过的 Configuration 类。
清单 15. db1.php
<?php require_once( 'DB.php' ); $dsn = 'mysql://root:password@localhost/config'; $db =& DB::Connect( $dsn, array() ); if (PEAR::isError($db)) { die($db->getMessage()); } class Configuration { private $configFile = 'config.xml'; private $items = array(); function __construct() { $this->parse(); } function __get($id) { return $this->items[ $id ]; } function __set($id,$v) { global $db; $this->items[ $id ] = $v; $sth1 = $db->prepare( 'DELETE FROM settings WHERE name=?' ); $db->execute( $sth1, $id ); if (PEAR::isError($db)) { die($db->getMessage()); } $sth2 = $db->prepare('INSERT INTO settings ( id, name, value ) VALUES ( 0, ?, ? )' ); $db->execute( $sth2, array( $id, $v ) ); if (PEAR::isError($db)) { die($db->getMessage()); } } function parse() { global $db; $doc = new DOMDocument(); $doc->load( $this->configFile ); $cn = $doc->getElementsByTagName( "config" ); $nodes = $cn->item(0)->getElementsByTagName( "*" ); foreach( $nodes as $node ) $this->items[ $node->nodeName ] = $node->nodeValue; $res = $db->query( 'SELECT name,value FROM settings' ); if (PEAR::isError($db)) { die($db->getMessage()); } while( $res->fetchInto( $row ) ) { $this->items[ $row[0] ] = $row[1]; } } } $c = new Configuration(); echo( $c->TemplateDirectory."\n" ); $c->TemplateDirectory = 'new foo'; echo( $c->TemplateDirectory."\n" ); ?>
|