EDIT 07/2015 (câu hỏi đã được chỉnh sửa từ câu trả lời ban đầu nhưng nguyên tắc cơ bản đều giống nhau)
NeverSELECT *
trong một môi trường sản xuất, nó sẽ chỉ trở lại cắn bạn trong kỳ lạ, không thể đoán trước và dường như không liên quan. Bằng cách chỉ định các cột bạn muốn, bạn sẽ đảm bảo rằng thứ tự cột, kiểu dữ liệu, ràng buộc và tất cả các loại phần tử khác sẽ không gây ra sự cố cho bạn trong thời gian dài.
Câu trả lời này vẫn chủ yếu hợp lệ vì vậy tôi sẽ để nguyên ở đây, nhưng việc lấy đi chính là: sử dụng PDO, 98% trong số những thứ bạn cần với nhiều hơn và nhiều hơn nữa API ngắn gọn trên cùng một kết thúc. Nếu bạn cần một API RDBMS cụ thể phức tạp hơn thì bạn đã hiểu được những vấn đề bạn có và tại sao bạn cần mysqli etc thay thế.
SELECT *
không hoạt động tốt với các câu lệnh chuẩn bị MySQL. Đó là một trong những lý do chính tôi khuyên bạn nên thay thế PDO - đó và yêu cầu vô lý để ràng buộc tham chiếu biến thay vì giá trị cho các tham số.
$stmt->bind_result($row);
này không được ràng buộc kết quả hàng cho một biến, nó sẽ chỉ được ràng buộc một cột duy nhất. Và bởi vì bạn đã sử dụng SELECT *
, nó không làm những gì bạn muốn nó.
Nếu bạn muốn sử dụng MySQLi trên PDO (như tôi muốn giới thiệu), có một vài ví dụ hay về cách SELECT *
trong các ý kiến như this one trên trang hướng dẫn sử dụng bind_result()
.
Hoặc bạn chỉ có thể chỉ định các cột bạn muốn lấy:
$sql_con = new mysqli('db', 'username', 'password', 'database');
if($stmt = $sql_con->prepare("SELECT name, countryCode FROM Country WHERE countryCode = ?")) {
$stmt->bind_param("s", $country_code);
$stmt->execute();
$stmt->bind_result($name, $countryCode);
while ($stmt->fetch()) {
// Because $name and $countryCode are passed by reference, their value
// changes on every iteration to reflect the current row
echo "<pre>";
echo "name: $name\n";
echo "countryCode: $countryCode\n";
echo "</pre>";
}
$stmt->close();
EDIT dựa trên mã mới của bạn, bạn nên làm điều này:
// $date1 will be int(2010), $date2 will be int(1980) because you didn't
// quote the strings!
//$date1 = 2012-01-01;
//$date2 = 2012-01-31;
// Connect to DB
$sql_con = new mysqli('db', 'username', 'password', 'database');
// Check for connection errors here!
// The query we want to execute
$sql = "
SELECT eventLogID
FROM Country
WHERE countryCode = ?
AND date BETWEEN ? AND ?
";
// Attempt to prepare the query
if ($stmt = $sql_con->prepare($sql)) {
// Pass the parameters
$date1 = '2012-01-01';
$date2 = '2012-01-31';
$stmt->bind_param("sss", $country_code, $date1, $date2);
// Execute the query
$stmt->execute();
if (!$stmt->errno) {
// Handle error here
}
// Pass a variable to hold the result
// Remember you are binding a *column*, not a row
$stmt->bind_result($eventLogID);
// Loop the results and fetch into an array
$logIds = array();
while ($stmt->fetch()) {
$logIds[] = $eventLogID;
}
// Tidy up
$stmt->close();
$sql_con->close();
// Do something with the results
print_r($logIds);
} else {
// Handle error here
}
Bạn sử dụng * trong truy vấn của bạn , nhưng $ hàng trong bind_result của bạn ($ row). bind_result nên chứa các cột mà tôi nghĩ. Đọc thêm tại đây: http://nl3.php.net/manual/en/mysqli-stmt.bind-result.php Vì vậy, biến hàng $ của bạn chứa cột đầu tiên của bất cứ điều gì nó * có nghĩa là. (Tránh * trong tất cả các truy vấn của bạn, nhưng đó là một vấn đề khác.) –