PHP フレームワーク Session.php 作成

2018年5月8日

みなさんこんにちは!タカモリです。

セッションについて

今回は、phpの初心者なら必ず一回くらいは頭の整理が追い付かなくなるのではないのかと思われるセッションに関するクラスをやっていきたいと思います。

このクラスはそもそものsrcが少し長いのと、セッション自体が少しややこしいので2回くらいに分割しようと思います。

自分の場合はphpの勉強をしているときに、「セッション」とか「cookie」とかいう単語がでてきたときには、そのページがなかったことにして次に進んでいました。

で、後で勉強するするといいながら手を付けず、最近になってようやく「はぁ。。勉強するか」みたいな感じでシブシブ勉強していった感じです。

ですが安心して下さい。確かにcookieやセッションというものは名前からして複雑そうなイメージがありますが、実際勉強してみると以外に複雑ではないということが分かってきます。

セッションというのを簡単に説明すると、webサイトが常にユーザーを同一のユーザーであるということを認識し続ける仕組みです。

例えばwebサイトのログイン画面があって、そこにパスワードとidを入力し、自分しか入ることができないマイページのような画面に遷移するとしましょう。

この場合、残念なことにサーバーだけではログインを入力した人と、マイページを使用している人が同一のユーザーであるということが実は認識できていないのです。

これを同一ユーザーであると紐づけることができる仕組みがセッションです。

この仕組みには更にcookieという機能を使います。これはサーバーから送られた情報をブラウザに保存することのできる仕組みです。

サーバーではphpで、ある関数が呼ばれると、「セッションid」と呼ばれるものを発行し、それとともに「セッションファイル」というものを作成します。

セッションファイルというのは、サーバー上に作成されるのですが、セッションidについては上述のcookieを利用してブラウザに送られ、ユーザーのパソコン内に保存されます。

すると、そのセッションidを保存したユーザーのパソコンからサーバーへのリクエスト時に一緒に保存されているセッションidも同時に送りつけるということをやります。

すると、リクエストを受けた際にwebサイトではユーザーが必要なsessionidを送ってきたかどうかというのを判断します。

先ほどのログイン画面での例でいうと、ログイン後のマイページの画面ではユーザーがsessionidを送ってきたかどうかの判断をします。

送ってきた場合は、同一ユーザーとして先ほどログインしてきたユーザーであるということがこれで判定できるわけです。

そして、ブラウザに対してセッションidを発行する為のphpの関数というのが「session_start()」関数です。今回のsrcでは初っ端からそのsession_start()関数を使用していきますので、これを頭にイメージしてsrcに入っていきたいと思います。

というわけで今回のsrcはこちら

__construct()メソッド

今回のコンストラクタには引数が指定されていないのだが、何がしたいのかというと上で話したセッションidをユーザーに送るということをやりたいのだ。またsession_start()関数はユーザーが既にsessionidを持っていた場合には挙動が変わり、そのsseionidで前回作成したセッションファイルがサーバー側にあるはずなので、それを参照する。

それともう一つこのメソッドには気になる点がある。このメソッドにはsession_start()関数を実行する前の条件式がある。 if(!self::$sessionStarted) という部分であるが、このメソッドを再度全て直訳すると、もし$sessionStartedプロパティがfalseでないならばセッションスタートを実行し、$sesionStartedプロパティをtrueに変える。となる。

$sessionStartedプロパティには予めfalseが初期値として代入されているわけだが、それはいいとして問題はこの変数がstaticな変数だということである。

簡単にstaticについて説明すると、staticは静的なプロパティやメソッドを指定するときに使われるのだが、具体的にはクラスをインスタンス化しなくてもこのプロパティにアクセスすることができるようになる。

ちなみにパーフェクトphpの説明によると、「何かしらの理由で2回以上Sessionクラスが生成された場合に複数回session_start()が呼ばれないよう、静的プロパティを使ってチェックしています。」ということらしい。これ以外には説明はない

いやわからんわ!!!!

俺も詰まったとまではいかないが、何故静的メソッドがチェックの役割を果たすのか結構考えた。その結果導き出した答えが次だ。

session_start()関数は2回呼ばれるとエラーを惹き起こしてしまう関数である。この関数がコンストラクタに指定されているということは、パーフェクトphpの言うとおり2回インスタンス化されてしまうと対処法が無い場合はエラーが発生してしまうこととなる。

そこで、2回インスタンス化されるということは、どういうことかということを考えると、このクラスの参照が2つできるということだ。そして一度目にnewされ、このクラスをもとにAというオブジェクトができた場合は、セッションはもちろん開始される。

問題は次だ。

続いて2回目のBというオブジェクトがこのクラスを元にインスタンス化されたときに、例えばこの$sessionStartedがただのプロパティだとすると、設計図であるクラスはAオブジェクトと同じsessionクラスでもあくまでAとBは違うオブジェクトな為、$sessionStartedは初期値のfalseが入っている為、何の意味もなく再度session_start()関数が呼ばれてしまう。

しかし、これが静的メソッドの場合はこの$sessionStartedはオブジェクトではなくクラスに属する為、一度目にnewされた状態に変更されている「true」が入っているのだ。その為2回目のインスタンス時にはsession_start()関数は呼ばれない。

なるほど!!自分で納得するのもおかしい話だが多分こういうことであってるはずだ!なので2回呼ばれたくない関数については静的プロパティを使用していると。

というわけで、今回は長くなってしまったのでコンストラクタのみとさせていたいただいたが、次回でこのクラスを最後まで終わらせたいと思う。