ごく最近PHPとmysqlを勉強しだした初心者です。
PHPでDBの検索フォームを作ろうとしているのですが、どうしてもわからないので質問させていただきました。
検索フォームに電話番号を入れると、該当する人の情報を表示させるようにしたいと思ってます。
私の持っている本では、SQLの検索を行うにはSELECT句を使い
SELECT フィールド名 FROM テーブル名 WHERE 条件文;
という風にあって、条件文がid=1とかの定数で指定したものしかありません。
検索フォームに入力された数値($_POSTの値)を条件文にいれて、検索フォームで入力された電話番号を検索するようにできますか?
もしできないなら、どのような形で作ればよいでしょうか?
贅沢ですが、できれば簡単に解説もしていただけると非常に助かります。
ご教授の程、何卒よろしくお願い致します。
No.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 "該当者が存在しません";
---ここまで---
といった感じになるかと思います。
mtaka2様
何から何までありがとうございました!!!
大変勉強にもなりました。
今後も勉強していきたいと思います。
ありがとうございました!!
No.4
- 回答日時:
> bind_result エラー
すみません、引数を間違えてました。
> id,c_id,name,tel,addressというフィールドを用意している。
にあわせて、
> $result = $stmt->bind_result($id, $c_id, $name, $tel, $address);
にしてください。
お世話になっております。
うまくいきました!!!
本当にありがとうございました!
あつかましいかも知れないのですが、もし教えていただけるのであれば
最後に1つだけ教えてください。
もし電話番号に該当者がいない場合は
「該当者が存在しません」
というようなメッセージを表示しようとしたら、おそらくifを使って
検索結果がfalseだったら
echo '該当者が存在しません';
というようになると思うのですが、色々試してみたのですが、エラー表示
ばかりになってうまくいきません…
もし気が向いたら教えてください。
本当にありがとうございました!!!
No.3
- 回答日時:
> それで最初に教えていただいた記述で試してみたのですが、
>特にエラーは出ないのですが結果が表示できません。。。
回答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の「クラス」について勉強してください。
何度もありがとうございます。
そして何度もすみません。
早速教えていただいた記述を試してみたのですが、
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);
の部分です。
私の設定とかがまずいのでしょうか?
本当にすみません。
何卒よろしくお願い致します。
No.2
- 回答日時:
> 丁寧に解説までしていただいたのですが、現在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を使うべきです。
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();
の部分などの -> はどういった意味なのか教えていただけないでしょうか?
本当にど素人で申し訳ありません。
よろしくお願い致します。
No.1
- 回答日時:
まともな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に侵入・改竄などを行うという攻撃の穴になってしまいます。
早速のご回答ありがとうございます。
丁寧に解説までしていただいたのですが、現在DBはmysqlでDBへのアクセスはphpmyadminを
使用しています。
この環境でやろうと思うと難しいのでしょうか?
会社で使うとかいうものでもなく、簡略化したようなものでも大丈夫なのですが…
もし簡単なやり方があればそちらも教えていただけると大変助かります。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Access(アクセス) Accessでセレクタをダブルクリックで別フォームで詳細表示 3 2022/12/20 10:36
- MySQL 書籍の内容はまともでしょうか? 1 2023/01/22 03:07
- Visual Basic(VBA) ユーザーフォーム「frm_基本❶」を立ち上げると新規で入力する行数を右下のNoとして表示しています。 1 2023/03/16 19:02
- Access(アクセス) AccessVBAで降順にするテーブル作成クエリを使用して作成したテーブルを削除し同一のテーブル作成 1 2023/01/06 11:17
- Excel(エクセル) PHPプログラムをエクセルに張り付けると検索ボックスがでてくる! 3 2022/05/08 07:10
- Excel(エクセル) 【Excel】指定のセル内容を基に別シートのセルを検索して選択する【VBA】 1 2022/06/16 16:16
- その他(ブラウザ) Mycrosoft Edge フォームの履歴を完全に削除したい 3 2022/08/11 09:59
- Access(アクセス) Accessフォーム 一部のレコードだけを抽出する方法について 1 2022/06/28 18:45
- Visual Basic(VBA) 検索のユーザーフォームの表示について 1 2023/03/27 23:31
- JavaScript ラジオボタンによるフォームの開閉を行いたい 3 2022/03/31 21:30
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルで最後の文字だけ置き...
-
Access パラメータクエリをcsv...
-
SQL Left Join で重複を排除す...
-
副問合せの書き方について
-
Unionした最後にGROUP BYを追加...
-
PL/SQLの変数について
-
android studio
-
VIEWの元のテーブルのindexって...
-
SQLite3でこんな便利なSQLはで...
-
selectした大量データをinsert...
-
複数のExcelアドインひとつのタ...
-
1テーブル&複数レコードの更新...
-
”photo id” とは何ぞや?
-
ある条件の最大値+1を初番する...
-
verilogに適したvimの設定を探...
-
group byのSQLでインデックスを...
-
insertを高速化させたい
-
親と子供が複数のSQL取得方法
-
テーブル作成です。どこかのス...
-
クエリ表示と、ADOで抽出したレ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルで最後の文字だけ置き...
-
SQL Left Join で重複を排除す...
-
VIEWの元のテーブルのindexって...
-
SQLサーバから、項目の属性(型...
-
select文のwhere句に配列を入れ...
-
副問合せの書き方について
-
マイクラPC版のコマンドで効率...
-
Unionした最後にGROUP BYを追加...
-
selectした大量データをinsert...
-
SQLにて特定の文字を除いた検索...
-
[SQLServer] テーブル名からカ...
-
1テーブル&複数レコードの更新...
-
inner joinをすると数がおかし...
-
クエリ表示と、ADOで抽出したレ...
-
ある条件の最大値+1を初番する...
-
sqlで、600行あるテーブルを100...
-
複数テーブルのGROUP BY の使い...
-
insertを高速化させたい
-
PL/SQLの変数について
-
キー毎の、ある列のmaxのレコー...
おすすめ情報