准备好的 select 语句的结果作为数组

result of prepared select statement as array

我想将准备好的语句的完整结果作为数组(key/value 对)获取,以便稍后在 str_replace() 函数中使用它。

我的 table 有三列,一个索引和字段 "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 循环,得到完整的结果,而不是从单行开始逐行累加。

我看了其他问题,想出了以下方法,但它不起作用("Warning: mysqli_fetch_assoc() expects parameter 1 to be 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); 但没有成功(得到 "Call to undefined function mysqli_fetch_all()")。

顺便说一句,我正在使用 PHP 5.6.


在有关 MYSQLND 的评论中进行一些回答和讨论后添加:

phpinfo() 在其 mysqlnd 部分显示以下信息:

Loaded plugins: mysqlnd,debug_trace,auth_plugin_mysql_native_password,auth_plugin_mysql_clear_password,auth_plugin_sha256_password

你试过这样的事情吗?

$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);
?>

确实有更简单的方法。请考虑使用 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 函数的答案

这就是我 fetch_all 使用 mysqli

准备好的语句的结果
$stmt = $db->prepare("SELECT x1, x2 FROM my_table")
$stmt->execute();
$result = $stmt->get_result();
$allRows = $result->fetch_all(MYSQLI_ASSOC);

您可以尝试使用如下函数扩展 mysqli_result class:

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();
}

请原谅我的英语

我认为这是不可能的,因为 mysqli_fetch_assoc() 使用 mysqli_result 作为参数,而 mysqli->prepare->execute returns 使用 mysqli_stmt 对象。

你可以做的是使用 答案的程序方式,或者你可以使用 $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);

PHP mysqli

的文档

编辑:我查看了您的评论和其他答案,很明显您没有 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 语句,因为它会在该点终止脚本的执行。

希望对您有所帮助:)

从前面的答案(缺少正确的 mysqlnd 分机 - 有两个,一个用于 mysqli,一个用于 PDO),我们可以得出结论,您有两个选项,您可以将准备好的语句与 while 循环或标准查询一起使用,但是 returns 您的结果作为关联数组。

由于您没有任何参数,您可以安全地使用普通 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 可用的

,这是最好的方法