3

準備されていない手続き型のメソッドでテストしたので、この特定のクエリが機能することはわかっています。ここにあります:

$name = 'introduction';
$mysqli = new mysqli('localhost', 'user', 'pass', 'db') or die('There was a problem connecting to the database.');
$stmt = $mysqli->prepare("SELECT name, content FROM sections WHERE name = ?");
$stmt->bind_param('s', $name);
$stmt->execute();
$stmt->bind_result($content);
$stmt->fetch();
echo  $content;
$stmt->close();

セクションテーブルのインデックスとしてid列があるので、php.netでの上記のステートメントを前提として、結果としてそれもバインドする必要があることに気付きました(ありがとう、Bill)。

新しいコードは次のとおりです。

$name = 'introduction';
$mysqli = new mysqli('localhost', 'user', 'pass', 'db') or die('There was a problem connecting to the database.');
$stmt = $mysqli->prepare("SELECT name, content FROM sections WHERE name = ?");
$stmt->bind_param('s', $name);
$stmt->execute();
$stmt->bind_result($id, $name, $content);
$stmt->fetch();
echo $content;
$stmt->close();

提案を提供できるすべての人に改めて感謝します。(興味があります。このようにプリペアドステートメントのOOPスタイルを使用すると、デバッグが困難になります。たとえば、実際に使用されたクエリを簡単に確認する方法はありますか?)

私が次のことをすると、簡単で汚い例として:

$name = 'introduction';
@mysql_connect('host', 'user', 'pass');
@mysql_select_db('db');
$query = "SELECT name,content FROM sections WHERE name = '$name'";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_object($result)) {
    $content = $row->content;
    echo $content;
}

私のデータが表示され、すべてが順調です。ただし、次のことを行う場合:

$name = 'introduction';
$mysqli = new mysqli('localhost', 'user', 'pass', 'db') or die('There was a problem connecting to the database.');
$stmt = $mysqli->prepare("SELECT name, content FROM sections WHERE name = ?");
$stmt->bind_param('s', $name);
$stmt->execute();
$stmt->bind_result($name, $content);
$stmt->fetch();
echo  $content;
$stmt->close();

私が正しいと信じていること(もちろん、そうでない場合は遠慮なく叫んでください)、私は何も得られません。さらに、そのコードでは、(念のために)html検証を行うと、内部サーバー警告(500)が表示されます。これは、SQLコードの問題であると見なされます。私はただのナッツですか?

4

2 に答える 2

4

ステートメントの準備やパラメーターの使用に問題はありませんが、バインディングの結果に問題があります。

http://php.net/manual/en/mysqli-stmt.bind-result.phpによると:

すべての列mysqli_stmt_execute()は、を呼び出す前後にバインドする必要があることに注意してくださいmysqli_stmt_fetch()

(強調鉱山)


上記のドキュメントは、テーブルのすべての列ではなく、クエリのすべての列と見なす必要があります。

さて、私はこれを自分で試しました。列を省略すると、次の$name警告が表示されます。

PHP Warning:  mysqli_stmt::bind_result(): Number of bind variables doesn't 
match number of fields in prepared statement in mysqli.php on line 9
PHP Stack trace:
PHP   1. {main}() /Users/bill/workspace/PHP/mysqli.php:0
PHP   2. mysqli_stmt->bind_result() /Users/bill/workspace/PHP/mysqli.php:9

しかし、それはデータをフェッチします。

$nameとクエリの結果の両方をバインドすると$content、エラーや警告なしで機能します。

だから私はあなたに尋ねることを余儀なくされています:あなたの条件に一致する行がデータベースにあるのは確かですか?つまり、どこname = 'introduction'?SQLでは、文字列の比較ではデフォルトで大文字と小文字が区別されることに注意してください。

よくある間違いの1つは、アドホッククエリに使用するデータベースとは異なるPHPスクリプトのデータベースに接続することです。したがって、データが適切なデータベースに存在することを確認していることを絶対に確認する必要があります。

于 2009-06-19T20:53:41.107 に答える
0

それはすべきではありません

$stmt->bind_result($name, $content);

2列を選択すると

于 2009-06-19T20:53:39.717 に答える