テスト駆動開発でルーターを作る Part5
作成日時: | 2020年7月9日 |
更新日時: | 2020年7月11日 |
こんにちは、やみともです。
今回は前回「テスト駆動開発でルーターを作る Part4」の続きです。
今回はpostメソッドのルーティングができるように実装を進めましょう。
と言ってもまずはテストからです。
具体的には$routing_tableスタティック変数にgetもしくはpostのメソッド情報も登録するようにし、routingメソッドでそれを参照して処理するようにしました。
[ Router.php ]
今回は短いですがここまでとします。
ちなみにこれまでの説明もこれからの説明も下のテスト駆動開発の本を参考にしています。
テスト駆動開発に興味のある方は購入されてはどうでしょうか。
今回は前回「テスト駆動開発でルーターを作る Part4」の続きです。
今回はpostメソッドのルーティングができるように実装を進めましょう。
と言ってもまずはテストからです。
テスト
[ RouterTest.php RouterTestクラス ] public function test_routing_post()
{
Router::post("/contact", "ContactPost");
list($controller_class_name, $params) = Router::routing("post", "/contact");
$this->assertEquals("ContactPost", $controller_class_name);
}
テスト失敗
以下のように失敗します。$ p PHPUnit 9.2.5 by Sebastian Bergmann and contributors. ...E 4 / 4 (100%) Time: 00:00.019, Memory: 4.00 MB There was 1 error: 1) RouterTest::test_routing_post Error: Call to undefined method Router::post() /Users/yuki/testblog/yamitomo_router/tests/RouterTest.php:35 ERRORS! Tests: 4, Assertions: 4, Errors: 1.
実装
Routerクラスを少し修正しました。具体的には$routing_tableスタティック変数にgetもしくはpostのメソッド情報も登録するようにし、routingメソッドでそれを参照して処理するようにしました。
[ Router.php ]
<?php
class Router
{
private static $routing_table = [];
public static function get(string $url, string $controller)
{
// ルーティングテーブルにルートを登録する
// ★getやpostなどのHTTPメソッドも登録するように変更した
array_push(self::$routing_table, [
"method" => "get",
"url" => $url,
"controller" => $controller
]);
}
public static function post(string $url, string $controller)
{
// ルーティングテーブルにルートを登録する
// ★getやpostなどのHTTPメソッドも登録するように変更した
array_push(self::$routing_table, [
"method" => "post",
"url" => $url,
"controller" => $controller
]);
}
public static function routing(string $method, string $url)
{
// 念のため小文字化しておく
$method = strtolower($method);
// ルーティングテーブルのルートを1つずつ見ていきマッチしたコントローラークラス名を返す
for ($i = 0; $i < count(self::$routing_table); $i++) {
$route = self::$routing_table[$i];
$route_method = $route["method"];
$url_pat = $route["url"];
$controller = $route["controller"];
if ($route_method != $method) continue;
// URLパターンの?を\?に変換する
$url_pat = str_replace("?", '\?', $url_pat);
// int型のパラメータ名を抽出列挙する
preg_match_all("/\[int (?P<ints>[a-zA-Z0-9_]+)\]/", $url_pat, $match);
$ints = $match["ints"];
// str型のパラメータ名を抽出列挙する
preg_match_all("/\[str (?P<strs>[a-zA-Z0-9_]+)\]/", $url_pat, $match);
$strs = $match["strs"];
// パターンの作成
$pat = preg_replace("/\[int ([a-zA-Z0-9_]+)\]/", "(?P<$1>0|[1-9][0-9]*)", $url_pat);
$pat = preg_replace("/\[str ([a-zA-Z0-9_]+)\]/", "(?P<$1>[a-zA-Z0-9_]+)", $pat);
if (preg_match("#^{$pat}$#", $url, $match)) {
$params = [];
for ($j = 0; $j < count($ints); $j++) {
$key = $ints[$j];
$params[$key] = intval($match[$key]);
}
for ($j = 0; $j < count($strs); $j++) {
$key = $strs[$j];
$params[$key] = $match[$key];
}
$params = $params == [] ? null : $params;
return [$controller, $params];
}
}
}
}
これでテストも通りました。今回は短いですがここまでとします。
次回予告 & 本紹介
次回以降もルーターライブラリを作っていきます。ちなみにこれまでの説明もこれからの説明も下のテスト駆動開発の本を参考にしています。
テスト駆動開発に興味のある方は購入されてはどうでしょうか。