Intereting Posts
Чтение PDF-файлов в PHP Проверьте, содержит ли переменная круглые ссылки Получить идентификатор транзакции заказа от authorize.net Авторизовать AIM PHP / mysqli, как узнать о недавно вставленном ID Загрузка изображения из src тега img в php Доступ к данным json из php Функция обратного вызова входа FB не отвечает, если пользователь уже зарегистрирован в facebook Дата отметки времени PHP для пользовательского часового пояса Как установить текстовое значение SimpleXmlElement без использования его родительского элемента? Как удалить расширение из строки (только реальное расширение!) Zend_Auth: разрешить пользователю вход в несколько таблиц / идентификаторов PHP и FFMPEG – Выполнение интеллектуального преобразования видео Что такое функция RECURSIVE в PHP? Компиляция расширения php с Visual Studio 2008, идентификатор MODULE не совпадает с php Сделать PHP исполнять и общаться с Java-приложением на веб-сервере

Переменная количество столбцов, возвращаемых в подготовленном операторе mysqli

У меня есть ситуация, когда создается динамический запрос, который может выбирать от 1 до более 300 разных столбцов в нескольких таблицах. В настоящее время он отлично работает, просто выполняя запрос, однако проблема, с которой я столкнулась в использовании подготовленного оператора, заключается в том, что я не знаю, как справиться с тем, что я не знаю, сколько столбцов я буду запрашивать каждый раз и поэтому не знают, как обрабатывать результаты. Причина, по которой я верю, что оператор привязки поможет, заключается в том, что как только этот запрос запускается один раз, он, скорее всего, (хотя и не всегда) будет запущен снова с теми же параметрами.

В настоящее время у меня есть что-то вроде этого:

$rows = array(); $this->statement = $this->db->prepare($query); $this->statement->bind_param('i',$id); $this->statement->execute(); $this->statement->bind_result($result); while($this->statement->fetch()) { $rows[] = $result; } 

Я знаю, что это не работает, как я хочу, мой вопрос заключается в том, как получить данные обратно из запроса. Возможно ли вернуть столбцы в ассоциативный массив по имени столбца, как стандартный запрос mysqli?

Solutions Collecting From Web of "Переменная количество столбцов, возвращаемых в подготовленном операторе mysqli"

Я не хочу использовать eval , это мое решение (похожее на ashurexm):

 $md = $stmt -> result_metadata(); $fields = $md -> fetch_fields(); $result = new stdClass(); // Actual result object $params = array(); // Array of fields passed to the bind_result method foreach($fields as $field) { $result -> {$field -> name} = null; $params[] = &$result -> {$field -> name}; } call_user_func_array(array($stmt, 'bind_result'), $params); 

Используя предложение mysqli_statement->result_metadata() о mysqli_statement->result_metadata() я смог объединить следующий код, который выполняет то, что я ищу, хотя производительность не быстрее, чем при использовании стандартного запроса. Я получаю statement->result_metadata() для создания ассоциативного массива для вызова bind_result . Я создаю инструкцию bind_result как строку и eval ее. Я знаю, что это не особенно безопасно, но это мой первый проход.

 public function executePreparedStatement() { if($this->statement->execute()) { $this->record = array(); $md = $this->statement->result_metadata(); $fields = $md->fetch_fields(); $bindResult = '$this->statement->bind_result('; foreach($fields as $field) { $bindResult .= "\$this->record['" . $field->name . "'],"; } $bindResult = substr($bindResult,0,strlen($bindResult) - 1) . ');'; eval($bindResult); return true; } else { $this->error = $this->db->error; return false; } } ... $this->prepareStatement($query); $this->bindParameter('i',$runId); if($this->executePreparedStatement()) { $report = new Report(); while($this->statement->fetch()) { $row = $this->record; $line = array(); foreach($row as $key => &$value) { array_push($line,$value); } $report->addLine($line); } return $report } в public function executePreparedStatement() { if($this->statement->execute()) { $this->record = array(); $md = $this->statement->result_metadata(); $fields = $md->fetch_fields(); $bindResult = '$this->statement->bind_result('; foreach($fields as $field) { $bindResult .= "\$this->record['" . $field->name . "'],"; } $bindResult = substr($bindResult,0,strlen($bindResult) - 1) . ');'; eval($bindResult); return true; } else { $this->error = $this->db->error; return false; } } ... $this->prepareStatement($query); $this->bindParameter('i',$runId); if($this->executePreparedStatement()) { $report = new Report(); while($this->statement->fetch()) { $row = $this->record; $line = array(); foreach($row as $key => &$value) { array_push($line,$value); } $report->addLine($line); } return $report } - public function executePreparedStatement() { if($this->statement->execute()) { $this->record = array(); $md = $this->statement->result_metadata(); $fields = $md->fetch_fields(); $bindResult = '$this->statement->bind_result('; foreach($fields as $field) { $bindResult .= "\$this->record['" . $field->name . "'],"; } $bindResult = substr($bindResult,0,strlen($bindResult) - 1) . ');'; eval($bindResult); return true; } else { $this->error = $this->db->error; return false; } } ... $this->prepareStatement($query); $this->bindParameter('i',$runId); if($this->executePreparedStatement()) { $report = new Report(); while($this->statement->fetch()) { $row = $this->record; $line = array(); foreach($row as $key => &$value) { array_push($line,$value); } $report->addLine($line); } return $report } 

Именно по этой причине mysqli никогда не следует использовать с подготовленными операторами.
Таким образом, вы должны использовать PDO вместо этого, что сделает ваш executePreparedStatement () в три строки:

 function executePreparedStatement($sql,$params) { $stm = $this->db->prepare($sql); $stm->execute($params); return $stm->fetchAll(); } - function executePreparedStatement($sql,$params) { $stm = $this->db->prepare($sql); $stm->execute($params); return $stm->fetchAll(); } 

используется так

 $sql = "SELECT * from news WHERE category=?"; $data = $this->executePreparedStatement($sql,$_GET['category']);