Я работаю над проектом для uni и использовал следующий код на testing server
чтобы get all devices
из таблицы на основе user_id
:
public function getAllDevices($user_id) { $stmt = $this->conn->prepare("SELECT * FROM devices WHERE primary_owner_id = ?"); $stmt->bind_param("i", $user_id); $stmt->execute(); $devices = $stmt->get_result(); $stmt->close(); return $devices; }
Это отлично работало на моем тестовом сервере, но возвращает эту ошибку при переходе на сервер университетского проекта:
Call to undefined method mysqli_stmt::get_result()
Некоторые googling предлагает использовать bind_result()
вместо get_result()
но я понятия не имею, как сделать это all fields
в таблице. В большинстве примеров показано только возвращение one field
Любая помощь приветствуется
Предполагая, что вы не можете использовать get_result()
и вам нужен массив устройств, вы можете сделать:
public function getAllDevices($user_id) { $stmt = $this->conn->prepare("SELECT device_id, device_name, device_info FROM devices WHERE primary_owner_id = ?"); $stmt->bind_param("i", $user_id); $stmt->execute(); $stmt->bind_result($id, $name, $info); $devices = array(); while($stmt->fetch()) { $tmp = array(); $tmp["id"] = $id; $tmp["name"] = $name; $tmp["info"] = $info; array_push($devices, $tmp); } $stmt->close(); return $devices; }
Это создает временный массив и сохраняет данные из каждой строки в нем, а затем подталкивает его к основному массиву. Насколько мне известно, вы не можете использовать SELECT *
в bind_result()
. Вместо этого вам будет досадно печатать все поля, которые вы хотите после SELECT
К настоящему времени вы, конечно, поняли идею привязки к нескольким переменным. Однако не верьте предупреждениям об использовании «SELECT *» с bind_result (). Вы можете хранить свои инструкции «SELECT *» … даже на вашем сервере, требуя, чтобы вы использовали bind_result (), но это немного сложно, потому что вы должны использовать PHP-вызов call_user_func_array () как способ передать произвольное (из-за «SELECT» * ") количество параметров bind_result (). Другие передо мной предоставили удобную функцию для этого в других местах на этих форумах. Я включаю его здесь:
// Take a statement and bind its fields to an assoc array in PHP with the same fieldnames function stmt_bind_assoc (&$stmt, &$bound_assoc) { $metadata = $stmt->result_metadata(); $fields = array(); $bound_assoc = array(); $fields[] = $stmt; while($field = $metadata->fetch_field()) { $fields[] = &$bound_assoc[$field->name]; } call_user_func_array("mysqli_stmt_bind_result", $fields); }
Теперь, чтобы использовать это, мы делаем что-то вроде:
function fetch_my_data() { $stmt = $conn->prepare("SELECT * FROM my_data_table"); $stmt->execute(); $result = array(); stmt_bind_assoc($stmt, $row); while ($stmt->fetch()) { $result[] = array_copy($row); } return $result; }
Теперь fetch_my_data () вернет массив ассоциативных массивов … все настроено на кодирование JSON или что-то еще.
Здесь очень коварно, что происходит. stmt_bind_assoc () создает пустой ассоциативный массив по ссылке, которую вы передаете ему ($ bound_assoc). Он использует result_metadata () и fetch_field () для получения списка возвращаемых полей и (с этим единственным оператором в цикле while) создает элемент в $bound_assoc
с этим $bound_assoc
и добавляет ссылку на него в массив $ fields. Затем массив $ fields передается в mysqli_stmt_bind_result. По-настоящему гладкая часть состоит в том, что никакие фактические значения не были переданы в $ bound_assoc . Вся выборка из запроса происходит в fetch_my_data (), как вы можете видеть из того, что stmt_bind_assoc()
вызывается до момента while($stmt->fetch())
.
Однако есть один улов: поскольку оператор привязан к ссылкам в $ bound_assoc, они будут меняться с каждым $stmt->fetch()
. Итак, вам нужно сделать глубокую копию строки $. Если вы этого не сделаете, все строки в массиве $ result будут содержать одно и то же: последняя строка, возвращаемая в вашем SELECT. Итак, я использую небольшую функцию array_copy (), которую я нашел в Google:
function array_copy( array $array ) { $result = array(); foreach( $array as $key => $val ) { if( is_array( $val ) ) { $result[$key] = arrayCopy( $val ); } elseif ( is_object( $val ) ) { $result[$key] = clone $val; } else { $result[$key] = $val; } } return $result; }
для использования bind_result()
вы не можете использовать запросы SELECT *
.
вместо этого вы должны выбрать отдельные имена таблиц, а затем привязать результаты в том же порядке. вот пример:
$stmt = $mysqli->prepare("SELECT foo, bar, what, why FROM table_name WHERE id = ?"); $stmt->bind_param("i", $id); if($stmt->execute()) { $stmt->bind_result($foo, $bar, $what, $why); if($stmt->fetch()) { $stmt->close(); }else{ //error binding result(no rows??) } }else{ //error with query }
Ваш вопрос предполагает, что на вашем локальном сервере установлен MySQL Native driver (MySQLnd) , но MySQL на сервере проекта отсутствует. Потому что get_result()
требует MySQLnd.
Поэтому, если вы все еще хотите использовать get_result()
вместо bind_result()
на сервере школьных проектов, тогда вы должны установить MySQLnd на сервер школьных проектов.
get_result()
теперь доступен только на PHP, установив собственный драйвер MySQL (mysqlnd). В некоторых средах может быть невозможно или желательно установить mysqlnd.
Несмотря на это, вы все равно можете использовать mysqli для выполнения запросов «select *» и получить результаты с именами полей, хотя это немного сложнее, чем использование get_result()
, и включает использование функции call_user_func_array()
php. См. Пример ниже, который выполняет простой запрос «select *» и выводит результаты (с именами столбцов) в таблицу HTML:
$maxaccountid=100; $sql="select * from accounts where account_id<?"; $stmt = $mysqli->prepare($sql); $stmt->bind_param('i', $maxaccountid); $stmt->execute(); print "<table border=1>"; print "<thead><tr>"; $i=0; $meta = $stmt->result_metadata(); $query_data=array(); while ($field = $meta->fetch_field()) { print "<th>" . $field->name . "</th>"; $var = $i; $$var = null; $query_data[$var] = &$$var; $i++; } print "</tr></thead>"; $r=0; call_user_func_array(array($stmt,'bind_result'), $query_data); while ($stmt->fetch()) { print "<tr>"; for ($i=0; $i<count($query_data); $i++) { print "<td>" . $query_data[$i] . "</td>"; } print "</tr>"; $r++; } print "</table>"; $stmt->close(); print $r . " Records<BR>";