此片段疑為某 XML 生成類別 (如 sql2xml 或自訂 ORM) 的內部方法集合,處理選項設定、DOM 節點建立、UTF-8 編碼、陣列深度合併、XML 字串匯入、XPath 查詢等輔助功能。
// 設定選項,支援巢狀陣列覆蓋合併
function SetOptions($options) {
foreach ($options as $option => $value) {
if (is_array($value) && !$delete) {
foreach ($value as $suboption => $subvalue) {
$this->{$option}[$suboption] = $subvalue;
}
} else {
$this->$option = $value;
}
}
}
// 陣列深度合併 (clobber 模式:後者覆蓋前者同鍵值)
function array_merge_clobber($a1, $a2) {
if (!is_array($a1) || !is_array($a2)) return false;
$newarray = $a1;
foreach ($a2 as $key => $val) {
if (is_array($val) && is_array($newarray[$key])) {
$newarray[$key] = $this->array_merge_clobber($newarray[$key], $val);
} else {
$newarray[$key] = $val;
}
}
return $newarray;
}
用途: 類別配置初始化,允許部分覆蓋巢狀設定 (如資料庫連線參數、輸出格式選項)。
// 可被子類覆寫的掛鉤方法
function insertNewResult(&$metadata) { /* 建立 根節點 */ }
function insertNewRow($parent_row, $res, $key, &$metadata) { /* 建立 節點 */ }
function insertNewElement($parent, $res, $key, &$metadata, &$subrow) {
return $parent->new_child($metadata[$key]["name"], $this->xml_encode(trim($res[$key])));
}
function addTableInfo($key, $value, &$metadata) { /* 擴充表資訊 */ }
設計模式: Template Method,核心流程在父類,關鍵節點建立委託子類自訂 (如自定義標籤名、屬性、CDATA 等)。
function xml_encode($text) {
if (function_exists('iconv') && isset($this->encoding_from, $this->encoding_to)) {
ini_set('track_errors', 1);
// 逸出 & 和 < (非標籤情況)
$text = iconv($this->encoding_from, $this->encoding_to,
preg_replace('/&(?!#?\w+;)/', '&',
preg_replace('/', '<', $text)
)
);
if (!isset($text)) {
// iconv 錯誤處理
return PEAR::raiseError($php_errormsg ?? 'iconv error', null, PEAR_ERROR_DIE);
}
return $text;
} else {
// 回退:簡單逸出 & 和 <
return trim(preg_replace('/&(?!#?\w+;)/', '&', preg_replace('/', '<', $text)));
}
}
關鍵點:
iconv 跨編碼轉換 (如 Big5 → UTF-8)。& 非實體引用時轉 &,< 非標籤時轉 <。function doXmlString2Xml($string, $xpath = null) {
// PHP 4.0.7+ 使用 DOMXML 物件操作
// PHP 4.0.6 回退:字串拼接後重新解析 (效能差、易錯)
// 支援 XPath 篩選匯入片段
// 支援 root 路徑前綴 (在指定父節點下建立結構再匯入)
}
現代替代: DOMDocument::loadXML() + DOMXPath + importNode(),標準、高效、無版本相容包袱。
function setEncoding($encoding_from = 'ISO-8859-1', $encoding_to = 'UTF-8') {
$this->encoding_from = $encoding_from;
$this->encoding_to = $encoding_to;
}
function SetParentTables($parentTables) {
foreach ($parentTables as $table => $parent) {
$table_info['parent_table'][$table] = $parent;
}
$this->SetOptions(['user_tableInfo' => $table_info]);
}
用於主從表關聯 XML 輸出 (如訂單-明細),指定父表關鍵欄位。
function getXpathValue($expr) {
$xpth = $this->xmldoc->xpath_new_context();
$xnode = xpath_eval($xpth, $expr);
if (isset($xnode->nodeset[0])) {
return $xnode->nodeset[0]->children()[0]->content;
}
return null;
}
function getXpathChildValues($expr) {
$xpth = $this->xmldoc->xpath_new_context();
$xnode = xpath_eval($xpth, $expr);
if (isset($xnode->nodeset[0])) {
$values = [];
foreach ($xnode->nodeset[0]->children() as $child) {
$values[$child->{$this->tagname}] = $child->children()[0]->content;
}
return $values;
}
return null;
}
class XmlBuilder {
private DOMDocument $dom;
private DOMElement $root;
private string $encoding = 'UTF-8';
public function __construct(string $rootName = 'root', string $encoding = 'UTF-8') {
$this->dom = new DOMDocument('1.0', $encoding);
$this->dom->formatOutput = true;
$this->root = $this->dom->createElement($rootName);
$this->dom->appendChild($this->root);
}
public function addResult(array $data, array $metadata): DOMElement {
$result = $this->dom->createElement('result');
foreach ($data as $row) {
$rowEl = $this->dom->createElement('row');
foreach ($row as $key => $value) {
$el = $this->dom->createElement($metadata[$key]['name'] ?? $key);
$el->textContent = (string)$value; // 自動逸出
$rowEl->appendChild($el);
}
$result->appendChild($rowEl);
}
$this->root->appendChild($result);
return $result;
}
public function importXmlString(string $xml, string $xpath = ''): void {
$fragment = new DOMDocument();
$fragment->loadXML($xml);
$xpathObj = new DOMXPath($fragment);
$nodes = $xpath ? $xpathObj->query($xpath) : [$fragment->documentElement];
foreach ($nodes as $node) {
$imported = $this->dom->importNode($node, true);
$this->root->appendChild($imported);
}
}
public function xpathValue(string $expr): ?string {
$xpath = new DOMXPath($this->dom);
$node = $xpath->query($expr)->item(0);
return $node?->textContent;
}
public function xpathChildValues(string $expr): array {
$xpath = new DOMXPath($this->dom);
$node = $xpath->query($expr)->item(0);
if (!$node) return [];
$values = [];
foreach ($node->childNodes as $child) {
if ($child->nodeType === XML_ELEMENT_NODE) {
$values[$child->localName] = $child->textContent;
}
}
return $values;
}
public function save(string $filename): void { $this->dom->save($filename); }
public function output(): string { return $this->dom->saveXML(); }
}
此代碼片段展示了早期 PHP (DOMXML 擴充) 時代 XML 處理的常見模式:編碼轉換、Template Method 擴充、XPath 查詢、字串匯入。現代開發請直接使用標準 DOMDocument + DOMXPath,享受完整 Unicode 支援、命名空間處理、Schema 驗證、XSLT 轉換等企業級功能,且無需維護相容層代碼。