未定義のメソッド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()の呼び出し

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

この行を書くと:

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

「ステートメントが準備されていません」と出力されます。IDEでクエリを直接実行すると、置き換えられますか?値でマークを付けると、正常に動作します。$ connオブジェクトは、プロジェクトの他のクエリで正常に機能することに注意してください。

何か助けてください.......


忘れたと思う$stmt = $conn->mysqli->stmt_init();
favoretti

これらの変数を確認してください $_POST['EmailID'], $_POST['SLA'], $_POST['Password']POSTメソッドでHTMLフォームを使用しが正しく送信されて
ajreal

@ajreal:変数は正しくポストされています。print_r($ _ POST)を使用してテストしました。
Kumar Kush

@favoretti:$ stmt = $ conn-> mysqli-> stmt_init();を使用してみました 。まだ運がない。
Kumar Kush

私が言及したいことの1つは、私が同様のコードを使用したことが他の場所であり、それらがうまく機能することです。
Kumar Kush

回答:


146

このメソッドのユーザーノートをお読みください:

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

mysqlndドライバーが必要です...それがウェブスペースにインストールされていない場合は、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のextension = php_mysqli_mysqlnd.dllのコメントを外しました。Apache2.2とMySQLサービスを再起動しました。extension = php_mysqli_libmysql.dllという行のコメントを外す必要がありますか?別のページのように、mysqlndはlibmysqlよりも高速です。また、mysqlndが最も人気のあるホスティングサービスプロバイダーにインストールされることを期待できますか?
Kumar Kush

1
stmt_init()は、手続き型の準備済みステートメントでのみ必要です。だからあなたはそれを必要としません!見て:リンクlibmysqlについては:わからない。そして、私はmysqlnd.dllのインストールのためにホスティングプロバイダーを当てにしません...いくつかの回避策を試してください!
ベケイ

2
注:mysqli_stmt::get_result()は、PHP v5.3.0以降でのみ使用できます。
ラプター

4
@bekayあなたは私に新しいラップトップと新しいウィンドウを保存しました。+10が利用可能だった場合、それを提供します
James Cushing

1
@ kush.impetus、どこからダウンロードしますphp_mysqli_mysqlnd.dllか?私php_mysqli.dllは自分のextフォルダにのみ持っ ています。
パセリエ2015年

51

したがって、MySQLネイティブドライバー(mysqlnd)ドライバーが使用できない場合、したがってget_resultの代わりにbind_resultおよびfetchを使用すると、コードは次のようになります。

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が利用できない場合に最適なソリューションです。
Zafer、2015

2
質問:$ EmailVerfied変数はどこから来たのですか?
ロティミ2017

@ Akintunde007:$EmailVerfiedへの呼び出しによって作成されますbind_result()
AbraCadaver

コードを使用して「Uncaught Error:Call to undefined method mysqli_stmt :: bind_results()」エラーを取得する
Devil's Dream

「select * from table_name」のようなSQLクエリがある場合、bind_result()内で宣言する方法。*オペレーター
Inderjeet

46

システムにmysqlndドライバーがありません!

(Debian / Ubuntuベースの)サーバーに新しいパッケージをインストールできる場合は、ドライバーをインストールします。

sudo apt-get install php5-mysqlnd

次にWebサーバーを再起動します。

sudo /etc/init.d/apache2 restart

39

の代わりを探している人のために、stmtオブジェクトを直接使用して、$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();
}

これは、ここで最も簡単なドロップイン交換の答えです。よくできました–ありがとうございます!
Alex Coleman

時間を大幅に節約できました。
Jahaziel 2016年

3
$statement->store_result();関数を呼び出す前に必要な場合は、それを関数に含めるだけではどうですか?
InsanityOnABun

ありがとうございました。ちょうど締め切りに私のお尻を救った
Kolob Canyon

20

PHPのバージョン7.2で、私はちょうど使用nd_mysqliの代わりにmysqliのと期待どおりに働きました。

godaddyホスティングサーバーにそれを有効にする手順-

  1. cpanelにログインします。
  2. 「Select PHP version」をクリックします。
  3. 最新の構成のスナップショットを提供されるようにチェックを外し、「mysqliのを」と有効「nd_mysqli」

ここに画像の説明を入力してください


2
ありがとう、頭がおかしくなりました!
Ussaid Iqbal

1
Haaa、これは私の時間を節約します!ブローありがとう!
Nurul Huda

1
すごい!cPanelの完全な回答
Rashid

1
どうもありがとうございます!!あなたは私の男を救う、私はあなたに十分に感謝することはできません
EnesÇalışkan13:

この回答は最上位にある必要があります
リシャブグサイン

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を選択することでした。

注意-cPanelの拡張機能セレクタにアクセスできる場合があります。(私は[PHPバージョンの選択]オプションからアクセスします。)


これは受け入れられる答えになるはずです。スクリプト全体を編集して別の方法を使用するよりも、拡張機能を有効にする方がはるかに優れています。ああ、それは私のために働いた:)
ArabianMaiden

私も同じ問題を抱えていました。実際、PHPのsession_start()関数を使用すると、存在しない値のようになりました。次に7.2、PHPのバージョンにアップグレードし、拡張子mysqlind_mysqli (修正済み)に変更しました 。しかし、私は2つの質問があります。2つの違いは何ですか?そして、その拡張機能を使用するためのセキュリティにギャップがある場合はどうなりますか?
jecorrales

6

この質問について何か新しい活動があったので久しぶりだと思います。しかし、他の投稿者がコメントしたget_result()ように、MySQLネイティブドライバー(mysqlnd)をインストールすることによってPHPでのみ利用可能になり、場合によっては、mysqlndをインストールすることが不可能または望ましくない場合があります。だから、私はこの答えを、get_result()提供する機能をどのように得るかについての情報とともに投稿することは役立つだろうと思いました-を使わずにget_result()

get_result()is / wasと組み合わせて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()ループを1行にまとめてコンパクトにすることもできます。

これがbind_result()、数値インデックス配列に各行の値を格納するために使用するソリューションを探している、および/またはを使用してレガシーコードを移行する方法を探しているすべての人に役立つことを願っていますget_result()。コメントを歓迎します。


ユップ。3年前にPDOに移行しました。とにかく、ありがとう。
Kumar Kush

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

と同じ機能を提供する2つの単純な関数を作成しました$stmt->get_result();が、mysqlndドライバーは必要ありません。

単に交換する

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

そして

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

(返される行の数を取得するには、を使用できます$stmt->num_rows。)

私が書いたこれら2つの関数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();関数を使用して返されるフィールドの数とフィールドを特定し、取得した結果を事前に作成された参照に自動的にバインドします。魅力的な作品!


なぜ反対票が投じられたのかわかりません。それは非常にうまく機能します-私は多くのプロジェクトで使用しました。
Stefan S.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.