PHP マイクロ ルーティング コントローラー
以前はディスパッチを使用していましたが、API は 4.0 から現在の 8.0 まで大きく変わりました。特に、コードをシンプルに保つために、下位互換性機能が失われました。
著者の核となる考えがあまりしっかりしていないように感じます。そこで、自分でホイールを作りたいという衝動に駆られました。
これは、openresty で実行できる小型ルーティング コントローラーで、かつて作者が大幅な改訂を行うのに役立ち、現在はこのプロジェクトの 2 番目の貢献者です。
このアイデアは学ぶ価値があります:
ツリー構造を使用して、URL とハンドラーの間のマッピング関係を保存します。 (ツリー構造に従って検索することで、コールバック関数 Olog(n) を効率的に見つけることができます。
ただし、正規表現をキー マッピング ハンドラーとして使用する従来の方法では、コールバック関数を見つける時間が不安定で、最悪の場合、 、すべての正規表現は 1 回実行する必要があります)
リクエスト メソッドを match 関数のカプセル化形式として定義します。ルートをマップするための便利なフォームを提供します。
上記の 2 つの非常に優れた機能を考慮して、この Lua ライブラリを PHP で書き直しました。同時に、作成プロセス中にいくつかの新機能が追加されました:
エラー API が追加されました。1 つの API は 2 つの呼び出しメソッドを提供します (これは、jquery のいくつかのメソッドに似た、ディスパッチでのいくつかの機能を利用します)。両方 エラー ハンドラーを定義し、エラー ハンドラーの役割をトリガーします。
フック API を追加し、呼び出しメソッドも 2 つあります。
デフォルトでは、「前」と「後」の 2 つのフックがトリガーされます。それぞれ実際のハンドラーの実行前と実行後。
「before」フックの後にユーザー定義のフックを実行します。これらのフックは、コールバック関数を定義するときに現在の URL に対して呼び出す必要があるフックのリストです。 (もちろん、これらすべてのフックにはユーザー定義のコールバック関数が必要です)
この小型ルーティング コントローラーは、packagist Web サイトに送信されており、composer ツールを通じてインストールできます
composer require lloydzhou/router
(new Router())/* 定义错误处理函数 */->error(401, function($message){ header('Location: /login', true, 302); die($message);})->error(405, function($message){ header('Location: /hello/world', true, 302);})->error(406, function($message){ die($message);})/* 定义hook函数,除了内置默认调用的before和after,还定义了检查登录的auth */->hook('auth', function($params){ if ('lloyd' == $params['name']) return $params; $params['router']->error(401, 'Forbiden');})/* 定义after这个钩子函数,支持json或者jsonp格式输出 */->hook('after', function($result, $router){ if ($result) { header('Content-type: application/'. ($_GET['jsoncallback']?'javascript':'json')); if ($_GET['jsoncallback']) print $_GET['jsoncallback']. '('. json_encode($result). ')'; else print json_encode($result); }})->hook('before', function($params){ //$params['name'] = 'lloydzhou'; return $params;})/* 定义url映射 */->get('/', function(){ echo "Hello world !!!";})->get('/hello/:name', function($name){ echo "Hello $name !!!";})->get('/hello/:name/again', function($name){ echo "Hello $name again !!!";}, 'auth')->get('/hello/:name.:ext', function($name, $ext){ if ('js' == $ext || 'json' == $ext) return array('name'=>$name); return array('code'=>1, 'msg'=>'error message...');}, 'auth')/* 程序入口,以当前的url查找对应的处理函数,并获取变量执行该函数 */->execute();
php -S 0.0.0.0:8888 test.php
curl -vvv 127.0.0.1:8888/hello/url未能映射成功,触发405错误处理函数, 自动跳转向 URL: "/hello/world"curl -vvv 127.0.0.1:8888/hello/lloyd 返回 "Hello lloyd !!!"curl -vvv 127.0.0.1:8888/hello/lloyd/again 返回 "Hello lloyd again !!!"curl -vvv 127.0.0.1:8888/hello/world/again 在钩子函数auth处理失败触发401错误处理函数, 自动跳转到 URL: "/login"curl -vvv 127.0.0.1:8888/hello/lloyd.json 支持“/”和“.”作为pathinfo的分隔符,并且和after钩子函数配合,返回json格式文本 {"name": "lloyd"}curl -vvv 127.0.0.1:8888/hello/lloyd.js?jsoncallback=test返回jsonp格式文本 test({"name": "lloyd"})curl -vvv 127.0.0.1:8888/hello/lloyd.jsx?jsoncallback=test最后的后缀名不匹配,输出错误jsonp格式的消息 test({"code":1,"msg":"error message..."})
URLとハンドラー間のマッピング関係を保存するためにツリー構造を使用します。 URL マッピング関数を検索する場合、コールバック関数を見つける効率は O(log n) であることが保証されます。
正規表現を使用した従来のキー マッピング ハンドラー方法では、コールバック関数を見つけるのに必要な時間が不安定で、最悪の場合、すべての正規表現を 1 回実行する必要があります。
このライブラリをテストし、同時に改善するために。そこで、このライブラリを別の ActiveRecord および MicroTpl と組み合わせて使用し、基本的にこれらのライブラリの API をカバーする簡単なブログを作成しました。