我正在为uni开发一个项目,并且已经在基于testing server
的表格的get all devices
到user_id
上使用了以下代码:
public function getAllDevices($user_id) {
$stmt = $this->conn->prepare("SELECT * FROM devices WHERE primary_owner_id = ?");
$stmt->bind_param("i", $user_id);
$stmt->execute();
$devices = $stmt->get_result();
$stmt->close();
return $devices;
}
这在我的测试服务器上工作正常,但在迁移到大学项目服务器时返回此错误:
Call to undefined method mysqli_stmt::get_result()
有些谷歌搜索建议使用bind_result()
代替get_result()
,但我不知道如何在表格中执行此操作all fields
。大多数示例仅显示返回one field
非常感谢任何帮助
答案 0 :(得分:7)
假设您无法使用get_result()
并且想要一系列设备,您可以这样做:
public function getAllDevices($user_id) {
$stmt = $this->conn->prepare("SELECT device_id, device_name, device_info FROM devices WHERE primary_owner_id = ?");
$stmt->bind_param("i", $user_id);
$stmt->execute();
$stmt->bind_result($id, $name, $info);
$devices = array();
while($stmt->fetch()) {
$tmp = array();
$tmp["id"] = $id;
$tmp["name"] = $name;
$tmp["info"] = $info;
array_push($devices, $tmp);
}
$stmt->close();
return $devices;
}
这将创建一个临时数组并存储其中每行的数据,然后将其推送到主数组。据我所知,您无法在SELECT *
中使用bind_result()
。相反,您会烦恼地在SELECT
答案 1 :(得分:3)
到目前为止,您已经掌握了绑定多个变量的想法。但是,不要相信不使用带有bind_result()的“SELECT *”的警告。您可以保留“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;
}
答案 2 :(得分:1)
要使用bind_result()
,您无法使用SELECT *
的查询。
相反,您必须选择单个列名称,然后以相同的顺序绑定结果。这是一个例子:
$stmt = $mysqli->prepare("SELECT foo, bar, what, why FROM table_name WHERE id = ?");
$stmt->bind_param("i", $id);
if($stmt->execute()) {
$stmt->bind_result($foo, $bar, $what, $why);
if($stmt->fetch()) {
$stmt->close();
}else{
//error binding result(no rows??)
}
}else{
//error with query
}
答案 3 :(得分:1)
您的问题表明您在本地服务器上安装了MySQL Native driver (MySQLnd),但学校项目服务器上缺少MySQLnd。因为get_result()
需要MySQLnd。
因此,如果您仍想在学校项目服务器上使用get_result()
而不是bind_result()
,那么您应该在学校项目服务器上安装MySQLnd。
答案 4 :(得分:0)
get_result()
现在只能通过安装MySQL本机驱动程序(mysqlnd)在PHP中使用。在某些环境中,可能无法或不希望安装mysqlnd。
尽管如此,您仍然可以使用mysqli来选择*'查询,并使用字段名称获取结果 - 虽然它比使用get_result()
稍微复杂一些,并涉及使用php的call_user_func_array()
函数。请参阅下面的示例,该示例执行简单的选择*'查询,并将结果(带列名称)输出到HTML表:
$maxaccountid=100;
$sql="select * from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $maxaccountid);
$stmt->execute();
print "<table border=1>";
print "<thead><tr>";
$i=0;
$meta = $stmt->result_metadata();
$query_data=array();
while ($field = $meta->fetch_field()) {
print "<th>" . $field->name . "</th>";
$var = $i;
$$var = null;
$query_data[$var] = &$$var;
$i++;
}
print "</tr></thead>";
$r=0;
call_user_func_array(array($stmt,'bind_result'), $query_data);
while ($stmt->fetch()) {
print "<tr>";
for ($i=0; $i<count($query_data); $i++) {
print "<td>" . $query_data[$i] . "</td>";
}
print "</tr>";
$r++;
}
print "</table>";
$stmt->close();
print $r . " Records<BR>";