<?php
$a = 3;
$b = 5;
$c = $a > $b ? 2 : 4; // $c = 4
echo $d = $a < $c; // 輸出什麼?為什麼是 1?
echo gettype($d); // boolean
var_dump($d); // bool(true)
/* 例 2 */
if ('ABC' == 0)
echo 'yes';
else
echo 'no'; // 輸出 yes!為什麼?
/* 例 3:運算子優先級陷阱 */
$h = +$g = 10;
echo $h, $g; // 輸出 1010?實際是什麼?
?>
PHP 是弱型別語言,允許不同型別資料直接混合運算。引擎會依據上下文自動、隱性地轉換型別。這帶來寫碼便利,卻也埋下無數坑。
== 的非對稱轉換"ABC" 轉數字為 0(非數字開頭),故 0 == "ABC" 為 true。"0" == "00" 為 true(兩邊皆轉數字 0)。===(全等)比較,同時檢查型別與值,避免隱性轉換驚喜。echo 的輸出型別轉換echo 只接受字串運算元。輸出前會自動轉換:
true → "1"false → ""(空字串)null → ""E_NOTICE / E_RECOVERABLE_ERROR(除非實作 __toString())因此 echo $a < $c 先運算比較得 true,再轉字串 "1" 輸出,故顯示 1。
. 的優先級與空格敏感度echo 100 . "ABC"; // 正確:100ABC (數字轉字串連接)
echo 100."ABC"; // 錯誤!解析器視 "100." 為浮點數 100.0,後接 "ABC" 導致語法錯誤
echo 100 ."ABC"; // 正確:100ABC
echo 100. "ABC"; // 錯誤!同理視為 100.0 "ABC"
鐵律:連接運算子 . 前後務必加空格,避免被誤判為浮點數小數點。
+ 強制轉數字echo 100 + "ABC"; // 100 ("ABC" → 0)
echo 100 + "20" . 30; // 12030 (先算 100+"20"=120,再連接 "30")
echo 100 + "20".30; // 錯誤!".30" 被解析為浮點數 0.30
empty() 的「假陽性」陷阱empty("0") → true(字串 "0" 被視為空)empty("00") → false(非 "0" 字串不視為空)empty(0), empty(0.0), empty(""), empty(null), empty([]) 皆為 true檢查使用者輸入時,勿直接用 empty(),改用:
function isTrulyEmpty($val) {
return $val === '' || $val === null || $val === []; // 依業務需求調整
}
// 或針對表單輸入
if (strlen(trim($_POST['field'])) === 0) { /* 真正為空 */ }
in_array() 預設鬆散比較$arr = ["00"];
in_array("0", $arr); // true!因為 "0" == "00"
in_array("0", $arr, true); // false(嚴格模式,檢查型別)
永遠傳入第三參數 true 啟用嚴格模式,除非你確定需要鬆散比較。
$h = +$g = 10賦值運算子 = 為右結合,等同 $h = +($g = 10):
$g = 10 → $g 變 10,整個運算式回傳 10+10 → 一元正號,無實際作用,值仍為 10$h = 10 → $h 變 10結果:$h=10, $g=10,輸出 1010。
| 場景 | 建議做法 |
|---|---|
| 比較值 | 預設用 ===,確需鬆散比較時才用 == 並加註解 |
in_array / array_search | 永遠加第三參數 true |
| 檢查字串是否為空 | 用 strlen(trim($str)) === 0 或 $str === '' |
| 字串連接 | . 前後加空格;複雜字串用 sprintf 或 heredoc |
| 布林輸出 | 明確轉換:echo $bool ? 'true' : 'false' |
| 關閉隱性轉換警告 | error_reporting(E_ALL & ~E_NOTICE)(不推薦,治標不治本) |
PHP 的弱型別與自動轉換是雙面刃。理解其規則、堅持嚴格比較、善用型別宣告(PHP 7+)、單元測試覆蓋邊界案例,才能駕馭這把利刃,寫出健壯、可預測的代碼。