ラジオボタンを選択した場合はソートした情報を抽出して、何も選択しない場合は全件抽出する方法をまとめました。普通にGETで実装すると、エラーメッセージが出てしまうので、filter_inputを使って実現します。
GETでラジオボタンがブランクだとエラーメッセージが出てしまう
name_tableというテーブルから、データを抽出してみます。
name | gender | name_reading1 |
優 | man | ゆう |
優一 | man | ゆういち |
祐一 | man | ゆういち |
優子 | woman | ゆうこ |
花子 | woman | はなこ |
↓ index.php 検索ページ
<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="description" content="テストサイト">
<title>Topページ</title>
<link rel="stylesheet" href="/main.css">
</head>
<body>
<form action="result_test.php" method="get" id="form">
<p>性別</p>
<input type="radio" name="gender" value="man" id="man"><label for="man" onclick="">男の子</label> <!-- inputとlabelのIDを同値にすることで、ラベル文字をクリックしてもチェックが入るようにする-->
<input type="radio" name="gender" value="woman" id="woman"><label for="woman" onclick="">女の子</label>
<input type="submit" value="検索" style="cursor:pointer">
</form>
</body>
</html>
↓ 結果表示ページ test_result.php
<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="description" content="テストサイト">
<title>結果ページ</title>
<link rel="stylesheet" href="/main.css">
</head>
<?php
try{
//GETで前画面から値を取得
$inputted_gender = $_GET['gender'];
//文字列に変換(セキュリティ対策)
$escaped_gender=htmlspecialchars($inputted_gender,ENT_QUOTES,'UTF-8');
define('DSN','mysql:dbname=naming;host=localhost');
define('DB_USERNAME','root');
define('DB_PASSWORD','');
$dbh = new PDO(DSN, DB_USERNAME, DB_PASSWORD); //MySQLのデータベースに接続
//例外処理。PDOのエラーレポートを表示
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// SQLを使ってレコードを読み込み
$sql ='SELECT * FROM name_table WHERE 1=1'; #1=1は必ずTrueとなるためソートされず全項目表示される
if($escaped_gender) $sql .= ' AND gender = :escaped_gender';
$stmt = $dbh->prepare($sql);
//SQLインジェクション対策のためにプリペアドステートメントを実行
if($escaped_gender) $stmt -> bindValue(':escaped_gender', $escaped_gender, PDO::PARAM_STR);
$stmt->execute();
// foreach文で配列の中身を一行ずつ出力
foreach ($stmt as $row) {
echo '<div>'.$row['name']."</div>\n";
}
// データベースから切断するプログラム
$dbh = null;
} catch (Exception $e)
{
print 'ただいま障害により表示できません。';
exit(); //強制終了の命令
}
?>
</body>
</html>
ラジオボタンを何も選択しないと、全件抽出できるものの上記のように Notice: Undefined index: gender in C:\xampp\htdocs\result_test.php on line 14
というエラーメッセージが表示されてしまいます。
filter_inputを使うと、GETでラジオボタンがブランクでもエラーメッセージが表示されない
index.phpファイルに変更はありません。test_result.phpのGET部をfilter_inputに変更します。こうすることでエラーメッセージが表示されなくなりました。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="description" content="テストサイト">
<title>結果ページ</title>
<link rel="stylesheet" href="/main.css">
</head>
<?php
try{
//filter_inputで前画面から値を取得し、文字列に変換(セキュリティ対策)
$escaped_gender = filter_input(INPUT_GET, 'gender', FILTER_SANITIZE_STRING);
//データベースに接続
define('DSN','mysql:dbname=naming;host=localhost');
define('DB_USERNAME','root');
define('DB_PASSWORD','');
$dbh = new PDO(DSN, DB_USERNAME, DB_PASSWORD); //MySQLのデータベースに接続
//例外処理。PDOのエラーレポートを表示
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// SQLを使ってレコードを読み込み
$sql ='SELECT * FROM name_table WHERE 1=1'; #1=1は必ずTrueとなるためソートされず全項目表示される
if($escaped_gender) $sql .= ' AND gender = :escaped_gender';
$stmt = $dbh->prepare($sql);
//SQLインジェクション対策のためにプリペアドステートメントを実行
if($escaped_gender) $stmt -> bindValue(':escaped_gender', $escaped_gender, PDO::PARAM_STR);
$stmt->execute();
// foreach文で配列の中身を一行ずつ出力
foreach ($stmt as $row) {
echo '<div>'.$row['name']."</div>\n";
}
// データベースから切断するプログラム
$dbh = null;
} catch (Exception $e)
{
print 'ただいま障害により表示できません。';
exit(); //強制終了の命令
}
?>
</body>
</html>
filter_inputとは
filter_inputとは、GETやPOSTでデータを受け取って、中身を検証して、変数に格納するメソッドです。詳しくは公式を参照してください。
https://www.php.net/manual/ja/function.filter-input.php
記述方法:filter_input(受取タイプ, 変数名, フィルタタイプ)
GETだけでなく、POSTも受け取れます。受取タイプは以下の5種類です。
- INPUT_GET
- INPUT_POST
- INPUT_COOKIE
- INPUT_SERVER
- INPUT_ENV
フィルタタイプは検証、除去など色々と用意されています。今回は FILTER_SANITIZE_STRING
を使って、filter_input内でエスケープ処理も行いました。これも詳しくは公式を参照してください。https://www.php.net/manual/ja/filter.filters.php
参照サイト:
【PHP】filter_input を使って、文字列、論理値、配列を受け取ってみる
https://b-estack.com/2018/10/24/useful_filter_input/
コメント