初めてのPHP ⑥。GETとPOSTのルーティング

初めてのPHP ⑥。GETとPOSTのルーティング
この記事はこんな悩みを解決します
  • GETやPOSTを使うためのルーティングを設定したい
  • データベースを扱うための準備がしたい
  • PHPを勉強したい

データベースが使えるようになるとデータを保存したり削除したりしたくなると思います。そのためにはHTMLのformを使い、GETやPOSTメソッドを設定します。GETやPOSTを機能させるため、前回のルーティングを編集して行きましょう。

この記事を読むことでGETやPOSTを使う準備ができます。

初めてのPHP ⑥。GETとPOSTのルーティング

GETやPOSTメソッドで渡って来たデータに対して適切なルーティングを行なって行きましょう。前回までのルーティングが基本になっているのでまだ確認していない方は下記の記事をチェックしてください。

全体のファイル構成は下記のようになっています。

─── PHP-start
    ├── core
        ├── Router.php
    ├── index.php  
    ├── routes.php  
    ├── view.php  
     ├── index.view.php 
    ├── controllers.php  

まずはHTMLを下記のように設定しましょう。

<body>
	<form method='GET' action='/comment'>
		<input name='comment'></input>
		<button type='submit'>Submit</button>
	</form>
</body>

ブラウザで確認すると下記のようになります。

では、actionで/commentにアクセスしようとしているのでルーティングを設定して行きます。

$router->define([
		'' => 'controllers/index.view.php',
 		'comment' => 'controllers/comment.php'
	]);

commentが渡って来たらcontrollers/comment.phpを機能させると設定してやります。

comment.phpではサーバーの情報を見れるようにしてやります。

<?php

var_dump($_SERVER);

では、ブラウザで確認してみましょう。commentと文字を入力してSubmitをクリックしてやります。

失敗してますね。
原因はroutesに登録した’comment’の後に?coment=commentが付いてきていることです。これにより、そんなルートはありませんと言われています。

この問題を解決するため、リクエストを読み込む方法を変える必要があります。
前回設定したindex.phpを確認してみましょう。

<?php

	require 'functions.php';

	$database = require 'core/bootstrap.php';

	require Router::load('routes.php')->direct(Request::uri());

?>

前回の記事で解説したようにdirect(Request::uri( ) )でroutes.phpで指定したルートを読み込んでいます。

ルーティングの変更

まずはuriメソッドを変えてやります。

class Request{
	public static function uri(){
		// return trim($_SERVER['REQUEST_URI'], '/');
    // 上記のままだとcomment?coment=commentがになるのでcommentだけにしてあげます。
		return trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/');
		//parse_urlでcomment?coment=commentを分解してPHP_URL_PATHでcommentのみにしています。
	}

}

これで余計な情報を取得せずにアクセスできます。

では、ブラウザでcommentと入力してsubmitをクリックします。

うまくサーバーの情報が取れてますね。

情報が多すぎてわかりにくいのでGETだけにしてあげます。

<?php

dd($_GET['comment']); //formでname='comment'にしたものが取れてくる

ブラウザで確認してみましょう。

うまく取れてきてますね。

これでGETはうまく行くのですがPOSTメソッドの場合はうまく動きません。(submitした後、リロードするとエラーになると思います。)

そこで、GETの場合とPOSTの場合で処理を変えてあげる必要があります。

POSTも機能する様に設定しよう

ルーティングを変えて行くためroutes.phpを編集します。

<?php

//$router->define([
//		'' => 'controllers/index.view.php',
// 		'comment' => 'controllers/comment.php'
//	]);

$router->get('', 'controllers/index.view.php');
$router->post('comment', 'controllers/comment.php');

//ブラウザで確認するようの処理
dd($router->routes);

defineの代わりにgetとpostメソッドを使っています。

Router.phpでgetとpostを定義して行きます。

class Router{
//$routesにGETとPOSTの配列を用意します。
	public $routes = [
		'GET' => [],
		'POST' => []
	];

	public static function load($file){
		$router = new static;
		require $file;
		return $router;
	}

//defineは使わないので消して良いです。
	public function define($routes){
		$this->routes = $routes;
	}

//上記で定義したroutesのGETに$uriをキーとして入れ、要素として$controllerを入れています。。
	public function get($uri, $controller){
		$this->routes['GET'][$uri] = $controller;
	}

//getと同じようにpostも書いて行きます。
	public function post($uri, $controller){
		$this->routes['POST'][$uri] = $controller;
	}

	public function direct($uri){
		if(array_key_exists($uri, $this->routes)){
			return $this->routes[$uri];
		}
}

少しごちゃごちゃして分かりにくいかもですが、$routesがどうなっているのか確認してみましょう。ブラウザでホーム画面にアクセスします。

GETとPOSTが配列の中にあり、さらにGETには” ”空白キーに対してindex.view.php、POSTにはcommentキーに対してcomment.phpが渡っています。

これで設定ができたので呼び出すときの処理も書いて行きます。

まずはindex.phpでdirectメソッドを使うときにGETかPOSTか判別できるようにしてやります。

// require Router::load('routes.php')->direct(Request::uri());
// 上記ではGETとPOSTを使い分けれないのでdirect関数にmethodを定義しています。
require Router::load('routes.php')->direct(Request::uri(), Request::method());

では、methodを定義して行きます。

public static function method(){
		return $_SERVER['REQUEST_METHOD'];
	}

さらに、directメソッドの中でmethodを使って処理して行きます。

//public function direct($uri){
//		if(array_key_exists($uri, $this->routes)){
//			return $this->routes[$uri];
//		}

//GETかPOSTの配列から$uriを探して$uriの要素を返すように設定しています。
public function direct($uri, $method){
		if(array_key_exists($uri, $this->routes[$method])){
			return $this->routes[$method][$uri];
		}

routesの中のGETかPOSTの配列に$uriがあれば$uriに応じたコントローラーを返すという設定です。

では、HTMLのGETをPOSTに変えて確認して行きましょう。

<body>
	<form method='POST' action='/comment'>
		<input name='comment'></input>
		<button type='submit'>Submit</button>
	</form>
</body>

コントローラーのcomment.phpもPOSTを取ってくるように変えて行きます。

<?php

dd($_POST['comment']);

commentと入力してsubmitしてみます。

入力した内容がうまく取れてきてますね。リロードしてもエラーにならないと思います。

これでGETやPOSTを使うためのルーティングが設定できました。

まとめ

今回はGETやPOSTのためのルーティングの設定を行いました。

データベースを扱うためには必要なルーティングです。次回はいよいよ入力した内容をデータベースに保存して行きましょう。

関連記事