mysqli_fetch_assoc()は、パラメーター/メンバー関数bind_param()の呼び出しエラーを予期しています。実際のmysqlエラーを取得して修正する方法は?

Mar 26 2014

私のローカル/開発環境では、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です。

回答

131 YourCommonSense Mar 26 2014 at 20:32

時には、あなたの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_reportingE_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つずつ実行して、問題を解決するか、スタックオーバーフローに関する回答可能な質問をしてください。