Tôi nhận ra rằng đã lâu rồi không có bất kỳ hoạt động mới nào về câu hỏi này. Nhưng, như những người đăng khác đã nhận xét - get_result()
hiện chỉ có sẵn trong PHP bằng cách cài đặt trình điều khiển gốc MySQL (mysqlnd) và trong một số trường hợp, có thể không thực hiện được hoặc không mong muốn cài đặt mysqlnd. Vì vậy, tôi nghĩ sẽ hữu ích nếu đăng câu trả lời này kèm theo thông tin về cách có được chức năng get_result()
cung cấp - mà không cần sử dụng get_result()
.
get_result()
is / thường được kết hợp với fetch_array()
để lặp qua một tập kết quả và lưu trữ các giá trị từ mỗi hàng của tập kết quả trong một mảng được lập chỉ mục số hoặc kết hợp. Ví dụ: đoạn mã bên dưới sử dụng get_result () với fetch_array () để lặp qua một tập kết quả, lưu trữ các giá trị từ mỗi hàng trong mảng $ data [] được lập chỉ mục số:
$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $c);
$stmt->execute();
$result = $stmt->get_result();
while($data = $result->fetch_array(MYSQLI_NUM)) {
print $data[0] . ', ' . $data[1] . "<BR>\n";
}
Tuy nhiên, nếu get_result()
không có sẵn (vì mysqlnd không được cài đặt), thì điều này dẫn đến vấn đề làm thế nào để lưu trữ các giá trị từ mỗi hàng của tập kết quả trong một mảng mà không cần sử dụng get_result()
. Hoặc, cách di chuyển mã kế thừa sử dụng get_result()
để chạy mà không có mã đó (ví dụ: sử dụng bind_result()
thay thế) - trong khi tác động ít nhất có thể đến phần còn lại của mã.
Nó chỉ ra rằng việc lưu trữ các giá trị từ mỗi hàng trong một mảng được lập chỉ mục bằng số không dễ sử dụng bind_result()
. bind_result()
mong đợi một danh sách các biến vô hướng (không phải là một mảng). Vì vậy, phải làm một số việc để làm cho nó lưu trữ các giá trị từ mỗi hàng của tập kết quả trong một mảng.
Tất nhiên, mã có thể dễ dàng được sửa đổi như sau:
$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $c);
$stmt->execute();
$stmt->bind_result($data[0], $data[1]);
while ($stmt->fetch()) {
print $data[0] . ', ' . $data[1] . "<BR>\n";
}
Tuy nhiên, điều này yêu cầu chúng tôi liệt kê rõ ràng $ data [0], $ data [1], v.v. trong lệnh gọi tới bind_result()
, điều này không lý tưởng. Chúng tôi muốn một giải pháp không yêu cầu chúng tôi phải liệt kê rõ ràng $ data [0], $ data [1], ... $ data [N-1] (trong đó N là số trường trong câu lệnh select) trong cuộc gọi tới bind_results()
. Nếu chúng tôi đang di chuyển một ứng dụng cũ có số lượng lớn các truy vấn và mỗi truy vấn có thể chứa một số trường khác nhau trongselect
mệnh đề, thì việc di chuyển sẽ rất tốn công sức và dễ xảy ra lỗi nếu chúng ta sử dụng một giải pháp như trên .
Lý tưởng nhất, chúng tôi muốn một đoạn mã 'thay thế thả vào' - để chỉ thay thế dòng chứa get_result()
hàm và vòng lặp while () trên dòng tiếp theo. Mã thay thế phải có cùng chức năng với mã mà nó đang thay thế, mà không ảnh hưởng đến bất kỳ dòng nào trước hoặc bất kỳ dòng nào sau đó - kể cả các dòng bên trong vòng lặp while (). Lý tưởng nhất là chúng tôi muốn mã thay thế càng nhỏ gọn càng tốt và chúng tôi không muốn phải xử lý mã thay thế dựa trên số lượng trường trong select
mệnh đề của truy vấn.
Tìm kiếm trên internet, tôi đã tìm thấy một số giải pháp sử dụng bind_param()
với call_user_func_array()
(ví dụ: Liên kết động các tham số mysqli_stmt và sau đó liên kết kết quả (PHP) ), nhưng hầu hết các giải pháp mà tôi tìm thấy cuối cùng đều dẫn đến kết quả được lưu trữ trong một mảng liên kết, không một mảng được lập chỉ mục bằng số và nhiều giải pháp trong số này không nhỏ gọn như tôi muốn và / hoặc không phù hợp như 'các giải pháp thay thế thả vào'. Tuy nhiên, từ các ví dụ mà tôi tìm thấy, tôi đã có thể đúc kết lại giải pháp này, phù hợp với hóa đơn:
$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $c);
$stmt->execute();
$data=array();
for ($i=0;$i<$mysqli->field_count;$i++) {
$var = $i;
$$var = null;
$data[$var] = &$$var;
}
call_user_func_array(array($stmt,'bind_result'), $data);
while ($stmt->fetch()) {
print $data[0] . ', ' . $data[1] . "<BR>\n";
}
Tất nhiên, vòng lặp for () có thể được thu gọn thành một dòng để làm cho nó gọn gàng hơn.
Tôi hy vọng điều này sẽ giúp ích cho bất kỳ ai đang tìm kiếm giải pháp sử dụng bind_result()
để lưu trữ các giá trị từ mỗi hàng trong một mảng được lập chỉ mục số và / hoặc đang tìm cách di chuyển mã kế thừa bằng cách sử dụng get_result()
. Bình luận được chào đón.
$stmt = $conn->mysqli->stmt_init();
?