Call to undefined method mysqli stmt:: get result

Oto Mój kod:

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();
$result = $stmt->get_result();

W ostatniej linijce pojawia się błąd: wywołanie niezdefiniowanej metody mysqli_stmt:: get_result()

Oto kod dla conn.php:

define('SERVER', 'localhost');
define('USER', 'root');
define('PASS', 'xxxx');
define('DB', 'xxxx');
class Connection{
    /**
     * @var Resource 
     */
    var $mysqli = null;

    function __construct(){
        try{
            if(!$this->mysqli){
                $this->mysqli = new MySQLi(SERVER, USER, PASS, DB);
                if(!$this->mysqli)
                    throw new Exception('Could not create connection using MySQLi', 'NO_CONNECTION');
            }
        }
        catch(Exception $ex){
            echo "ERROR: ".$e->getMessage();
        }
    }
}

Jeśli napiszę tę linijkę:

if(!stmt) echo 'Statement prepared'; else echo 'Statement NOT prepared';

Drukuje 'oświadczenie nie przygotowane' . Jeśli uruchamiam zapytanie bezpośrednio w IDE zastępowanie ? znaki z wartościami, to działa dobrze. Zauważ, że obiekt $conn działa dobrze w innych zapytaniach w projekcie.

Proszę o pomoc.......
 96
Author: kush.impetus, 2011-11-30

9 answers

Proszę przeczytać notatki użytkownika dla tej metody:

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

Wymaga sterownika mysqlnd... jeśli nie jest on zainstalowany w Twojej przestrzeni webowej, będziesz musiał pracować z BIND_RESULT & FETCH!

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

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

 135
Author: bekay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-09 09:42:28

Jeśli więc natywny sterownik MySQL (mysqlnd) nie jest dostępny, a zatem używając bind_result i fetch zamiast get_result , kod staje się:

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
Author: Bert Regelink,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-03 11:06:56

W Twoim systemie brakuje sterownika mysqlnd!

Jeśli jesteś w stanie zainstalować nowe pakiety na swoim serwerze (opartym na Debianie/Ubuntu), zainstaluj sterownik:

sudo apt-get install php5-mysqlnd

A następnie uruchom ponownie serwer WWW:

sudo /etc/init.d/apache2 restart
 42
Author: M_R_K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-21 06:40:30

Dla tych, którzy szukają alternatywy dla $result = stmt->get_result() stworzyłem tę funkcję, która pozwala naśladować $result->fetch_assoc (), ale używając bezpośrednio obiektu 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;
}

Jak widać tworzy tablicę i pobiera ją z danymi wiersza, ponieważ wewnętrznie używa $stmt - >fetch (), można ją wywołać tak, jak można wywołać mysqli_result::fetch_assoc (tylko upewnij się, że obiekt $stmt jest otwarty, a wynik jest przechowywany):

//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();
}
Mam nadzieję, że to pomoże.
 31
Author: MasterKitano,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-17 19:36:05

Wiem, że już na to odpowiedziano, na czym polega rzeczywisty problem, jednak chcę zaoferować proste obejście.

Chciałem użyć metody get_results (), ale nie miałem sterownika i nie jestem gdzieś, gdzie mogę go dodać. Więc zanim zadzwoniłem

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

Utworzyłem pustą tablicę, a następnie po prostu powiązałem wyniki jako klucze w tej tablicy:

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

Aby wyniki te mogły być łatwo przekazywane do metod lub rzucane do obiektu w celu dalszego użyj.

Mam nadzieję, że to pomoże każdemu, kto chce zrobić coś podobnego.
 10
Author: Kirkland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-12 17:24:49

Oto moja alternatywa. On zorientowane obiektowo i jest bardziej jak mysql / mysqli rzeczy.

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();
    }
}

Użycie:

$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
Author: fzyzcjy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-25 01:11:05

Zdaję sobie sprawę, że minęło trochę czasu, odkąd pojawiły się nowe aktywności na ten temat. Ale, jak skomentowały inne plakaty - get_result() jest teraz dostępna tylko w PHP, instalując natywny sterownik MySQL (mysqlnd), aw niektórych przypadkach instalacja mysqlnd może nie być możliwa lub pożądana. Pomyślałem więc, że pomocne będzie zamieszczenie tej odpowiedzi z informacjami o tym, jak uzyskać funkcjonalność, którą oferuje get_result() - bez użycia get_result().

get_result() jest / był często łączony z fetch_array(), aby pętli przez zestaw wyników i przechowuje wartości z każdego wiersza zestawu wyników w tablicy indeksowanej numerycznie lub asocjacyjnej. Na przykład poniższy kod używa get_result() z fetch_array() do pętli przez zestaw wyników, przechowując wartości z każdego wiersza w numerycznie indeksowanej tablicy $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"; 
}

Jeśli jednak get_result() nie jest dostępna (ponieważ mysqlnd nie jest zainstalowany), to prowadzi to do problemu z przechowywaniem wartości z każdego wiersza wyniku ustawionego w tablicy, bez użycia get_result(). Lub, jak przenieść kod starszy, który używa get_result(), aby działać bez niego (np. używając bind_result() zamiast) - przy jak najmniejszym wpływie na resztę kodu.

Okazuje się, że przechowywanie wartości z każdego wiersza w tablicy indeksowanej numerycznie nie jest tak proste przy użyciu bind_result(). bind_result() oczekuje listy zmiennych skalarnych (nie tablicy). Tak więc, trzeba trochę zrobić, aby zapisać wartości z każdego wiersza wyniku ustawionego w tablicy.

Oczywiście, kod może być łatwo zmodyfikowano w następujący sposób:

$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"; 
}

Ale To wymaga od nas jawnej listy $data[0], $data[1], itd. indywidualnie w wezwaniu do bind_result(), co nie jest idealne. Chcemy rozwiązania, które nie wymaga od nas jawnej listy $data[0], $data [1],... $data [N-1] (gdzie N jest liczbą pól w instrukcji select) w wywołaniu bind_results(). Jeśli migrujemy starszą aplikację, która ma dużą liczbę zapytań, a każde zapytanie może zawierać inną liczbę pól w select klauzula, migracja będzie bardzo pracochłonna i podatna na błędy, jeśli użyjemy rozwiązania takiego jak powyższe.

Najlepiej, aby fragment kodu 'drop-in replacement' zastąpił tylko linię zawierającą funkcję get_result() i pętlę while() w następnej linii. Kod zastępczy powinien mieć tę samą funkcję co Kod zastępujący, bez wpływu na którąkolwiek z linii przed lub po - włączając w to linie wewnątrz pętli while (). Idealnie chcemy kod zastępczy ma być jak najbardziej zwarty i nie chcemy, aby Kod zastępczy opierał się na liczbie pól w klauzuli select zapytania.

Szukając w Internecie, znalazłem szereg rozwiązań, które wykorzystują bind_param() z call_user_func_array() (na przykład, dynamicznie binduje parametry mysqli_stmt, a następnie bind result (PHP) ), ale większość rozwiązań, które znalazłem, ostatecznie prowadzi do tego, że wyniki są przechowywane w tablicy asocjacyjnej, a nie numerycznie indeksowanej tablicy, wiele z tych rozwiązań nie było tak kompaktowych, jak bym chciał i / lub nie nadawało się jako "zamienniki typu drop-in". Jednak z przykładów, które znalazłem, udało mi się połączyć To rozwiązanie, które pasuje do ustawy: {]}

$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"; 
}

Oczywiście pętla for() Może być zwinięta w jedną linię, aby uczynić ją bardziej zwartą.

Mam nadzieję, że pomoże to każdemu, kto szuka rozwiązania za pomocą bind_result() do przechowywania wartości z każdego wiersza w tablicy numerycznie indeksowanej i / lub szuka sposobu migracja kodu źródłowego za pomocą get_result(). Komentarze mile widziane.

 5
Author: mti2935,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:01

Napisałem dwie proste funkcje, które dają taką samą funkcjonalność jak $stmt->get_result();, ale nie wymagają sterownika mysqlnd.

Po prostu zastąp

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

I

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

(aby uzyskać liczbę zwróconych wierszy, możesz użyć $stmt->num_rows.)

Wystarczy umieścić te dwie funkcje napisałem gdzieś w Twoim skrypcie PHP. (np. tuż przy bottom)

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;
}

Jak to działa :

Mój kod używa funkcji $stmt->result_metadata();, aby dowiedzieć się, ile i które pola są zwracane, a następnie automatycznie wiąże pobrane wyniki z wcześniej utworzonymi referencjami. Działa jak urok!

 1
Author: Stefan S.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-21 12:02:14

Miałem ten sam błąd na moim serwerze-PHP 7.0 z mysqlnd rozszerzenie już włączone.

Rozwiązanie było dla mnie (dzięki ta strona) polegało na usunięciu zaznaczenia rozszerzenia mysqlii wybraniu nd_mysqli.

NB - możesz mieć dostęp do selektora rozszerzeń w swoim cPanel. (Uzyskuję dostęp do mojej poprzez opcję Select PHP Version.)

 1
Author: ban-geoengineering,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-06 09:24:24