PHP 歷史包袱導致許多同功能函數並存,且型別系統寬鬆,極易產生誤解。本文針對六組高頻混淆點,從底層機制、實際表現、最佳實踐三維度徹底釐清。
| 特性 | echo | |
|---|---|---|
| 返回值 | 無 | 總是返回 1(可用於表達式) |
| 參數 | 可接受多參數 echo 'a', 'b' | 單一參數 |
| 效能 | 略快(無返回值開銷) | 稍慢 |
| 用法建議 | 日常輸出首選 | 需在表達式中輸出時使用 |
<?php
// print 可用於三元運算
$flag ? print 'Yes' : print 'No'; // 合法
// echo 'a', 'b'; // 合法
// echo ('a', 'b'); // 錯誤:echo 非函數,不可加括號包裹多參數
?>
| 特性 | include | require |
|---|---|---|
| 失敗行為 | 發出 E_WARNING,腳本繼續執行 | 拋出 E_COMPILE_ERROR,腳本終止 |
| 條件包含 | 支援動態判斷 if ($cond) include 'a.php'; | 編譯期解析,無條件包含(即使在 if(false) 內) |
| 返回值 | 包含檔可返回值供接收 | 同 |
核心差異:
require是編譯期指令,include是執行期指令。現代框架普遍使用自動載入器,直接require核心檔案,業務邏輯按需include視圖。
realpath 正規化),大小寫敏感度依作業系統(Windows 不敏感,Linux 敏感)。_once 開銷可忽略;未啟用時每次檢查路徑表有微小成本。'' vs NULL vs 0| 值 | gettype() | === '' | === null | === 0 | == '' | == null | == 0 |
|---|---|---|---|---|---|---|---|
'' | string | true | false | false | true | true | true |
null | NULL | false | true | false | true | true | false |
0 | integer | false | false | true | true | false | true |
false | boolean | false | false | false | true | true | true |
記憶口訣:=== 比較「值+型別」,== 僅比較「值」(會進行型別轉換)。
| 變數狀態 | isset() | empty() | !isset() |
|---|---|---|---|
| 未定義 | false | true | true |
定義但賦值 null | false | true | true |
0 / '0' / '' / false / [] | true | true | false |
| 非空值 | true | false | false |
關鍵陷阱:
empty($var)將0、'0'視為「空」,導致 ID 為 0 的記錄被誤判為未傳遞。
建議:檢查「是否傳遞」用isset()或array_key_exists();檢查「業務意義上的空」用自定義邏輯$val === '' || $val === null。
<?php
'' == null; // true (型別轉換後比較值)
'' === null; // false (型別不同:string vs NULL)
'123' == 123; // true
'123' === 123; // false (string vs int)
0 == false; // true
0 === false; // false (int vs bool)
?>
鐵律:除非極其確定需要型別轉換,永遠使用 === 和 !==。PHP 8.0+ 更嚴格:0 == 'foo' 現在為 false(非數字字串不再轉為 0)。
| 場景 | 推薦寫法 | 避免寫法 |
|---|---|---|
| 輸出變數 | echo $var; | print $var; |
| 核心檔案載入 | require 'core.php'; | include 'core.php'; |
| 視圖/條件載入 | include 'view.php'; | require 'view.php'; |
| 判斷變數是否定義 | isset($var) | !empty($var) (會誤判 0) |
| 判斷字串非空 | $str !== '' | !empty($str) (會誤判 '0') |
| 比較值 | $a === $b | $a == $b |