セッションがうまくいかないと思ったときの仮説検証


エンジニア初心者がPHPの勉強でつまづいたところを備忘録として記載しています。
自作でToDoアプリを作成しようと思っていまして、そのsignup機能の実装においてエラーが起きました。
以下にまとめます!

目次

  • 前提
  • 課題と結論
  • 仮説1(セッションの不具合)
  • 仮説1の検証と結果
  • 仮設2(コーディングミス)
  • 仮設2の検証と結果
  • まとめ

前提

アカウント作成、signup機能でのエラーです。
フローは
signup画面→確認画面→登録thanks画面→signin画面を想定しており、
signup画面で「2つの条件を両方とも満たす場合」のみ確認画面に遷移するよう設定します。

また、条件とは以下で、満たさない場合はエラーを表示して確認画面に遷移しないようにするような機能を作っています。
・メールアドレスが空欄ではない
・パスワードが4文字未満ではない

課題と結論

課題:2つの条件を満たしていないにもかかわらず、画面遷移をしてしまう
結論:コーディングミスがあった

仮説1

最初の仮説は、セッションがうまく機能していないのではないかと考えました。
セッションの値がうまく反映されない場合はphp.iniというファイルの設定を確認する必要があると『よくわかるPHPの教科書』で読んだので、引っ張り出して確認しました。

; Initialize session on request startup.
session.auto_start = 0

初期値では session.auto_start = 0 となっていますが、
session.auto_start = 1 に変える必要があるみたいです。
ちなみに、上記本には以下のように記載されています。

この値が0の場合、Cookieが利用できない設定になっているためセッションが利用できません。そのため、これを「1」にしてWebサーバーを再起動すると良いでしょう。

(他情報をググると変更する必要はない、むしろ変えない方が望ましいなどのコメントがあったので、セッションやCookieについて深ぼる時にはこの辺りがわかるようになっていたい。)

仮説1の検証と結果

検証しましたが、変化はありませんでした。解決せず。
そもそもなぜセッションに焦点を当てたかの確からしい事実がないので、外れやすい仮説だったなーと思います。
とはいえ知識全然ないので、こういう仮説をどんどん立てていきたいと思います(量をこなして質が上がっていくと思っているタイプです)

仮説2

コーディングミスはないか。
初学者としてはここが大半なので、まあここに着目するのは当たり前なのですが、
改めて今は「2つの条件を両方とも満たす場合」のみ画面遷移するはずなのに、条件を満たさずとも画面を遷移できちゃっている状態です。

ここで気になるのが、条件をうまく判定できていないのではないかという点。
・メールアドレスが空欄ではない
・パスワードが4文字未満ではない
つまり、上記が空欄だと判定されていない理由があるのではないか、と考えました。

仮説2の検証と結果

検証する場所は
・フォームの各入力項目における空欄かどうか判定する(文字数を満たしているか判定する)部分
・セッション開始後の条件文(画面遷移するか判断する部分)
です。

フォームの各入力項目における空欄かどうか判定する(文字数を満たしているか判定する)部分

<dt><label for="password">password</label></dt>
<dd><input type="password" id="password" name="password" size="10" maxlength="20" value="<?php echo htmlspecialchars($_POST['password'], ENT_QUOTES); ?>" />
  <?php if($error['password'] == 'blank'): ?>
    <p class="error">* パスワードを入力してください</p>
  <?php endif; ?>
  <?php if($error['password'] == 'Length'): ?>
    <p class="error">* パスワードは4文字以上で入力してください</p>
  <?php endif; ?>
</dd>

==で判定しているので、問題なさそう。スペルミスも特に見つからず。

セッション開始後の条件文(画面遷移するか判断する部分)

ここで見つかりました。
以下はエラー状態のコーディングです。

<?php
session_start();
if (!empty($_POST)) {
  // エラーの確認
  if ($_POST['email'] == '') {
    $error['email'] == 'blank';
  }
  if (strlen($_POST['password']) < 4) {
    $error['password'] == 'Length';
  }
  if ($_POST['password'] == '') {
    $error['password'] == 'blank';
  }
  if (empty($error)) {
    $_SESSION['join'] = $_POST;
    header('Location: check.php');
    exit();
  }
}

うまくいったときは以下です。

<?php
session_start();
if (!empty($_POST)) {
  if ($_POST['email'] == '') {
    $error['email'] = 'blank';
  }
  if (strlen($_POST['password']) < 4) {
    $error['password'] = 'Length';
  }
  if ($_POST['password'] == '') {
    $error['password'] = 'blank';
  }
  if (empty($error)) {
    $_SESSION['join'] = $_POST;
    header('Location: check.php');
    exit();
  }
}

違いは、要するにここです。

誤 : $error['AAA'] == 'BBB'
正 : $error['AAA'] = 'BBB'

ifの中に記載しているところなので、配列にblankと代入する必要があるのですが、
代入ではなく比較演算子を使っていました(なんという凡ミス)。

最後の条件で配列が空だったら、ということが書いてあるので、
代入されずずっと比較し続けていたので、空のままだったようです。

まとめ

整理して感じたのは2つあります。
・確からしい事実を元に仮説を立てる方が効率が良い
・もし仮説を立ててなぜその仮説を立てたかを言語化できない場合は、上記が不十分な可能性が非常に高い

特に今回は「自分がなぜセッションに着目したか」を振り返ると未熟だと感じています。
今回着目した背景は正直、参考書に記載されていたからです(勉強不足が露呈した、、)
セッションがそもそもうまくいっていない状態とは何かを、全然理解していないんだと思いました。

今回はコーディングミスが原因だとわかりましたが、セッションの機能についてまとめて発信できたらと思います。
課題を深ぼることはある程度どの人もできると思いますが、どれを課題と特定して深ぼるかという着眼点、仮説を立てるポイントが重要だと感じました。
初学者が「何を聞いたらいいかわからない」というのはこの辺にあるのではと思ったので、自分が次直面する課題も、将来誰かの質問に応えるときもこの感覚は持っておこうと思います。

成功より失敗からの方が多くの学びが得られますね!
読んでいただきありがとうございます。