准备好的选择语句的结果作为数组
Posted
技术标签:
【中文标题】准备好的选择语句的结果作为数组【英文标题】:result of prepared select statement as array 【发布时间】:2018-12-21 19:33:47 【问题描述】:我想以数组(键/值对)的形式获取准备好的语句的完整结果,以便稍后在 str_replace()
函数中使用它。
我的表有三列,一个索引和字段“x1”和“x2”。我成功使用了以下内容:
$db = new mysqli("servername", "username", "pw", "dbname");
if($ps1 = $db->prepare("SELECT x1, x2 FROM my_table"))
$ps1->execute();
$ps1->bind_result($search, $replace);
$result = array();
while ($ps1->fetch())
$result[$search] = $replace;
$ps1->close();
但是,我认为必须有一种更简单的方法,没有while
循环,得到完整的结果,而不是从单行一一相加。
我查看了其他问题,想出了以下问题,但它不起作用(“警告:mysqli_fetch_assoc() 期望参数 1 为 mysqli_result”):
if($ps1 = $db->prepare("SELECT x1, x2 FROM my_table"))
$ps1->execute();
$result = mysqli_fetch_assoc($ps1);
return $result;
$ps1->close();
我也尝试了$result = mysqli_fetch_all($ps1);
,但没有成功(得到“调用未定义函数 mysqli_fetch_all()”)。
顺便说一句,我使用的是 php 5.6。
在 cmets 中有关 MYSQLND 的一些答案和讨论后添加:
phpinfo()
在其mysqlnd
部分显示以下信息:
加载的插件: mysqlnd,debug_trace,auth_plugin_mysql_native_password,auth_plugin_mysql_clear_password,auth_plugin_sha256_password
【问题讨论】:
不确定为什么会出现该错误。不过,您应该全程使用 OOP。不过,该函数 php.net/manual/en/mysqli-result.fetch-assoc.php 仍然只返回 1 行。可以试试php.net/manual/en/mysqli-result.fetch-all.php。 php.net/manual/en/mysqli.error.php 是否提供更多关于为什么$ps1
不是结果对象的信息?
@user3783243 感谢您的回答!我尝试了$result = mysqli_fetch_all($ps1);
,但没有成功(“调用未定义的函数 mysqli_fetch_all()”)。抱歉,这个我慢。你能推荐一段代码吗?
您使用的是什么 PHP 版本?此外,我认为您仍然会遇到$ps1
的问题,因为基于该错误它不是结果对象,请尝试printf("Errormessage: %s\n", $ps1->error);
。
我更多的是 PDO 用户,这正在离开我的专业领域,但查看其他论坛/线程,似乎需要配置 mysqlnd
【参考方案1】:
确实有更简单的方法。请考虑使用array_column:
$link = mysqli_connect("localhost", "my_user", "my_password", "world");
/* check connection */
if (mysqli_connect_errno())
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
$query = "SELECT x1, x2 FROM my_table";
if ($stmt = mysqli_prepare($link, $query))
/* execute statement */
mysqli_stmt_execute($stmt);
/* get result object */
$rows = mysqli_fetch_all(mysqli_stmt_get_result($stmt), MYSQLI_ASSOC);
/* get formatted object */
$result = array_column($rows, 'x2', 'x1');
/* close statement */
mysqli_stmt_close($stmt);
/* close connection */
mysqli_close($link);
编辑:更新了使用程序 mysqli 函数的答案
【讨论】:
与其他答案相同:您的代码使用 PDO(我没有),所以我得到Call to undefined method mysqli_stmt::fetchAll() in ...
我已经更新了我的答案,并对其进行了测试。它做你想做的事
与其他答案相同的问题:Fatal error: Call to undefined function mysqli_fetch_all()
好的,你能发布 phpinfo() 的结果吗?所以我们知道我们在处理什么
请注意我的问题的补充【参考方案2】:
你尝试过这样的事情吗?
$db = new mysqli("servername", "username", "pw", "dbname");
if($ps1 = $db->prepare("SELECT x1, x2 FROM my_table"))
$ps1->execute();
$result = $ps1->fetchAll(PDO::FETCH_NAMED);
$ps1->close();
更新
我的意思是这样(如果你已经安装了mysqlnd驱动)
<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");
/* check connection */
if (mysqli_connect_errno())
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
$query = "SELECT Name, CountryCode FROM City ORDER by ID DESC LIMIT 150,5";
if ($stmt = mysqli_prepare($link, $query))
/* execute statement */
mysqli_stmt_execute($stmt);
/* get result object */
$result = mysqli_fetch_all(mysqli_stmt_get_result($stmt));
/* close statement */
mysqli_stmt_close($stmt);
/* close connection */
mysqli_close($link);
?>
【讨论】:
好吧:您的代码使用 PDO(我没有),所以我得到Call to undefined method mysqli_stmt::fetchAll() in ...
如果你不使用 PDO - 那么你必须自己迭代结果集 - 完全如官方手册中所示php.net/manual/en/mysqli-stmt.fetch.php
你的意思是像我在问题的第一部分中发布的代码一样?...
回复:您的编辑:这适用于打印结果,但这就像我的问题中的第一个代码示例(我必须使用 while 循环来填充新数组):它没有t 给我一个包含所有键/值对的数组,我以后可以在后续函数中使用它。
复杂性通常是主观的 :)) 即使底层连接器库提供了一次获取所有结果的方法 - 它不一定适用于高级语言。迭代结果集是一种标准做法——就像我们迭代 html 表格行和单元格一样。【参考方案3】:
这就是我 fetch_all
使用 mysqli 准备语句的结果
$stmt = $db->prepare("SELECT x1, x2 FROM my_table")
$stmt->execute();
$result = $stmt->get_result();
$allRows = $result->fetch_all(MYSQLI_ASSOC);
【讨论】:
这给了我Fatal error: Call to undefined method mysqli_stmt::get_result()...
@Johannes 你可能没有安装mysqlnd driver
。检查这个answer
不幸的是,我无权在该服务器(共享网络空间)上安装任何东西,我必须使用给定的配置和它提供的几个选项......
在这种情况下,如果您唯一关心的是“更简单的代码”,为什么不在函数中包含该获取循环并在您的主代码中调用它。可能还有其他解决方案,但很抱歉我只知道这些【参考方案4】:
请原谅我的英语
我认为这是不可能的,因为mysqli_fetch_assoc()
将mysqli_result
作为参数,而mysqli->prepare->execute
返回mysqli_stmt
对象。
您可以做的是使用JesusTheHun's 答案的程序方式,或者您可以使用$ps1 = $db->query($stmt)
而不是prepare and execute
,然后将其传递给$ps1->fetch_all(MYSQLI_ASSOC)
例子:
if($ps1 = $db->query("SELECT x1, x2 FROM my_table"))
$result = $ps1->fetch_all(MYSQLI_ASSOC);
$ps1->close();
return $result;
print_r($result);
mysqli 的 PHP 文档
【讨论】:
在return语句后关闭$ps1
有什么意义?【参考方案5】:
您可以尝试使用如下函数扩展 mysqli_result 类:
public function my_fetch_keyval()
for ($result = array(); $tmp = $this->fetch_row();)
// Expecting 2 columns. 1st = Key; 2nd = Value
$result[$tmp[0]] = $tmp[1];
return $result;
然后你可以在你的代码中使用它:
if($ps1 = $db->prepare("SELECT x1, x2 FROM my_table"))
$ps1->execute();
$my_assoc_array = $ps1->my_fetch_keyval();
$ps1->close();
【讨论】:
【参考方案6】:编辑:我浏览了您的 cmets 和其他答案,很明显您没有 Mysql 本机驱动程序。
如果你不想使用mysqlnd,我相信你不能摆脱那个while循环;)
================================================ ==============
你好像错过了一件事!
您需要调用get_result()
方法,然后对该对象调用fetch_all()
。
$db = new mysqli("servername", "username", "pw", "dbname");
if($ps1 = $db->prepare("SELECT x1, x2 FROM my_table"))
$ps1->execute();
$result = $ps1->get_result()->fetch_all();
//return $result;
$ps1->close();
echo '<pre>';
print_r($result);
另外请注意,我已经注释掉了 return
语句,因为它会在此时终止脚本的执行。
希望对你有帮助:)
【讨论】:
【参考方案7】:根据之前的答案(没有正确的mysqlnd
分机 - 有两个,一个用于mysqli
,一个用于PDO
),我们可以得出结论,您有两个选择,您可以使用带有 while 循环或标准查询的准备好的语句,但会将结果作为关联数组返回。
由于你没有任何参数,你可以安全地使用普通的 ole 查询,因为:
a) 没有您必须转义的用户输入,您的语句中没有参数,因此没有安全风险
b) 准备好的语句的性能提升是疏忽的,因为您将它用作普通的 ole SQL 查询。当您一遍又一遍地重复使用相同的语句时,只更改绑定到它的参数值,准备好的语句就会大放异彩
让我们切入正题:
$conn = mysqli($host, $user, $pass, $dbname);
$query = $conn->query("SELECT x1, x2 FROM your_table");
$result = $query->fetch_assoc();
结果将采用以下格式:
[
'x1' => 'v1',
'x2' => 'v2'
]
如果您需要整个数据集而不仅仅是一个项目,请使用以下内容:
$result = $query->fetch_all(MYSQLI_ASSOC);
结果将如下所示:
[
[
'x1' => 'v1',
'x2' => 'v2'
],
[
'x1' => 'v1',
'x2' => 'v2'
],
...
]
更新
现在我看到mysqli::fetch_all
也会为您抛出一个错误,那么恐怕没有循环就无法获取整个数据集。如果您想要替代您的方法,可能是这样的:
$query = $conn->query("SELECT x1, x2 FROM your_table");
$results = [];
for ($i = 0; $i < $query->num_rows; $i++)
$row = $query->fetch_assoc();
$results[$row['x1']] = $row['x2'];
或者这个:
while($row = $query->fetch_assoc())
$results[$row['x1']] = $row['x2'];
但老实说,那你不妨按照你最初的方式去,如果你没有mysqli::fetch_all
可用,这是最好的方法
【讨论】:
以上是关于准备好的选择语句的结果作为数组的主要内容,如果未能解决你的问题,请参考以下文章