Tanımlanmamış yönteme çağrı mysqli_stmt :: get_result


113

İşte kodum:

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

Son satırdaki hatayı şu şekilde alıyorum: Tanımlanmamış yönteme çağrı mysqli_stmt :: get_result ()

İşte conn.php için kod:

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

Bu satırı yazarsam:

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

'İfade hazırlanmamış' yazdırır . Sorguyu doğrudan IDE değiştirerek çalıştırırsam? değerlerle işaretler, iyi çalışıyor. Lütfen $ conn nesnesinin projedeki diğer sorgularda düzgün çalıştığını unutmayın.

Herhangi bir yardım lütfen .......


Ne unuttum düşünüyorum $stmt = $conn->mysqli->stmt_init();?
favoretti

Lütfen bu değişkenlerin $_POST['EmailID'], $_POST['SLA'], $_POST['Password']POST yöntemiyle bir HTML formu kullanılarak doğru bir şekilde gönderilip gönderilmediğini kontrol edin
ajreal

@ajreal: Değişkenler doğru bir şekilde gönderiliyor. Onları print_r ($ _ POST) kullanarak test ettim.
Kumar Kush

@favoretti: $ stmt = $ conn-> mysqli-> stmt_init (); . Hala şans yok.
Kumar Kush

Bahsetmek istediğim bir şey, benzer kodlar kullandığım başka yerlerdir ve iyi çalışıyorlar.
Kumar Kush

Yanıtlar:


146

Lütfen bu yöntem için kullanıcı notlarını okuyun:

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

Mysqlnd sürücüsünü gerektirir ... web alanınızda kurulu değilse, BIND_RESULT & FETCH ile çalışmanız gerekecektir!

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

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


4
Çok teşekkürler. İşe yaradı. I uncommented uzantısı = php_mysqli_mysqlnd.dll olarak php.ini ; ve Apache2.2 ve MySQL hizmetlerini yeniden başlattı. Satır uzantısı = php_mysqli_libmysql.dll'nin açıklamasını kaldırmalı mıyım? Başka bir sayfaya göre mysqlnd, libmysql'den daha hızlıdır. Ayrıca, mysqlnd'nin en popüler barındırma hizmeti sağlayıcılarına yüklenmesini bekleyebilir miyim?
Kumar Kush

1
stmt_init () yalnızca prosedürle ilgili olarak hazırlanmış bir ifade için gereklidir. yani buna ihtiyacınız yok! Bak: bağlantı libmysql gelince : bilmiyorum. Ve mysqlnd.dll'nin kurulumu için barındırma sağlayıcılarına güvenmem ... daha iyi bir çözüm deneyin!
bekay

2
Not: mysqli_stmt::get_result()yalnızca PHP v5.3.0 veya üzeri sürümlerde mevcuttur.
Raptor

4
@bekay Bana yeni bir dizüstü bilgisayar ve yeni bir pencere kurtardın. +10 müsait olsaydı sana verirdim
James Cushing

1
@ kush.impetus, nereden indirirsiniz php_mysqli_mysqlnd.dll? Sadece olurdu php_mysqli.dllbenim de extklasöründe.
Pacerier

51

MySQL Yerli Sürücü (mysqlnd) sürücüsü ve bu nedenle kullanmıyor Yani eğer bind_result ve getir yerine get_result , kod olur:

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

$ stmt-> bind_result benim zamanımı kaydetti. Get_result mevcut olmadığında harika bir çözümdür.
Zafer

2
soru: $ EmailVerfied değişkeni nereden geliyor?
Rotimi

@ Akintunde007: $EmailVerfiedçağrı tarafından oluşturulur bind_result().
AbraCadaver

Kod kullanılarak "Yakalanmamış Hata: Tanımlanmamış bir yönteme çağrı mysqli_stmt :: bind_results ()" hatası alınıyor
Devil's Dream

"Tablo_adından * seçin" gibi bir sql sorgum varsa, bind_result () içinde nasıl bildirilir. * operator
Inderjeet

46

Sisteminizde mysqlnd sürücüsü eksik!

(Debian / Ubuntu tabanlı) sunucunuza yeni paketler yükleyebiliyorsanız, sürücüyü kurun:

sudo apt-get install php5-mysqlnd

ve ardından web sunucunuzu yeniden başlatın:

sudo /etc/init.d/apache2 restart

39

Ben'e bir alternatif arayanlar için $result = $stmt->get_result(), bunu taklit etmenize izin veren $result->fetch_assoc()ancak doğrudan stmt nesnesini kullanarak bu işlevi yaptım :

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

gördüğünüz gibi bir dizi oluşturur ve onu satır verileriyle getirir, çünkü $stmt->fetch()dahili olarak kullandığı için , onu çağıracağınız gibi çağırabilirsiniz mysqli_result::fetch_assoc(sadece $stmtnesnenin açık olduğundan ve sonucun saklandığından emin olun ):

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

Bu, buradaki en kolay yedek cevaptır. Harika çalıştı - teşekkürler!
Alex Coleman

Bana çok zaman kazandırdı!
Jahaziel

3
Eğer $statement->store_result();işlev çağrılmadan önce ihtiyaç vardır, neden sadece işlevinde dahil?
InsanityOnABun

Teşekkür ederim. Kıçımı son teslim tarihine kadar kurtardım
Kolob Canyon

20

PHP sürüm 7.2 ile mysqli yerine nd_mysqli kullandım ve beklendiği gibi çalıştı.

GoDaddy barındırma sunucusuna etkinleştirmek için adımlar-

  1. Cpanel'e giriş yapın.
  2. "PHP sürümünü seç" e tıklayın .
  3. Sağlandığı gibi, en son yapılandırmaların anlık görüntüsü "mysqli" nin işaretini kaldırın ve "nd_mysqli" yi etkinleştirin .

görüntü açıklamasını buraya girin


2
Teşekkür ederim, deliriyordum!
Ussaid Iqbal

1
Haaa, bu benim zamanımı kurtarıyor! Teşekkür ederim kardeşim!
Nurul Huda

1
harika! cPanel için mükemmel cevap
Rashid

1
Çok teşekkür ederim!! Beni kurtar dostum, sana yeterince teşekkür edemem
Enes Çalışkan

Bu cevap en üstte olmalı
Rishabh Gusain

10

Asıl sorunun ne olduğu konusunda bunun zaten yanıtlanmış olduğunu biliyorum, ancak basit bir çözüm önermek istiyorum.

Get_results () yöntemini kullanmak istedim ancak sürücüm yoktu ve bunu ekleyebileceğim bir yerde değilim. Ben aramadan önce

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

Boş bir dizi oluşturdum ve ardından sonuçları bu dizideki anahtarlar olarak bağladım:

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

böylece bu sonuçlar kolaylıkla yöntemlere aktarılabilir veya daha sonra kullanılmak üzere bir nesneye dönüştürülebilir.

Umarım bu, benzer bir şey yapmak isteyen herkese yardımcı olur.


7

Sunucumda da aynı hatayı alıyordum - mysqlnd uzantısı zaten etkinleştirilmiş PHP 7.0 .

Çözüm benim için ( bu sayfa sayesinde ) mysqli uzantısının seçimini kaldırmak ve bunun yerine nd_mysqli'yi seçmekti .

NB - cPanel'inizdeki uzantı seçiciye erişebilirsiniz. (Benimkine PHP Sürümünü Seç seçeneğiyle erişiyorum .)


Kabul edilen cevap bu olmalıdır. Uzantıyı etkinleştirmek, tüm komut dosyanızı başka bir yöntemi kullanmak için düzenlemekten çok daha iyidir! Oh ve benim için çalıştı :)
ArabianMaiden

Ben de aynı sorunu yaşadım. Aslında, PHP'nin session_start()işlevini kullanmak beni var olmayan bir değer gibi yaptı. Sonra sürümüne yükseltilmiş 7.2PHP ve uzatılmasını değişti mysqliüzere nd_mysqli (sabit). Ama iki sorum var, ikisi arasındaki fark nedir? ve bu uzantıyı kullanmak için güvenlikte herhangi bir boşluk olacaksa?
jecorrales

6

Bu soruyla ilgili yeni bir faaliyetin olmasının üzerinden epey zaman geçtiğinin farkındayım. Ancak, diğer yazarların da belirttiği gibi - get_result()artık sadece MySQL yerel sürücüsünü (mysqlnd) yükleyerek PHP'de mevcut ve bazı durumlarda mysqlnd kurmak mümkün veya istenmeyebilir. Yani, bundan böyle işlevselliğini olsun nasıl bilgi ile bu cevabı göndermek için yararlı olacağını düşündüm get_result()kullanmadan - teklifler get_result().

get_result()genellikle fetch_array()bir sonuç kümesinde döngü yapmak ve sonuç kümesinin her satırındaki değerleri sayısal olarak dizinlenmiş veya ilişkilendirilebilir bir dizide depolamak için ile birleştirilmiştir. Örneğin, aşağıdaki kod, bir sonuç kümesi boyunca döngü yapmak için get_result () işlevini kullanarak fetch_array () kullanır ve sayısal olarak dizine alınmış $ data [] dizisindeki her satırdaki değerleri depolar:

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

Bununla birlikte, get_result()mevcut değilse (çünkü mysqlnd kurulu değildir), bu, bir sonuç kümesinin her bir satırındaki değerlerin kullanılmadan bir dizide nasıl saklanacağı sorununa yol açar get_result(). Veya, get_result()onsuz çalıştırmak için kullanan eski kodun nasıl taşınacağı (ör.bind_result() geri kalanını olabildiğince az etkilerken, Bunun yerine ).

Her satırdaki değerleri sayısal olarak indekslenmiş bir dizide saklamanın kullanımının o kadar kolay olmadığı ortaya çıktı bind_result(). bind_result()skaler değişkenlerin bir listesini bekler (bir dizi değil). Bu nedenle, sonuç kümesinin her satırındaki değerleri bir dizide saklamak için biraz şey yapmak gerekir.

Elbette, kod aşağıdaki gibi kolayca değiştirilebilir:

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

Ancak bu, çağrıda $ data [0], $ data [1], vs.'yi ayrı ayrı listelememizi gerektirir bind_result()ki bu ideal değildir. $ Data [0], $ data [1], ... $ data [N-1] (burada N, select ifadesindeki alanların sayısıdır) açıkça listelememizi gerektirmeyen bir çözüm istiyoruz görüşmede bind_results(). Çok sayıda sorgusu olan eski bir uygulamayı taşıyorsak ve her sorgu selectcümlecikte farklı sayıda alan içeriyorsa , geçiş çok yoğun iş gücü gerektirir ve yukarıdaki gibi bir çözüm kullanırsak hataya meyillidir. .

İdeal olarak, sadece get_result()işlevi içeren satırı ve sonraki satırdaki while () döngüsünü değiştirmek için bir 'drop-in değiştirme' kod parçacığı istiyoruz . Değiştirilen kod, while () döngüsünün içindeki satırlar da dahil olmak üzere önceki veya sonraki satırlardan herhangi birini etkilemeden değiştirdiği kodla aynı işleve sahip olmalıdır. İdeal olarak, değiştirme kodunun olabildiğince kompakt olmasını istiyoruz ve değiştirme kodunu select, sorgunun cümlesindeki alanların sayısına bağlı olarak karşılamak zorunda kalmak istemiyoruz .

İnternette arama yaparken, bind_param()birlikte kullanılan bir dizi çözüm buldum call_user_func_array() (örneğin, dinamik olarak mysqli_stmt parametrelerini bağla ve ardından sonucu bağla (PHP) ), ancak bulduğum çoğu çözüm sonuçların sonuçların ilişkilendirilebilir bir dizide depolanmasına yol açtığını değil sayısal olarak indekslenmiş bir dizi ve bu çözümlerin çoğu benim istediğim kadar kompakt değildi ve / veya 'drop-in değişimleri' kadar uygun değildi. Ancak bulduğum örneklerden, faturaya uyan bu çözümü bir araya getirmeyi başardım:

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

Elbette, for () döngüsü daha kompakt hale getirmek için tek bir satıra daraltılabilir.

Umarım bu bind_result(), her satırdaki değerleri sayısal olarak indekslenmiş bir dizide depolamak için bir çözüm arayan ve / veya eski kodu kullanarak geçiş yapmanın bir yolunu arayan herkese yardımcı olur get_result(). Yorumlar hoş geldiniz.


Yupp. 3 yıl önce PDO'ya geçti. Her şekilde teşekkürler.
Kumar Kush

5

İşte benim alternatifim. Öyle nesne yönelimli ve mysql / mysqli şeyler gibi daha fazladır.

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

Kullanımı:

$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

2

Aynı işlevselliği sağlayan iki basit işlev yazdım $stmt->get_result();, ancak bunlar mysqlnd sürücüsüne ihtiyaç duymuyor.

Sadece değiştirirsin

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

ve

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

(Döndürülen satırların sayısını almak için kullanabilirsiniz $stmt->num_rows.)

Sadece yazdığım bu iki işlevi PHP Script'inizde bir yere yerleştirmelisiniz . (örneğin sağ altta)

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

Nasıl çalışır :

$stmt->result_metadata();Kodum, kaç tane ve hangi alanın döndürüldüğünü bulmak için işlevi kullanır ve ardından getirilen sonuçları önceden oluşturulmuş referanslara otomatik olarak bağlar. Tıkır tıkır çalışıyor!


Neden olumsuz oy verildiğine dair hiçbir fikrim yok. Çok iyi çalışıyor - birçok projede kullandım.
Stefan S.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.