常見新手錯誤:將產生圖片的 PHP 代碼直接嵌入 HTML 中,導致瀏覽器顯示亂碼。根本原因是 HTTP 回應只能有一種 Content-Type,混合輸出會破壞圖片二進位資料流。
<!-- 錯誤:HTML 中直接嵌入圖片產生代碼 -->
<html>
<body>
<h1>我的驗證碼</h1>
<?php
// 產生 PNG 圖片
header("Content-Type: image/png");
$im = imagecreatetruecolor(100, 30);
// ... 繪圖代碼 ...
imagepng($im);
imagedestroy($im);
?>
</body>
</html>
結果: 瀏覽器先收到 HTML 文本,再收到 PNG 二進位,導致圖片顯示為亂碼或破圖。
建立獨立 captcha.php,純粹輸出圖片,不含任何 HTML/空白字元:
<?php
// captcha.php
session_start();
// 1. 產生驗證碼
$code = '';
for ($i = 0; $i < 4; $i++) $code .= mt_rand(0, 9);
$_SESSION['captcha'] = $code;
// 2. 繪圖
$im = imagecreatetruecolor(100, 36);
$bg = imagecolorallocate($im, 240, 240, 240);
$text = imagecolorallocate($im, 0, 0, 0);
imagefill($im, 0, 0, $bg);
// 干擾線/點...
for ($i = 0; $i < 4; $i++) {
imagestring($im, 5, 10 + $i * 22, 6, $code[$i], $text);
}
// 3. 輸出
header('Content-Type: image/png');
header('Cache-Control: no-store, no-cache, must-revalidate');
imagepng($im);
imagedestroy($im);
?>
<!-- form.php -->
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>登入</title></head>
<body>
<form action="verify.php" method="post">
<label>驗證碼:
<input type="text" name="captcha" maxlength="4" required>
<img src="captcha.php" id="captchaImg" alt="點擊更換" style="vertical-align: middle; cursor: pointer;">
</label>
<button type="submit">送出</button>
</form>
<script>
document.getElementById('captchaImg').onclick = function() {
this.src = 'captcha.php?' + Date.now(); // 防快取
};
</script>
</body>
</html>
<?php
// verify.php
session_start();
if (strtolower($_POST['captcha'] ?? '') !== strtolower($_SESSION['captcha'] ?? '')) {
die('驗證碼錯誤');
}
unset($_SESSION['captcha']);
// 後續業務邏輯...
echo '驗證通過';
?>
| 錯誤做法 | 正確做法 |
|---|---|
HTML 中混入 header('Content-Type: image/...') | 獨立 .php 檔案專責輸出圖片 |
<img src="data.php"> 但 data.php 也輸出 HTML | data.php 只 輸出圖片二進位 |
| 圖片代碼前後有空白行/ BOM | 純 PHP 模式 (省略 ?>),無任何輸出 |
若必須單一檔案,可將圖片 Base64 編碼內嵌:
<?php
ob_start();
// 產生圖片到緩衝區
$im = imagecreatetruecolor(50, 20);
// ... 繪圖 ...
imagepng($im);
$pngData = ob_get_clean();
$base64 = base64_encode($pngData);
imagedestroy($im);
?>
<img src="data:image/png;base64," alt="圖片">
缺點: 增加 HTML 體積 ~33%,不利快取,僅適合極小圖標 (如 1x1 追蹤像素)。
header() 前 零輸出 (含 var_dump、錯誤訊息)。error_reporting(E_ALL) 捕獲隱性警告。Content-Type 是否為 image/png。