Learning Objectives
- 說出 PHP 的起源、名稱的意思,以及它是在伺服器上執行的語言
- 說明一個網頁請求的旅程:瀏覽器送出請求、伺服器執行 PHP、產生 HTML 回傳
- 說明為什麼瀏覽器看不到 PHP 程式碼,只看得到它輸出的結果
- 用 php -v 確認版本、用 php 指令執行程式、用 php -S 開啟內建的開發用伺服器
- 寫出第一支用 echo 輸出文字與變數的 PHP 程式
為什麼要學 PHP
你打開一個部落格、在購物網站把商品放進購物車、在論壇留言:這些網頁的內容不是事先寫死的, 而是伺服器在你請求的那一刻用程式產生的。PHP 就是專門做這件事的語言:在網站伺服器上執行,產生網頁再送給瀏覽器。
PHP 的入門門檻低:一個 .php 檔案可以直接寫 HTML,在需要變化的地方插入一小段程式。
很多常見的網站軟體都用 PHP 寫成,例如部落格與架站系統 WordPress、維基百科使用的 MediaWiki,以及 Laravel 這類網站開發框架。
學會 PHP,你就能看懂、修改這些系統,也能從頭做出自己的動態網站。
這一課先認識 PHP 的來歷與特點,再看「一個網頁請求」在伺服器上發生了什麼事,最後寫出第一支 PHP 程式。
PHP 的起源與名稱
PHP 的作者是 Rasmus Lerdorf。1994 年,他用 C 語言寫了一組小程式,用來管理自己的個人網頁, 例如記錄有多少人看過他的履歷。他把這組工具叫做 Personal Home Page Tools(個人首頁工具),簡稱 PHP Tools。 1995 年 6 月,他把原始碼公開給所有人使用,越來越多人加入改進。
| 時間 | 事件 |
|---|---|
| 1994 年 | Rasmus Lerdorf 寫出最早的 PHP Tools |
| 1995 年 6 月 | 原始碼公開釋出 |
| 1998 年 6 月 | PHP 3.0 發布,是第一個和今天的 PHP 很接近的版本;由 Andi Gutmans、Zeev Suraski 等人組成的開發團隊重寫 |
| 2000 年 5 月 | PHP 4.0 發布,使用新的 Zend Engine(名稱取自 Zeev 與 Andi) |
| 2004 年 7 月 | PHP 5 發布 |
| 2015 年 12 月 | PHP 7.0 發布(中間沒有 PHP 6) |
| 2020 年 11 月 | PHP 8.0 發布 |
後來名稱改成單純的 PHP,意思變成 PHP: Hypertext Preprocessor(超文字前置處理器)。 這是一個遞迴縮寫:縮寫的第一個字母就是 PHP 自己。「超文字」指的是 HTML,「前置處理」指的是:在網頁送給瀏覽器之前,先由 PHP 處理一遍。
CodeLab 的 PHP 課程以 PHP 8.3 為準。
PHP 的特點
| 特點 | 意思 |
|---|---|
| 伺服器端執行 | 程式在網站伺服器上執行,瀏覽器只收到執行的結果(通常是 HTML) |
| 可以嵌在 HTML 裡 | 一個檔案可以混合 HTML 與 <?php … ?> 程式區塊,第 02 課會詳細介紹 |
| 動態型別 | 變數不用宣告型別,同一個變數可以先放數字、再放字串;需要時也可以加上型別宣告 |
| 直譯執行 | 不用自己先編譯,改完存檔、重新整理網頁就看到結果(PHP 內部會先把程式轉成中間碼再執行,也可以快取起來) |
| 開放原始碼、跨平台 | 免費使用,Linux、Windows、macOS 都能執行,大多數虛擬主機都支援 |
| 內建大量函式 | 字串、陣列、日期、檔案、資料庫、JSON 等常用功能都有現成的函式 |
如果你學過 Python 或 JavaScript,可以這樣對照:PHP 和 Python 一樣是動態型別、直譯執行; 和瀏覽器裡的 JavaScript 不同,PHP 不在使用者的電腦上執行,而是在伺服器上。
一個網頁請求的旅程
當你在瀏覽器輸入 https://example.com/news.php 按下 Enter,會發生這些事:
[瀏覽器]
│ 1. 請求:GET /news.php
▼
[網站伺服器] 2. 看到網址是 .php 檔案,交給 PHP
│
▼
[PHP] 3. 從第一行執行到最後一行,用 echo 輸出 HTML
│
▼
[網站伺服器] 4. 回應:狀態碼 200 + 產生好的 HTML
│
▼
[瀏覽器] 5. 把 HTML 畫成網頁
- 瀏覽器送出一個 HTTP 請求(request),說明要哪一個網址
- 網站伺服器(例如 Apache、Nginx)看到網址是
.php檔案,就交給 PHP 執行 - PHP 從第一行執行到最後一行,
echo輸出的文字、<?php … ?>以外的 HTML,都依序收集成回應的內容 - 伺服器把內容連同狀態碼(200 代表成功)當成 HTTP 回應(response)送回瀏覽器
- 瀏覽器只拿到 HTML,把它畫成你看到的網頁
重點:瀏覽器看不到 PHP 程式碼。你在瀏覽器按「檢視網頁原始碼」,看到的是 PHP 執行之後的輸出。 這也代表寫在 PHP 裡的資料庫密碼不會被使用者看到;反過來說,PHP 也沒辦法直接操作已經送到瀏覽器的畫面, 使用者點按鈕要讓伺服器做事,必須再送一次請求。
每一次請求,PHP 都從頭執行一次程式,執行完就結束;上一次請求的變數不會留到下一次。 要記住使用者的資料,需要 Cookie、Session 或資料庫(第 16 課與之後介紹)。
安裝 PHP、執行程式、開啟內建伺服器
以下是在 Linux(Ubuntu 24.04)終端機的操作,套件庫提供的是 PHP 8.3。macOS 可以用 Homebrew 執行 brew install php;Windows 可以從 windows.php.net 下載,或在 WSL 裡的 Ubuntu 操作,指令相同。版本號與日期依你的環境而不同。
-
1
安裝並確認版本
php-cli是命令列版本的 PHP。安裝之後用php -v確認版本:第一行的8.3.6是 PHP 的版本,cli表示這是命令列(Command Line Interface)版本,NTS表示非執行緒安全版本(一般用途就是這個)。 -
2
用 php 指令執行一支程式
PHP 不只能做網頁,也可以在終端機直接執行。
php 檔名會從頭執行這個檔案,把輸出印在終端機上。php -r可以直接執行一行程式(不用寫<?php),適合快速試一個函式。 -
3
開啟內建的開發用伺服器
php -S localhost:8000把目前的資料夾當成網站根目錄,在 8000 埠開一個網頁伺服器。打開瀏覽器到http://localhost:8000/page.php就能看到網頁;每一個請求,終端機都會印出一行紀錄,[200]是狀態碼。按 Ctrl+C 停止伺服器。這個伺服器只用來開發與測試,正式的網站要用 Apache 或 Nginx 這類伺服器。 -
4
瀏覽器收到的只有 HTML
開另一個終端機,用
curl模擬瀏覽器請求同一個網址,印出伺服器回應的內容:裡面只有 HTML,<?php、$title這些程式碼都不見了,換成了執行的結果。和直接用cat看原始檔比較一下。
第一支程式:echo
echo 把後面的內容輸出。字串放在引號裡;"\n" 是換行。一個 echo 可以用逗號接好幾個值,依序輸出。注意最後一行:單引號字串裡的 \n 不會變成換行,而是原樣輸出兩個字元。每一行敘述都以分號 ; 結束。
變數:把值存起來
PHP 的變數以 $ 開頭,用 = 把值存進去(指派)。看左邊的變數區:每執行一行,就多一個變數或改變一個值。雙引號字串裡的 {$age} 會換成變數的值,第 03 課會詳細介紹。
PHP 產生一個網頁
這支程式前半是 PHP、後半是 HTML。?> 之後的 HTML 會原樣輸出,<?= $title ?> 會換成變數的值(<?= 是「輸出這個值」的簡寫,第 02 課介紹)。看最後的輸出:瀏覽器收到的就是這三行 HTML,裡面沒有任何 PHP 程式碼。
想一想:伺服器與瀏覽器
上面的 page.php 放在網站上,使用者用瀏覽器打開,再按「檢視網頁原始碼」,會看到什麼?
下面的程式會印出什麼?
<?php
$city = '台北';
echo "我住在 {$city}\n";
echo '我住在 {$city}';
PHP 7 與 PHP 8 的重要改變
網路上的 PHP 教學很多是十幾年前寫的,看到的寫法可能已經過時。認識幾個重要版本,你就知道哪些寫法是新的:
| 版本 | 發布 | 重要改變 |
|---|---|---|
| PHP 7.0 | 2015 年 12 月 | 新版的 Zend Engine,官方發布說明指出執行速度與記憶體用量都比 PHP 5.6 大幅改善;加入參數與回傳值的型別宣告、null 合併運算子 ?? |
| PHP 8.0 | 2020 年 11 月 | 加入 JIT(Just-In-Time)編譯;聯合型別(一個參數可以接受好幾種型別)、具名引數、match 運算式、nullsafe 運算子 ?->;字串與數字的比較規則更合理(第 04 課);內建函式收到錯誤型別的引數時一律丟出錯誤 |
| PHP 8.1 | 2021 年 11 月 | 列舉(enum)、唯讀屬性(readonly) |
| PHP 8.2 | 2022 年 12 月 | 唯讀類別;"${var}" 這種字串插值寫法被標為棄用 |
| PHP 8.3 | 2023 年 11 月 | 類別常數可以宣告型別、新增 json_validate() 等函式 |
之後還有 PHP 8.4(2024 年 11 月)與 8.5(2025 年 11 月)。每個版本有兩年的一般支援,之後兩年只修補安全性問題; 正式網站應該使用仍在支援期內的版本,可以到 php.net 的「Supported Versions」頁面查詢。
關於 JIT:官方的說明是 JIT 讓大量計算的程式明顯變快,但一般網頁應用的效能和 PHP 7.4 差不多, 因為網站大部分時間花在等待資料庫與網路。所以不要期待「升級到 8 網站就變快好幾倍」。
這些功能大多會在後面的課程用到。現在只要記得:從 PHP 7 開始可以宣告型別,PHP 8 讓很多過去默默出錯的地方改成直接報錯, 對初學者是好事:錯誤越早被發現,越容易修正。
想一想:PHP 的特點與工具
「PHP」這個名稱現在代表什麼?
在一個資料夾裡執行 php -S localhost:8000,會發生什麼事?
下面的程式會印出什麼?
<?php
$price = 120;
$qty = 3;
echo "共 ", $price * $qty, " 元\n";
$qty = 5;
echo "改成 ", $qty, " 件\n";
動手做:自我介紹
程式已經準備好三個變數。請用 echo 印出下面三行(年級的地方要用變數計算,不要直接寫數字):
我是 Amy
就讀資訊管理學系 2 年級
明年就是 3 年級了
重點回顧
- PHP 由 Rasmus Lerdorf 在 1994 年開始撰寫,1995 年公開;名稱現在是遞迴縮寫 PHP: Hypertext Preprocessor
- PHP 是伺服器端語言:伺服器執行 PHP,把輸出的 HTML 回傳,瀏覽器看不到 PHP 程式碼
- 一個網頁請求:瀏覽器送出請求 → 伺服器交給 PHP 執行 → 輸出 HTML → 回應給瀏覽器畫出來;每次請求都從頭執行一次
- 特點:可以嵌在 HTML 裡、動態型別、直譯執行、開放原始碼、內建大量函式
- PHP 7 大幅提升效能並加入型別宣告與
??;PHP 8 加入 JIT、match、具名引數等,很多錯誤改成直接報錯。本課程以 PHP 8.3 為準 php -v看版本、php 檔名執行程式、php -S localhost:8000開啟開發用伺服器echo輸出文字,敘述以;結束;變數以$開頭,用=指派