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

PHP 廣告調用類實戰:單例模式、Flash/圖片雙模式、JS 輸出支援、鏈式調用設計

     編輯:PHP 綜合知識

需求場景

CMS/門戶網站需在多處調用廣告:側邊欄、內文插入、彈窗等。要求:

  • 按 ID 或排序調用單條廣告。
  • 支援圖片(JPG/PNG/GIF)與 Flash (SWF) 兩種素材。
  • 提供直接 HTML 輸出與 document.write JS 輸出兩種模式(便於靜態頁面引入)。
  • 代碼復用、易維護、擴展性強。

類設計亮點

  1. 靜態單例調用:Adv::getContentById(35),無需實例化,全局唯一狀態管理。
  2. 鏈式方法入口:四個公共靜態方法對應四種調用場景,內部統一轉發 getContent()。
  3. 素材類型自動識別:解析文件後綴,自動生成 <img> 或完整 <object>+<embed> Flash 代碼(含透明模式、點擊跳轉)。
  4. JS 模式自動轉義:addslashes() 轉義雙引號、反斜槓,確保 document.write 不報錯。
  5. 狀態自動重置:每次調用結束重置靜態屬性,避免狀態汙染。

核心代碼精簡版(去除舊式 HTML 佈局,採用現代語義化標籤)

<?php
class Adv {
    private static $id = 0;
    private static $order = 0;
    private static $isJs = false;

    // === 公共入口 ===
    public static function getContentById(int $id): string {
        self::$id = $id;
        return self::getContent();
    }
    public static function getContentByIdJS(int $id): string {
        self::$id = $id;
        self::$isJs = true;
        return self::getContent();
    }
    public static function getContentByOrder(int $order): string {
        self::$order = $order;
        return self::getContent();
    }
    public static function getContentByOrderJS(int $order): string {
        self::$order = $order;
        self::$isJs = true;
        return self::getContent();
    }

    // === 核心邏輯 ===
    private static function getContent(): string {
        // 1. 構建 SQL
        $sql = "SELECT `pic`, `width`, `height`, `url` FROM `" . TABLE_ADV . "` ";
        if (self::$id) {
            $sql .= "WHERE `id` = " . (int)self::$id;
        } else {
            $sql .= "WHERE `order` = " . (int)self::$order . " ORDER BY `id` DESC";
        }
        $sql .= " LIMIT 1";

        // 2. 執行查詢(假設 Database::Get() 返回單例 PDO 包裝器)
        $db = Database::Get();
        $db->SqlStr = $sql;
        if (!$db->Query() || empty($db->ResultArr)) {
            self::reset();
            return '';
        }
        $row = $db->ResultArr[0];
        [$file, $width, $height, $url] = $row;

        // 3. 判斷素材類型
        $ext = strtoupper(pathinfo($file, PATHINFO_EXTENSION));
        $html = '';
        if ($ext === 'SWF') {
            // Flash 廣告:現代瀏覽器已棄用,此處保留邏輯供遷移參考
            $html = self::buildFlashHtml($file, $width, $height, $url);
        } else {
            // 圖片廣告:響應式、語義化
            $html = '<a href="' . htmlspecialchars($url, ENT_QUOTES) . '" target="_blank" rel="noopener">';
            $html .= '<img src="' . htmlspecialchars($file, ENT_QUOTES) . '" width="' . (int)$width . '" height="' . (int)$height . '" alt="Ad" loading="lazy" />';
            $html .= '</a>';
        }

        // 4. JS 模式轉義
        if (self::$isJs) {
            $html = 'document.write("' . addslashes($html) . '");';
        }

        // 5. 重置狀態並返回
        self::reset();
        return $html;
    }

    private static function buildFlashHtml(string $file, int $w, int $h, string $url): string {
        // 簡化版:實際生產建議用 JS 庫 (如 swfobject) 動態嵌入
        return '<object type="application/x-shockwave-flash" data="' . htmlspecialchars($file) . '" width="' . $w . '" height="' . $h . '">'
             . '<param name="movie" value="' . htmlspecialchars($file) . '" />'
             . '<param name="wmode" value="transparent" />'
             . '<param name="quality" value="high" />'
             . '<a href="' . htmlspecialchars($url) . '" target="_blank"><img src="' . htmlspecialchars($file) . '" width="' . $w . '" height="' . $h . '" alt="Flash Ad" /></a>'
             . '</object>';
    }

    private static function reset(): void {
        self::$id = 0;
        self::$order = 0;
        self::$isJs = false;
    }
}

模板中調用示例

<!-- 直接輸出 HTML -->
<div class="sidebar-ad">
    <?php echo Adv::getContentById(5); ?>
</div>

<!-- 靜態頁面引入 JS -->
<script src="?mod=adv&id=5&output=js"></script>
<!-- 後端路由處理:output=js 時調用 Adv::getContentByIdJS() -->

現代化改進建議

  1. 棄用 Flash:瀏覽器已全面停用,素材統一轉 MP4/WebM 或 GIF/APNG,用 <video> 或 <img>。
  2. 依賴注入替換靜態調用:構造函數注入 DatabaseInterface,便於單元測試(Mock DB)。
  3. 緩存層:廣告數據讀多寫少,引入 Redis 緩存 adv:{id},TTL 5 分鐘,減輕 DB 壓力。
  4. 素材合法性驗證:上傳時檢測 MIME、尺寸、惡意腳本,存儲路徑隨機化防止遍歷。
  5. 曝光/點擊統計:生成廣告 HTML 時埋入 data-ad-id,前端 JS 上報曝光;點擊跳轉經中轉頁 /ad/click?id=xxx 記錄點擊再 302 跳目標。

總結

該類展示了 PHP 早期「工具類」設計模式:靜態門面 + 內部單例狀態 + 多入口統一核心。雖然 Flash 邏輯已過時,但「素材類型自適應、雙輸出模式、狀態隔離」的思想在現代廣告 SDK、組件庫中依然通用。

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