プロが教える店舗&オフィスのセキュリティ対策術

ごく最近PHPとmysqlを勉強しだした初心者です。

PHPでDBの検索フォームを作ろうとしているのですが、どうしてもわからないので質問させていただきました。

検索フォームに電話番号を入れると、該当する人の情報を表示させるようにしたいと思ってます。


私の持っている本では、SQLの検索を行うにはSELECT句を使い

  SELECT フィールド名 FROM テーブル名 WHERE 条件文;

という風にあって、条件文がid=1とかの定数で指定したものしかありません。


検索フォームに入力された数値($_POSTの値)を条件文にいれて、検索フォームで入力された電話番号を検索するようにできますか?
もしできないなら、どのような形で作ればよいでしょうか?

贅沢ですが、できれば簡単に解説もしていただけると非常に助かります。

ご教授の程、何卒よろしくお願い致します。

A 回答 (5件)

> もし電話番号に該当者がいない場合は


> 「該当者が存在しません」

$stmt->fetch で条件に該当する件数文だけのループを回していますから、
このループ回数が0回だった時が「該当者が存在しない」時ということになります。
それを数える変数処理でも入れておけばいいでしょう。
あと、私の書いたコードでは、事前にテーブルヘッダを出力していますが、これは該当なしの時は出力不要なので、ちょっと順番を変えて

---ここから---
print "<table><tr><th>id</th><th>c_id</th><th>name</th><th>address</th>\n";
while ($stmt->fetch()) {
print "<tr><td>$id</td><td>$c_id</td><td>$tel</td><td>$address</td></tr>\n";
}
---ここまで---
の部分が

---ここから---
$count = 0;
while ($stmt->fetch()) {
if ($count == 0) print "<table><tr><th>id</th><th>c_id</th><th>tel</th><th>name</th><th>address</th>\n"; #最初の一回だけ出力
print "<tr><td>$id</td><td>$c_id</td><td>$tel</td><td>$name</td><td>$address</td></tr>\n";
$count++;
}
if ($count == 0) print "該当者が存在しません";
---ここまで---
といった感じになるかと思います。
    • good
    • 0
この回答へのお礼

mtaka2様

何から何までありがとうございました!!!
大変勉強にもなりました。

今後も勉強していきたいと思います。
ありがとうございました!!

お礼日時:2011/04/20 18:50

> bind_result エラー


すみません、引数を間違えてました。

> id,c_id,name,tel,addressというフィールドを用意している。

にあわせて、
> $result = $stmt->bind_result($id, $c_id, $name, $tel, $address);
にしてください。
    • good
    • 0
この回答へのお礼

お世話になっております。

うまくいきました!!!
本当にありがとうございました!


あつかましいかも知れないのですが、もし教えていただけるのであれば
最後に1つだけ教えてください。

もし電話番号に該当者がいない場合は
「該当者が存在しません」
というようなメッセージを表示しようとしたら、おそらくifを使って
検索結果がfalseだったら
echo '該当者が存在しません';
というようになると思うのですが、色々試してみたのですが、エラー表示
ばかりになってうまくいきません…

もし気が向いたら教えてください。
本当にありがとうございました!!!

お礼日時:2011/04/20 18:18

> それで最初に教えていただいた記述で試してみたのですが、


>特にエラーは出ないのですが結果が表示できません。。。

回答1のコードは、SQLを発行するところまでです。結果を取得・表示する部分がありません。
そこまで含めると下記のようになります。(うまく動かなかった時の原因究明のため、前半部もエラーチェックのコードを追加しています)

tel_search.php
---ここから---
$db = new mysqli('localhost', 'root', '','torys');
if ($db->connect_error) die("DB接続エラー:".$db->connect_error);
$sql = "SELECT * FROM `customer` WHERE `tel` = ?";
$stmt = $db->prepare($sql);
if (!$stmt) die("prepare エラー:".$db->error);
$result = $stmt->bind_param("s", $_POST['tel_no']);
if (!$result) die("bind_param エラー:".$db->error);
$result = $stmt->execute();
if (!$result) die("execte エラー:".$db->error);
$result = $stmt->bind_result($id, $c_id, $tel, $address);
if (!$result) die("bind_result エラー:".$db->error);
print "<table><tr><th>id</th><th>c_id</th><th>name</th><th>address</th>\n";
while ($stmt->fetch()) {
print "<tr><td>$id</td><td>$c_id</td><td>$tel</td><td>$address</td></tr>\n";
}
$stmt->close();
$db->close();
---ここまで---


> -> はどういった意味なのか教えていただけないでしょうか?
「->」は、クラスのインスタンス参照を示す演算子です。

1行目の「$db = new mysqli…」で、mysqli 型のデータ(インスタンス)を作成しており、
「$stmt = $db->prepare(…)」は、mysqli型のデータ$db に対して、メソッド(関数) prepare を呼び出しています)
クラスについてはここで簡単に語れるようなものではありませんので、詳しくはPHPの「クラス」について勉強してください。
    • good
    • 0
この回答へのお礼

何度もありがとうございます。
そして何度もすみません。

早速教えていただいた記述を試してみたのですが、

Warning: mysqli_stmt::bind_result() [mysqli-stmt.bind-result]: Number of bind variables doesn't match number of fields in prepared statement in C:\xampp\htdocs\tel_search.php on line 21
bind_result エラー:

というエラーになってしまいます。
21行目は
$result = $stmt->bind_result($id, $c_id, $tel, $address);
の部分です。

私の設定とかがまずいのでしょうか?
本当にすみません。

何卒よろしくお願い致します。

お礼日時:2011/04/20 14:44

> 丁寧に解説までしていただいたのですが、現在DBはmysqlでDBへのアクセスはphpmyadminを


使用しています。


phpMyAdmin は、Web経由で直接MySQLのDBを読み書きするツールです。
PHPのアプリケーションから phpMyAdmin を使うことはできません。

PHP から MySQL のDBにアクセスする方法にはいくつかあります。その代表的なのが「mysql」「mysqli」「PDO」です。

mysql: http://www.php.net/manual/ja/book.mysql.php
mysqli: http://php.net/manual/ja/book.mysqli.php
PDO: http://www.php.net/manual/ja/book.pdo.php

どれを使っても PHP プログラムからMySQLのDBにアクセスできます。
どれが使えるからはPHPサーバのインストール状況次第です。

mysqlは一番古いライブラリであり、設計仕様が古いのであまりお薦めできません。mysqliはmysqlの改良型ライブラリ。
PDOはMySQLにもアクセス可能な、MySQLに限定されない汎用のDBアクセスライブラリです。
今後の事を考えると、出来ればPDOかmysqliを使うべきです。
    • good
    • 0
この回答へのお礼

mtaka2様

ご回答ありがとうございます。
mtaka2様の仰る通りにとりあえずmysqliで作成するようにしました。

それで最初に教えていただいた記述で試してみたのですが、
特にエラーは出ないのですが結果が表示できません。。。

現在の状況がこちらです。

・xamppでsqliが使えるように設定(phpmyadminでPHP 拡張: mysqliと表示されている)
接続環境は host:localhost user_name:root password:なし
・torysというDBにcustomerというテーブルを作っていて、id,c_id,name,tel,addressという
 フィールドを用意している。(とりあえず2名分だけ登録されている)

index.htmlのフォーム
<form id="tel" name="tel" method="post" action="tel_search.php">
<dl>
<dt>
<label for="tel_no">電話番号</label>
</dt>
<dd>
<input name="tel_no" type="text" id="tel_no" size="20" maxlength="255" style="ime-mode:disabled" />
</dd>
</dl>
<input type ="submit" value="検索する" />
</form>

tel_search.php
(htmlの部分は割愛)
<?php
$db = new mysqli('localhost', 'root', '','torys');
$sql = "SELECT * FROM `customer` WHERE `tel` = ?";
$stmt = $db->prepare($sql);
$stmt->bind_param("s", $_POST['tel_no']);
$stmt->execute();
?>
(htmlの部分は割愛)

という状態です。

これで、customerテーブルに登録された人の情報を電話番号から探して表示するにはどうしたら
良いでしょうか?


あともしよければ
$stmt->execute();
の部分などの -> はどういった意味なのか教えていただけないでしょうか?

本当にど素人で申し訳ありません。
よろしくお願い致します。

お礼日時:2011/04/20 13:22

まともなWebアプリなら、「prepared statement」を使います。



DBへのアクセス方法に何を使われているのかわかりませんが、例えばmysqliなら、

---ここから---
$db = new mysqli(…);
$sql = "SELECT * FROM `テーブル名` WHERE `tel` = ?";
$stmt = $db->prepare($sql);
$stmt->bind_param("s", $_POST[tel]);
$stmt->execute();
---ここまで---

といった感じです。
「prepared statement」を使うと、SQL文で「?」にしている部分について、その内容を別途指定できるのです。
上述の記述なら、`tel`=? の ? の部分に $_POST[tel] の値を入れてDB検索が行われます。

mysqliで説明しましたが、PDO などでも関数名は違いますが同様の記述が可能です。
mysqli: http://www.php.net/manual/ja/mysqli.prepare.php
PDO: http://www.php.net/manual/ja/pdo.prepare.php

mysql は、prepared statement が使えませんので、出来れば mysqli か PDO を使いましょう。


なお、その手のアプリの参考例としてよく見受けられる手軽な方法として
$sql = "SELECT * FROM `テーブル名` WHERE `tel` = `".$_POST[tel]."`";
のように、変数を埋め込んだSQL文字列を生成するというものがありますが、
こういうやりかたは、絶対に行ってはいけません。
「SQLインジェクション」という、不正なパラメータを指定することでDBに侵入・改竄などを行うという攻撃の穴になってしまいます。
    • good
    • 0
この回答へのお礼

早速のご回答ありがとうございます。

丁寧に解説までしていただいたのですが、現在DBはmysqlでDBへのアクセスはphpmyadminを
使用しています。

この環境でやろうと思うと難しいのでしょうか?
会社で使うとかいうものでもなく、簡略化したようなものでも大丈夫なのですが…

もし簡単なやり方があればそちらも教えていただけると大変助かります。

お礼日時:2011/04/20 09:27

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!