результат подготовленной инструкции 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
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);
?>
Действительно, есть более простой способ. Пожалуйста, рассмотрите возможность использования столбца 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_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
Вы можете попытаться расширить класс 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();
}
Редактировать: Я просмотрел ваши комментарии и другие ответы, и ясно, что у вас нет собственного драйвера 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
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
в наличии