mysqli_fetch_assoc()はパラメーターを期待しています/メンバー関数の呼び出しbind_param()エラー。実際のmysqlエラーを取得して修正するにはどうすればよいですか?


109

私のローカル/開発環境では、MySQLiクエリは正常に実行されています。しかし、Webホスト環境にアップロードすると、次のエラーが発生します。

致命的なエラー:非オブジェクトのメンバー関数bind_param()の呼び出し...

これがコードです:

global $mysqli;
$stmt = $mysqli->prepare("SELECT id, description FROM tbl_page_answer_category WHERE cur_own_id = ?");
$stmt->bind_param('i', $cur_id);
$stmt->execute();
$stmt->bind_result($uid, $desc);

クエリを確認するために、コントロールパネルのphpMyAdminからクエリを実行しようとしましたが、結果はOKです。


$mysqli変数を開始する場所を確認できますか?
リケシュ2014年

MySQLユーザーにSELECTクエリを実行する権限がない可能性があります。確認しましたか?
Amal Murali 14年

思い浮かぶのは、利用可能なmysqliがないか、MySQLに接続するために間違った認証情報を提供したことです。
NB 2014年

@YourCommonSense-古いタイトルでは、重複する参照についてこの質問を見つけるのが簡単でした。
Paul Spiegel

@Paulはい、これも私の最大の関心事です。Googleの検索と全体的な認識のために、タイトルを変更しました。平均的なPHPユーザーの場合、コードとさまざまな環境との関係は不明です。しかし、それ以来、私もそれを見つけるのに苦労しています。ブックマークに入れてしまう。認識できるが関連性のあるタイトルを提案できるなら、それは素晴らしいことです
常識

回答:


123

MySQLiコードが次のようなエラーを生成することがありますmysqli_fetch_assoc() expects parameter...Call to a member function bind_param()...または類似しました。または、エラーがなくても、クエリがまったく機能しない。これは、クエリの実行に失敗したことを意味します。

クエリが失敗するたびに、MySQLには理由を説明するエラーメッセージが表示されます。残念ながら、デフォルトではこのようなエラーはPHPに転送されず、上記の不可解なエラーメッセージしか表示されません。したがって、MySQLエラーを報告するようにPHPとMySQLiを設定することが非常に重要です。エラーメッセージが表示されたら、簡単に修正できます。

MySQLiでエラーメッセージを取得する方法

まず最初に、MySQLiがすべての環境で接続する前に、常に次の行を用意しください。

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

その後、すべてのMySQLエラーはPHP例外に転送されます。キャッチされなかった例外は、PHPの致命的なエラーになります。したがって、MySQLエラーの場合、従来のPHPエラーが発生します。これにより、エラーの原因がすぐにわかります。スタックトレースは、エラーが発生した正確な場所にあなたを導きます。

異なる環境でPHPを構成する方法

PHPエラー報告に関する私の記事の要点は次のとおり
です。開発サーバーとライブサーバーのエラー報告は異なる必要があります。開発サーバーではエラーを画面に表示すると便利ですが、ライブサーバーではエラーメッセージをログに記録する必要があるため、後でエラーログでエラーを見つけることができます。

したがって、対応する構成オプションを次の値に設定する必要があります。

  • 開発サーバー

    • error_reporting に設定する必要があります E_ALL値ます。
    • log_errors 1に設定する必要があります(開発用PCにもログがあると便利です)
    • display_errors 1に設定する必要があります
  • 本番サーバー

    • error_reportingE_ALL値に設定する必要があります。
    • log_errors 1に設定する必要があります
    • display_errors 0に設定する必要があります

実際の使い方は?

ちょうど任意のコードを削除することを手動でエラーをチェックし、すべてのものor die()if ($result)など。すぐにデータベース相互作用コードを書いてください:

$stmt = $this->con->prepare("INSERT INTO table(name, quantity) VALUES (?,?)");
$stmt->bind_param("si", $name, $quantity);
$stmt->execute();

再び、周りの条件なしで。エラーが発生した場合は、コード内の他のエラーとして処理されます。たとえば、開発用PCでは画面に表示されるだけですが、ライブサイトではプログラマーのためにログに記録されますが、ユーザーの便宜のためにエラーハンドラーを使用することもできます(ただし、これは別の話です。 MySQLi、ただし上記のリンク先の記事でそれについて読むことができます)。

表示されるエラーメッセージをどうするか

まず、問題のあるクエリを見つける必要があります。エラーメッセージには、ファイル名と、エラーが発生した正確なスポットの行番号が含まれます。単純なコードで十分ですが、コードで関数またはクラスを使用している場合は、スタックトレースをたどって問題のクエリを見つける必要がある場合があります。

エラーメッセージが表示されたら、それを読んで理解する必要があります。軽視しないとわかりにくいかもしれませんが、学習者は、エラーメッセージが単なる警告信号ではなく、実際に問題の詳細な説明を含んでいるという事実を見落としがちです。エラーメッセージを読んで問題を修正するだけです。

  • たとえば、特定のテーブルが存在しないと表示されている場合は、スペル、タイプミス、大文字と小文字を確認する必要があります。また、PHPスクリプトが正しいデータベースに接続していることを確認する必要があります
  • または、SQL構文にエラーがあると表示された場合は、SQLを調べる必要があります。また、問題箇所は、エラーメッセージで引用されているクエリ部分の直前です。

エラーメッセージがわからない場合は、Googleで検索してみてください。そして結果を閲覧するときは、率直に解決策を与えるのではなく、エラーを説明する答えに固執してください。特定のケースでは解決策が機能しない可能性がありますが、説明は問題を理解し、自分で問題を修正できるようにするのに役立ちます。

エラーメッセージも信頼する必要があります。トークンの数がバインドされた変数の数と一致しないという場合、それそう。欠落しているテーブルまたは列についても同様です。選択が与えられた場合、それがあなた自身の間違いであるか、エラーメッセージが間違っているかにかかわらず、常に前者に固執してください。繰り返しになりますが、このサイトに関する何百もの質問から、このアドバイスが非常に役立つことがわかります。

エラー報告に関して決してしてはいけないことのリスト

  • エラー抑制演算子(@)は使用しないでください。プログラマーがエラーメッセージを読み取れなくなり、エラーを修正できなくなります。
  • 使用しないでくださいdie()またはecho無条件画面にエラーメッセージを出力したり、他の関数を。PHPはそれ自体でエラーを報告し、正しい方法でそれを行うことができます-環境に依存するため、PHPに任せてください。
  • クエリ結果を手動でテストするための条件を追加しないでください(などif($result))。エラー例外が有効になっていると、このような状態は役に立たなくなります。
  • try..catchエラーメッセージをエコーするために演算子を使用しないでください。この演算子は、トランザクションのロールバックなどのエラー処理を実行するために使用する必要があります。しかし、エラーを報告するためだけに使用しないでください-上記で学習したように、PHPはすでに正しい方法でそれを実行できます。

PS
時々、エラーはないが結果もない。つまり、条件に一致するデータがデータベースに存在しません。この場合、たとえあなたがデータを誓うことができ、基準が大丈夫であっても、あなたはこの事実を認めなければなりません。ではない。もう一度確認する必要があります。この問題に役立つ記事「データベースの相互作用をデバッグする方法」があります。PDO用に書かれていますが、原理は同じです。この手順を1ステップずつ実行して、問題を解決するか、Stack Overflowについて回答可能な質問をしてください。


@を使用する@AdamWinterは常に間違っており、この特定のケースでは10倍になります。プログラムへのエラーメッセージは、身体の痛みと同じです。それはあなたの足が骨折しているように何かが間違っていることを教えてくれます。そして、鎮痛剤を服用して続行するだけでなく、脚を固定する必要があります。こっちも一緒。PHPは、期待する変数がないことを通知します。したがって、この変数を使用可能にするには、フォームなどを修正する必要があります。エラーを回避するためのコードを記述するだけではありません。
常識
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.