質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.59%

ラジオボタンでなぜかFemaleにチェックがついてしまう

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 1,696

score 44

フォームにある、Male,Femaleをチェックするラジオボタンで、初期画面はどちらも選択してある状態に無いんですが、一度エラーを出して(1箇所ブランクとか)再入力時、ラジオボタンのチェックがFemaleについてしまいます。

(chromeブラウザでHTMLをチェックしたら、MaleとFemale両方がcheckedとなっていました。)

これを、ユーザーがもしラジオボタンをブランクでエラーを出したならブランクのまま、もしMaleを選択してて、他の箇所でエラーを出したなら、Maleをそのままチェックしていて欲しいのですが、どのように書けばいいでしょうか。

<?php
 /*  Program name: form.inc
  *  Description:  Defines a form that collects a user's 
  *                name and phone number.
  */
$labels1 = array( "username" => "User Name",
                          "phone" => "Phone",
                  "email" => "Email");
$labels2 = array ("password" => "Password");
$gen = array("Male" , "Female");
$date = date("Y-m-d H:i:s");
$submit = "Submit";
?>

<html>
<head>
  <title>Register</title>
  <style type='text/css'>
   <!--
      form {
        margin: 1.5em 0 0 0;
        padding: 0;
      }
      #field {padding-bottom: 1em;}
      label {
        font-weight: bold;
        float: left;
        width: 20%;
        margin-right: 1em;
        text-align: right;
      }
      #submit {
        margin-left: 35%;
      }
   -->
 </style>
</head>
<body>
<h3>Registration</h3>
  <?php
   echo "<form action='$_SERVER[PHP_SELF]' method='POST'>"
     ?>
    <fieldset  style="background: #EFEFEF; width:630px; border: 1px solid #CC0000; height:100%; padding-left:10px; padding-right:10px; padding-top:10px; padding-bottom:10px;">
    <legend>Registration Form</legend>
    <?php
  foreach($labels1 as $field => $label1)
  {
    echo "<div id='field'><label for='$field'>$label1</label>
            <input id='$field' name='$field' type='text' value='".@$_POST[$field]."'
               size='50%' maxlength='65' /></div>\n";
  }
foreach($labels2 as $field => $label2)
  {
    echo "<div id='field'><label for='$field'>$label2</label>
            <input id='$field' name='$field' type='password' value='".@$_POST[$field]."'
               size='50%' maxlength='65' /></div>\n";
  }
echo "<div class='gen'> <label>Gender</label>";
foreach($gen as $value)
{
     echo "<input type='radio' name='gen' ";
     if(isset($_POST['gen'])  == $value)
     {
          echo " checked";
     }
     echo " value='$value' style='margin-left: 10%'/>$value";
}
echo "</div>";

  echo "<input type='hidden' name='submitted' value='yes'>";   
  echo "<div id='submit'>
          <input type='submit' name='pButton' value='$submit'></div>";
?>
</fieldset>
</form>
</body>
</html>
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+4

if(isset($_POST['gen'])  == $value)

ここが問題で、isset()はtrue/falseしか返しませんが、true == 文字列という比較では文字列がboolに変換されるので、空文字列や'0'などを除いて必ずtrueとなってしまいます。

ちゃんと$_POSTの中身を判定する必要があります。

// その1:略さずに書く
if(isset($_POST['gen']) && $_POST['gen'] === $value)

// その2:エラーを止める
if(@$_POST['gen'] === $value)

// その3:PHP 7ではこうも書ける
if(($_POST['gen'] ?? '') === $value)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/25 12:30

    略してることすらわかってなかったのですが、こちらで解決しました。
    初心者なので、まず略されてないコードを書いて理解しないとダメですね。勉強になります。
    その3も思い切って試してみました。
    いろんな方法を教えていただきまして、ありがとうございます。

    キャンセル

+3

2つの問題があります。

1つめは比較演算子。PHPの == 演算子は非常にゆるい判定で、true と "Male" を比較するとなんと true を返します。

$hoge = 'hello';
var_dump(isset($hoge) == 'Male');

# bool(true)

まとも(?)な判定を行う場合は、=== 演算子を使ってください。

$hoge = 'hello';
var_dump(isset($hoge) === 'Male');

# bool(false)

== はPHPの "クソ仕様" として有名で、本当にたびたびトラブルの原因になるので、極力 === を使うよう心がけてください。

PHP: 比較演算子 - Manual


2つめに、今回の checked の判定は、$_POST['gen'] がセットされていて、かつ その値が Male / Female であることが条件ですので、判定式は2つになるはずです。

if(isset($_POST['gen'])  == $value) { echo " checked"; }

↓

if(isset($_POST['gen']) && $_POST['gen'] === $value) { echo " checked"; }

なお PHP7.0 以降では、NULL合体演算子 という新しい演算子を使ってもう少しシンプルに書けます。

if($value === $_POST['gen'] ?? null) { echo " checked"; }

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/25 12:35

    とてもわかりやすい説明をありがとうございます。上の方とすごく迷ったのですが、初心者の私にはその1その2その3の説明があったのが今後の理解に役に立ちそうだったので上の方をベストアンサーとさせていただきました。
    ==はクソなんですね。知らなかったです。今後は===を使っていこうと思います。
    またいろいろ質問させていただくと思いますので、よろしくお願いします。

    キャンセル

+2

本題にあまり関係ないですが
「$_SERVER[PHP_SELF]」はセキュリティ的に使用しない方がいい
$_SERVER["SCRIPT_NAME"]を検討ください

また全体的に冗長な書き方をされているようなので
HTML部分はテンプレート化した方がよいと思いますよ

 追記

念の為追記しておきます。
POST値の参照は長く以下a1のような方式を取られていましたが
a2のようにPHP5以降インテリジェントでスマートなfilter_input()
整備されたこともあり使わない手はないと思います。
(filter_inputはデータの整合性をチェックしたり、デフォルト値の指定をすることができます)
またa3のような書き方もできますが、任意にエラーを無視する方式のため
あまりおすすめできません。
参考になれば幸いです

<form method="post">
<input type="text" name="a">
<input type="submit" value="go">
</form>

<?PHP
$a1=isset($_POST["a"])?$_POST["a"]:NULL;
var_dump($a1);

$a2=filter_input(INPUT_POST,"a");
var_dump($a2);

$a3=@$_POST["3"];
var_dump($a2);
?>

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/25 12:23

    $_SERVERの件、ありがとうございます。勉強になります。
    コードの書き方は、学校の教えでこんな形で私もだいぶ頭が混乱しています。

    キャンセル

  • 2017/05/25 12:37

    POSTデータの受け方について追記しておきました

    キャンセル

  • 2017/05/25 12:43 編集

    本当ですね。filter_inputの方がすっきりしてて、パッと見てすぐ理解できました。
    学校の教科書がなぜか積極的に@を使うんです。おっしゃる通り、エラーを無視するようなのでa3みたいな方法はあまり好きじゃないなぁと思っています。
    ありがとうございます。
    今後ともよろしくお願いします。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.59%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る