問題現象
執行 mysql_query() 後直接 echo $result 或 var_dump($result) 顯示 Resource id #4,而非期望的數據行。原因:mysql_query 返回的是結果集資源句柄,必須用提取函數逐行讀取。
正確處理流程
<?php
// 1. 執行查詢
$result = mysql_query("SELECT imagePath FROM anypaiInfo WHERE schoolId = 1 AND id = $random");
if (!$result) {
die('查詢失敗: ' . mysql_error());
}
// 2. 提取單行(對象模式)
$row = mysql_fetch_object($result);
if ($row) {
$imageUrl = $row->imagePath; // 通過屬性訪問字段
echo "圖片地址: $imageUrl";
} else {
echo "無匹配記錄";
}
// 3. 釋放結果集(可選,腳本結束自動釋放)
mysql_free_result($result);
?>
四種提取函數對比
| 函數 | 返回類型 | 訪問方式 | 適用場景 |
| mysql_fetch_object() | object / false | $row->field | 面向對象代碼、字段名含特殊字符 |
| mysql_fetch_assoc() | array / false | $row['field'] | 最常用、鍵名為字段名 |
| mysql_fetch_array() | array / false | $row[0] 或 $row['field'] | 需同時用數字/字符串索引(預設雙模式) |
| mysql_fetch_row() | array / false | $row[0] | 僅需數字索引、性能略高 |
完整遍歷示例
<?php
$result = mysql_query("SELECT id, name, email FROM users WHERE status = 1");
if (!$result) die(mysql_error());
// 方式 1:while 循環 + fetch_assoc(推薦)
while ($row = mysql_fetch_assoc($result)) {
echo "ID: {$row['id']}, Name: {$row['name']}, Email: {$row['email']}\n";
}
// 方式 2:一次性獲取所有行(小結果集)
$rows = [];
while ($row = mysql_fetch_assoc($result)) {
$rows[] = $row;
}
// 現在 $rows 是二維數組,可隨意遍歷多次
print_r($rows);
mysql_free_result($result);
?>
關鍵避坑指南
| 錯誤做法 | 後果 | 正確做法 |
直接 echo $result | 輸出 Resource id #N | 必須先 fetch |
| 重複 fetch 同一結果集 | 指針已到末尾,返回 false | 用 mysql_data_seek($result, 0) 重置指針,或先存入數組 |
未判斷 mysql_query 返回 false | 後續 fetch 報警告 | 嚴格判斷 if (!$result) die(...) |
| 在循環中執行新查詢 | 嵌套查詢導致 N+1 問題 | 用 JOIN 或預先批量查詢 |
⚠️ 重要:mysql_* 已棄用/移除
- PHP 5.5.0 棄用,PHP 7.0.0 完全移除
- 新項目必須使用 mysqli 或 PDO
mysqli 對應寫法(面向過程)
<?php
$mysqli = new mysqli('localhost', 'user', 'pass', 'db');
if ($mysqli->connect_errno) die('連接失敗: ' . $mysqli->connect_error);
$sql = "SELECT imagePath FROM anypaiInfo WHERE schoolId = 1 AND id = ?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $random);
$stmt->execute();
$result = $stmt->get_result();
if ($row = $result->fetch_object()) {
$imageUrl = $row->imagePath;
}
$stmt->close();
$mysqli->close();
?>
PDO 對應寫法(推薦)
<?php
$pdo = new PDO('mysql:host=localhost;dbname=db;charset=utf8mb4', 'user', 'pass', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ, // 默認返回對象
]);
$stmt = $pdo->prepare("SELECT imagePath FROM anypaiInfo WHERE schoolId = 1 AND id = ?");
$stmt->execute([$random]);
$row = $stmt->fetch(); // 直接返回對象或 false
if ($row) {
$imageUrl = $row->imagePath;
}
?>
總結
mysql_query 返回 資源句柄,非數據本身
- 必須用
mysql_fetch_object/assoc/array/row 逐行提取
- 舊代碼維護時注意判斷返回值、釋放資源
- 新項目請直接使用 PDO,支援預處理、異常模式、多種獲取模式