:::

6. 製作顯示單一文章的功能

  1. 讀出單一文章的功能算簡單,只要取出一筆,故不需要跑迴圈,順便取出縮圖即可。
  2. 一樣讓AI來幫忙:
    請用PHP8寫一個show()函數,可以傳入$id後,到資料庫取得該筆資料
    有json格式的欄位,也請轉成陣列,最後傳回該筆資料的所有值。
    資料需要過濾,包括json轉陣列的欄位,避免XSS攻擊
    資料庫物件$pdo已經存在,無須重新執行。

     

  3. AI的回應如下:
    <?php
    
    function show(int $id): array
    {
        global $pdo;
    
        try {
            // 準備 SQL 語句
            $sql = "SELECT * FROM school_news WHERE id = ?";
            $stmt = $pdo->prepare($sql);
            
            // 執行查詢
            $stmt->execute([$id]);
            
            // 獲取結果
            $result = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if (!$result) {
                throw new Exception("找不到 ID 為 {$id} 的資料");
            }
            
            // 處理 JSON 格式的欄位
            if (isset($result['media']) && is_string($result['media'])) {
                $result['media'] = json_decode($result['media'], true) ?? [];
            }
            
            // 過濾資料以防止 XSS 攻擊
            $filtered_result = array_map(function($value) {
                if (is_string($value)) {
                    return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
                } elseif (is_array($value)) {
                    return array_map(function($v) {
                        return is_string($v) ? htmlspecialchars($v, ENT_QUOTES, 'UTF-8') : $v;
                    }, $value);
                }
                return $value;
            }, $result);
            
            return $filtered_result;
            
        } catch (PDOException $e) {
            // 記錄資料庫錯誤
            error_log("Database Error: " . $e->getMessage());
            throw new Exception("資料庫查詢錯誤");
        } catch (Exception $e) {
            // 記錄其他錯誤
            error_log("Error: " . $e->getMessage());
            throw $e;
        }
    }
    
    // 使用示例
    try {
        $news_data = show(1); // 假設我們要獲取 ID 為 1 的新聞
        print_r($news_data);
    } catch (Exception $e) {
        echo "錯誤: " . $e->getMessage();
    }
    
    // 使用示例
    try {
        $news_data = show(1); // 假設我們要獲取 ID 為 1 的新聞
        print_r($news_data);
    } catch (Exception $e) {
        echo "錯誤: " . $e->getMessage();
    }
    

     

    1. 使用 PHP 8 的類型聲明,函數接受一個整數 ID 並返回一個陣列。
    2. 使用預處理語句來防止 SQL 注入攻擊。
    3. 使用 htmlspecialchars() 函數對所有字串值進行 XSS 防護。
    4. 將 JSON 格式的 media 欄位轉換為 PHP 陣列。
    5. 使用全局變量 $pdo 作為資料庫連接對象。
    6. 包含錯誤處理,區分資料庫錯誤和其他錯誤。
    7. 如果找不到指定 ID 的資料,會拋出一個異常。

修改 index.php

  1. 先加入變數過濾
    $id = filter_input_var('id', 'int');

     

  2. 因為沒有傳入 $op 所以會執行 default: 的部份。但這部份目前是列出所有文章,因此,我們可以改一下,增加 !empty() 判斷,若是 $id 不是空白,就讀取資料,並套用show.tpl 樣板(目前不存在)
    default:
    	if (!empty($id)) {
    		$smarty->assign('news', show($id));
    		$op = "show";
    	} else {
    		$op = "main";
    	}
    	break;

     

  3. 將 AI 產生的 show() 函數貼到 index.php 的最下方

  4. 開啟 templates\main.tpl 並另存為新檔 templates\show.tpl
    {include file="article.tpl" slider=true title="最新消息" date="2024-08-06" school="龍崎國小" count=88168 author="吳弘凱" content="<p>文章完整內容,文章完整內容,文章完整內容,文章完整內容,文章完整內容,文章完整內容。文章完整內容,文章完整內容,文章完整內容,文章完整內容,文章完整內容,文章完整內容。</p>
    <p>文章完整內容,文章完整內容,文章完整內容,文章完整內容,文章完整內容,文章完整內容。文章完整內容,文章完整內容,文章完整內容,文章完整內容,文章完整內容,文章完整內容。</p>" link="" thumb=""}
    

     

  5. 暫時先這樣,然後手動在網址輸入 http://localhost/php8/index.php?id=1 看看是否有順利執行(雖然真實內容還沒出現)

:::

書籍目錄

展開 | 闔起

https%3A%2F%2Fcampus-xoops.tn.edu.tw%2Fmodules%2Ftad_book3%2Fpage.php%3Ftbdsn%3D2020%26tbsn%3D55

計數器

今天: 1078107810781078
昨天: 2027202720272027
總計: 7972119797211979721197972119797211979721197972119