результат подготовленного оператора select как массив

Я хотел бы получить полный результат подготовленного оператора в виде массива (пары ключ/значение), чтобы позже использовать его в функции 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 цикла, получение полного результата, не суммируется из отдельных строк один за другим.

Я рассмотрел другие вопросы, и я придумал следующее, но это не сработает ("Warning: 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()").

BTW, я использую PHP 5.6.


ДОПОЛНЕНИЕ после некоторых ответов и обсуждения в комментариях относительно MYSQLND:

phpinfo() отображает следующую информацию в разделе mysqlnd:

Загруженные плагины: mysqlnd, debug_trace, auth_plugin_mysql_native_password, auth_plugin_mysql_clear_password, auth_plugin_sha256_password

Ответ 1

Вы попробовали что-то вроде этого?

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

Ответ 2

Существует более простой способ. Пожалуйста, рассмотрите возможность использования 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);

EDIT: обновленный ответ для использования процедурных функций mysqli

Ответ 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);

Ответ 4

Извините мой английский

Я не думаю, что это возможно, потому что mysqli_fetch_assoc() принимает mysqli_result в качестве аргумента, тогда как mysqli->prepare->execute возвращает объект mysqli_stmt.

Что вы могли бы сделать, это использовать процедурный путь из JesusTheHun в ответ или вы можете использовать $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

Ответ 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

Изменение: я просмотрел ваши комментарии и другие ответы, и ясно, что у вас нет родного драйвера Mysql.

Если вы не хотите использовать mysqlnd, я считаю, что вы не можете избавиться от этого while loop;)

================================================== ==========

Кажется, вы пропустили одну вещь!

Вам нужно вызвать метод 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 ext - есть два, один для 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