अपरिभाषित विधि के लिए कॉल करें mysqli_stmt :: get_result


113

यहाँ मेरा कोड है:

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

मुझे अंतिम पंक्ति पर त्रुटि मिलती है: अपरिभाषित पद्धति पर कॉल करें mysqli_stmt :: get_result ()

यहाँ con.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();
        }
    }
}

अगर मैं यह पंक्ति लिखूँ:

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

यह 'स्टेटमेंट नॉट रेडी ' प्रिंट करता है । अगर मैं आईडीई के स्थान पर सीधे क्वेरी चलाता हूं? मूल्यों के साथ निशान, यह ठीक काम करता है। कृपया ध्यान दें कि परियोजना में अन्य प्रश्नों में $ कॉन ऑब्जेक्ट ठीक काम करता है।

कोई मदद कृपया ……।


मुझे लगता है कि आप भूल गए $stmt = $conn->mysqli->stmt_init();?
अनुकूली

कृपया जाँचें कि क्या ये चर $_POST['EmailID'], $_POST['SLA'], $_POST['Password']सही तरीके से HTML फॉर्म का उपयोग करके प्रस्तुत किए गए हैं
ajreal

@ असली: चर सही तरीके से पोस्ट किए जा रहे हैं। मैंने Print_r ($ _ POST) का उपयोग करके उनका परीक्षण किया।
कुमार कुश

@favoretti: मैंने $ stmt = $ con-> mysqli-> stmt_init () का उपयोग करने की कोशिश की ; । फिर भी नसीब नहीं।
कुमार कुश

एक बात जिसका मैं उल्लेख करना चाहूंगा, वह यह है कि मैंने इसी तरह के कोड का उपयोग किया है अन्य स्थान हैं और वे ठीक काम करते हैं।
कुमार कुश

जवाबों:


146

कृपया इस विधि के लिए उपयोगकर्ता नोट पढ़ें:

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

इसके लिए mysqlnd ड्राइवर की आवश्यकता होती है ... यदि यह आपके webspace पर स्थापित नहीं है, तो आपको BIND_RESULT & FETCH के साथ काम करना होगा!

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

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


4
बहुत बहुत धन्यवाद। वह काम किया। मैंने php.ini में एक्सटेंशन = php_mysqli_mysqlnd.dll को अनइंस्टॉल किया ; और Apache2.2 और MySQL सेवाओं को पुनः आरंभ किया। क्या मुझे लाइन एक्सटेंशन = php_mysqli_libmysql.dll को असहज करना चाहिए ? एक अन्य पृष्ठ के अनुसार, mysqlnd libmysql से अधिक तेज़ है। इसके अलावा, क्या मैं सबसे लोकप्रिय होस्टिंग सेवा प्रदाताओं पर स्थापित mysqlnd की उम्मीद कर सकता हूं?
कुमार कुश

1
stmt_init () केवल प्रक्रियात्मक तैयार विवरण के लिए आवश्यक है। तो आपको इसकी आवश्यकता नहीं है! देखो: लिंक के रूप में libmysql : पता नहीं है। और मैं mysqlnd.dll की स्थापना के लिए होस्टिंग प्रदाताओं पर भरोसा नहीं करूंगा ... बेहतर कुछ समाधान की कोशिश करो!
बेके डे

2
नोट: mysqli_stmt::get_result()केवल PHP v5.3.0 या इसके बाद के संस्करण पर उपलब्ध है।
रैप्टर

4
@ आप एक नया लैपटॉप और एक नई विंडो सहेज कर रखे हैं। अगर +10 उपलब्ध होते तो मैं आपको दे देता
जेम्स कुशिंग

1
@ kush.impetus, आप कहां डाउनलोड करते हैं php_mysqli_mysqlnd.dll? मैं केवल php_mysqli.dllअपने extफ़ोल्डर में हूँ ।
पचेरियर

51

तो अगर MySQL मूल निवासी चालक (mysqlnd) ड्राइवर उपलब्ध नहीं है, और इसलिए उपयोग कर रहा है bind_result और लाने के बजाय 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();

$ stmt-> bind_result मेरा समय बचता है। यह एक बढ़िया उपाय है जब get_result उपलब्ध नहीं है।
ज़फर

2
प्रश्न: चर $ EmailVerfied कहां से आता है?
रोटिमी

@ Akintunde007: $EmailVerfiedको कॉल द्वारा बनाया गया है bind_result()
AbraCadaver

एक "अनकवर्ड एरर: अपरिभाषित विधि पर कॉल करें mysqli_stmt :: bind_results ()" कोड का उपयोग करके त्रुटि
डेविल्स ड्रीम

यदि मेरे पास "table_name से चयन करें" जैसी sql क्वेरी है तो bind_result () के अंदर कैसे घोषित करें। * ऑपरेटर
इंद्रजीत

46

आपके सिस्टम को mysqlnd ड्राइवर याद आ रहा है!

यदि आप अपने (Debian / Ubuntu- आधारित) सर्वर पर नए पैकेज स्थापित करने में सक्षम हैं, तो ड्राइवर स्थापित करें:

sudo apt-get install php5-mysqlnd

और फिर अपना वेब सर्वर पुनः आरंभ करें:

sudo /etc/init.d/apache2 restart

39

उन लोगों के लिए, $result = $stmt->get_result()जिन्होंने इस समारोह के लिए एक विकल्प की खोज की है, जो आपको $result->fetch_assoc()सीधे नकल वस्तु का उपयोग करने की अनुमति देता है :

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

यह सबसे आसान ड्रॉप-इन प्रतिस्थापन उत्तर है। महान काम किया - धन्यवाद!
एलेक्स कोलमैन

मुझे बहुत समय बचा लिया!
जाहजिल

3
यदि $statement->store_result();फ़ंक्शन को कॉल करने से पहले आवश्यक है, तो इसे फ़ंक्शन में शामिल क्यों न करें?
इन्सानिटीऑनबून

धन्यवाद। बस एक समय सीमा पर मेरे गधे को बचाया
Kolob Canyon

20

PHP के संस्करण 7.2 के साथ मैंने सिर्फ mysqli के बजाय nd_mysqli का उपयोग किया और यह उम्मीद के मुताबिक काम किया।

गोडैडी होस्टिंग सर्वर में इसे सक्षम करने के लिए कदम-

  1. Cpanel में लॉगिन करें।
  2. "PHP संस्करण चुनें" पर क्लिक करें
  3. जैसा कि नवीनतम विन्यास का स्नैपशॉट "mysqli" को अनचेक करता है और "nd_mysqli" को सक्षम करता है ।

यहां छवि विवरण दर्ज करें


2
थैंक यू, मैं पागल हो रहा था!
उस्सैद इकबाल

1
हा, यह मेरा समय बचाता है! धन्यवाद!
नुरुल हुदा

1
महान! cPanel का सही उत्तर
रशीद

1
बहुत बहुत धन्यवाद!! तुम मुझे बचाओ यार, मैं तुम्हें बहुत धन्यवाद नहीं दे सकता
Enes ıalışkan

यह उत्तर शीर्ष पर होना चाहिए
ऋषभ गुसाईं

10

मुझे पता है कि यह पहले से ही उत्तर दिया गया था कि वास्तविक समस्या क्या है, हालांकि मैं एक सरल समाधान प्रस्तुत करना चाहता हूं।

मैं get_results () विधि का उपयोग करना चाहता था, हालांकि मेरे पास ड्राइवर नहीं था, और मैं कहीं नहीं हूं कि मुझे जोड़ा जा सके। इसलिए, पहले मैंने फोन किया

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

मैंने एक खाली सरणी बनाई, और फिर परिणाम को उस सरणी में कुंजियों के रूप में बांधा:

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

ताकि उन परिणामों को आसानी से तरीकों में पारित किया जा सके या आगे उपयोग के लिए किसी वस्तु में डाला जा सके।

आशा है कि यह किसी की मदद करता है जो कुछ ऐसा ही करना चाहता है।


7

मैं अपने सर्वर पर यही त्रुटि प्राप्त कर रहा था - पहले से सक्षम mysqlnd एक्सटेंशन के साथ PHP 7.0 ।

समाधान मेरे लिए था ( इस पृष्ठ के लिए धन्यवाद ) के बजाय mysqli एक्सटेंशन का चयन करना और nd_mysqli का चयन करना था।

NB - आप अपने cPanel में एक्सटेंशन चयनकर्ता तक पहुंचने में सक्षम हो सकते हैं। (मैं PHP संस्करण विकल्प का चयन करके मेरा उपयोग करता हूं ।)


यह स्वीकृत उत्तर होना चाहिए। किसी अन्य विधि का उपयोग करने के लिए अपनी पूरी स्क्रिप्ट को संपादित करने की तुलना में एक्सटेंशन को सक्षम करने के लिए बहुत बेहतर है! ओह, और इसने मेरे लिए काम किया :)
अरेबियनमैन

मुझे भी यही समस्या थी। वास्तव में, PHP के session_start()फ़ंक्शन का उपयोग करके मुझे एक गैर-मौजूद मूल्य की तरह बनाया गया था। तब मैं संस्करण में उन्नत 7.2PHP के और के विस्तार बदल mysqliकरने के लिए nd_mysqli (निर्धारित)। लेकिन, मेरे दो सवाल हैं, दोनों में क्या अंतर है? और अगर उस विस्तार का उपयोग करने के लिए सुरक्षा में कोई अंतर होगा?
jecorrales

6

मुझे एहसास है कि इस सवाल पर कोई नई गतिविधि होने के बाद से कुछ समय हो गया है। लेकिन, जैसा कि अन्य पोस्टरों ने टिप्पणी की है - get_result()अब केवल MySQL के मूल चालक (mysqlnd) को स्थापित करके PHP में उपलब्ध है, और कुछ मामलों में, mysqlnd को स्थापित करना संभव या वांछनीय नहीं हो सकता है। इसलिए, मुझे लगा कि इस उत्तर को इस जानकारी के साथ पोस्ट करना उपयोगी होगा कि कैसे कार्यक्षमता मिलती है get_result()- बिना उपयोग के get_result()

get_result()/ / को अक्सर fetch_array()परिणाम सेट के माध्यम से लूप के साथ जोड़ा जाता था और एक संख्यात्मक रूप से अनुक्रमित या साहचर्य सरणी में सेट किए गए परिणाम की प्रत्येक पंक्ति से मूल्यों को संग्रहीत करता है। उदाहरण के लिए, नीचे दिया गया कोड एक परिणाम सेट के माध्यम से प्राप्त करने के लिए get_result () with fetch_array () का उपयोग करता है, प्रत्येक पंक्ति से मानों को संख्यात्मक रूप से अनुक्रमित $ डेटा [] सरणी में संग्रहीत करता है:

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

लेकिन, इसके लिए हमें कॉल में व्यक्तिगत रूप से कॉल करने के लिए $ डेटा [0], $ डेटा [1] आदि को स्पष्ट रूप से सूचीबद्ध करना होगा bind_result(), जो आदर्श नहीं है। हम एक ऐसा समाधान चाहते हैं जिसके लिए हमें स्पष्ट रूप से $ डेटा [0], $ डेटा [1], ... $ डेटा [N-1] (जहाँ N, चयन कथन में फ़ील्ड की संख्या हो) को सूचीबद्ध करने की आवश्यकता नहीं है करने के लिए कॉल में bind_results()। यदि हम एक ऐसी विरासत एप्लिकेशन का माइग्रेशन कर रहे हैं जिसमें बड़ी संख्या में क्वेरीज़ हैं, और प्रत्येक क्वेरी में selectक्लॉज़ में अलग-अलग फ़ील्ड हो सकती हैं , तो माइग्रेशन बहुत ही सघन होगा और यदि हम ऊपर दिए गए समाधान का उपयोग करते हैं तो त्रुटि का खतरा होगा ।

आदर्श रूप में, हम 'ड्रॉप-इन रिप्लेसमेंट' कोड का एक स्निपेट चाहते हैं - get_result()अगली पंक्ति में फ़ंक्शन और जबकि () लूप वाली बस लाइन को बदलने के लिए । प्रतिस्थापन कोड में समान फ़ंक्शन होना चाहिए जो कोड को बदल रहा है, पहले किसी भी रेखा को प्रभावित किए बिना, या बाद में लाइनों में से किसी को प्रभावित किए बिना - जबकि () लूप के अंदर की पंक्तियों सहित। आदर्श रूप से हम चाहते हैं कि प्रतिस्थापन कोड जितना संभव हो उतना कॉम्पैक्ट हो, और हम 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"; 
}

बेशक, () लूप को अधिक कॉम्पैक्ट बनाने के लिए एक पंक्ति में ढहाया जा सकता है।

मुझे आशा है कि यह किसी को भी मदद करता है जो bind_result()प्रत्येक पंक्ति से मानों को संख्यात्मक रूप से अनुक्रमित सरणी में संग्रहीत करने के लिए एक समाधान का उपयोग कर रहा है और / या विरासत कोड का उपयोग करने के लिए एक तरीका खोज रहा है get_result()। टिप्पणियाँ स्वागत है।


Yupp। 3 साल पहले पीडीओ में स्थानांतरित कर दिया गया। फिर भी धन्यवाद।
कुमार कुश

5

यहाँ मेरा विकल्प है। यह ऑब्जेक्ट-ओरिएंटेड है और अधिक 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

2

मैंने दो सरल कार्य लिखे हैं जो समान कार्यक्षमता देते हैं $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();फ़ंक्शन का उपयोग यह पता लगाने के लिए करता है कि कितने और कौन से फ़ील्ड वापस किए गए हैं और फिर स्वचालित रूप से पहले से बनाए गए संदर्भों के लिए प्राप्त परिणामों को बांधता है। एक जादू की तरह काम करता है!


पता नहीं क्यों इसे नीचा दिखाया गया था। यह बहुत अच्छी तरह से काम करता है - मैंने कई परियोजनाओं में इसका इस्तेमाल किया है।
स्टीफन एस।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.