PHP 門檻低、上手快,但「能跑」不代表「正確」。本文整理初學者最常踩的 14 個坑,附上原因分析與最佳實踐解法,助你避開新手村陷阱。
<?php
// form.html → process.php
echo $username; // Notice: Undefined variable
echo $_POST['username']; // 正常
PHP 5.4+ 預設 register_globals = Off,不再自動將 `$_GET`、`$_POST`、`$_SESSION` 註冊為全域變數。
$_GET、$_POST、$_REQUEST、$_SESSION、$_COOKIE、$_SERVER、$_FILES、$_ENVInput::get('username')// URL: test.php?name=中文
echo $_GET['name']; // 亂碼或空白
瀏覽器編碼(UTF-8)與伺服器解碼(系統預設 ANSI/GBK)不一致。
// 前端編碼
連結
// 後端解碼(若必要)
$name = urldecode($_GET['name']);
// 根本解決:統一 UTF-8
// 1. HTML:
// 2. PHP: header('Content-Type: text/html; charset=UTF-8');
// 3. 資料庫: CHARSET utf8mb4
// 4. Apache: AddDefaultCharset UTF-8
session_start();
$_SESSION['user'] = 'john';
// 重新整理 → $_SESSION 為空
php.ini 預設 session.save_path = "/tmp"(Linux 路徑),Windows 無此目錄。
; php.ini
session.save_path = "C:/Windows/Temp" ; 或自訂可寫目錄
; 程式碼中動態設定(需在 session_start() 前)
ini_set('session.save_path', __DIR__ . '/sessions');
生產環境直接顯示堆疊追蹤、資料庫憑證、路徑資訊。
; php.ini 生產環境
display_errors = Off
display_startup_errors = Off
log_errors = On
error_log = /var/log/php_errors.log
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
; 開發環境
display_errors = On
error_reporting = E_ALL
程式碼中:error_reporting(E_ALL); ini_set('display_errors', '1');
Warning: Cannot modify header information - headers already sent by...
header()/session_start()/setcookie() 之前?> 後的空白行?>ob_start() 在腳本最開頭systemctl restart php-fpm / apachectl restartphp --ini 或 phpinfo() 查看 Loaded Configuration Fileopcache_reset()$sql = "INSERT INTO users (name) VALUES ('$name')";
mysqli_query($conn, $sql); // 失敗卻不報錯
$sql = "INSERT INTO users (name) VALUES (?)";
$stmt = mysqli_prepare($conn, $sql);
mysqli_stmt_bind_param($stmt, 's', $name);
if (!mysqli_stmt_execute($stmt)) {
error_log('SQL Error: ' . mysqli_stmt_error($stmt));
// 處理失敗
}
// 開發環境直接顯示
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
// 或 PDO
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
| 特性 | include | require |
|---|---|---|
| 檔案不存在 | E_WARNING,繼續執行 | E_COMPILE_ERROR,腳本終止 |
| 回傳值 | 成功回傳 1,可被 include 檔案覆蓋 | 同 |
| 建議用途 | 選用性檔案(樣板、廣告) | 核心依賴(設定、函數庫、類別) |
| 變數狀態 | isset() | empty() |
|---|---|---|
| 未定義 | false | true |
| null | false | true |
| '' (空字串) | true | true |
| 0 (整數) | true | true |
| '0' (字串) | true | true |
| [] (空陣列) | true | true |
| false | true | true |