到现在为止,您肯定已经掌握了绑定到多个变量的想法。但是,不要相信关于不使用“SELECT *”和 bind_result() 的警告。您可以保留您的“SELECT *”语句......即使在您的服务器上要求您使用 bind_result(),但这有点复杂,因为您必须使用 PHP 的 call_user_func_array() 作为传递任意值的方式(因为“SELECT *") bind_result() 的参数数量。在我之前的其他人已经在这些论坛的其他地方发布了一个方便的功能。我把它包括在这里:
// Take a statement and bind its fields to an assoc array in PHP with the same fieldnames
function stmt_bind_assoc (&$stmt, &$bound_assoc) {
$metadata = $stmt->result_metadata();
$fields = array();
$bound_assoc = array();
$fields[] = $stmt;
while($field = $metadata->fetch_field()) {
$fields[] = &$bound_assoc[$field->name];
}
call_user_func_array("mysqli_stmt_bind_result", $fields);
}
现在,要使用它,我们执行以下操作:
function fetch_my_data() {
$stmt = $conn->prepare("SELECT * FROM my_data_table");
$stmt->execute();
$result = array();
stmt_bind_assoc($stmt, $row);
while ($stmt->fetch()) {
$result[] = array_copy($row);
}
return $result;
}
现在,fetch_my_data() 将返回一个关联数组的数组...全部设置为编码为 JSON 或其他。
这里发生的事情有点狡猾。 stmt_bind_assoc() 在您传递给它的引用 ($bound_assoc) 处构造一个空关联数组。它使用 result_metadata() 和 fetch_field() 来获取返回字段的列表,并(在 while 循环中使用该单个语句)在 $bound_assoc 中使用该字段名创建一个元素,并在 $fields 数组中附加对它的引用。然后将 $fields 数组传递给 mysqli_stmt_bind_result。真正巧妙的部分是还没有将实际值传递到 $bound_assoc。从查询中获取数据的所有过程都发生在 fetch_my_data() 中,从 stmt_bind_assoc() 在 while($stmt->fetch()) 之前调用这一事实可以看出。
但是有一个问题:因为该语句已绑定到 $bound_assoc 中的引用,所以它们将随着每个$stmt->fetch() 而改变。因此,您需要制作 $row 的深层副本。如果不这样做,$result 数组中的 所有 行将包含相同的内容:SELECT 中返回的最后一行。所以,我正在使用我在 Google 中找到的一个小 array_copy() 函数:
function array_copy( array $array ) {
$result = array();
foreach( $array as $key => $val ) {
if( is_array( $val ) ) {
$result[$key] = arrayCopy( $val );
} elseif ( is_object( $val ) ) {
$result[$key] = clone $val;
} else {
$result[$key] = $val;
}
}
return $result;
}