【PHP】ラジオボタンが未選択のときにGETでブランクを渡したい

ラジオボタンを選択した場合はソートした情報を抽出して、何も選択しない場合は全件抽出する方法をまとめました。普通にGETで実装すると、エラーメッセージが出てしまうので、filter_inputを使って実現します。

GETでラジオボタンがブランクだとエラーメッセージが出てしまう

name_tableというテーブルから、データを抽出してみます。

namegendername_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/

コメント

タイトルとURLをコピーしました