迷い人

日々勉強。勉強の先に何か見つかるといいなぁ

【PHP】パーフェクトPHPを解説してみる その3

本日はホーム画面からつぶやきを投稿した時の処理について解説したいと思います。

 

この記事でわかること

  • ホーム画面でつぶやいた後、つぶやき結果がDB登録されるまでの流れ

 

ホーム画面でつぶやいてからその結果がDB登録されるまで

f:id:oyaoya1123:20191014234358p:plain

まずホーム画面は以下の様になっています。

 

views/status/index.php

<?php $this->setLayoutVar('title', 'ホーム') ?> <h2>ホーム</h2>
#つぶやく登録フォーム <form action="<?php echo $base_url; ?>/status/post" method="post"> <input type="hidden" name="_token" value="<?php echo $this->escape($_token); ?>" /> <textarea name="body" row="2" cols="60"><?php echo $this->escape($body); ?></textarea> <p> <input type="submit" value="発言" /> </p> </form>
#つぶやき内容を表示 <div id="statuses"> <?php foreach($statuses as $status): ?> <?php echo $this->render('status/status', array('status' => $status)); ?> <?php endforeach; ?> </div>

 

textareaに入力された内容がpostで送信されます。

送信先はactionで指定されている通り「<?php echo $base_url; ?>/status/post」になります。

 

この送信先URLは以下のコントローラとアクションに対応しています。 

  • コントローラ → StatusController
  • アクション → postAction

 

投稿されたつぶやきをDB登録するためのメソッドpostActionについて

postActionメソッドはかなり長いですが、以下の様になっています。

 

controllers/StatusController.php

public function postAction() {
#メソッドがpostかチェック if (!$this->request->isPost()){ $this->forward404(); }
#csrf対策チェック $token = $this->request->getPost('_token'); if (!$this->checkCsrfToken('status/post', $token)){ return $this->redirect('/'); }
#つぶやき内容を取得 $body = $this->request->getPost('body'); $errors = array();
#つぶやき内容のチェック if(!strlen($body)){ $errors[] = 'ひとことを入力してください'; } else if (mb_strlen($body) > 200 ) { $errors[] = 'ひとことは200文字以内で入力してください'; } if (count($errors) === 0) {
#チェックでエラーが無かった場合、つぶやきを登録し、ホーム画面に戻る $user = $this->session->get('user'); $this->db_manager->get('Status')->insert($user['id'], $body); return $this->redirect('/'); } $user = $this->session->get('user'); $statuses = $this->db_manager->get('Status') ->fetchAllPersonalArchivesByUserId($user['id']); #チェックでerrorがあった時はホーム画面に戻る return $this->render(array( 'errors' => $errors, 'body' => $body, 'statuses' => $statuses, '_token' => $this->generateCsrfToken('status/post'), ), 'index'); }

 

コードの中にもコメントを書きましたが、コードを大きく分けると以下のようになります。

 

  • methodがpostかチェック
  • csrf対策チェック
  • つぶやき内容を取得
  • つぶやき内容をチェック
  • チェックでエラーがなければ、つぶやき内容を登録し、ホーム画面に遷移戻る
  • エラーがある場合はつぶやきのDB登録を行わずに、ホーム画面に戻る

 

methodがpostかチェック

送信データのmethodがpostかチェックします。今回はformタグでmethod=postと宣言しているのでチェックOKとなります。チェックする関数はRequestクラスで定義されています。

 

csrf対策チェック

簡単に解説すると、悪意あるユーザが本来のアカウント登録以外のページからアクセスしてきた時に、アカウント登録ページに戻します。

今回でいえば「status/post」に対応するトークンと呼ばれる文字列が送られてこない場合、戻ることになります。

 

つぶやき内容を取得

postで送信されてきたユーザIDとパスワードを取得しています。

 

つぶやき内容をチェック

文字数をチェックしています。

 

チェックでエラーがなければ、つぶやきを登録し、ホーム画面に戻る

少し複雑ですが順番に解説していきます。

まず、session->get('user')でログイン中のユーザ情報を取得します。

次にget('Status')でStatusRepositroyのインスタンスを作成し、insert()でstatusテーブルにつぶやきを登録しています。登録する時にログイン中のユーザIDも渡しています。

最後にリダイレクトでホームページ表示処理が動くことになります。

 

postAction実行後の処理

これまでの処理の大きな流れは以下の様になっています。

 

run(){
  resolve()
  runAction(){
    findController()
    run() ⇦ こいつがpostActionを呼び出して実行した
    setContent()
    }
  send()
}

 

各関数の機能を簡単に説明すると以下の様になっています。

  • run 処理全体を管理
  • resolve コントローラとアクションを特定
  • runAction アクション実行処理を管理
  • findController コントローラのインスタンスを作成
  • run アクションの実行
  • setContent アクション結果を格納
  • send アクション結果を画面に表示

 

今回はpostActionメソッドの最後にredirectで「"/"」を指定しているので、つぶやきをDB登録後にホーム画面に戻ることになります。

 

ホーム画面表示はまた別のメソッドが動くことになるので、その処理は次回に行いたいと思います。

 

おつかれさまでした。これでホーム画面からつぶやきを投稿し、DB登録までを解説しました。