虛擬社區用戶資料讀取頻繁但更新較少,每次開啟資料庫連線、查詢、解析、關閉開銷大。將單筆用戶資料序列化為 XML 檔案,按需載入,大幅降低資料庫壓力。
<?php
define("ENTER", chr(13).chr(10));
class DATA_XML {
var $parser, $tags, $on, $root, $Data = array();
function DATA_XML($filename, $root) {
$this->root = $root;
$this->parser = xml_parser_create();
xml_set_object($this->parser, $this);
xml_set_element_handler($this->parser, "tag_on", "tag_off");
xml_set_character_data_handler($this->parser, "getdata");
xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); // 嚴格大小寫
if (file_exists($filename)) {
$fp = fopen($filename, "r");
$content = fread($fp, filesize($filename));
fclose($fp);
$this->parse($content);
}
}
function parse($data) { xml_parse($this->parser, $data); }
function tag_on($parser, $tag, $attrs) {
$this->on = true;
$this->tags = $tag;
}
function tag_off($parser, $tag) { $this->on = false; }
function getdata($parser, $cdata) {
if ($this->on && $this->tags != $this->root) {
$this->Data[$this->tags] = trim($cdata); // 關鍵:標籤當鍵名
}
}
function check($str) { return strlen($str) < 1 ? ' ' : $str; }
function saveas($filename) {
$c = '<?xml version="1.0" encoding="gb2312"?>'.ENTER;
$c .= "<{$this->root}>".ENTER;
foreach ($this->Data as $key => $val) {
$c .= "<$key>".$this->check($val)."</$key>".ENTER;
}
$c .= "</{$this->root}>".ENTER;
$fp = fopen($filename, "w");
fwrite($fp, $c);
fclose($fp);
}
}
?>
<?php
// 建立新檔
$xml = new DATA_XML("path/arm.xml", "DATA");
$xml->Data["UserName"] = "關羽";
$xml->Data["Nick"] = "關雲長";
$xml->saveas("path/arm.xml");
unset($xml);
// 讀取、修改、新增、存回
$xml = new DATA_XML("path/arm.xml", "DATA");
echo $xml->Data["Nick"]; // 顯示
$xml->Data["Nick"] = "關老爺"; // UPDATE
$xml->Data["Master"] = "劉備"; // INSERT
$xml->saveas("path/arm.xml"); // 覆蓋存檔
?>
| 優點 | 缺點 |
|---|---|
| 極簡單,無資料庫依賴 | 不支援巢狀結構、陣列、屬性 |
| 單檔案對應單實體,直觀 | 併發寫入無鎖定機制,易資料遺失 |
| 適合唯讀多、寫入少場景 | 檔案大時載入解析慢,無索引 |
| 人類可讀、易備份遷移 | 編碼固定 gb2312,不支援 Unicode |
SimpleXML 或 DOMDocument 取代底層 XML Parserflock())小型專案、單機部署、用戶 Profile、設定檔、靜態內容片段、快速原型。不可用於高併發、交易性、關聯查詢場景。