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

PHP + XML + XSLT + MySQL 企業級數據發布架構:從環境搭建到實戰應用

     編輯:PHP 綜合知識

架構願景:數據與展現徹底分離

採用 PHP (數據層) → XML (中間數據格式) → XSLT (轉換邏輯) → HTML (展現層) 的管道架構,實現:

  • 數據獲取邏輯與展示模板完全解耦
  • 同一數據源輸出多種格式 (HTML, PDF, CSV, RSS, JSON)
  • 前端重構零觸動後端代碼
  • 利用 XSLT 圖靈完備特性實現複雜邏輯

環境搭建:擴展依賴與路徑陷阱

必裝 PHP 擴展 (Windows 為例)

; php.ini
extension=php_domxml.dll    ; XML DOM 操作核心
extension=php_xslt.dll      ; XSLT 處理器 (基於 libxslt)
extension=php_iconv.dll     ; 字符集轉換 (關鍵:GB2312 ↔ UTF-8)

致命坑點:PHP 安裝目錄下的 dlls/ 目錄必須加入系統 PATH 環境變量,否則 Apache 啟動報「找不到動態鏈接庫」。Linux 下需編譯安裝 libxslt、libxml2、libiconv 並指定 --with-xsl、--with-iconv。

PEAR 類庫依賴

; php.ini
include_path = ".;D:\php\pear"  ; 指向 PEAR 安裝路徑
; 需安裝: DB.php (數據庫抽象), XML_SQL2XML (SQL→XML)

修改後必須重啟 Apache 生效,僅 reload 無效。

核心代碼實戰:企業用戶信息發布

1. 數據庫表結構

CREATE TABLE yhxx (
    nsrnm VARCHAR(15) PRIMARY KEY,  -- 納稅人代碼
    qymc  VARCHAR(200) NOT NULL,    -- 企業名稱
    qydh  VARCHAR(50)               -- 電話
) ENGINE=MyISAM DEFAULT CHARSET=gb2312;

2. PHP 控制器 browseData.php

<?php
require_once "DB.php";  // PEAR DB 抽象層

// 數據庫連接配置
$dsn = "mysql://root:abcd@202.96.215.200/test";
$db = DB::connect($dsn);
if (DB::isError($db)) die($db->getMessage());

// 通用函數:讀取 XSL 模板
function readXsl($filename) {
    if (!file_exists($filename)) die("模板文件 $filename 不存在");
    return implode('', file($filename));
}

// 核心轉換函數:數據 + XSL → HTML
function getHtml($arydata, $xslstring) {
    global $db;
    include_once("XML/sql2xml.php");  // PEAR XML_SQL2XML
    
    $sql2xml = new xml_sql2xml($db);
    $sql2xml->setEncoding("GB2312");  // 指定輸出編碼
    
    // 配置 XML 結構
    $sql2xml->SetOptions([
        'tagNameRow'    => 'row',
        'tagNameResult' => 'result'
    ]);
    
    // 注入數據數組
    $sql2xml->add($arydata);
    $xmlstring = $sql2xml->getxml();  // 生成 XML 字符串
    
    // XSLT 轉換
    $arguments = [
        '/_xml' => $xmlstring,
        '/_xsl' => $xslstring
    ];
    $xh = xslt_create();
    $result = xslt_process($xh, 'arg:/_xml', 'arg:/_xsl', null, $arguments);
    xslt_free($xh);
    
    return $result ?: "XSLT 轉換失敗: " . xslt_error($xh);
}

// 業務邏輯:查詢數據
$sql = "SELECT nsrnm, qymc, qydh FROM yhxx";
$res = $db->query($sql);
if (DB::isError($res)) die("SQL 執行錯誤");

$data = [];
while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
    $data[] = $row;
}

// 載入 XSL 模板並輸出
$htmlStr = readXsl("browseData.html");  // 實為 XSL 文件
echo getHtml($data, $htmlStr);
?>

3. XSLT 模板 browseData.html (實為 .xsl)

<?xml version="1.0" encoding="gb2312"?>
<xsl:stylesheet version="1.0" xmlns:xsl="https://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="1.0" encoding="GB2312" indent="yes" />

<xsl:template match="/">
<html xmlns="https://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
    <title>企業用戶信息列表</title>
</head>
<body>
    <table border="1" cellpadding="0" cellspacing="0" style="border-collapse: collapse" width="100%">
        <thead>
            <tr style="background:#C0C0C0">
                <th width="21%">納稅人代碼</th>
                <th width="50%">企業名稱</th>
                <th width="29%">聯繫電話</th>
            </tr>
        </thead>
        <tbody>
            <xsl:for-each select="/result/row">  <!-- XPath 匹配 XML 結構 -->
            <tr>
                <td><xsl:value-of select="nsrnm" /></td>
                <td><xsl:value-of select="qymc" /></td>
                <td><xsl:value-of select="qydh" /></td>
            </tr>
            </xsl:for-each>
        </tbody>
    </table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

4. 生成的 XML 中間結構 (調試用)

<?xml version="1.0" encoding="GB2312"?>
<result>
    <row>
        <nsrnm>310109040111985</nsrnm>
        <qymc>喬家飲食發展有限公司</qymc>
        <qydh>8621-63346626</qydh>
    </row>
    <row>...</row>
</result>

進階技巧與避坑指南

1. 編碼轉換鏈路管理

// 數據庫連接指定字符集 (MySQL 4.1+)
$db->query("SET NAMES gb2312");  // 或 utf8

// XML_SQL2XML 設置輸出編碼
$sql2xml->setEncoding("GB2312"); // 必須與 XSL output encoding 一致

// XSL 輸出聲明
<xsl:output method="html" encoding="GB2312" />

// PHP 輸出 Header
header("Content-Type: text/html; charset=gb2312");

鐵律:數據庫 → PHP → XML → XSL → 瀏覽器,**全鏈路編碼統一**,否則亂碼無解。

2. XSLT 中使用 PHP 函數 (註冊函數)

<?php
function xsl_date_format($timestamp) {
    return date('Y-m-d H:i', $timestamp);
}
xslt_register_php_functions($xh); // 啟用 PHP 函數調用
?>
<!-- XSL 中調用 -->
<td><xsl:value-of select="php:function('xsl_date_format', created_at)" /></td>

3. 性能優化:緩存 XSL 編譯結果

$xslDom = domxml_open_file('template.xsl'); // 解析為 DOM
$xslDoc = xslt_process($xh, $xmlDom, $xslDom); // 直接用 DOM 避免重複解析
// 或使用 APCu/Redis 緩存 $xslstring

4. 大數據分頁處理

XML_SQL2XML 不支持流式處理,大數據集會導致內存爆炸。解決方案:

  • SQL 層面 LIMIT 分頁
  • 改用 XMLWriter 流式生成 XML
  • 或遷移至現代架構 (見下文)

現代化遷移路線圖:為什麼 2024 年不再推薦此架構?

痛點現代替代方案
XSLT 學習曲線陡峭、調試困難模板引擎: Twig, Blade, Latte (語法直觀, IDE 支持完善)
PHP 8.x 移除 ext/xslt, 依賴 PECL 維護艱難原生 PHP 模板 / 前端框架 (Vue/React) + API
XML 冗長, 解析性能差, 內存佔用高JSON 輕量高效, 配合 JSONPath/JQ 查詢
PEAR 停止維護, 依賴鏈脆弱Composer + Packagist 現代依賴管理
服務端渲染阻塞, 首屏慢SSR (Next.js/Nuxt) / SSG / Island Architecture

遷移示例:Twig + Symfony/PDO 重構

<?php
// Controller
$stmt = $pdo->query("SELECT nsrnm, qymc, qydh FROM yhxx LIMIT 20");
$companies = $stmt->fetchAll(PDO::FETCH_ASSOC);

echo $twig->render('company/list.html.twig', ['companies' => $companies]);
{# company/list.html.twig #}
<table>
    <thead><tr><th>代碼</th><th>名稱</th><th>電話</th></tr></thead>
    <tbody>
    {% for c in companies %}
        <tr>
            <td>{{ c.nsrnm }}</td>
            <td>{{ c.qymc }}</td>
            <td>{{ c.qydh }}</td>
        </tr>
    {% endfor %}
    </tbody>
</table>

結語

XML+XSLT 架構曾是企業級應用集成 (EAI) 的標準化選擇,體現了「數據與展現分離」的先進思想。但在 PHP 生態演進至今日,**擁抱 Composer、現代模板引擎、前後端分離** 才是理性選擇。理解這段歷史,是為了更好地設計未來——架構服務於業務,技術服務於架構,拒絕為技術而技術。

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