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

PHP 靜態頁生成類:模板替換與檔案輸出的輕量實現

     編輯:PHP 相關知識

靜態化是提升 PHP 應用承載能力的經典策略:將動態頁面預渲染為靜態 HTML,Web 伺服器直接回傳靜態檔案,完全繞過 PHP 解析。本文解析一個輕量的 Shtml 類,實現模板變數替換、目錄自動建立、檔案寫入全流程,適合中小型專案快速接入靜態化。

核心功能

  • 模板變數替換:<FIELD_變數名> 佔位符 → 實際資料
  • 多層目錄自動建立:支援絕對/相對路徑
  • 檔案寫入模式控制:覆蓋/追加
  • 輸出緩衝回調整合:一鍵將當前輸出靜態化

類結構與關鍵方法

<?php
class Shtml
{
    public $template = '';      // 模板內容
    public $dataSource = [];    // 替換資料陣列
    public $dir = '';           // 輸出目錄
    public $fileName = '';      // 輸出檔案名
    public $mode = 'wb';        // 寫入模式
    private $handle = false;    // 檔案控制代碼

    public function __construct(string $fileName = '')
    {
        $this->fileName = $fileName;
    }

    // 綁定替換資料
    public function bindData(array $data): void
    {
        $this->dataSource = $data;
    }

    // 設定輸出目錄
    public function setDir(string $dir): void
    {
        $this->dir = $dir;
    }

    // 設定檔案名
    public function setFileName(string $fileName): string
    {
        return $this->fileName = $fileName;
    }

    // 開啟檔案
    public function open()
    {
        $path = $this->resolvePath($this->fileName);
        $this->handle = @fopen($path, $this->mode);
        return $this->handle;
    }

    // 寫入內容
    public function write(string $content): int|false
    {
        return $this->handle ? fwrite($this->handle, $content) : false;
    }

    // 關閉檔案
    public function close(): bool
    {
        return $this->handle ? fclose($this->handle) : false;
    }

    // 遞迴建立多層目錄
    public function mkDir(string $pathname): void
    {
        $pathname = str_replace('\\', '/', $pathname);
        $parts = explode('/', $pathname);
        $current = ($parts[0] === '') ? $_SERVER['DOCUMENT_ROOT'] : $_SERVER['DOCUMENT_ROOT'] . dirname($_SERVER['PHP_SELF']);
        
        foreach ($parts as $part) {
            if ($part === '') continue;
            $current .= '/' . $part;
            if (!is_dir($current)) {
                @mkdir($current, 0755, true);
            }
        }
    }

    // 執行靜態化:替換 → 建立目錄 → 寫入
    public function create(): void
    {
        $content = $this->template;
        foreach ($this->dataSource as $key => $val) {
            $content = str_replace("", $val, $content);
        }
        $this->mkDir(dirname($this->fileName));
        $this->open();
        $this->write($content);
        $this->close();
    }

    private function resolvePath(string $path): string
    {
        if (str_starts_with($path, '/')) {
            return $_SERVER['DOCUMENT_ROOT'] . $path;
        }
        return $path;
    }
}

輸出緩衝整合:一鍵靜態化當前頁面

<?php
function createShtml(): void
{
    ob_start('callbackCreateShtml');
}

function callbackCreateShtml(string $buffer): string
{
    $page = (int)($_REQUEST['page'] ?? 0);
    
    $shtml = new Shtml();
    $base = $_SERVER['DOCUMENT_ROOT'] . dirname($_SERVER['PHP_SELF']);
    $script = basename($_SERVER['PHP_SELF'], '.php');
    $file = $page > 0 ? "{$script}_{$page}.html" : "{$script}.html";
    
    $shtml->setFileName($base . '/' . $file);
    $shtml->template = $buffer;
    $shtml->create();
    
    return $buffer; // 仍正常輸出給瀏覽器
}

使用範例

1. 模板檔案 article.tpl

```html <FIELD_TITLE>

作者: | 時間:
```

2. PHP 業務邏輯

<?php
require 'Shtml.php';

// 1. 讀取模板
$tpl = file_get_contents('article.tpl');

// 2. 準備資料
$data = [
    'TITLE'   => 'PHP 靜態化實戰',
    'AUTHOR'  => '開發者',
    'DATE'    => date('Y-m-d H:i:s'),
    'CONTENT' => '這裡是文章內容...'
];

// 3. 執行靜態化
$shtml = new Shtml('/var/www/html/articles/2024/01/15/article-001.html');
$shtml->template = $tpl;
$shtml->bindData($data);
$shtml->create();

echo "靜態頁已生成!";

進階優化方向

痛點優化方案
大流量併發寫入同一檔案檔案鎖(flock)/ 暫存檔 + rename 原子替換
模板語法單一(無邏輯/迴圈)引入 Twig/Blade 或自製簡易模板引擎
靜態檔案更新策略資料變更觸發重新生成 / 定時任務全量重建 / CDN 快取清除 API
分頁/列表頁靜態化生成 index.html、page_2.html... 或使用 Nginx fastcgi_cache 替代
多伺服器同步共享儲存(NFS/GlusterFS)或部屬時同步推送

適用場景與替代方案

  • 適用:內容型站點(文章、商品詳情)、更新頻率低、流量大的頁面
  • 不適用:高度個性化頁面(用戶儀表板)、即時性極強頁面(股票行情)、權限控制複雜頁面
  • 現代替代:Nginx fastcgi_cache / Varnish / Cloudflare Page Rules — 無需修改代碼,運維層面解決靜態化

靜態化不是銀彈,但對「讀多寫少」場景極具性價比。理解原理、評估成本、選擇合適層次介入,才是架構師的功課。

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