階段一:教材梳理與核心總結 (Summary of Core Concepts)
這份教材的背景是關於「網際網路與多媒體應用開發(Internet and Multimedia Applications Development)」。其知識框架主要分為前端介面、後端邏輯與伺服器架設、資料庫管理與整合,以及進階的 API 應用。
以下是文檔中提取的核心考點與英文原文定義:
- 前端多媒體與繪圖 (HTML5 Canvas)
Canvas: "The element can be used to draw graphics using scripting (usually JavaScript)."- 解析:考點在於如何使用
CanvasRenderingContext2D來繪製路徑、幾何圖形、文字,以及設定顏色、漸層與陰影。
- 伺服器與資料庫建置 (Server & DB Administration)
Web Servers: "Listen for HTTP requests on a network, receive HTTP requests made by user agents (usually web browsers)."- 解析:重點在於 Apache 與 MySQL 的安裝、配置(如
httpd.conf,my.ini),以及使用 phpMyAdmin 進行資料庫管理與備份。
- 伺服器端腳本語言 (PHP Programming)
PHP: "PHP ("PHP: Hypertext Preprocessor") is a server-side HTML embedded scripting language used to create dynamic Web pages."- 解析:必須熟悉 PHP 的變數宣告、字串處理、陣列(包含關聯陣列)、迴圈邏輯、自訂函數,以及表單資料接收(
$_GET,$_POST,$_REQUEST)與檔案上傳機制。
- 狀態管理 (State Management)
State Management: "HTTP is a stateless protocol. This means that state is NOT preserved between HTTP requests... Methods of maintaining state: Passing hidden variables, Cookies, Session."- 解析:網頁本身不會記憶使用者資訊。考點在於如何使用
setcookie()把資料存在客戶端,或使用session_start()把資料存在伺服器端。
- 資料庫操作與整合 (Database Integration)
mysqli: "PHP includes a set of functions that allows it to perform standard SQL operations on a variety of DBMSs."- 解析:如何透過
mysqli_connect()連線資料庫,使用mysqli_query()執行 SQL 語法,並以mysqli_fetch_assoc()提取資料。
- DOM 與非同步通訊 (DOM, JSON & AJAX)
DOM: "DOM ("Document Object Model") is a representation of the current web page as a set of JavaScript objects."AJAX: "AJAX is a way to read data from a web server without reloading your page."
- 解析:考綱要求能利用 JavaScript 操控網頁元素,並透過 AJAX (
XMLHttpRequest或 jQuery$.ajax()) 傳遞與解析 JSON/XML 資料,實現無重新整理的資料更新。
- 網路服務 API (Web Services & Google Maps)
Web Services: "Web services are web-based applications that use open, XML-based standards and transport protocols to exchange data with clients."- 解析:實務應用考點為介接 Google Maps JavaScript API,包含設定經緯度、縮放級別、標記 (Markers) 以及路徑規劃 (Directions)。
階段二:界定學習目標與里程碑 (Learning Outcomes)
透過接下來的特訓,你預期將達成以下目標,這也是考試的重點拿分區塊:
- 環境建置與除錯能力:能獨立設定 WAMP 環境,並閱讀
phpinfo()與錯誤日誌進行設定調校。 - 後端邏輯與資料庫串接:能使用 PHP 處理 HTML 表單提交的資料(包含防呆與檔案上傳),並完成 MySQL 資料庫的 CRUD (新增、讀取、更新、刪除) 操作。
- 會話控制與安全性:理解 HTTP 的無狀態特性,並能實作 Cookie 與 Session 以控管使用者登入狀態。
- 前端互動與 API 整合:能使用 HTML5 Canvas 繪圖,並結合 AJAX、JSON 與第三方 API(如 Google Maps)開發高互動性的動態網頁。
階段三:學習地圖與備考計畫 (Learning Map)
為確保你在有限的時間內高效內化,我將這份教材拆解為 6 個次主題 (Sub-topics)。我們將採取「概念解析 -> 實例白話翻譯 -> 實戰測驗」的循環模式來攻克每一個主題。
- Sub-topic 1: Web 環境建置與 PHP 基礎 (Lessons 2, 3, 7)
- Apache/MySQL 基本概念與配置。
- PHP 變數、輸出 (
echo,print,printf)、字串與陣列操作。
- Sub-topic 2: 表單處理與檔案上傳 (Lesson 4)
- GET vs POST。
- 資料接收 (
$_REQUEST,$_GET,$_POST) 與$_FILES處理機制。
- Sub-topic 3: 狀態管理 Cookies & Sessions (Lesson 6)
- Cookie 的建立、讀取與刪除。
- Session 的生命週期與
$_SESSION應用。
- Sub-topic 4: PHP 與 MySQL 資料庫整合 (Lessons 2, 5)
- 資料庫建置與 SQL 語法基礎。
- PHP
mysqli擴充功能實作 (Connect, Query, Fetch, Close)。
- Sub-topic 5: DOM 操作與 AJAX/JSON 傳輸 (Lessons 8, 9)
- HTML/XML DOM 節點選取與修改。
- JSON 格式轉換 (
json_encode,json_decode,JSON.parse)。 - AJAX 非同步請求 (
XMLHttpRequest, jQuery$.ajax())。
- Sub-topic 6: 前端繪圖與 Web Services API (Lessons 1, 10)
- HTML5 Canvas 2D 繪圖實作。
- Google Maps API 整合與 Marker/路線規劃。
我們現在正式進入 Sub-topic 1: Web 環境建置與 PHP 基礎。這部分的重點是理解網頁是如何運作的,以及認識我們接下來要使用的工具。
1. 網頁的運作原理與 WAMP 伺服器環境
我們要開發的是「動態網頁」,這牽涉到「前端(Client-side)」與「後端(Server-side)」的合作。
原文定義:
- "Client-Side Programming is good in: Checking and validation of user's information... Responding user's actions and event performed on the browser."
- "Server-Side Programming is good in: Adding up-to-date information using database on the server. Controlling the content of a web page under different situations..."
- "WAMP (Windows, Apache, MySQL, PHP) Server... Apache, the web server... MySQL, the database management system... PHP, the programming language"
💡 白話文與生活比喻(餐廳運作模型):
想像你開了一家名為 WAMP 的全能餐廳:
- W (Windows):這家餐廳的地皮跟建築物(作業系統)。
- A (Apache Web Server):餐廳的服務生。負責在門口監聽(Listen)客人的點單(HTTP requests),然後把客人要的菜端上桌(HTTP responses)。
- P (PHP):餐廳的主廚。他負責處理邏輯,例如判斷客人是不是 VIP、計算結帳金額。他會讀取你寫的腳本(PHP Script)來動態生成網頁內容(也就是做菜)。
- M (MySQL):餐廳的食材倉庫/冰箱(資料庫)。主廚 (PHP) 會去倉庫找新鮮的食材(Data)來做菜。
而客人的瀏覽器(如 Chrome),就是 Client-Side。它只負責看菜單、填寫點菜單(驗證有沒有漏填),以及把菜吃掉(顯示畫面)。
2. 伺服器配置的兩大神器:php.ini 與 phpinfo()
當我們架設好伺服器後,有時候需要修改設定(例如允許客人上傳多大的照片)。
原文定義:
- "
php.iniConfiguration File... To changephp.inisettings in WAMP, choose PHP =>php.ini, open the text file to make changes, save the file and restart the WAMP."
- "
phpinfo()is a function that used to output the information about the PHP configuration in the server... is a valuable debugging tool"
💡 白話文解釋:
php.ini:這是餐廳的內部管理規章。裡面規定了像是post_max_size(最大點單容量) 或upload_max_filesize(最大上傳檔案大小)。記住,修改完規章後,必須重新啟動伺服器 (Restart WAMP),新規定才會生效。
phpinfo():這是一個 PHP 內建的指令。只要在網頁寫下<?php phpinfo(); ?>,就像是呼叫「餐廳營運狀態報表」,它會印出目前所有的設定值、系統版本,是工程師找 Bug 時最愛用的工具。
3. PHP 程式語言基礎
PHP 的語法和 JavaScript 有點像,但它有一些獨特的標記。
原文定義:
- "When PHP parses a file, it looks for the opening and closing tags...
<?phpand?>"
- "PHP doesn't require you to declare a variable before using it. PHP knows that something is a variable by the fact that the name is preceded with a dollar sign like this
$abc."
- "Associative array:
$cities['france'] = "paris";"
💡 白話文解釋與易錯提醒:
- 標籤 (Tags):PHP 程式碼必須包在
<?php與?>裡面,否則伺服器會把它當成一般的純文字或 HTML 顯示出來。
- 變數 (Variables):PHP 的變數超級好認,前面一定要加錢字號
$。例如$userName = "John";。字串連接不像 Java 或 JS 用+號,PHP 是用小數點.來連接(例如:"Hello " . $userName)。
- 陣列 (Arrays):除了用數字
0, 1, 2當作索引的普通陣列,PHP 非常愛用「關聯陣列 (Associative Array)」。你可以把它想像成一本字典,用文字當作鑰匙 (Key) 來找資料。例如:$student['name'] = "Mary";。
Sub-topic 2: 表單處理與檔案上傳 (Form Data & File Uploads)
這個章節的重點在於「前端(瀏覽器)如何將使用者的輸入,正確無誤地打包送到後端(伺服器)」。
1. 傳遞資料的兩大門派:GET vs. POST
HTML 表單 <form> 在傳送資料時,有兩種主要的方法(Method)。
原文定義:
- "a GET request passes the parameters to the server as a query string... GET is limited to browser's URL length... information is more private (not shown in browser address bar)"
- "a POST request embeds the parameters in HTTP request, not in the URL"
💡 白話文與生活比喻(寄信模型):
- GET(寄明信片):當你使用 GET 時,資料會直接附加在網址的最後面,這稱為 Query String(例如
?name=Sue&meal=pizza)。- 優點:可以加到我的最愛(Bookmark),也可以把網址直接貼給朋友看。
- 缺點:大家都能在網址列看到內容(毫無隱私),而且明信片版面有限,大約只能塞 100-200 個字元。
- POST(寄密封包裹):資料被藏在 HTTP 請求的內部傳送,網址列完全看不出痕跡。
- 優點:適合傳送私密資訊(例如登入密碼),且容量沒有嚴格限制,適合傳遞大筆資料。
- 缺點:不能被加到我的最愛。如果使用者按「上一頁」,常常會跳出「確認重新提交表單 (POSTDATA)」的警告訊息。
2. 伺服器如何收件?(Superglobals)
當前端把表單送出後,後端的 PHP 主廚要怎麼拿到這些資料呢?PHP 準備了三個「超級陣列(Superglobals)」來接招。
原文定義:
- "You need to use the environment variables
$_GET,$_POSTor$_REQUEST."
💡 白話文與易錯提醒:
$_GET['變數名稱']:專門用來接收 GET 方法送來的資料。
$_POST['變數名稱']:專門用來接收 POST 方法送來的資料。
$_REQUEST['變數名稱']:這是一個「萬能信箱」,無論前端是用 GET 還是 POST 傳過來,它通通都能收。不過實務上為了安全性,通常會明確指定使用$_GET或$_POST。
3. 檔案上傳的兩大鐵律 (File Uploading)
這是一個超級常考的實作題!要讓網頁具備上傳檔案(如圖片、履歷)的功能,前後端都有嚴格的規定。
原文定義:
- "Make sure that the form uses
method="post"... The form also needs the following attribute:enctype="multipart/form-data"... Without the requirements above, the file upload will not work."
- "
move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)"
💡 白話文拆解:
- 前端(HTML)的鐵律:表單方法必須是
method="post",並且「一定」要加上通關密語enctype="multipart/form-data"。這是在告訴伺服器:「注意囉,這次傳過來的不是單純的文字,而是被拆解的二進位檔案。」如果沒寫這個屬性,上傳絕對會失敗。
- 後端(PHP)的鐵律:檔案資料不會放在
$_POST裡,而是有一個專屬的陣列叫做$_FILES。檔案上傳到伺服器後,一開始只會存在「暫存區 (tmp_name)」,你必須使用 PHP 的move_uploaded_file()函數,手動把檔案搬移到指定的真實資料夾(例如upload/),這個上傳動作才算真正完成。
Sub-topic 3: 狀態管理 Cookies & Sessions。
這一個章節要解決的核心問題是:「既然網頁本身沒有記憶力,那我們該怎麼記住使用者是誰?」
1. 為什麼需要狀態管理?(HTTP is Stateless)
在學習 Cookie 和 Session 之前,我們必須先認識 HTTP 協定的一個致命缺點。
原文定義:
- "HTTP is a stateless protocol. This means that state is NOT preserved between HTTP requests on the same site."
- "Methods of maintaining state: Passing hidden variables, Cookies, Session."
💡 白話文與生活比喻(金魚腦服務生): HTTP 協定就像是一個擁有「金魚腦(只有三秒記憶)」的餐廳服務生。 當你點完餐(發出 Request)並拿到食物(收到 Response)後,這個服務生就會立刻忘記你是誰。如果你想要再加點一杯飲料,服務生會把你當成全新的客人,要求你重新驗證身分(例如重新登入)。 為了解決這個問題,工程師發明了兩種主要的方法來「維持狀態(Maintaining state)」:Cookies 和 Session。
2. Cookie:把記憶放在客人的口袋裡
Cookie 是一種把資料存在「客戶端(瀏覽器)」的技術。
原文定義:
- "Cookies are simple text strings of the form of name=value which are stored persistently on the browser."
- "The data persists on the browser until a specified expiry period elapses."
- "Since cookies are kept on the client side... Users can delete cookies themselves"
💡 白話文與生活比喻(餐廳集點卡):
因為服務生(伺服器)記不住你,所以餐廳決定發給你一張「實體集點卡(Cookie)」,並請你放在自己的錢包(瀏覽器)裡。下次你再來餐廳時,只要出示這張卡片,服務生就知道你來過幾次了。
- 特性:卡片是保存在客人身上的,所以客人可以隨時把它丟掉(刪除 Cookie)。
- 壽命:卡片上會印有「有效期限(Expiry period)」,時間到了卡片就會失效。
💻 PHP 實作語法:
- 建立 Cookie:使用
setcookie(name, value, expire)。例如設定一個存活 3600 秒(一小時)的 Cookie:setcookie("mycookie", "Hello", time()+3600);
- 讀取 Cookie:使用全域變數
$_COOKIE['變數名稱']。例如:echo $_COOKIE['mycookie'];
- 刪除 Cookie(常考題!):PHP 沒有直接刪除 Cookie 的指令。你必須重新設定同一個 Cookie,並且把它的過期時間設定在「過去」。例如:
setcookie("mycookie", "", time() - 60);
3. Session:把記憶鎖在伺服器的保險箱
Session 是一種把資料存在「伺服器端」的技術。
原文定義:
- "Using session, a web server can keep some data on the server and the data can be used from one page to another page."
- "keep the data on the server only and give the browser a 'key' to allow it to uniquely identify the session. We call this key a 'session identifier'."
- "save the session identifier as a cookie with its default name called PHPSESSID."
💡 白話文與生活比喻(健身房置物櫃): 如果你不希望把重要的個人資訊(例如信用卡號、購物車內容)直接寫在卡片(Cookie)上讓別人看到,你可以改用 Session。 這就像是健身房的專屬置物櫃。餐廳(伺服器)把你的重要資料鎖在一個專屬的櫃子裡,然後只交給你一把帶有編號的鑰匙(Session Identifier)。這把鑰匙通常會偽裝成一個名為 PHPSESSID 的 Cookie 存在你的瀏覽器裡。你下次來只要出示鑰匙,伺服器就會幫你打開對應的櫃子。
💻 PHP 實作語法:
- 啟動 Session(鐵律):在任何需要使用 Session 的 PHP 檔案最頂端,必須呼叫
session_start();,否則無法讀取鑰匙。
- 寫入/讀取 Session:使用全域變數
$_SESSION['變數名稱']。例如:$_SESSION['name'] = "Peter";
- 刪除 Session:
- 清空單一變數:
unset($_SESSION['xyz']); - 徹底銷毀整個置物櫃(通常用於「登出」功能):
session_destroy();
- 清空單一變數:
階段推進:Sub-topic 4: PHP 與 MySQL 資料庫整合 (Database Integration)
既然你已經成功攻克了狀態管理,現在我們要進入整份考綱最核心的重頭戲:如何讓 PHP (主廚) 去 MySQL (倉庫) 拿資料? 這部分在實作題與除錯題的配分極重。
1. 建立連線 (Connect)
要拿資料,必須先打電話給倉庫管理員。
原文定義:
- "The
mysqli_connect()function is used to open a new connection to MySQL server and select a database."
- "
$conn = mysqli_connect($hostname, $username, $pwd, $db) or die(mysqli_connect_error());"
💡 白話文與生活比喻:
mysqli_connect() 就像是打電話到倉庫。你需要提供四個資訊:
$hostname(分機號碼,通常是127.0.0.1或localhost)$username(你的員工代號,例如root)$pwd(你的密碼)$db(你要找的是哪個具體的倉庫房間) 如果電話打不通(連線失敗),我們會用die()函數直接「掛斷」並報錯,不讓程式繼續往下跑。
2. 執行查詢 (Query)
電話打通後,你要告訴管理員你想做什麼。
原文定義:
- "The
mysqli_query()function takes as parameters a query to perform on the database and a link."
- "
$rs = mysqli_query($conn, $sql)"
💡 白話文與生活比喻:
mysqli_query() 就像是下達指令。你需要給它兩個參數:
$conn(剛剛打通的那通電話)$sql(你的 SQL 指令,例如SELECT * FROM user) 管理員聽懂後,會去倉庫把你要的貨物全部打包成一個大包裹(Result Set,變數通常命名為$rs)送過來。
3. 提取資料 (Fetch)
收到大包裹 $rs 後,PHP 不能直接把它印出來,必須把裡面的資料一筆一筆拿出來。
原文定義:
- "The
mysqli_fetch_assoc()function may be used to fetch a record from the result into an associative array."
- "You can use the function in a loop to iterate through all records in the result set.
while($rc = mysqli_fetch_assoc($rs)) { ... }"
💡 白話文與生活比喻(常考重點!): 包裹 $rs 裡面可能裝了 100 筆會員資料。mysqli_fetch_assoc() 這個動作就像是「從包裹裡拿出一個檔案夾」,並且把它轉成以文字當作鑰匙的「關聯陣列 (Associative array)」。 因為我們不知道包裹裡總共有幾個檔案夾,所以一定要搭配 while 迴圈,只要還能拿出東西,就繼續拿,直到包裹空了為止。
4. 善後處理 (Free & Close)
事情做完後,要有好習慣。
原文定義:
- "
mysqli_free_result(): is used to free the memory associated with the result set."
- "
mysqli_close(): is used close a previously opened database connection."
💡 白話文解釋:
mysqli_free_result($rs):把包裹的包裝紙和暫存記憶體清空,釋放資源。
mysqli_close($conn):把電話掛斷,結束連線。
我們現在正式進入這份考綱中最進階、也最考驗前後端整合邏輯的魔王關卡:Sub-topic 5: DOM 操作與 AJAX/JSON 傳輸。
這個章節要解決的核心問題是:「如何在不重新載入整個網頁的情況下,讓前端畫面與後端資料庫進行對話與更新?」
1. DOM 操作:解構網頁的積木 (Document Object Model)
網頁被瀏覽器載入後,就不再只是純文字的 HTML,而是會被轉換成一個可以被程式操作的「物件模型」。
原文定義:
- "DOM ("Document Object Model") is a representation of the current web page as a set of JavaScript objects."
- "Everything is a node in HTML/XML DOM... The document itself is a document node. All HTML/XML elements are element nodes."
💡 白話文與實務比喻: 把網頁想像成一座用樂高積木拼成的城堡。DOM 就是這座城堡的「結構圖」。HTML 裡的每一個標籤(像是 <div>, <p>, <a>)都是一塊獨立的樂高積木(節點 Node)。 當你在前端開發中,實作動態的 CSS 分頁切換效果,或者為特定的程式碼區塊加上 Syntax Highlighting(語法高亮)時,底層運作的原理就是透過 JavaScript 查閱這張結構圖,找到特定的樂高積木,然後修改它的外觀或內容。
💻 考綱核心操作語法:
- 找積木:
document.getElementById("id名稱")(最常用) 或document.getElementsByTagName("標籤名稱")。
- 換積木內容/樣式:找到元素後,可以使用
element.innerHTML改變裡面的 HTML 內容,或使用element.style.property改變 CSS 樣式。
2. JSON:前後端溝通的國際通用語 (JavaScript Object Notation)
前端 (JavaScript) 和後端 (PHP) 是兩種不同的語言,它們在傳遞複雜資料(如陣列、物件)時需要一個共同的翻譯標準。
原文定義:
- "JSON ("JavaScript Object Notation") is a lightweight data-interchange format... It is based on a subset of the JavaScript Programming Language."
- "JSON is parsed into a ready-to-use JavaScript object."
💡 白話文解釋: JSON 就像是程式界的「世界語」。它本質上是一串純文字字串,但有著極度嚴謹的格式(使用 {} 包裝物件,[] 包裝陣列)。
- 前端處理 (JavaScript):
JSON.parse(字串):把收到的 JSON 字串「解凍」成 JS 物件或陣列。JSON.stringify(物件):把 JS 物件「冷凍」成字串準備送出。
- 後端處理 (PHP):
json_encode(陣列):將 PHP 的陣列轉換為 JSON 字串。json_decode(字串, true):將 JSON 字串轉回 PHP 的陣列。
3. AJAX:背景默默做事的服務生 (Asynchronous JavaScript and XML)
這是現代網頁擁有流暢體驗的關鍵技術。
原文定義:
- "AJAX is a way to read data from a web server without reloading your page."
- "With Asynchronous, user can keep interacting with page while data loads"
💡 白話文與生活比喻:
- 傳統同步 (Synchronous):就像去速食店櫃台點餐,點完後你必須一直站在櫃台前等(網頁畫面卡住、變成全白),直到餐點做好你才能回座位吃(整個畫面重新載入)。
- 非同步 (Asynchronous / AJAX):就像去美食街拿到一個「震動取餐呼叫器」。你點完餐(發出 Request)後,可以回座位繼續滑手機或跟朋友聊天(網頁繼續讓使用者點擊、互動)。當後端把資料準備好時,呼叫器震動(觸發 Callback 函數),前端再把拿到的資料透過 DOM 局部更新到畫面上。
💻 jQuery AJAX 實作語法 (常考填空或簡答):
教材中推薦使用 jQuery 來簡化 AJAX 請求:
Sub-topic 6: 前端繪圖與 Web Services API。
這個章節不僅是現代全端開發的亮點,更考驗你如何運用 JavaScript 將網頁從「靜態文件」升級為「動態互動應用」。我們馬上開始!
1. HTML5 Canvas 基本繪圖 (Basic Drawing)
過去在處理網頁版面配置、分頁樣式或處理程式碼的語法高亮 (Syntax Highlighting) 時,我們操作的都是一塊一塊的 DOM 節點。但 Canvas 截然不同,它打破了 DOM 的限制。
原文定義:
- "The
<canvas>element can be used to draw graphics using scripting (usually JavaScript)." - "The origin of this grid is positioned in the top left corner at coordinate (0,0). All elements are placed relative to this origin. All angles are measured in radian."
💡 白話文與實務比喻 (白板與麥克筆): 你可以把 <canvas> 想像成網頁上的一塊空白玻璃白板。HTML 只是把白板掛到牆上(定義寬高),你必須透過 JavaScript 拿起「麥克筆(CanvasRenderingContext2D)」在上面一筆一畫地畫圖。
- 座標系統易錯點:Canvas 的
(0,0)原點在左上角。X 軸往右是正數,Y 軸往下才是正數。 - 畫線四部曲 (Drawing Paths):
beginPath():打開麥克筆蓋,準備畫新圖形。moveTo(x, y):把手懸空移動到某個座標(不會留下痕跡)。lineTo(x, y)或arc():筆尖碰觸白板,規劃出線條或圓弧的路徑。stroke()或fill():這一步最重要!前面的動作只是「打草稿」,必須呼叫stroke()(描邊) 或fill()(填色),真正的顏料才會塗到白板上。
2. Web Services 與 Google Maps API 整合
現代網頁幾乎不可能所有功能都自己刻,在進行系統架構或外部功能擴充時,我們經常需要依賴外部資源。
原文定義:
- "Web services are web-based applications that use open, XML-based standards and transport protocols to exchange data with clients."
- "The Google Maps web services are a collection of HTTP interfaces to Google services providing geographic data for your maps applications."
💡 白話文與實務比喻 (外包與 API 串接): Web Services 就像是把特定的工作「外包」給別人的伺服器。在日常的 API 串接任務中,我們常透過 HTTP 請求發送參數(或設定 HTTP Headers),然後對方回傳資料。Google Maps API 就是一種極度強大的 Web Service。
💻 實作 Google Maps 的三大鐵律:
- 取得認證 (Authentication):你必須在
<script>載入 API 時,附上你的API_KEY,否則 Google 不會理你的請求。 - 地圖初始化 (Init Map):必須準備一個 JavaScript 物件,裡面設定好兩大必備參數:
center:地圖的中心點座標(包含lat緯度與lng經度)。zoom:縮放級別(0 代表看整個地球,數字越大看得越近)。
- 加上圖釘 (Markers):透過建立
google.maps.Marker物件,並將position設為特定的經緯度,就能在地圖上打卡標記。
階段一:期末考卷結構與出題邏輯分析 (Exam Structure & Logic Analysis)
根據「4523M-考試題目架構分析」,這份考卷涵蓋所有課堂內容(除了明確排除的 Google API)。整份試卷分為兩個部分,總分 100 分。

階段二:學習路徑拆解與計畫表 (Learning Path Decomposition)
面對 7 到 8 題的實戰題型,我建議我們將複習流程分為 5 個實戰特訓區塊 (Sub-topics)。在每個區塊中,我會使用「費曼學習法」,以歷年試卷的真實代碼為範本,一行一行翻譯給你聽,並直接抽考你核心語法:
- Sub-topic 1: 數據結構大換血 (A1, A2)
- 目標:徹底放棄 Python,專攻 PHP 的 String & Array 操作與 Key-Value 賦值邏輯。
- 實戰:模擬最新的字串分割與陣列提取考法。
- Sub-topic 2: 表單與狀態守門員 (A3, A4)
- 目標:掌握
POST表單驗證(特別是empty陷阱)、Cookie 時間計算與 Session 陣列寫入。 - 實戰:破解 2021/2024 年試卷中的 A3 與 A4 代碼填空。
- 目標:掌握
- Sub-topic 3: 前後端非同步溝通 (A5, B2)
- 目標:精通 JSON 格式轉換與 jQuery
$.ajax()請求,並動態修改 DOM 元素(文字與圖片)。 - 實戰:結合歷年試卷的 Top Song、COVID-19 疫情更新、天氣資訊看板等題目進行解析。
- 目標:精通 JSON 格式轉換與 jQuery
- Sub-topic 4: 資料庫 CRUD 實戰 (B1)
- 目標:默寫出完整的 PHP MySQL 連線、查詢、迴圈印出表格的起手式。
- 實戰:拆解消費券查詢 (Spend Enquiry) 與超市產品查詢 (Supermarket) 考題。
- Sub-topic 5: 畫布動態渲染 (B3)
- 目標:理解 Canvas 座標系轉換與動態重繪邏輯。
- 實戰:破解 Logo 繪製、Sine 函數圖、火柴人 (Hangman) 動態更新等填空題。
1. 關聯式陣列 (Associative Array) 與遍歷 (Iteration)
在過去的 Python 考題中常考 Dictionary,現在換成 PHP,考的就是「關聯式陣列」。
原文定義:
- "An array is a list of values. Each value can be retrieved independently... Associative array:
$cities['france'] = "paris";" - "PHP provides a construct that can be used to iterate a non-sequential array:
foreach ($anArray as $value) { ... }"
💡 白話文與生活比喻(置物櫃標籤): 一般的陣列像是編號 0, 1, 2 的置物櫃。但關聯式陣列 (Associative Array) 允許你在置物櫃上貼「文字標籤 (Key)」。 例如,你想存學生的成績:$marks = array("Peter"=>85, "Mary"=>90);。在這裡,"Peter" 就是鑰匙 (Key),85 就是內容物 (Value)。 當老闆要你把所有置物櫃打開檢查一遍時,你不需要管它有幾個,只要派出 foreach 這個萬能巡邏員,它就會自動幫你把陣列從頭到尾掃描一次。
2. 字串與陣列的超級轉換器 (explode & implode)
這是 A1/A2 題型最愛考的必殺技!如何把長字串切開,又如何把陣列黏回去。
原文定義:
- "
explode()-- Splitting a string into an array so that each element contains a portion of the string." - "
implode()-- Opposite of the explode() function which combines an array's elements into a single string, separated by a specified character."
💡 白話文與生活比喻(切壽司與串燒):
explode(刀子, 壽司捲):想像你是一個日本料理師傅,拿到一長條名為$str = "Apple;Orange;Banana"的壽司捲。你設定分界點為分號";"。一刀切下去,它就變成了一盤裝著三塊獨立水果的陣列$arr。implode(竹籤, 壽司塊):相反地,你現在有一盤陣列$arr,你想把它做成烤肉串。你拿了一根逗號竹籤","把它們全部串起來,它就變回了一條長長的純文字字串"Apple, Orange, Banana"。
3. 字串的定位與切割 (strpos & substr)
如果你不需要轉成陣列,只是想從一段文字中「挖」出特定內容,就要用這兩把剪刀。
原文定義:
- "
strpos(string, search_string): Performs a case-sensitive search and returns the position of the first-occurrence"
- "
substr(string, start_position, len_of_substring): Returns a portion of a string"
💡 白話文解析 (地圖與剪刀):
strpos(地圖座標):它會告訴你某個特定的字在字串裡的精確座標。常考陷阱:電腦的座標是從0開始數的。
substr(剪刀):你告訴它「從第幾個字開始剪(start_position)」以及「要剪多長(len_of_substring)」,它就會把那段字剪下來給你。如果省略長度,它就會一路剪到字串的最後面。
💡 生活實例:
假設系統收到使用者的 Email:$email = "student@vtc.edu.hk";
- 你想找出
@的位置:$pos = strpos($email, "@");(這會回傳7,因為 s 是第 0 個位置) - 你想把帳號剪下來(從座標 0 開始,長度為 7):
$account = substr($email, 0, $pos);(就會精準得到"student")
Sub-topic 2: 表單與狀態守門員 (A3, A4)。
根據最新的考試架構分析,這兩題的考法非常固定:A3 專攻表單的防呆驗證(特別是 empty 的應用),A4 則是考驗 Cookie 時間計算與 Session 陣列的操作。
第一環節:知識講解與內化 (Feynman Technique)
1. A3 核心考點:表單驗證與 empty() 陷阱
當使用者按下 HTML 表單的 Submit 按鈕,資料會送到 PHP 後端。
原文定義:
- "You need to use the environment variables
$_GET,$_POSTor$_REQUEST." - 考綱分析明確指出:"測驗有考empty,今年或許會考 / form驗證的時候沒有提交東西,會岔開(提交空表單)... Empty string 檢查"。
💡 白話文與生活比喻(空包裹陷阱):
想像郵差(POST method)送來一個名為 $_POST['username'] 的包裹。
isset()(有沒有這個包裹?):只檢查包裹存不存在。只要使用者有按 Submit,即使什麼都沒填,包裹還是會送來,所以isset()會判定為 True。empty()(包裹裡面是不是空的?):這是今年極有可能考出的防呆機制!如果使用者提交了空表單(Empty string""),包裹裡面沒東西。用empty($_POST['username'])就能精準抓出這種「幽靈包裹」並報錯。
2. A4 核心考點:Cookie 的建立與讀取
因為 HTTP 協定是無狀態的(stateless),我們需要把使用者的資訊存在他的瀏覽器裡。
原文定義:
- "Cookies are simple text strings of the form of name=value which are stored persistently on the browser."
- "setcookie(string name, string value, int expire)"
💡 白話文與考點提醒(集點卡的有效期限):
- 建立 Cookie:你發給客人一張名為
lowestPrice的集點卡。考試最愛考有效期限的數學計算!例如考綱提到的30*60,代表 30 分鐘(因為單位是秒)。所以語法會是:setcookie("lowestPrice", $price, time() + 30 * 60);。 - 讀取 Cookie:客人下次來,你要檢查他有沒有帶卡片,使用
isset($_COOKIE['lowestPrice'])。
3. A4 核心考點:Session 的陣列操作
如果資料太機密或太多,我們會把資料存在伺服器端(Session)。
原文定義:
- "To use sessions, you need to call the
session_start()built-in method at the top of your PHP script." - 考綱分析指出:"session 變量不需要預先設定,直接一行設定好... tips: php特色 = 所有數據最終都會放入associative array"。
💡 白話文與易錯提醒(無底洞置物櫃):
- 第一步鐵律:檔案最開頭一定要寫
session_start();,這是開啟置物櫃的萬能鑰匙。 - 直接塞入陣列:PHP 很聰明,如果你要把買的食物名稱一個個塞進 Session 裡,你不需要預先宣告它是一個陣列。根據考點,你可以直接寫
$_SESSION['Food'][] = $name;,這對中括號[]就代表「把資料從最後面推入陣列中」。最後再用剛剛學過的implode(", ", $_SESSION['Food'])把它串成文字印出來。
階段推進:Sub-topic 3 - 前後端非同步溝通 (A5, B2)
狀態管理搞定後,我們要進入歷年試卷中配分極重(橫跨 A 部份與 B 部份大題)的核心技術:JSON 與 AJAX。 這部分的考題非常制式,A5 通常考 JSON 轉換與簡單的 AJAX 接收;B2 則是進階版,考你拿到 JSON 後,怎麼用 JavaScript 去替換網頁上的文字與圖片。
1. JSON 轉換:後端主廚的打包術 (A5a)
當 PHP 處理完資料(陣列格式),要交給前端時,必須把它轉換成國際通用語言 JSON。
原文定義:
- "PHP's
json_encode()function converts a PHP array into a PHP string as JSON representation."
💡 白話文解析: 這題根本是送分題。不管題目給你的 PHP 陣列叫 $transcriptInfo 還是 $canteenOrder,要把它轉成 JSON 印出來,永遠只有一行代碼: echo json_encode($變數名稱);。
2. jQuery AJAX:默默做事的送貨員 (A5b, B2)
前端要怎麼在「不重新整理網頁」的情況下,向後端拿這包 JSON 呢?
原文定義:
- "AJAX is a way to read data from a web server without reloading your page."
- "
$.ajax(options): A set of key/value pairs that configure the Ajax request."
💡 必背的 AJAX 默寫模板 (A5b, B2 填空題常客): 試卷中一定會挖空讓你填這幾個設定值:
3. 動態更新 DOM:拆包裹擺盤 (B2)
在 AJAX 的 success 函數裡,我們會拿到打包好的 JSON 物件(例如 result)。接下來就是要把裡面的資料塞進 HTML 裡。
💡 白話文與實戰對應:
- 換文字:找到標籤,然後換掉裡面的內容。
- 語法:
document.getElementById('id名稱').innerHTML = result.title;
- 語法:
- 換圖片 (歷年 B2 必考!):根據拿到的數據,動態切換天氣圖案或上漲/下跌箭頭。
- 語法:
document.getElementById('imgID').src = 'img/' + result.imageFile;
- 語法:
- 換樣式 (CSS):動態改變背景顏色。
- 語法:
document.getElementById('id名稱').style.backgroundColor = "lightblue";
- 語法:
1. B1 核心考點:PHP 與 MySQL 的四步舞曲
B1 大題通常會給你一個資料庫的 Schema(綱要)與幾筆假資料,要求你寫出完整的 PHP 程式碼,把資料從資料庫撈出來並印在 HTML 表格中。你必須默寫出以下四個標準動作。
原文定義:
- "The
mysqli_connect()function is used to open a new connection to MySQL server..." - "The
mysqli_query()function takes as parameters a query to perform on the database and a link." - "The
mysqli_fetch_assoc()function may be used to fetch a record from the result into an associative array." - "
mysqli_free_result()function is used to free the memory...mysqli_close()function is used close a previously opened database connection."
💡 白話文與生活比喻(向倉庫調貨):
- Step 1: 連線 (Connect):
mysqli_connect('主機', '帳號', '密碼', '資料庫名')。這就像是打電話給倉庫管理員,你必須提供你的分機號碼(通常是127.0.0.1)、員工代號(admin)與密碼。 - Step 2: 查詢 (Query):
mysqli_query($conn, $sql)。電話打通後,你對著電話下達指令(例如$sql = "SELECT * FROM product"),管理員聽懂後,會去倉庫把你要的貨物全部打包成一個大包裹(Result Set,變數通常命名為$rs或$resultSet)送過來。 - Step 3: 提取 (Fetch) 與迴圈:
mysqli_fetch_assoc($rs)。這是 B1 最常考的重點!大包裹不能直接印在網頁上,你必須搭配while迴圈,一次從包裹裡拿出一個「關聯式陣列(以文字當鑰匙的檔案夾)」,直到包裹空了為止。 - Step 4: 釋放與關閉 (Free & Close):貨拿完之後要有好習慣。把包裹的包裝紙和暫存記憶體清空
mysqli_free_result($rs),並把電話掛斷mysqli_close($conn)。
根據「4523M-考試題目架構分析」與歷年試卷,B3 是一道非常靈活的綜合應用題。它不僅考驗你對 HTML5 Canvas 的繪圖語法,更考驗你如何結合 JavaScript 與 HTML 表單控制項(例如 <input type="range"> 滑桿),實作出「只要拉動滑桿,圖形就會跟著改變」的動態效果。
知識講解與內化 (Feynman Technique)
1. 動態重繪的關鍵:先擦乾淨,再畫上去
在 Canvas 題型中,最大的陷阱就是忘記「擦白板」。
原文定義:
- "
clearRect(x, y, width, height): Clears the specified rectangular area, making it fully transparent."
💡 白話文與生活比喻(玻璃白板與板擦): Canvas 就像是一塊透明的玻璃白板。當使用者拉動網頁上的滑桿,要求把火柴人的頭(圓形)變大時,如果你直接畫一個大圓,它會直接疊加在原本的小圓上面。 因此,動態渲染的鐵律是:每次畫圖的第一個動作,絕對是拿板擦(clearRect)把整塊白板從座標 (0,0) 開始,一路擦到最右下角 (width, height)。
2. 畫圖四部曲 (Drawing Paths)
在白板上畫圖,必須按照嚴格的順序。
原文定義:
- "to begin a path :
beginPath()." - "to set the starting point :
moveTo(x,y)." - "add elements... Each element adds a new endpoint to the current path." (e.g.,
lineTo,arc) - "to render the current path...
fill()orstroke()"
💡 白話文解析(拿麥克筆畫圖):
- Step 1:
beginPath():打開麥克筆蓋,宣告我要開始畫一個全新的圖形了。如果不寫這行,之前畫過的東西會跟著新圖形再被描一次。 - Step 2:
moveTo(x, y):把手懸空移動到某個起點座標,此時筆尖還沒碰到白板,所以不會留下痕跡。 - Step 3:
lineTo(x, y)/arc(...):筆尖貼著白板滑動,這時只是在「打草稿」規劃路徑。 - Step 4:
stroke()或fill():這是最常忘記的步驟!草稿打完後,必須大喊一聲「上色!」,呼叫stroke()(描邊) 或fill()(填滿顏色),墨水才會真正印在白板上。
3. 觸發事件 (Event Handlers)
要讓圖形動起來,必須靠 HTML 表單元素的事件來呼叫 JavaScript 畫圖函數。
歷年試卷實戰觀察: 在 2020-2021 與 2024-2025 的試卷中,滑桿 (Slider) 或下拉選單改變數值時重繪圖形,都是透過 HTML 屬性來綁定事件。
💡 考點提醒: 當滑桿 <input type="range"> 或下拉選單 <select> 的值發生改變時,對應的觸發事件叫做 onchange。考試常挖空這個屬性讓你填。
題號操練 1:A1 — String Processing
我們現在正式按照題號進行:
本輪先完整完成 A1。你作答後,我會逐格批改、評分和補救,然後自動進入 A2。
Current direction: Python and Google API are excluded. A1 focuses on String Processing.
過往試卷的 A1 曾以 Python 考 palindrome、字串反轉、重複字元及 pattern,但現在應把焦點轉移到 PHP String Processing。舊題的解題邏輯仍有用,但不必背 Python 語法。 [A910ireh2_...1u_l94.pdf | PDF]
A1.1 題型定位
A1 通常考什麼?
A1 是短程式補充題,常見格式是:
“Write the missing code for parts (a) to (e).”
你通常會看到:
- 一段 PHP 程式;
- 4–6 個空格;
- 程式註解;
- 指定輸出;
- 每格填入一個 expression、function call 或 statement。
預計考核內容
A1.2 費曼第一步:String 到底是什麼?
“Individual characters in a string can be referenced using the array operator [ ]. The index starts at 0.”
白話解釋
String 就是一排有編號的字元。
例如:
在電腦眼中,它是:
因此:
如果想取得最後一個字元,可以使用:
因為:
必背英文
The index of the first character is 0.
The index of the last character is the string length minus one.
常見陷阱
錯誤:
因為長度是 8,但最後一個有效索引是 7。
正確:
A1.3 strlen():計算字串長度
“strlen(string) returns the number of characters in a string.”
語法
例子
輸出:
費曼比喻
strlen() 就像點名:逐個數出字串裡有多少個字元。
常見考法
考法一:直接顯示長度
考法二:作為 loop condition
考法三:取得最後一個字元
A1.4 PHP 字串連接:. 和 .=
“PHP uses two kinds of string operators, concatenation (.) and concatenating assignment (.=).”
1. .:把兩段文字接起來
結果:
2. .=:在原本字串後面追加內容
等同於:
結果:
費曼比喻
. 像用膠水把兩張紙貼在一起:
.= 則像在同一張紙後面繼續寫:
超高頻錯誤
PHP 字串不能使用 + 連接。
錯誤:
正確:
必背英文
PHP uses the dot operator to concatenate strings.
A1.5 strrev():反轉字串
“strrev($string) reverses the string $string.”
語法
例子
輸出:
另一個例子:
輸出:
Palindrome 判斷
“A palindrome is a word which reads the same backward as forward.”
Palindrome 是正讀和反讀都相同的字,例如:
完整 PHP 判斷:
使用:
費曼拆解
以 level 為例:
以 apple 為例:
必背判斷式
A1.6 strpos():尋找字串位置
“strpos(string, search_string) performs a case-sensitive search and returns the position of the first occurrence.”
語法
例子
輸出:
因為:
找不到時的結果
$result 會是:
超高頻陷阱:位置 0
假設:
結果是:
如果寫:
程式可能誤以為沒有找到,因為 PHP 會將 0 視為 false。
正確寫法:
必背英文
strpos()returnsfalseif the substring is not found.
Use !== false to distinguish position zero from not found.
A1.7 substr():擷取部分字串
“substr(string, start_position, length) returns a portion of a string.”
基本語法
例子
輸出:
拆解:
省略 length
輸出:
意思是:
從 index 3 開始,一直取到字串結尾。
負數位置
輸出:
輸出:
不過考試最常見的仍是:
A1.8 綜合例子:拆解 Email Address
題目
給定:
要求找出:
解題流程
Step 1:找出 @ 的位置
結果:
Step 2:擷取 @ 前面的內容
意思是:
結果:
Step 3:擷取 @ 後面的內容
為什麼要 + 1?
完整答案
費曼總結
不需要把 email 當成特殊資料來背,只要理解:
這個邏輯也適用於:
A1.9 strstr() 與 substr() 的分別
“strstr(string, search_string) returns a substring from the first occurrence of the search string to the end.”
例子
輸出:
如果不希望保留 @,比較適合使用:
結果:
對照
A1.10 String 與 Array 的轉換
explode():String → Array
“explode() splits a string into an array.”
結果:
費曼比喻
explode() 像沿著虛線剪紙:
變成:
implode():Array → String
“implode() combines an array's elements into a single string, separated by a specified character.”
結果:
必背對照
這一組函式可能同時在:
- A1 String
- A2 Array
- A4 Session/Cookie
出現。
A1.11 模擬歷屆試卷完整示範題
題目
下面的 PHP 程式檢查單字是否是 palindrome,並抽取 email 的 username 和 domain。
請填寫 (a) 至 (f)。
預期輸出:
逐格費曼解題
(a) 函式要回傳什麼?
註解概念是判斷 palindrome。
Palindrome 的條件:
答案:
(b) if 裡需要什麼?
已經有一個 function:
因此直接呼叫:
(c) 找 @ 的位置
使用:
(d) Username 的長度
@ 之前的字元數,剛好等於 @ 的 index:
(e) Domain 的起點
要跳過 @,所以:
(f) 顯示哪個變數?
前面已建立:
完整答案
A1.12 考試看到空格時如何反推?
空格位置判斷法
空格在 = 後面
代表需要:
Expression or function return value
例如:
空格在 if (...) 裡
代表需要:
Boolean condition
例如:
空格在 function argument
代表需要:
A value or expression
例如:
空格後有分號
可能是完整 statement:
空格位於 output 中
通常是 variable 或 function call:
A1.13 必背清單
String functions
Operators
解題句型
Return true if the word is a palindrome.
Find the position of a substring.
Extract a substring before the delimiter.
Extract a substring after the delimiter.
Convert a string into an array.
A1 隨堂測驗
請直接按照考試格式填 (a) 至 (h),不需要解釋。
題目:Product Code Processing
程式要處理以下 product code:
預期輸出:
請填空:
作答格式
評分標準
- 每格 1 分,共 8 分;
- 7–8 分:達標,自動進入 A2 Array Processing;
- 5–6 分:先修正盲點,再進入 A2;
- 0–4 分:針對錯誤函式進行簡短補救題。
(a)strlen($code)
完整程式:echo "Code length: " . strlen($code) . "<br>";
(b)strrev($code)
結果:52-tsaoT-DOOF
(c)explode("-", $code)
題目要把一個 String 切成 Array:"FOOD-Toast-25"
↓ explode("-")
["FOOD", "Toast", "25"]explode() splits a string into an array.
implode() combines array elements into a string.
必背方向:
explode:String → Array
implode:Array → String
而且 implode("-", $code) 不只方向錯誤,第二個參數也應該是 array,不應是 string。
(d)$parts[0]
因為切割後:$parts = ["FOOD", "Toast", "25"];
(e)$parts[1]
結果:
Toast
(f)$parts[2]
結果:
25
(g)strpos($product, "T") !== false
這是 A1 最重要的陷阱之一。
Toast 的第一個字母就是 T:字元: T o a s t
索引: 0 1 2 3 4
因此:strpos("Toast", "T")傳回:0正確判斷: returns
if (strpos($product, "T") !== false) {
echo "The product name contains the letter T.";
}
strpos()false if the substring is not found.
Use !== false to distinguish position zero from not found.
注意這裡應使用:!== false而不是:!= 0也不建議寫:> 0因為搜尋內容可能就在 index 0。
(h)strlen($code)-1
完整程式:$lastCharacter = $code[strlen($code) - 1];結果是:5因為:字串長度 = 13正確完整答案
最後索引 = 13 - 1 = 12<?php
$code = "FOOD-Toast-25";
echo "Code length: " . strlen($code) . "<br>";
echo "Reversed: " . strrev($code) . "<br>";
$parts = explode("-", $code);
$category = $parts[0];$product = $parts[1];$price = $parts[2];
echo "Category: " . $category . "<br>";
echo "Product: " . $product . "<br>";
echo "Price: " . $price . "<br>";
if (strpos($product, "T") !== false) {
echo "The product name contains the letter T.";
}
$lastCharacter = $code[strlen($code) - 1];
?>
A1 補救題
題目:Student Record
給定字串:
250299909,Tai Ming,HDSE
預期輸出:
Student ID: 250299909
Name: Tai Ming
Programme: HDSE
The name contains Ming.
Last character of Student ID: 0
請填寫 (a) 至 (f):
<?php
$record = "250299909,Tai Ming,HDSE";
$student = (a) ;
$studentID = (b) ;$name = (c) ;$programme = (d) ;
echo "Student ID: " . $studentID . "<br>";echo "Name: " . $name . "<br>";echo "Programme: " . $programme . "<br>";
if ( (e) ) { echo "The name contains Hon.<br>";}
$lastCharacter = $studentID[ (f) ];
echo "Last character of Student ID: " . $lastCharacter;
?>
請用以下格式回答:
(a)(b)(c)(d)(e)(f)
A1 補救題批改:6 / 6,全對 ✅
你的答案:
全部正確。
你已經修正的盲點
你現在能正確區分:
也能正確處理 strpos() 的特殊情況:
Use !== false to distinguish position zero from “not found.”A1 最終評估
技能
結果
strlen()
已掌握
strrev()
已掌握
explode()
修正後已掌握
Array index
修正後已掌握
strpos() !== false
修正後已掌握
最後字元索引
已掌握
A1 Learning Outcome:達標。
題號操練 2:A2 — Array Processing
根據目前的考試方向,原先 A1–A2 的 Python 題會由 String & Array 取代。因此 A2 的主要目標是掌握 PHP 的:
- Indexed Array
- Associative Array
- Nested Array
foreach- Search and Filter
- Total、Maximum、Minimum
- 加入元素
- Array 與 String 的轉換
A2.1 Array 是什麼?
“An array is a list of values. Each value can be retrieved independently of one another and can also be changed without affecting the other values.”
費曼解釋
Array 就像一排有編號的置物櫃。
在電腦中可以理解成:
取得資料:
修改資料:
現在變成:
必背英文
An indexed array uses numeric indexes.
The first element has an index of zero.
A2.2 建立 Indexed Array
PHP 常見的兩種寫法:
或較簡潔的:
兩者意思相同。
計算元素數目:count()
輸出:
count() returns the number of elements in an array.注意:
錯誤:
正確:
A2.3 在 Array 後面加入元素
方法一:使用空索引 []
結果:
方法二:使用 array_push()
在考試中,較常見也較簡單的是:
例如 A4 Session 題經常出現:
意思是:
將$name加到 session 中Food陣列的最後。
必背英文
Append a new element to the array.
A2.4 使用 for 遍歷 Indexed Array
輸出:
費曼拆解
從第一格開始。
只要還沒有走出陣列範圍,就繼續。
每次移到下一格。
高頻錯誤
錯誤:
當 $i 等於 count($items) 時,已超出最後一格。
如果共有 3 個元素:
所以正確條件是:
A2.5 使用 foreach 遍歷 Array
“PHP provides a construct that can be used to iterate a non-sequential array.”
只取 value
逐次執行時:
同時取得 index 和 value
輸出:
必背格式
A2.6 Associative Array
“If you want to associate a particular key with a value, you can use the => operator.”Indexed Array 的問題
假設一個產品是:
你必須記住:
這容易混淆。
Associative Array
可以改成:
結構:
取得資料:
費曼比喻
Indexed Array 像沒有標籤的抽屜:
Associative Array 像有文字標籤的抽屜:
易錯寫法
錯誤:
考試建議寫成:
A2.7 Nested Array
一張訂單通常不只一個 item,因此會使用「陣列裡面再放陣列」。
資料結構圖
逐層取值
取得 canteen:
取得 items array:
取得第一個 item:
取得第一個 item 的名稱:
取得第二個 item 的價格:
結果:
費曼口訣
每看到一個 [],就是往資料內走一層:
A2.8 遍歷 Nested Array
輸出:
執行流程:
所以 loop 內應使用:
而不是:
因為 name 屬於每一個 item,不是最外層 $order。
A2.9 Total:累加總數
題目
計算所有 items 的總價。
結果:
費曼解釋
$total 像收銀機顯示器:
為什麼要先寫 $total = 0?
如果沒有初始化,程式不知道應從什麼數字開始累加。
必背英文
Initialize the accumulator before the loop.
Accumulate the price of each item.
A2.10 Count:按照條件計數
題目
計算 Food 類別有多少個 items。
費曼解釋
這裡不是加價格,而是每找到一個符合條件的 item,就在計數器上加一。
常見區別
計算總價:
計算數量:
A2.11 Filter:找出符合條件的元素
題目
將所有 Food 名稱放入 $foodNames。
如果資料有 Toast 和 Noodle:
最後可使用:
輸出:
這個模式在 A4 Session 題極常出現:
A2.12 Maximum 和 Minimum
找最低價格
為什麼先使用第一筆?
因為最低價格應該來自真實資料。
假設寫:
但所有商品價格都大於 0:
最低價格會錯誤地保留為 0。
所以應該:
找最高價格
必背英文
Assume the first element has the lowest value.
Update the minimum when a lower value is found.
A2.13 同時保存最低價商品
有時題目不只要求找最低價格,也要求找商品名稱。
方法一:保存整筆 item
顯示:
費曼解釋
不要只保存最低分數,要保存「整張商品卡」。
如此最後可以同時知道商品名稱、價格和類型。
A2.14 Search:尋找指定商品
為什麼需要 $found?
如果 loop 結束仍是:
就代表沒有找到。
break 的作用
Terminate the loop immediately after the item is found.
找到後不必再檢查後面的資料:
A2.15 Duplicate Check
過往 A2 的 Order 題要求避免加入重複 item。即使 Python 已排除,這個陣列邏輯仍可能用 PHP 考核。
方法一:簡單 indexed array
in_array() checks whether a value exists in an array.方法二:Nested array
如果每個 item 是 associative array,不能只寫:
因為 $order["items"] 裡面放的是完整 array,不是單純名稱。
需要 loop:
A2.16 完整模擬試題示範
題目
以下程式處理 canteen order:
要求輸出:
請填寫:
逐步解題
(a) Canteen 在最外層
(b) 要計算 items 數量
(c) 先假設第一筆價格最低
(d) 遍歷 items array
(e) 累加當前 item 的價格
(f) 符合 Food 時保存名稱
(g) 找到更低價格時更新
(h) 將名稱陣列接成字串
完整答案
A2.17 考試解題決策圖
A2 必背英文與語法
Create an empty array.
Append an element to an array.
Loop through every element.
Count the number of elements.
Accumulate the total price.
Assume that the first item has the lowest price.
Join the array elements into a string.
A2 隨堂測驗:完整考試格式
題目:Module Result Processing
以下陣列儲存三個 modules:
程式需要輸出:
通過分數是 40。請填寫 (a) 至 (j):
作答格式
評分標準
- 每格 1 分,共 10 分;
- 9–10 分:A2 達標,直接進入 A3 Form Processing;
- 7–8 分:修正錯誤後進入 A3;
- 0–6 分:先完成一題 Nested Array 補救題。
A2 隨堂測驗批改:6 / 10
你已掌握 Nested Array 的外層結構、初始化、count() 與 foreach。主要錯誤有兩類:
foreach內使用了錯誤的變數名稱;- 最後忘記用
implode()把 array 轉為 string。
逐格批改
(a) ✅ 正確
$student["name"]
取得最外層 associative array 的 name:
$student├── ["name"] → Kam Hon└── ["modules"] → [...]
(b) ✅ 正確
count($student["modules"])
count() returns the number of elements in an array.modules 裡有三個元素,因此輸出:
3
(c) ✅ 正確
0
計算總分前,累加器應初始化為:
$totalMarks = 0;
Initialize the accumulator before the loop.
(d) ✅ 正確
[]
要收集通過的 module codes,所以先建立 empty array:
$passedModules = [];
(e) ✅ 正確
$student["modules"][0]["mark"]
這表示:
進入 $student→ 進入 ["modules"]→ 取得第一筆 [0]→ 取得 ["mark"]
結果是:
68
找 maximum/minimum 時,以第一筆真實資料作初始化是正確做法。
Assume that the first module has the highest mark.
(f) ✅ 正確
$student["modules"]
完整結構:
foreach ($student["modules"] as $module) {
每次 loop,當前記錄會放入單數變數:
$module
(g) ❌ 變數名稱錯誤
你的答案:
$modules["mark"]
正確答案:
$module["mark"]
因為 foreach 寫的是:
foreach ($student["modules"] as $module)
這代表:
原本的完整陣列:$student["modules"]當前的一筆資料:$module
第一次 loop:
$module = [ "code" => "ITP4523M", "mark" => 68];
所以應寫:
$totalMarks += $module["mark"];
(h) ❌ 同樣是變數名稱錯誤
你的答案:
$modules["code"]
正確答案:
$module["code"]
完整程式:
if ($module["mark"] >= 40) { $passedModules[] = $module["code"];}
每找到一個合格科目,就把該科目的 module code 加到陣列末尾。
執行後:
$passedModules = [ "ITP4523M", "ITP4513M"];
(i) ❌ 應使用 $module
你的答案:
$modules["mark"] > $highestMark
正確答案:
$module["mark"] > $highestMark
完整判斷:
if ($module["mark"] > $highestMark) { $highestMark = $module["mark"];}
執行過程:
初始 highestMark = 68
第一筆 68:68 > 68 → false
第二筆 35:35 > 68 → false
第三筆 72:72 > 68 → truehighestMark 更新為 72
(j) ❌ Array 不能直接當成所需字串輸出
你的答案:
$passedModules
正確答案:
implode(", ", $passedModules)
目前 $passedModules 是 array:
[ "ITP4523M", "ITP4513M"]
題目要求輸出一行文字:
ITP4523M, ITP4513M
所以需要:
implode(", ", $passedModules)`
implode() combines array elements into a single string.
正確答案總表
(a) $student["name"]
(b) count($student["modules"])
(c) 0
(d) []
(e) $student["modules"][0]["mark"]
(f) $student["modules"]
(g) $module["mark"]
(h) $module["code"]
(i) $module["mark"] > $highestMark
(j) implode(", ", $passedModules)
完整正確程式
<?php
$student = [ "name" => "Kam Hon", "modules" => [ ["code" => "ITP4523M", "mark" => 68], ["code" => "ITP4507M", "mark" => 35], ["code" => "ITP4513M", "mark" => 72] ]];
echo "Student: " . $student["name"] . "<br>";
echo "Number of modules: " . count($student["modules"]) . "<br>";
$totalMarks = 0;$passedModules = [];
$highestMark = $student["modules"][0]["mark"];
foreach ($student["modules"] as $module) { $totalMarks += $module["mark"];
if ($module["mark"] >= 40) { $passedModules[] = $module["code"]; }
if ($module["mark"] > $highestMark) { $highestMark = $module["mark"]; }}
echo "Total marks: " . $totalMarks . "<br>";
echo "Passed modules: " . implode(", ", $passedModules) . "<br>";
echo "Highest mark: " . $highestMark;
?>
輸出:
Student: Kam HonNumber of modules: 3Total marks: 175Passed modules: ITP4523M, ITP4513MHighest mark: 72
核心盲點:Array 名稱與單筆變數
你的資料處理邏輯是正確的,錯誤主要是把 $module 寫成 $modules。
foreach ($student["modules"] as $module)
可翻譯為:
From the collection$student["modules"], take each individual record and temporarily call it$module.
資料角色
$student["modules"] → 全部 modules 的陣列$module → 當前正在處理的一筆 module
因此:
count($student["modules"])
是計算全部 modules。
但在 loop 內:
$module["mark"]$module["code"]``
是讀取當前一筆資料。
費曼口訣
Plural means the collection; singular means the current record.
$modules → 整個集合$module → 當前一筆
A2 補救題:Nested Array
完成這題後直接進入 A3 Form Processing。
題目:Canteen Order
$order = [ "canteen" => "ABC Canteen", "items" => [ ["name" => "Toast", "price" => 15, "type" => "Food"], ["name" => "Coffee", "price" => 22, "type" => "Drink"], ["name" => "Noodle", "price" => 35, "type" => "Food"] ]];
預期輸出:
Canteen: ABC CanteenTotal price: 72Food items: Toast, NoodleMost expensive item: Noodle
請填空:
<?php
echo "Canteen: " . (a) . "<br>";
$totalPrice = (b) ;$foodItems = (c) ;
$mostExpensive = (d) ;
foreach ( (e) as $item) {
$totalPrice += (f) ;
if ($item["type"] == "Food") { $foodItems[] = (g) ; }
if ($item["price"] > $mostExpensive["price"]) { $mostExpensive = (h) ; }}
echo "Total price: " . $totalPrice . "<br>";
echo "Food items: " . (i) . "<br>";
echo "Most expensive item: " . (j) ;
?>
提示
這題的 $mostExpensive 要保存整筆 item,不是只保存 price:
$mostExpensive├── ["name"]├── ["price"]└── ["type"]
請按照以下格式作答:
(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)
A2 補救題批改:6 / 10
你已經掌握:
- 外層 associative array;
- 初始化 accumulator;
- 建立空陣列;
foreach當前記錄;- 累加價格;
- 收集符合條件的名稱。
目前主要盲點是:
題目要求保存「整筆 item」時,你只保存了 item name,或保存了整個 items 集合。
正確答案總覽
逐格批改
(a) ✅ 正確
取得最外層的 canteen name。
(b) ✅ 正確
總價累加器從零開始:
(c) ✅ 正確
建立空陣列,準備收集 Food items:
(d) ❌ 應取得第一筆 item,不是整個 items 集合
你的答案:
這代表全部商品:
但 $mostExpensive 應保存一筆商品記錄:
正確答案:
初始值會是:
因此後面才能使用:
Assume that the first item is the most expensive item.
(e) ✅ 正確
完整程式:
角色分工:
(f) ✅ 正確
完整程式:
執行過程:
(g) ✅ 正確
完整程式:
最後:
(h) ❌ 應保存整筆 $item
你的答案:
這只會保存:
但下一次比較需要:
如果 $mostExpensive 只是 "Noodle",就沒有 ["price"] 可以讀取。
正確答案:
完整程式:
費曼解釋
題目不是只保存「冠軍名字」,而是保存整張冠軍資料卡:
這樣之後可以自由取得:
(i) ⚠️ 概念正確,但輸出格式不完全符合
你的答案:
會輸出:
題目要求:
正確答案應在逗號後加入空格:
考試中若題目要求完全符合指定輸出,separator 也要準確。
(j) ❌ 應取得整筆記錄中的名稱
你的答案:
但 $mostExpensive 是 associative array,不能直接當成商品名稱輸出。
正確答案:
結果:
正確完整程式
A2 最終補強重點
你要特別記住兩種保存方式的差別。
只保存價格
最後只能知道價格:
保存整筆記錄
最後可以知道所有欄位:
If the question asks for information about the winning record, store the entire record.
A2 的核心邏輯已經完成。接下來進入固定高頻題:
題號操練 3:A3 — PHP Form Processing
A3.1 題型定位
A3 歷年通常要求完成一個 self-submitting HTML/PHP form,主要考:
- Form attributes;
GET或POST;- Input
name、value和required; - 判斷表單有沒有提交;
- 判斷 radio/checkbox 有沒有選取;
- Server-side validation;
- 條件運算;
- 顯示錯誤或成功訊息。
典型題目指示:
“The program must submit the form to itself by POST method.”
“Check if the form is submitted.”
“Check if a plan is selected.”
“Display error message(s) when the input is invalid.”
A3.2 Form 的資料流程
費曼比喻
把 HTML Form 想成一張申請表:
name:欄位名稱;value:填入或選取的內容;method:送件方式;action:送去哪個櫃台;- PHP:審核申請表的職員。
A3.3 <form> 的兩個核心 attributes
“The action attribute gives the URL of the server web service that will process the form’s data.”
“The method attribute specifies whether the server should use an HTTP GET or POST request.”
POST 表單
這表示:
如果題目要求提交回自己,常見答案是:
有時也可能使用:
但補充題通常期望直接填指定檔案名稱。
A3.4 GET 與 POST
“A GET request passes the parameters to the server as a query string.”
“A POST request embeds the parameters in the HTTP request, not in the URL.”
GET
可能產生:
適合:
- Search;
- Filter;
- 可放入 bookmark 的查詢;
- B1 category 查詢。
POST
資料不會直接顯示在 URL。
適合:
- 新增資料;
- 表單驗證;
- 登入;
- A3 計算及確認表單。
必背對照
A3.5 name 和 id 的分別
這是 A3 最重要的觀念之一。
name
決定提交到 PHP 的 key:
id
主要讓 JavaScript 或 CSS 找到 HTML element:
費曼比喻
name是申請表上的欄位名稱;id是網頁元件的座位編號。
Only successful form controls with a name are submitted to the server.
如果只有 id、沒有 name:
PHP 通常無法透過以下方式取得:
A3.6 value 的作用
Radio button:
如果選取 Food,提交的資料是:
如果選取 Drink:
“The value attribute controls what will be submitted if that control is selected.”
常見誤解
畫面顯示的文字:
不一定等於提交值。真正提交的內容由:
決定。
A3.7 required:Browser-side Validation
如果欄位空白,browser 會阻止一般表單提交。
The required attribute enforces input in the browser.但 required 不代表 PHP 不用檢查。
使用者可能:
- 移除 HTML attribute;
- 直接發送 request;
- 提交空白字串;
- 傳送不合法資料。
因此仍應做 server-side validation:
A3.8 判斷表單有沒有提交
典型 Submit button:
提交後,通常會出現:
所以:
Check whether the form is submitted.
費曼解釋
isset() 是檢查包裹裡有沒有名為 submit 的欄位。
A3.9 isset() 與 empty()
isset()
檢查 variable/array key 是否存在,而且不是 null。
適合:
- Radio button;
- Checkbox;
- Submit button;
- 有可能完全不提交的欄位。
empty()
檢查值是否為空。
會將以下值視為 empty:
適合:
- Text field 沒有填寫;
- Submitted value 是空字串。
Radio button 為何通常使用 isset()?
如果使用者沒有選取任何 radio button:
Browser 通常完全不提交 type。
也就是:
可能不存在。
所以:
必背英文
Check whether an item type is selected.
Check whether an item type is not selected.
A3.10 extract($_POST)
歷屆題目經常給:
假設:
執行:
會建立:
費曼解釋
$_POST 原本像一個裝有多張卡片的盒子:
extract() 把每張卡片變成獨立 variable。
考試注意順序
應先確認表單已提交,再讀取資料:
而且,如果 radio 未選,$type 可能不會被建立。因此通常仍使用:
檢查。
A3.11 建立 Error Flags
2024–2025 類型的 A3 題目使用 Boolean flags:
費曼解釋
Flag 就像警告燈:
然後分別顯示錯誤:
最後只有兩個警告燈都沒亮,才能成功:
也可寫成:
兩者邏輯相同。
A3.12 AND、OR 與 NOT
AND:兩個條件都成立
例如:
意思:
OR:其中一個成立
例如:
意思:
只要其中一個錯誤存在,就代表輸入不合法。
NOT:反轉 Boolean
例如:
意思:
A3.13 經典題型一:Discount Calculation
條件
標準程式
總價:
費曼拆解
假設:
原價:
付款比例:
折後價:
顯示折扣百分比
儲存的是:
但畫面要顯示:
所以:
A3.14 printf() 格式化輸出
“The printf() function outputs a formatted string.”例如:
Placeholder
因此:
意思是:
參數對應
對應:
The number and order of placeholders must match the arguments.
A3.15 經典題型二:顯示多個 Validation Errors
假設要求:
- Name 不可為空;
- 必須選 type;
- Price 不可超過 100;
- 所有輸入正確才成功。
為什麼不用 else if 顯示錯誤?
如果使用者同時:
- 沒填 name;
- 沒選 type;
- price 太高;
題目可能要求同時顯示三個錯誤。
若使用:
只會顯示第一個成立的錯誤。
所以每個錯誤應使用獨立 if:
A3.16 完整歷屆模式示範
題目
建立 canteen item form:
- 使用 POST;
- 表單提交回
A3.php; - Name 和 Price 必填;
- Type 是 Food 或 Drink;
- 未選 type 顯示錯誤;
- price 大於 100 顯示錯誤;
- 沒有錯誤才顯示成功訊息。
完整答案
A3.17 填空題反推方法
空格在 <form ...>
需要 HTML attribute:
空格在 <input ...>
可能需要:
空格在 isset(...)
通常需要 superglobal 和 key:
空格前有 !
通常:
組合後:
空格在 if (...)
需要 Boolean expression:
或:
A3 必背語法清單
Form
Submission
Radio/Checkbox selection
Empty text
Read submitted value
Extract
No-error condition
A3 隨堂測驗:完整考試格式
題目:Course Registration Form
功能要求:
- Form 使用 POST,提交回
A3.php; - Student Name 必填;
- 必須選擇
Full-time或Part-time; - Study Hours 必須介於 1 至 20;
- 如果沒有選 mode,顯示錯誤;
- 如果 hours 大於 20,顯示錯誤;
- 沒有錯誤才顯示成功訊息。
請填寫 (a) 至 (j):
A3 隨堂測驗:Course Registration Form
剛才的程式碼確實被截斷了。以下是完整版本,請填寫 (a) 至 (j)。
功能要求
- Form 使用 POST,並提交回
A3.php; Student Name必填;Study Hours必須填寫,允許範圍為 1–20;- 必須選擇
Full-time或Part-time; - 沒有選擇 study mode 時,顯示錯誤;
- Study hours 大於 20 時,顯示錯誤;
- 沒有錯誤時,顯示成功訊息。
Check whether the form is submitted.
Check whether a study mode is selected.
Display the success message only if no input error exists.
完整題目
<html><body>
<form (ent Name: <input type="text" name="studentName" (b) > <br>
Study Hours: <input type="number" name="hours" min="1" max="20" (b) > <br>
Study Mode:
<input type="radio" name="mode" value="Full-time">Full-time
<input type="radio" name="mode" value="Part-time">Part-time <br>
<input type="submit" name="submit" value="Register">
</form>
<?php
$formSubmitted = (c) ;
if ($formSubmitted) {
extract( (d) );
$modeNotSelected = ! (e) ;
$hoursTooHigh = (f) ;
if ($modeNotSelected) { echo "ERROR: Select a study mode.<br>"; }
if ($hoursTooHigh) { echo "ERROR: Study hours cannot exceed 20.<br>"; }
if ( (g) ) { echo "Student " . (h) . " has registered for " . (i) . " mode with " . (j) . " study hours."; }}
?>
</body></html>
預期成功輸出
如果使用者輸入:
Student Name: Kam HonStudy Hours: 12Study Mode: Full-time
應顯示:
Student Kam Hon has registered for Full-time mode with 12 study hours.
預期錯誤輸出
如果沒有選擇 Study Mode:
ERROR: Select a study mode.
如果 Study Hours 是 25:
ERROR: Study hours cannot exceed 20.
如果兩個錯誤同時存在,兩個錯誤訊息都應顯示。
作答格式
(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)
小提示
(a):完整的 form method attribute;(b):HTML 必填 attribute,同一答案使用兩次;(c):檢查submit是否存在於$_POST;(d):extract()要處理的 associative array;(e):檢查mode是否存在;前面已經有!;(f):檢查$hours是否大於 20;(g):兩個錯誤都不存在;(h)–(j):因為已執行extract(),可直接使用建立出來的 variables。
A3 隨堂測驗批改:8 / 10 ✅
整體表現不錯。你已掌握:
- Form 的
method與action - HTML
required - 使用
isset()判斷表單提交 extract($_POST)- Error flags
- 無錯誤條件
- 提交後的 variables
只有 (e) 漏掉右括號,以及 (f) 多寫了分號。兩者都屬於考試常見的「上下文式語法錯誤」。
逐格批改
(a) ✅ 正確
你的答案:
完整結構:
符合:
Submit the form to itself by POST method.
(b) ✅ 正確
完整輸入欄位:
required 是 HTML Boolean attribute,不需要寫:
直接寫 required 即可。
(c) ✅ 正確
完整程式:
Check whether the form is submitted.
這裡使用 isset(),是因為要判斷 submit key 是否存在於 $_POST。
(d) ✅ 正確
完整程式:
例如提交資料:
執行 extract($_POST) 後會建立:
(e) ❌ 邏輯正確,但漏掉右括號
你的答案:
正確答案:
因為題目的前面已經提供 !:
填入後應成為:
費曼拆解
意思是:
前面加入 !:
意思就反轉成:
Check whether a study mode is not selected.
(f) ❌ 條件正確,但不應在填空內加入分號
你的答案:
正確答案:
原因是題目已經在空格後提供分號:
如果把你的答案原樣放入,會變成:
它可能在 PHP 中被視為多出一個空 statement,但在 missing-code 題目裡,應只填空格需要的 Boolean expression,不要重複題目已有的標點。
正確完整程式:
考試判斷技巧
看到:
空格通常只需填:
例如:
不要再加分號,因為題目已提供。
(g) ✅ 正確
你的答案:
完整程式:
意思是:
只有兩個錯誤都不存在,才顯示成功訊息。
Display the success message only if no input error exists.
也可以理解成:
(h) ✅ 正確
因為已經執行:
所以可以直接使用 $studentName。
(i) ✅ 正確
如果選取:
那麼:
(j) ✅ 正確
會顯示使用者提交的 study hours。
正確答案總表
完整正確程式
A3 重要補充:題目本身有一個驗證細節
HTML 已經寫:
一般情況下,瀏覽器會阻止使用者提交大於 20 的值。因此正常使用界面時,PHP 未必會收到 25。
但是題目仍要求 PHP 檢查:
這不是重複,而是兩層驗證:
費曼比喻
- HTML validation 像大樓門口的保全;
- PHP validation 像辦公室內部的審核員。
即使有人繞過門口保全,內部仍要再次審核。
Client-side validation improves usability, but server-side validation enforces the rule.
A3 考試語法精準度提醒
你的邏輯已經正確,現在要注意「空格需要什麼種類的答案」。
Expression
題目:
填:
不要加分號。
Function call
題目:
填:
不要填:
否則會變成重複呼叫。
HTML attributes
題目:
填:
這裡不是 PHP statement。
Boolean condition
題目:
填:
不要再加括號或分號,除非空格涵蓋它們。
A1–A3 階段總結
題號
主題
最終狀態
需要留意
A1
String Processing
達標
explode()、strpos() !== false
A2
Array Processing
基本達標
單筆 $item 與完整集合 $items;保存整筆 record
A3
Form Processing
達標
括號、分號及填空上下文
你目前最需要記住的三句
explode() converts a string into an array.
Plural represents the collection; singular represents the current record.
Use isset() to check whether a radio-button value was submitted.
下一個題號是 A4 — Session and Cookie Processing,核心會是:
A4 — Session and Cookie Processing
A4 是近年最穩定、最容易重複出現題型的題目之一。
根據歷屆試卷:
- 2021–2022:COVID Test Results
- 找最年長的人
- 將 Positive 人名存入 Session
- 將 oldest person 存入 Cookie
- 2024–2025:Canteen Order
- 找最低價商品
- 將 Food Items 存入 Session
- 將 lowest price 存入 Cookie
雖然故事不同,但題目骨架幾乎完全一樣。
A4 考試核心公式
你幾乎可以把 A4 理解成:
A4.1 Session 和 Cookie 是什麼?
教材原文:
“HTTP is a stateless protocol.”
“Using cookie, a web server can ask a browser to ‘remember’ a piece of information.”
“Using session, a web server can keep some data on the server.”
費曼解釋
假設你去餐廳吃飯。
Cookie
Cookie 像:
放在你身上。
例如:
下次來的時候:
Server 就知道:
Session
Session 像:
存在餐廳裡。
例如:
保存:
這些資料不放在 Browser。
考試最愛問
Cookie 放在哪裡?
答案:
Session 放在哪裡?
答案:
哪一個比較適合放 Array?
答案:
因為歷屆題目幾乎都把:
放進:
A4.2 第一行永遠是什麼?
答案:
歷屆答案
2021:
2025:
為什麼?
因為 PHP 要先開啟 Session。
教材原文:
“session_start()”
“Using session, a web server can keep some data on the server.”
必背
考試出現:
而且位置在最頂部。
答案通常就是:
A4.3 歷屆資料結構分析
2021 題
結構:
2025 題
結構:
費曼觀察
其實兩題完全一樣。
2021:
2025:
2021:
2025:
只是欄位名字不同而已。
A4.4 Cookie 題固定套路
Lowest Price
先假設:
為什麼?
因為第一個 item 的 price:
所以:
結果:
然後:
判斷:
成立:
圖像理解
比較:
答案:
A4.5 找 Maximum
另一種常考:
比較:
成立:
最後:
得到:
重要觀念
如果題目最後要輸出:
要保存:
不要只保存:
否則最後不知道名字。
A4.6 Session 題固定套路
建立 Session Array
歷屆答案:
或
收集資料
Food:
Positive:
費曼理解
每找到符合條件的人:
例如:
最後變:
A4.7 Cookie 題固定套路
教材原型:
費曼拆解
Cookie 三部分:
例子:
1800 秒是多少?
三天
2021 題:
公式:
A4.8 讀取 Cookie
考試高頻:
意思:
否則:
表示:
讀取:
範例:
A4.9 implode()
歷屆超常見。
教材原文:
“implode() combines an array's elements into a single string.”
Session 裡是:
不能直接:
要:
結果:
A4 必背骨架(100%要會)
A4 歷屆題型預測
根據近年題目規律:
類型一
Cookie:
Session:
類型二
Cookie:
Session:
類型三
Cookie:
Session:
A4 第一題實戰測驗
請直接填空。
預期功能
- Session 保存所有非 Drink 名稱
- Cookie 保存最低價格
- Cookie 一小時後到期
請回答:
答對 5–6 格,我們就直接進入歷屆真題風格的 A4 第二題(Oldest Person / Lowest Price 綜合題)。
A4 第一題批改:4 / 6
你已掌握 A4 最重要的三個核心:
✅ session_start()
✅ Lowest Price 初始化
✅ Cookie 時間計算
錯的地方集中在:
(a) ✅ 正確
你的答案:
A4 幾乎每年第一格都是:
A session must be started before using $_SESSION.
(b) ✅ 正確
你的答案:
第一筆資料:
因此:
等於:
最低價格初始化正確。
(c) ⚠️ 概念正確,但 Session 名稱不符
你的答案:
正確答案:
因為題目已經給你:
所以後面必須加入同一個 Session Array。
完整:
結果:
(d) ✅ 正確
你的答案:
完整:
執行:
最後:
(e) ✅ 正確
你的答案:
換算:
等同:
(f) ❌ Session 名稱錯誤
你的答案:
應該是:
因為之前儲存的是:
而不是:
完整:
輸出:
正確答案
A4 最重要觀念
你開始出現一個歷屆常見錯誤:
Session Name 必須一致
建立:
加入:
輸出:
不能出現:
然後:
或者:
因為 Session 名稱不同。
A4 第二題(歷屆真題級)
這題已經接近 2021 + 2025 的正式考試難度。
題目:Student Result Processing
要求:
Session
保存所有:
到:
Cookie
保存:
到:
Cookie:
顯示
再次進入頁面時:
填空題
作答格式
提示
這題基本上就是:
真正考場上大約 8–10 分鐘要完成。完成這題後,我們就會進入歷屆高頻 A5 JSON + AJAX。
A4 第二題批改:6 / 8 ✅
這題已經非常接近正式考試。
你的 Session、Cookie、Expiry Time、Pass Students 全部正確。
只有兩個錯誤:
(c)Highest Mark 初始化(g)Cookie 讀取方式
逐格批改
(a) ✅
正確。
(b) ✅
放回原程式:
完全正確。
(c) ❌
你的答案:
這時候還沒有進入:
所以:
根本不存在。
正確:
第一筆資料:
因此:
結果:
(d) ✅
正確。
最後得到:
(e) ✅
正確。
(f) ✅
換算:
正確。
(g) ❌
你的答案:
此時已經進入:
表示:
所以必須從 Cookie 讀。
正確:
完整:
(h) ✅
完整:
輸出:
正確答案
A4 考官最愛的 5 個空格
近年 A4 幾乎每份卷都在考下面這些:
類型 1
類型 2
類型 3
類型 4
類型 5
A4 歷屆考試骨架(直接背)
如果你能把這個模板默寫出來,A4 通常能拿到 70–90% 分數。
A4 學習成果評估
能力
狀態
session_start()
✅
$_SESSION Array
✅
$_SESSION[] append
✅
Minimum / Maximum
✅
setcookie()
✅
Cookie Expiry 計算
✅
$_COOKIE 讀取
⚠️ 需再注意
implode()
✅
A4 成績
已達到進入下一題資格。
下一站:A5 — JSON + AJAX
A5 是近年最穩定的題型之一:
歷屆主要出現:
- Student Transcript
- Canteen Order
- Weather Data
- Song List
但骨架幾乎完全一樣。
我們下一步會直接進入:
A5.1 JSON 結構閱讀與 json_encode() 真題操練
A5.2 AJAX 必背模板(每年幾乎固定出現)
A5.3 歷屆 A5 Fill-in-the-Blanks 全真題模式
題號操練 5:A5 — JSON + AJAX
我們回到正確順序,正式進行 A5。這一題通常分為:
歷屆常見背景包括:
- Transcript:計算通過、失敗科目及平均分
- Order:計算訂單總額及搜尋商品
- Canteen:讀取商品名稱、價格及類型
題目背景會改,但解題骨架非常固定。 [A910ireh2_...1u_l94.pdf | PDF]
A5.1 歷屆題型定位
2021–2022:Transcript
試卷要求 PHP 產生以下結構:
然後使用 AJAX:
- 讀取
getJSON.php; - 顯示學生名稱;
- 遍歷
modules; - 判斷 Pass/Fail;
- 計算平均分;
- 使用
alert()顯示結果。 [A910ireh2_...1u_l94.pdf | PDF]
2024–2025:Canteen Order
題目要求建立訂單 JSON,再用 AJAX:
- 取得
itemsarray; - 計算訂單總額;
- 呼叫函式搜尋指定商品;
- 回傳該商品價格;
- 使用
alert(message)顯示結果。 [A910ireh2_...1u_l94.pdf | PDF]
A5.2 JSON 的基本結構
原文重點
“JSON is built on name/value pairs and ordered lists.”
“json_encode() converts PHP array to JSON string.”
費曼解釋
JSON 就像一張跨語言通用的資料表。
PHP 內部使用 PHP array:
經過:
會變成 JSON:
JavaScript 收到後,就能使用:
A5.3 Object、Array 和 Property
JSON 只有三個外觀要先認得。
1. Object:大括號 { }
JavaScript 存取:
2. Array:中括號 [ ]
JavaScript 存取:
3. Object 裡包含 Array
資料樹:
存取:
必背英文
An object is accessed by its property name.
An array element is accessed by its numeric index.
A5.4 PHP Associative Array 轉 JSON
典型 PHP 題目
要求產生:
完整 PHP 答案
費曼式逐層建立
第一層:整張訂單
第二層:普通 property
第三層:Items array
第四層:每一筆 item
最後:
A5.5 PHP Array 與 JSON 的符號對照
例如 PHP:
轉換後 JSON:
常見錯誤
在 PHP array 中錯寫 JSON 冒號:
PHP 正確語法應是:
json_encode() 才會把 => 轉換成 JSON 的 :。
A5.6 AJAX 必背模板
原文重點
“The jQuery $.ajax() method” retrieves data dynamically and processes it through a success callback.[A910ireh2_...1u_l94.pdf | PDF]
必背骨架
A5 最常挖空的四部分:
A5.7 AJAX 費曼解釋
把 AJAX 想像成網頁裡的服務生:
各 property 的作用:
A5.8 result 代表什麼?
result 是 AJAX 成功取得並解析後的完整 JSON object。
假設 JSON 是:
那麼:
結果:
而:
代表整個 items array。
A5.9 遍歷 JSON Array
標準 Loop
費曼拆解
代表 items 的數量。
代表目前這一筆 item。
為了讓後面容易閱讀,可以寫:
接著使用:
而不必每次都寫:
A5.10 計算 Total Amount
假設:
總額公式:
JavaScript:
執行過程:
必背英文
Initialize the accumulator before the loop.
Accumulate the subtotal of each item.
A5.11 Pass、Fail 與 Average
以 2021–2022 Transcript 題為例,Passing Mark 是 40。 [A910ireh2_...1u_l94.pdf | PDF]
平均:
注意 property 名稱
試卷 JSON 使用的是:
因此 JavaScript 必須使用:
不能自行改為:
JSON property 必須完全一致。
A5.12 建立 Message
Loop 中追加:
判斷:
最後:
顯示:
必背英文
Display the message in an alert box.
A5.13 =、+= 和 ++
這三種符號經常同時出現在 A5。
Assignment
意思:把新值放入 variable。
Append/Accumulate
等同:
數字累加:
Increment
等同:
A5.14 Search Function
2024–2025 題型會把搜尋功能放在另一個 function。 [A910ireh2_...1u_l94.pdf | PDF]
費曼解釋
為什麼 return "Item not found" 在 loop 外?
錯誤寫法:
這會在第一筆不符合時立即結束,根本不檢查第二筆。
正確:
A5.15 完整歷屆模式示範:Transcript
PHP:getJSON.php
AJAX:A5.html
A5.16 考場解題順序
第一步:先畫 JSON Tree
例如:
第二步:找 Array
看到:
表示通常需要:
第三步:確認 property spelling
答案必須以 JSON 原文為準。
第四步:完成 AJAX 四格
第五步:完成 loop
第六步:完成計算或訊息
A5 必背模板
PHP JSON
AJAX
A5 隨堂測驗:完整真題格式
A5(a):PHP Array → JSON
目標 JSON:
請填寫 (a) 至 (d):
A5(b):AJAX Processing
要求:
- 使用 GET;
- 從
getJSON.php取得 JSON; - 計算所有商品的總額;
- 顯示:
請填寫 (e) 至 (l):
作答格式
評分標準
- 每格 1 分,共 12 分;
- 10–12 分:A5 達標,進入 B1;
- 7–9 分:修正 AJAX/JSON 盲點後進入 B1;
- 0–6 分:進行一題 Transcript 補救題。
A5 隨堂測驗批改:11 / 12 ✅
表現很好。你已掌握:
- PHP associative array 建構
json_encode()- AJAX 四個主要 properties
- JSON object/array 存取
forloopalert(message)
唯一錯誤是 (k):取得當前商品價格時,少了 array index/當前 item。
逐格批改
(a) ✅
完整:
(b) ✅
完整:
(c) ✅
這是 number,因此不需要加引號。
(d) ✅
放回原題:
json_encode() converts a PHP value into its JSON representation.注意空格後已經有分號,所以答案內不用再加分號。
(e) ✅
單引號或雙引號均可:
(f) ✅
完整:
(g) ✅
完整:
這讓 jQuery 將回傳資料解析成 JavaScript object。
(h) ✅
資料樹:
所以最外層 property 使用:
(i) ✅
完整 loop:
Use the array’s length property as the loop boundary.
(j) ✅
完整:
這一步把當前商品記錄存入 item:
(k) ❌ 少了當前 item/array index
你的答案:
result.items 是整個 array:
Array 本身沒有直接名為 price 的 property。必須先指定其中一筆。
由於前一行已經寫:
最佳答案是:
完整:
也可以寫成:
但使用 item 更簡潔。
計算過程
關鍵觀念
代表整個集合。
代表當前一筆記錄。
代表當前一筆記錄的價格。
這和 A2 的概念完全相同:
Plural represents the collection; singular represents the current record.
(l) ✅
放回題目:
你的答案裡似乎夾有不可見的 Unicode 字元,但程式邏輯完全正確。考試手寫不受影響;若在電腦輸入程式,建議重新輸入純文字:
正確答案總表
完整正確答案
getJSON.php
AJAX
預期輸出:
A5 最終評估
技能
狀態
建立 PHP associative array
✅
建立 nested array
✅
json_encode()
✅
AJAX type
✅
AJAX url
✅
AJAX dataType
✅
success callback
✅
JSON property access
✅
JSON array loop
✅
當前記錄存取
⚠️ 注意 array index
累加計算
✅
alert()
✅
A5 Learning Outcome:達標
你現在應能處理這套資料流:
Section A 階段總結
題號
核心題型
狀態
最需要注意
A1
String Processing
達標
explode()、strpos() !== false
A2
Array Processing
基本達標
集合和當前記錄的差異
A3
Form Processing
達標
填空已有的括號、分號
A4
Session and Cookie
達標
第二次載入從 $_COOKIE 讀取
A5
JSON and AJAX
達標
items[i].property
從 A2 到 A5 重複出現的共同觀念
接下來應按照題號進入:
B1 — PHP + MySQL Database
核心模板是:
題號操練 6:B1 — PHP + MySQL Database
B1 通常是 Section B 第一題、15 分長題。歷屆背景雖然不同,但核心流程非常固定:
- 2021–2022:Consumption Voucher Spending Enquiry
- 2024–2025:Supermarket Product Search
- 其他歷屆題:Order Status 查詢及更新
你真正要掌握的是:
B1.1 歷屆題目結構
2021–2022:Spending Enquiry
題目給定:
- Database host、username、password、database name
spendDetailstable schema- Card ID 查詢表單
- Spending categories
- Existing records
要求:
- 根據 Card ID 查詢交易;
- 按類別累加消費;
- 建立 category hyperlinks;
- 從 query string 取得
cNum和sCat; - 顯示指定 category 的交易紀錄。 [A910ireh2_...1u_l94.pdf | PDF]
2024–2025:Product Search
題目給定:
producttable schema- Database connection information
- Category drop-down list
- 預期搜尋結果畫面
要求:
- 使用 GET 取得 category;
- 連接資料庫;
- 執行
SELECT ... WHERE ...; - 逐筆讀取 products;
- 建立 HTML table;
- 釋放 result set;
- 關閉 connection。 [A910ireh2_...1u_l94.pdf | PDF]
B1.2 必背七步流程
“The mysqli_connect() function is used to open a new connection to MySQL server and select a database.”
“The mysqli_fetch_assoc() function may be used to fetch a record from the result into an associative array.”
[A910ireh2_...1u_l94.pdf | PDF]
英文口訣:
Connect → SQL → Query → Fetch → Display → Free → Close
B1.3 Step 1 — Connect to MySQL
固定語法
參數順序必須背熟:
2024–2025 類型
試卷給定:
答案:
[A910ireh2_...1u_l94.pdf | PDF]
費曼解釋
把 Database 想成一間有保安的資料倉庫:
mysqli_connect() 成功後會回傳 connection object,保存於:
後面的 query 都需要它。
常見錯誤
錯誤一:參數次序錯誤
正確:
錯誤二:使用 query error 檢查 connection
Connection 失敗時應用:
不是:
B1.4 Step 2 — Construct SQL
查詢所有 records
意思:
加上條件
意思:
使用表單資料
如果 URL 是:
PHP 取得:
SQL 實際效果:
費曼解釋
SQL 像寫給倉庫職員的取貨單:
必背 SQL 結構
B1.5 SQL 中的引號
文字值通常需要單引號:
如果欄位是文字:
如果是純數字:
歷屆題目中,category、card ID、order ID 多以文字形式處理,應特別注意引號。 [A910ireh2_...1u_l94.pdf | PDF]
B1.6 Step 3 — Execute Query
固定語法
通常會加入錯誤處理:
參數次序
必背:
費曼解釋
$sql:寫好的取貨單;mysqli_query():把取貨單交給 Database;$resultSet:Database 找到後交回來的一疊 records。
B1.7 Connection 與 Result Set 的差別
這是 B1 最容易錯的地方。
Connection
代表與 Database 的連線。
用於:
Result Set
代表 SELECT 查回來的 records。
用於:
費曼口訣
不要寫成:
正確是:
B1.8 Step 4 — Fetch Records
固定模式
mysqli_fetch_assoc() 每次取出一筆 record,並把欄位名稱當作 key。
假設 table record 是:
取得後:
所以可以:
為什麼用 while?
因為不知道查詢會回傳多少筆:
可視為:
B1.9 Step 5 — Display HTML Table
Table Heading
每筆資料
關閉 Table
B1.10 printf() 的參數對應
對應關係:
必背 placeholder
Spending 題常用:
因為 database schema 的 spending amount 是 decimal。 [A910ireh2_...1u_l94.pdf | PDF]
B1.11 Step 6–7 — Free and Close
釋放 Result Set
Free the memory associated with the result set.
關閉 Connection
Close the previously opened database connection.
順序:
B1.12 完整 Product Search 類型
B1.13 mysqli_num_rows()
如果要判斷有沒有結果:
mysqli_num_rows() returns the number of rows in a result set.如果沒有任何 matching records:
注意它接收的是:
不是:
B1.14 第二種高頻模式:分類累加
2021–2022 Spending 題不只顯示 records,還要求按 category 累加。 [A910ireh2_...1u_l94.pdf | PDF]
初始化
Fetch and accumulate
費曼解釋
像把收據分進三個盒子:
每拿出一張收據,就根據 category 放入相應累加器。
B1.15 建立 Query String Hyperlink
歷屆題要求生成:
HTML:
動態版本:
Query String 結構
例如:
PHP 讀取:
B1.16 第二次 SQL 查詢
當使用者點選 category hyperlink:
SQL 的 AND
表示兩個條件必須同時成立:
B1.17 UPDATE 題型
部分歷屆題要求修改 Order Status。核心語法:
結構:
費曼解釋
最危險錯誤
如果漏掉 WHERE:
可能會把整張表所有 records 都改成 Fulfilled。
因此:
An UPDATE statement normally requires a WHERE condition to identify the target record.
B1.18 常見錯誤整理
1. Query 參數倒轉
錯誤:
正確:
2. Fetch 使用 Connection
錯誤:
正確:
3. 欄位名稱不一致
Schema 是:
不能自行寫成:
必須完全遵照 database schema。
4. WHERE 文字值沒有 quote
錯誤:
正確:
5. printf() 參數數量不一致
有 3 個 placeholders,卻只有 2 個 arguments,會出錯。
6. 把 $_GET 和 $_POST 混用
Form:
應讀:
若 Form 使用 POST:
才讀:
B1 必背模板
B1 隨堂測驗:正式考試格式
Database Information
Table:student
Column
Meaning
studentID
Student identity number
studentName
Student name
programme
Programme code
mark
Module mark
HTML form 使用 GET,提交欄位:
程式要:
- 查詢所選 programme 的學生;
- 顯示 Student ID、Name、Mark;
- 只在有 records 時顯示 table;
- 最後釋放 result set 並關閉 connection。
請填寫 (a) 至 (l):
額外 SQL 題
若要把 studentID 等於 S001 的 mark 修改成提交的 $_POST["mark"],完成:
執行該 SQL:
作答格式
評分標準
- 每格 1 分,共 12 分;
- 10–12 分:B1 達標,進入 B2;
- 7–9 分:修正 SQL/MySQLi 盲點後進入 B2;
- 0–6 分:先完成一題 Database Pipeline 補救題。
B1 隨堂測驗批改:8 / 12
你的 MySQLi Pipeline 已大致掌握:
主要錯誤集中在:
(a)漏掉mysqli_connect()的右括號;(b)沿用了上一題的productSQL,沒有按照本題 schema;(k)應使用UPDATE,不是SELECT;- 部分答案加入了題目本身已提供的逗號或分號。
逐格批改
(a) ⚠️ 概念正確,但漏掉右括號
你的答案:
正確答案:
放回原題後:
Connection parameter order: host, username, password, database.
(b) ❌ Table、column 與 GET key 都不符合本題
你的答案:
這是之前 Supermarket 題的 SQL。本題資料表及欄位是:
正確答案:
放入 PHP string:
也可先建立變數,以提高可讀性:
考試技巧
SQL 答案必須逐項對照題目:
不要直接套用上一題的 table 和 column 名稱。
(c) ✅ 正確
完整:
mysqli_query() receives the connection first and the SQL statement second.
(d) ✅ 正確
完整:
mysqli_num_rows() 要接收 result set,不是 connection。
(e) ✅ 正確
完整:
每次 loop 都會把一筆 database record 轉成 associative array:
(f)–(h) ✅ 欄位正確,但答案內不需要逗號
你填的是:
題目在每個空格後已經提供逗號:
所以填空本身應是:
完整:
欄位次序與 placeholders 正確:
(i) ✅ 函式正確;填空時不需重複分號
你的答案:
題目原本是:
因此最精準的填空答案是:
完整:
(j) ✅ 函式正確;填空時不需重複分號
你的答案:
精準填空:
完整:
(k) ❌ 應使用 UPDATE,不是 SELECT
題目要求:
將studentID等於S001的mark修改為$_POST["mark"]。
你的答案只是查詢:
正確 SQL:
完整:
UPDATE 必背結構
費曼翻譯:
為什麼 WHERE 極重要?
如果漏掉:
便可能把所有學生的 mark 一起修改。
The WHERE clause identifies the record to be updated.
(l) ✅ 正確
完整:
若要加入錯誤處理:
正確答案總表
完整正確程式
UPDATE 部分:
B1 盲點總結
盲點一:不能沿用上一題的 Schema
你必須每次先圈出:
這次應是:
盲點二:SELECT 與 UPDATE 的用途
用來讀取資料:
用來修改資料:
盲點三:填空已有標點
題目:
只填:
題目:
只填:
不要重複逗號或分號。
B1 最終能力評估
能力
狀態
mysqli_connect()
已掌握,注意括號
SELECT
基本掌握,需嚴格對照 schema
WHERE
基本掌握
mysqli_query()
已掌握
mysqli_num_rows()
已掌握
mysqli_fetch_assoc()
已掌握
Associative record access
已掌握
printf() HTML table
已掌握
mysqli_free_result()
已掌握
mysqli_close()
已掌握
UPDATE
需要加強
填空標點判斷
需要注意
B1 Learning Outcome:基本達標。
進入 B2 前必背
下一題按順序是:
B2 — AJAX + JSON + DOM
主要歷屆形式:
核心將是:
題號操練 7:B2 — AJAX + JSON + DOM
B2 通常是 Section B 第二題,15 分長題。歷屆主要形式:
- 2021–2022:Weekly Top Song
- AJAX 讀取
topsong.json - 顯示年份、週數和歌曲數量
- 找最高票
- 動態建立歌曲表格
- 冠軍歌曲加入圖片
- 建立 HTML5 Audio control
- AJAX 讀取
- 2024–2025:Weather Details
- AJAX 讀取
weather.json - 更新日期、溫度、濕度
- 根據
logoID選擇天氣圖片 - 修改 DOM 元素及 CSS style。 [A910ireh2_...1u_l94.pdf | PDF]
- AJAX 讀取
B2.1 A5 與 B2 的差別
你在 A5 已掌握:
AJAX→ JSON→ Loop→ Calculation→ alert()
B2 則進一步要求:
AJAX→ JSON→ Loop/Search/Maximum→ 建立 HTML→ 修改 DOM→ 在頁面顯示結果
最大分別是:
A5:通常用 alert(message)B2:通常用 innerHTML 更新頁面
B2.2 必背 AJAX 骨架
“The displayed data will be retrieved dynamically from a text file using AJAX.”
歷屆答案的固定形式是:
$(document).ready(function () {
$.ajax({ type: "GET", url: "data.json", dataType: "json",
success: function (result) { // process result } });
});
[A910ireh2_...1u_l94.pdf | PDF]
四大固定屬性
type: "GET"
表示使用 HTTP GET。
url: "data.json"
表示 JSON 檔案位置。
dataType: "json"
告訴 jQuery 將回傳資料當成 JSON。
success: function (result)
取得資料成功後執行。
B2.3 費曼解釋:AJAX 如何更新網頁?
想像餐廳桌面就是目前的 Web page。
一般重新載入:
把整張桌子清空→ 重新擺設所有東西
AJAX:
保留整張桌子→ 服務生只拿一碟新菜過來→ 更新桌上的其中一個位置
流程:
Browser │ │ AJAX GET ▼JSON File │ │ JSON Response ▼success(result) │ ├─ 計算資料 ├─ 建立 HTML string └─ 更新 DOM
B2.4 DOM 是什麼?
“The DOM represents the structure of an HTML document and allows JavaScript to access and modify its elements.”
以 HTML 為例:
<body> <h2 id="pageTitle"></h2> <div id="output"></div></body>
可以視為:
document└── body ├── h2#pageTitle └── div#output
JavaScript 使用:
document.getElementById("pageTitle")
取得指定 element。
修改內容
document .getElementById("pageTitle") .innerHTML = "Weekly Top Song";
必背英文
Retrieve the element with the specified ID.
document.getElementById("elementID")
Update the content of the element.
element.innerHTML = content;
B2.5 getElementById() 的正確拼法
正確:
document.getElementById("output")
注意:
Element是單數;Id的I是大寫;- JavaScript 是 case-sensitive。
錯誤:
document.getElementsByID("output")
正確:
document.getElementById("output")
教材擷取文字中部分答案顯示 getElementsByID,但標準 JavaScript DOM API 應寫作 getElementById()。
B2.6 innerHTML 的 = 與 +=
取代原有內容
output.innerHTML = "Hello";
如果元素原本有內容,會被取代。
追加內容
output.innerHTML += " World";
等同:
output.innerHTML = output.innerHTML + " World";
歷屆 Weather 題的例子
先建立最高溫:
wTempRange.innerHTML = "Range: " + weather.highest + "°";
再追加最低溫:
wTempRange.innerHTML += "-" + weather.lowest + "°";
最後效果:
Range: 36°-26°
[A910ireh2_...1u_l94.pdf | PDF]
B2.7 2021–2022:Weekly Top Song 資料結構
歷屆 JSON 結構大致是:
{ "year": 2022, "week": 25, "song": [ { "title": "Muffin man", "singer": "Lady Jaja", "file": "muffin.mp3", "vote": 194 }, { "title": "Humpty Dumpty", "singer": "Andy Lai", "file": "dumpty.mp3", "vote": 308 }, { "title": "Rock-a-bye Baby", "singer": "Peach Ginger", "file": "rock.mp3", "vote": 234 } ]}
[A910ireh2_...1u_l94.pdf | PDF]
資料樹
result├── year├── week└── song ├── [0] │ ├── title │ ├── singer │ ├── file │ └── vote ├── [1] │ ├── title │ ├── singer │ ├── file │ └── vote └── [2] ├── title ├── singer ├── file └── vote
B2.8 讀取最外層資料
建立 Page Description:
var pageDesc = result.year + " Week " + result.week;
結果:
2022 Week 25
計算歌曲數量:
var songCount = result.song.length + " songs";
結果:
3 songs
更新 DOM:
document .getElementById("pageDesc") .innerHTML = pageDesc;
document .getElementById("songCount") .innerHTML = songCount;
B2.9 將 Array 傳入另一個 Function
AJAX success 中:
loadData(result.song);
函式:
function loadData(song) { // song 現在就是 result.song array}
費曼解釋
result 是整個包裹:
year、week、song
但 loadData() 只負責歌曲,所以只把歌曲清單交給它:
loadData(result.song);
在函式內:
song → 全部歌曲清單song[i] → 當前歌曲
B2.10 找 Maximum Value
Weekly Top Song 要找最高票歌曲。
標準函式
function findMax(voteSong) {
var max = 0;
for ( var j = 0; j < voteSong.length; j++ ) { if (voteSong[j].vote > max) { max = voteSong[j].vote; } }
return max;}
費曼執行過程
Votes:
194、308、234
流程:
初始 max = 0
194 > 0→ max = 194
308 > 194→ max = 308
234 > 308→ false
答案:308
為什麼參數叫 voteSong?
外面可能寫:
findMax(song)
函式內的 parameter 可以叫另一個名稱:
function findMax(voteSong)
兩者角色:
song → 呼叫端的 arrayvoteSong → 函式內接收到的同一個 array
B2.11 Maximum 的初始化
歷屆票數都是非負數,因此可寫:
var max = 0;
更通用的寫法是:
var max = voteSong[0].vote;
如果資料可能有負數,使用第一筆會更安全。
但考試填空時,要依題目已給程式結構作答;若題目已提供:
var max = 0;
不必改寫。
B2.12 動態建立 HTML Table
先建立 table heading
var content = "<table border='1'>";
content += "<tr>" + "<th>No.</th>" + "<th>Title</th>" + "<th>Singer</th>" + "<th>Vote</th>" + "</tr>";
Loop 每一首歌曲
for ( var i = 0; i < song.length; i++) { var index = i + 1;
content += "<tr>";
content += "<td>" + index + "</td>";
content += "<td>" + song[i].title + "</td>";
content += "<td>" + song[i].singer + "</td>";
content += "<td>" + song[i].vote + "</td>";
content += "</tr>";}
關閉 table
content += "</table>";
更新 DOM
document .getElementById("songList") .innerHTML = content;
B2.13 為什麼 Row Number 是 i + 1?
Array index:
0、1、2
人類看到的行號:
1、2、3
因此:
var index = i + 1;
Array indexing starts at zero, but display row numbering usually starts at one.
B2.14 冠軍歌曲顯示圖片
先取得最高票:
var maxVote = findMax(song);
在 loop 內:
if (maxVote == song[i].vote) { content += "champion.png";}
完整 title cell
content += "<td>" + song[i].title;
if (maxVote == song[i].vote) { content += "champion.png";}
content += "</td>";
費曼解釋
先寫歌曲名稱,但先不要關閉 </td>:
<td>Humpty Dumpty
如果是冠軍,就接圖片:
champion.png
最後才關閉:
</td>
結果:
<td> Humpty Dumpty champion.png</td>
B2.15 HTML5 Audio Control
歷屆題要求從 song 子資料夾播放 MP3。 [A910ireh2_...1u_l94.pdf | PDF]
content += "<td>";
content += "<audio controls>";
content += "song/" + song[i].file + "";
content += "</audio>";
content += "</td>";
如果:
song[i].file == "muffin.mp3"
產生的 HTML:
<audio controls> song/muffin.mp3</audio>
必背路徑組合
"song/" + song[i].file
B2.16 2024–2025:Weather 題資料結構
JSON:
{ "date": "2025-07-22", "temp": "30", "highest": "34", "lowest": "26", "humidity": "71", "logoID": 1}
[A910ireh2_...1u_l94.pdf | PDF]
資料樹:
weather├── date├── temp├── highest├── lowest├── humidity└── logoID
這題沒有 nested array,所以通常不需要 loop。
B2.17 Weather AJAX
$.ajax({ type: "GET", url: "weather.json", dataType: "json",
success: function (weather) { showWeather(weather); }});
weather 是完整 JSON object。
B2.18 取得 DOM Elements
var wLogoBG = document.getElementById("wLogoBG");
var wLogo = document.getElementById("wLogo");
var wDate = document.getElementById("wDate");
var wTemp = document.getElementById("wTemp");
var wTempRange = document.getElementById("wTempRange");
var wHumd = document.getElementById("wHumd");
B2.19 修改 Style
wLogoBG.style.backgroundColor = "lightblue";
結構:
Element→ style→ CSS property
CSS 原本可能寫:
background-color
JavaScript style property 使用 camelCase:
backgroundColor
其他例子:
element.style.fontWeight = "bold";element.style.fontSize = "20px";element.style.color = "blue";
B2.20 顯示 Weather Data
wDate.innerHTML = "Date: " + weather.date;
wTemp.innerHTML = "Temperature: " + weather.temp + "°";
wTempRange.innerHTML = "Range: " + weather.highest + "°";
追加最低溫:
wTempRange.innerHTML += "-" + weather.lowest + "°";
濕度:
wHumd.innerHTML = "Humidity: " + weather.humidity + "%";
B2.21 根據 ID 選擇圖片
題目提供:
var arrFile = [ "sunny.png", "cloudy.png", "rain.png", "thunderstorm.png"];
對照:
logoID 0 → sunny.pnglogoID 1 → cloudy.pnglogoID 2 → rain.pnglogoID 3 → thunderstorm.png
所以:
imgLogo.src = "img/" + arrFile[logoID];
如果:
logoID == 1
產生:
img/cloudy.png
費曼解釋
logoID 直接當 array index:
arrFile[1]→ cloudy.png
再加資料夾:
img/ + cloudy.png→ img/cloudy.png
B2.22 設定 Image Attribute
歷屆答案:
imgLogo.setAttribute( "width", 128);
也可寫:
imgLogo.width = 128;
但填空題若題目已提供:
imgLogo.________;
且註解要求 set width,應根據上下文填:
setAttribute("width", 128)
[A910ireh2_...1u_l94.pdf | PDF]
B2.23 Weekly Top Song 完整骨架
$(document).ready(function () {
$.ajax({ type: "GET", url: "topsong.json", dataType: "json",
success: function (result) {
var pageDesc = result.year + " Week " + result.week;
var songCount = result.song.length + " songs";
document .getElementById("pageDesc") .innerHTML = pageDesc;
document .getElementById("songCount") .innerHTML = songCount;
loadData(result.song); } });});
function findMax(voteSong) {
var max = 0;
for ( var j = 0; j < voteSong.length; j++ ) { if (voteSong[j].vote > max) { max = voteSong[j].vote; } }
return max;}
function loadData(song) {
var maxVote = findMax(song);
var content = "<table border='1'>";
content += "<tr>" + "<th>No.</th>" + "<th>Title</th>" + "<th>Singer</th>" + "<th>Listen</th>" + "<th>Vote</th>" + "</tr>";
for ( var i = 0; i < song.length; i++ ) { var index = i + 1;
content += "<tr>";
content += "<td>" + index + "</td>";
content += "<td>" + song[i].title;
if (maxVote == song[i].vote) { content += "champion.png"; }
content += "</td>";
content += "<td>" + song[i].singer + "</td>";
content += "<td>"; content += "<audio controls>";
content += "song/" + song[i].file + "";
content += "</audio>"; content += "</td>";
content += "<td>" + song[i].vote + "</td>";
content += "</tr>"; }
content += "</table>";
document .getElementById("songList") .innerHTML = content;}
B2.24 考試解題流程
Step 1:畫 JSON Tree
result├── ...└── array └── [i] ├── property └── property
Step 2:找 HTML IDs
例如:
<h2 id="pageDesc"><div id="songList">
那麼 JavaScript 多半需要:
document.getElementById("pageDesc")document.getElementById("songList")
Step 3:完成 AJAX
typeurldataTypesuccess
Step 4:判斷有沒有 Array
有 [ ]:
for (...)
沒有 [ ]:
直接使用 object.property
Step 5:檢查輸出形式
更新文字 → innerHTML更新圖片 → src更新 CSS → style.property建立音訊 → <audio><source>
B2 常見失分位
1. 忘記 .length
錯誤:
i < result.song
正確:
i < result.song.length
2. Collection 與 Current Record 混淆
錯誤:
result.song.title
正確:
result.song[i].title
或:
var songItem = result.song[i];songItem.title;
3. getElementById() 拼錯
正確:
getElementById
4. innerHTML 大小寫錯誤
正確:
innerHTML
不是:
innerHtml
5. 圖片路徑漏掉資料夾
錯誤:
imgLogo.src = arrFile[logoID];
如果圖片位於 img folder,正確:
imgLogo.src = "img/" + arrFile[logoID];
6. 找 Max 時沒有更新 max
if (song[i].vote > max) { max = song[i].vote;}
7. 建立 HTML 時漏關閉標籤
例如:
<tr><td><audio>
對應結束:
</audio></td></tr>
B2 必背模板
$.ajax({ type: "GET", url: "data.json", dataType: "json",
success: function (result) { displayData(result); }});
function displayData(result) {
var content = "";
for ( var i = 0; i < result.items.length; i++ ) { content += result.items[i].name; }
document .getElementById("output") .innerHTML = content;}
B2 隨堂測驗:真題格式
JSON:movie.json
{ "year": 2026, "movies": [ { "title": "Web Adventure", "category": "Drama", "rating": 78, "poster": "web.jpg" }, { "title": "Database Hero", "category": "Comedy", "rating": 91, "poster": "database.jpg" }, { "title": "Canvas World", "category": "Animation", "rating": 85, "poster": "canvas.jpg" } ]}
HTML 已有:
<h2 id="pageTitle"></h2><div id="movieList"></div>
功能要求:
- 使用 AJAX GET 讀取
movie.json; - Page title 顯示
Movies 2026; - 找出最高 rating;
- 動態建立 table;
- 每行顯示 title、category、rating 和 poster;
- 最高 rating 的電影後加上
★; - Poster 位於
imgfolder; - 最後將 table 放入
movieList。
請填寫 (a) 至 (n)
$(document).ready(function () {
$.ajax({ type: (a) , url: (b) , dataType: (c) ,
success: function (result) {
var pageTitle = "Movies " + (d);
document .getElementById( (e) ) .innerHTML = pageTitle;
loadMovies( (f) ); } });});
function findMaxRating(movies) {
var max = 0;
for ( var j = 0; j < (g) ; j++ ) { if ( movies[j].rating > max ) { max = (h) ; } }
return max;}
function loadMovies(movies) {
var maxRating = findMaxRating(movies);
var content = "<table border='1'>" + "<tr>" + "<th>Title</th>" + "<th>Category</th>" + "<th>Rating</th>" + "<th>Poster</th>" + "</tr>";
for ( var i = 0; i < (i) ; i++ ) { content += "<tr>";
content += "<td>" + (j);
if ( maxRating == (k) ) { content += " ★"; }
content += "</td>";
content += "<td>" + (l) + "</td>";
content += "<td>" + movies[i].rating + "</td>";
content += "<td> + "' width='100'></td>";
content += "</tr>"; }
content += "</table>";
document .getElementById("movieList") .innerHTML = (n);}
作答格式
(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)(m)(n)
評分標準
- 每格 1 分,共 14 分;
- 12–14 分:B2 達標,進入 B3 Canvas;
- 9–11 分:修正 DOM/Array 盲點後進入 B3;
- 0–8 分:完成一題 Weather DOM 補救題。
B2 隨堂測驗批改:8 / 13 個可評分空格
先說明:原題的 (m) 圖片 HTML 那一行被截斷,因此 (m) 不計分。其餘 13 格中,你答對 8 格。
你已掌握:
- AJAX 三個固定 properties
- 最外層 JSON property
- DOM element ID
- 將 JSON array 傳入 function
- Maximum value 更新
- 最後以
innerHTML顯示內容
目前主要盲點:
- 傳入
loadMovies()後,函式內應使用參數movies; - Array 需要用
[i]或[j]指定當前 record; title和category的欄位位置混淆;- 動態圖片的 HTML 字串組合。
一、逐格批改
(a) ✅ 正確
完整:
(b) ✅ 正確
完整:
(c) ✅ 正確
完整:
(d) ✅ 正確
完整:
輸出:
(e) ✅ 正確
完整:
(f) ✅ 正確
完整:
這一步非常重要:傳入的是 movies array,不是整個 result。
(g) ❌ Function 內應使用參數 movies
你的答案:
正確答案:
因為函式定義是:
當呼叫:
函式內可用的 array 名稱就是:
而且原 AJAX callback 使用的是單數:
並不存在:
完整:
費曼口訣
Inside a function, use the parameter declared by that function.
所以函式裡使用:
(h) ✅ 正確
完整:
執行:
(i) ❌ 同樣應使用 movies.length
你的答案:
正確答案:
因為目前位於:
函式已經收到完整 movies array。因此:
二、最重要盲點:資料變數的生命週期
AJAX callback:
這裡:
進入函式後:
這裡:
所以函式內不需要再寫:
直接使用:
即可。
(j) ❌ 應取得當前電影的 Title
你的答案:
正確答案:
原本程式結構是:
這是 table 的第一欄,而 heading 是:
因此要顯示:
完整:
注意尚未立即關閉 </td>,因為最高分電影後面還要加入:
(k) ❌ 應比較當前電影的 Rating
你的答案:
正確答案:
完整:
資料結構:
不能寫:
因為 movies 是 array,沒有直接的 rating property。
必須指定一筆:
(l) ❌ 這一欄要求 Category
你的答案:
但前一欄已經顯示 Title,這一欄的 heading 是:
所以正確答案:
完整:
(m) ⚪ 原題被截斷,不計分
原本應該是建立 poster image:
正確 (m):
如果當前電影是:
產生的路徑就是:
完整 HTML string:
更清楚的單行寫法:
(n) ✅ 正確
完整:
將整個 table HTML 放入:
三、正確答案總表
四、完整正確程式
五、預期輸出結構
Database Hero 的 rating 是 91,最高,所以加入:
六、B2 最重要的資料角色
你這次最需要補強的是以下角色轉換:
必背英文
The array is passed to the function through its parameter.
Use the function parameter inside the function body.
Select the current record before accessing its property.
七、B2 補救題
你本次是 8/13,先做一題短補救,完成後進入 B3 Canvas。
JSON
程式
HTML 已有:
請填:
B2 補救題批改:4 / 5 ✅
你的答案:
(a) ✅ 正確
因為:
傳入的是 products array。
(b) ✅ 正確
完整:
(c) ✅ 正確
輸出:
(d) ❌
你的答案:
這是最常見的 DOM 題錯誤。
題目給你:
因此:
應填:
不是:
(e) ✅ 正確
完整:
正確答案
B2 最終評估
能力
狀態
AJAX 骨架
✅
JSON Tree
✅
DOM
✅
innerHTML
✅
Loop
✅
Maximum Search
✅
Dynamic Table
✅
Image Mapping
⚠️
Collection vs Current Record
⚠️
B2 成績
已達標,可以進入最後一題:
B3 — HTML5 Canvas(15 分)
歷屆出現:
核心永遠是:
B3 必背原文
“Paths are created with beginPath(), moveTo(), lineTo(), arc(), fill(), and stroke().”
“Transformations: translate(), rotate(), scale()”
Canvas 只要記住畫畫流程
就像:
B3 歷屆最常考的 10 個函式
B3 第一條必背語句
取得 Canvas:
第二條必背語句
每次重畫前:
幾乎每年都有。
第三條必背語句
畫線:
第四條必背語句
畫圓:
第五條必背語句
顯示文字:
第六條必背語句
Slider 改變後重新畫圖:
歷屆非常高頻。
下個回合我們直接按照歷屆 2024–2025 Hangman 題 的模式,逐格完成整條 Canvas 長題。這是 B3 最接近真實考試的版本。
B3 — HTML5 Canvas(歷屆真題模式:2024–2025 Hangman)
這題是近年最接近正式考試的 Canvas 題型。
核心流程:
B3.1 題目結構分析
歷屆 Hangman 題要求:
真正考的是:
B3.2 Canvas 資料流
B3.3 必背第一格
取得 Radius
題目幾乎每年都會出:
費曼解釋
HTML:
得到的是:
字串。
所以:
轉成:
數字。
B3.4 必背第二格
重畫前一定出現:
為什麼?
如果不停重畫:
畫面會變成:
所以:
Clear the canvas before redrawing.
B3.5 畫頭(Arc)
原文:
Paths are created with beginPath(), moveTo(), lineTo(), arc(), fill(), and stroke().
標準答案
費曼理解
圓其實是:
畫完整圓:
因為:
B3.6 歷屆超高頻
這一格每年都很像。
通常考:
B3.7 畫直線
必背模板:
費曼理解
B3.8 歷屆最愛寫成 Function
B3.9 填文字
歷屆答案:
費曼理解
意思:
B3.10 文字置中
另一份歷屆題:
然後:
必背英文
Align text horizontally at the centre.
Align text vertically in the middle.
B3.11 onchange 重畫
歷屆超高頻。
HTML:
意思:
B3.12 onload
另一個常考:
意思:
B3.13 最容易失分的位置
錯誤一
忘記:
錯誤二
忘記:
結果:
錯誤三
忘記:
結果:
錯誤四
使用:
而不是:
這只會畫半圓。
B3 真題級 Fill In The Blanks
題目
HTML
JavaScript
作答格式
提示
這題已經非常接近:
2024–2025 Hangman 題
你會用到的答案全部來自以下固定模板:
如果這題能拿到 9/11 以上,代表你已達到 B3 及整份 ITP4523M 期末卷的核心答題能力。