PHP вызов неопределенного метода mysqli_stmt :: get_result () [duplicate]

Каждый открытый файл имеет связанную позицию. Когда вы читаете (), вы читаете с этой позиции. Например, read(10) считывает первые 10 байт из вновь открытого файла, затем другой read(10) считывает следующие 10 байтов. read() без аргументов считывает все содержимое файла, оставляя позицию файла в конце файла. В следующий раз, когда вы вызываете read(), читать нечего.

Вы можете использовать seek для перемещения позиции файла. Или, вероятно, лучше в вашем случае было бы сделать один read() и сохранить результат для обоих поисков.

98
задан kush.impetus 30 November 2011 в 06:38
поделиться

10 ответов

Пожалуйста, прочтите примечания пользователя для этого метода:

http://php.net/manual/en/mysqli-stmt.get-result.php

Требуется драйвер mysqlnd ... если он не установлен на вашем веб-пространстве, вам придется работать с BIND_RESULT & amp; FETCH!

https://secure.php.net/manual/en/mysqli-stmt.bind-result.php

https : //secure.php.net/manual/en/mysqli-stmt.fetch.php

133
ответ дан Matt Gibson 17 August 2018 в 20:20
поделиться
  • 1
    Большое спасибо. Это сработало. Я раскомментировал расширение = php_mysqli_mysqlnd.dll в php.ini ; и перезапустили службы Apache2.2 и MySQL. Должен ли я раскомментировать строку extension = php_mysqli_libmysql.dll ? Как и на другой странице, mysqlnd быстрее libmysql. Кроме того, могу ли я ожидать, что mysqlnd будет установлен на большинстве популярных хостинг-провайдеров? – kush.impetus 1 December 2011 в 19:05
  • 2
    stmt_init () требуется только для процедурного подготовленного оператора. так что вам это не нужно! Посмотрите: link Что касается libmysql : не знаю. И я не буду рассчитывать на хостинг-провайдеров для установки mysqlnd.dll ... лучше попробуйте обходное решение! – bekay 1 December 2011 в 19:32
  • 3
    Примечание. mysqli_stmt::get_result() доступен только на PHP версии 5.0 или выше. – Raptor 28 November 2012 в 15:54
  • 4
    @bekay Вы только что спасли мне новый ноутбук и новое окно. Если бы было доступно +10, я бы дал вам это – James Cushing 24 April 2014 в 11:59
  • 5
    @ kush.impetus, где вы загружаете php_mysqli_mysqlnd.dll? У меня было бы php_mysqli.dll в моей папке ext. – Pacerier 29 June 2015 в 10:07

Я получал эту же ошибку на своем сервере - PHP 7.0 с расширением mysqlnd уже включен.

Решение было для меня (благодаря этой странице ) было отменять выбор mysqli и выберите nd_mysqli.

Примечание. Вы можете иметь доступ к селектору расширений в вашей cPanel. (Я получаю доступ к моей версии через опцию «Выбрать версию PHP».)

1
ответ дан ban-geoengineering 17 August 2018 в 20:20
поделиться

Итак, если драйвер MySQL Native Driver (mysqlnd) недоступен, и поэтому с помощью bind_result и fetch вместо get_result код становится:

include 'conn.php';
$conn = new Connection();
$query = 'SELECT EmailVerified, Blocked FROM users WHERE Email = ? AND SLA = ? AND `Password` = ?';
$stmt = $conn->mysqli->prepare($query);
$stmt->bind_param('sss', $_POST['EmailID'], $_POST['SLA'], $_POST['Password']);
$stmt->execute();
$stmt->bind_result($EmailVerified, $Blocked);
while ($stmt->fetch())
{
   /* Use $EmailVerified and $Blocked */
}
$stmt->close();
$conn->mysqli->close();
42
ответ дан Bert Regelink 17 August 2018 в 20:20
поделиться
  • 1
    $ stmt- & gt; bind_result сохраняется мое время. Это отличное решение, когда get_result недоступен. – Zafer 11 February 2015 в 20:38
  • 2
    вопрос: откуда взялась переменная $ EmailVerfied? – Rotimi Olawale 27 February 2017 в 14:19
  • 3
    @ Akintunde007: $EmailVerfied создается вызовом bind_result(). – AbraCadaver 24 January 2018 в 19:54
  • 4
    Получение «Неуправляемая ошибка: вызов неопределенного метода mysqli_stmt :: bind_results () & quot; с помощью кода – Devil's Dream 20 February 2018 в 09:53
  • 5
    Если у меня есть запрос sql, например «Выбрать» из table_name & quot; то как объявить внутри bind_result (). * оператор – Inderjeet 7 August 2018 в 08:27

В вашей системе отсутствует драйвер mysqlnd!

Если вы можете установить новые пакеты на своем (на сервере Debian / Ubuntu), установите драйвер:

sudo apt-get install php5-mysqlnd

, а затем перезапустите веб-сервер:

sudo /etc/init.d/apache2 restart
42
ответ дан Cody Gray 17 August 2018 в 20:20
поделиться

Я понимаю, что прошло какое-то время, поскольку в этом вопросе была новая деятельность. Но, как комментировали другие плакаты, get_result() теперь доступен только на PHP, установив собственный драйвер MySQL (mysqlnd), и в некоторых случаях может оказаться невозможным или желательным установить mysqlnd. Итак, я подумал, что было бы полезно опубликовать этот ответ с информацией о том, как получить функциональность, предлагаемую get_result(), - без использования get_result().

get_result() / часто сочетается с fetch_array() прокручивать результирующий набор и сохранять значения из каждой строки результирующего набора в числовом индексированном или ассоциативном массиве. Например, приведенный ниже код использует get_result () с fetch_array () для циклического преобразования в результирующий набор, сохраняя значения из каждой строки в числовом индексированном массиве $ data []:

$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);                 
$stmt->bind_param('i', $c);                                             
$stmt->execute();
$result = $stmt->get_result();       
while($data = $result->fetch_array(MYSQLI_NUM)) {
   print $data[0] . ', ' . $data[1] . "<BR>\n"; 
}

Однако, если get_result() недоступен (поскольку mysqlnd не установлен), это приводит к проблеме сохранения значений из каждой строки результирующего набора в массиве без использования get_result(). Или, как переносить устаревший код, который использует get_result() для запуска без него (например, используя bind_result() вместо этого), - как можно меньше воздействовать на остальную часть кода.

Оказывается, что сохранение значения из каждой строки в массиве с числовой индексацией не так прямолинейны, используя bind_result(). bind_result() ожидает список скалярных переменных (а не массив). Таким образом, требуется некоторое выполнение, чтобы сохранить значения из каждой строки результирующего набора в массиве.

Конечно, код можно легко изменить следующим образом:

$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);                 
$stmt->bind_param('i', $c);                                             
$stmt->execute();
$stmt->bind_result($data[0], $data[1]);
while ($stmt->fetch()) {
   print $data[0] . ', ' . $data[1] . "<BR>\n"; 
}

Но для этого требуется, чтобы явным образом перечислял $ data [0], $ data [1] и т. д. индивидуально в вызове bind_result(), что не является идеальным. Мы хотим, чтобы решение, которое не требует, чтобы явным образом перечислил $ data [0], $ data [1], ... $ data [N-1] (где N - количество полей в инструкции select) в вызове bind_results(). Если мы переносим устаревшее приложение с большим количеством запросов, и каждый запрос может содержать другое количество полей в предложении select, миграция будет очень трудоемкой и подверженной ошибкам, если мы используем такое решение, как

В идеале нам нужен фрагмент кода «замены замены», чтобы заменить только строку, содержащую функцию get_result(), и цикл while () на следующей строке. Код замены должен иметь ту же функцию, что и код, который он заменяет, не затрагивая ни одну из строк раньше или любую из строк после - включая строки внутри цикла while (). В идеале мы хотим, чтобы код замены был как можно более компактным, и мы не хотим, чтобы код замены был заменен на количество полей в предложении select запроса.

Поиск в Интернете я нашел ряд решений, которые используют bind_param() с call_user_func_array() (например, Динамически связывают параметры mysqli_stmt, а затем связывают результат (PHP) ), но большинство решений, которые я нашел в конечном итоге приводят к сохранению результатов в ассоциативном массиве, а не в численном индексировании массива, и многие из этих решений были не такими компактными, как я хотел бы и / или не были бы пригодны в качестве «замены для замены». Однако из приведенных мною примеров я смог собрать это решение, которое соответствует счету:

$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);                 
$stmt->bind_param('i', $c);                                             
$stmt->execute();
$data=array();
for ($i=0;$i<$mysqli->field_count;$i++) { 
    $var = $i;
    $$var = null; 
    $data[$var] = &$$var; 
}
call_user_func_array(array($stmt,'bind_result'), $data);
while ($stmt->fetch()) {
   print $data[0] . ', ' . $data[1] . "<BR>\n"; 
}

Конечно, цикл for () может быть свернут в одну строку, чтобы сделать это более компактный.

Надеюсь, это поможет любому, кто ищет решение, используя bind_result() для хранения значений из каждой строки в массиве с числовой индексацией и / или ищет способ переноса устаревшего кода с помощью get_result() , Комментарии приветствуются.

5
ответ дан Community 17 August 2018 в 20:20
поделиться

Вот моя альтернатива. Это объектно-ориентированное и больше похоже на вещи mysql / mysqli.

class MMySqliStmt{
    private $stmt;
    private $row;

    public function __construct($stmt){
        $this->stmt = $stmt;
        $md = $stmt->result_metadata();
        $params = array();
        while($field = $md->fetch_field()) {
            $params[] = &$this->row[$field->name];
        }
        call_user_func_array(array($stmt, 'bind_result'), $params) or die('Sql Error');
    }

    public function fetch_array(){
        if($this->stmt->fetch()){
            $result = array();
            foreach($this->row as $k => $v){
                $result[$k] = $v;
            }
            return $result;
        }else{
            return false;
        }
    }

    public function free(){
        $this->stmt->close();
    }
}

Использование:

$stmt = $conn->prepare($str);
//...bind_param... and so on
if(!$stmt->execute())die('Mysql Query(Execute) Error : '.$str);
$result = new MMySqliStmt($stmt);
while($row = $result->fetch_array()){
    array_push($arr, $row);
    //for example, use $row['id']
}
$result->free();
//for example, use the $arr
5
ответ дан fzyzcjy 17 August 2018 в 20:20
поделиться

для тех, кто ищет альтернативу $ result = stmt-> get_result () Я сделал эту функцию, которая позволяет вам имитировать $ result-> fetch_assoc (), но напрямую используя объект stmt:

function fetchAssocStatement($stmt)
{
    if($stmt->num_rows>0)
    {
        $result = array();
        $md = $stmt->result_metadata();
        $params = array();
        while($field = $md->fetch_field()) {
            $params[] = &$result[$field->name];
        }
        call_user_func_array(array($stmt, 'bind_result'), $params);
        if($stmt->fetch())
            return $result;
    }

    return null;
}

, поскольку вы можете видеть, что он создает массив и извлекает его с данными строки, поскольку он использует внутреннюю оболочку $ stmt-> fetch (), вы можете вызвать ее так же, как вы бы вызвали mysqli_result :: fetch_assoc (просто убедитесь что объект $ stmt открыт и результат сохраняется):

//mysqliConnection is your mysqli connection object
if($stmt = $mysqli_connection->prepare($query))
{
    $stmt->execute();
    $stmt->store_result();

    while($assoc_array = fetchAssocStatement($stmt))
    {
        //do your magic
    }

    $stmt->close();
}

надеюсь, что это поможет.

31
ответ дан Ĭsααc tիε βöss 17 August 2018 в 20:20
поделиться
  • 1
    Это самый простой ответ на замену. Работал отлично - спасибо! – Alex Coleman 23 September 2015 в 02:14
  • 2
    Спасла здесь большую головную боль, спасибо! – coopwatts 9 February 2016 в 10:27
  • 3
    Сэкономил мне много времени! – Jahaziel 21 March 2016 в 17:50
  • 4
    отлично поработал для меня +1 спасибо – RozzA 19 July 2016 в 02:30
  • 5
    Если для вызова функции требуется $statement->store_result();, почему бы просто не включить ее в функцию? – InsanityOnABun 18 August 2016 в 20:01

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

Я хотел использовать метод get_results (), однако у меня не было драйвера , и я не где-то, я могу добавить это. Итак, прежде чем я позвонил

$stmt->bind_results($var1,$var2,$var3,$var4...etc);

, я создал пустой массив и просто привязал результаты как ключи в этом массиве:

$result = array();
$stmt->bind_results($result['var1'],$result['var2'],$result['var3'],$result['var4']...etc);

, чтобы эти результаты могли быть легко переданы в методы или переданы объекту для дальнейшего использования.

Надеюсь, это поможет любому, кто хочет сделать что-то подобное.

10
ответ дан Kirkland 17 August 2018 в 20:20
поделиться

Я написал две простые функции, которые дают ту же функциональность, что и $stmt->get_result();, но они не требуют драйвера mysqlnd.

Вы просто замените

$result = $stmt->get_result(); на $fields = bindAll($stmt);

и

$row= $stmt->get_result(); с $row = fetchRowAssoc($stmt, $fields);.

(Чтобы получить числа возвращаемых строк, вы можете использовать $stmt->num_rows.)

Вам просто нужно разместить эти две функции, которые я написал где-то в вашем PHP-скрипте. (например, справа внизу)

function bindAll($stmt) {
    $meta = $stmt->result_metadata();
    $fields = array();
    $fieldRefs = array();
    while ($field = $meta->fetch_field())
    {
        $fields[$field->name] = "";
        $fieldRefs[] = &$fields[$field->name];
    }

    call_user_func_array(array($stmt, 'bind_result'), $fieldRefs);
    $stmt->store_result();
    //var_dump($fields);
    return $fields;
}

function fetchRowAssoc($stmt, &$fields) {
    if ($stmt->fetch()) {
        return $fields;
    }
    return false;
}

Как это работает :

В моем коде используется функция $stmt->result_metadata();, чтобы выяснить, сколько и какие поля возвращаются, а затем автоматически привязывает полученные результаты к предварительно созданным ссылкам. Работает как очарование!

1
ответ дан Stefan S. 17 August 2018 в 20:20
поделиться
  • 1
    Не знаю, почему это было приостановлено. Он работает очень хорошо - я использовал его во многих проектах. – Stefan S. 5 March 2018 в 05:01
0
ответ дан IRSHAD 29 October 2018 в 19:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: