результат подготовленной инструкции 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, получить полный результат, а не складываться из отдельных строк по одной.

Я рассмотрел другие вопросы и пришел к выводу, что ниже, но это не работает ("Предупреждение: 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.


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

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

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

Author: Nimeshka Srimal, 2018-07-13

7 answers

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

$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);
?>
 0
Author: IVO GELOV, 2018-07-17 15:51:11

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

 2
Author: JesusTheHun, 2018-07-17 16:22:59

Вот как я fetch_all результаты с подготовленными заявлениями с использованием mysqli

$stmt = $db->prepare("SELECT x1, x2 FROM my_table")
$stmt->execute();
$result = $stmt->get_result();
$allRows = $result->fetch_all(MYSQLI_ASSOC);
 1
Author: Accountant م, 2018-07-17 16:43:36

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

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

 1
Author: Saleh Mahmood, 2018-09-18 13:34:31

Вы можете попытаться расширить класс 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();
}
 0
Author: Julio, 2018-07-20 23:17:05

Редактировать: Я просмотрел ваши комментарии и другие ответы, и ясно, что у вас нет собственного драйвера 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 поскольку в этот момент он завершает выполнение сценария.

Надеюсь, это поможет:)

 0
Author: Nimeshka Srimal, 2018-07-23 17:14:59

Из предыдущих ответов (отсутствие правильного mysqlnd ext - есть два, один для mysqli и один для PDO), мы можем сделать вывод, что у вас есть два варианта, вы можете использовать подготовленные операторы с циклом while или стандартный запрос, но который возвращает ваш результат в виде ассоциативного массива.

Поскольку у вас нет никаких параметров, вы можете безопасно использовать простой ole-запрос, потому что:

A) Нет пользовательского ввода, который вам нужно избежать, нет параметры в вашем заявлении, следовательно, угрозы безопасности нет

Б) Прирост производительности подготовленного оператора незначителен, если таковой имеется, потому что вы используете его в качестве простого запроса 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 в наличии

 0
Author: Sasa Blagojevic, 2018-07-23 17:53:01