szenis / 路由
一个小巧简单的PHP路由器
v2.0.3
2017-10-28 15:04 UTC
Requires
- php: >=5.3.0
Requires (Dev)
- phpunit/phpunit: 4.1.x
This package is not auto-updated.
Last update: 2024-09-28 18:58:38 UTC
README
更新从0.x或1.x版本将会破坏您的代码!升级前请阅读文档!
入门指南
步骤 1 - .htaccess文件 在您项目的根目录创建一个 .htaccess文件并填写以下代码
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes...
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
步骤 2 - require szenis/routing
在您的终端执行: composer require szenis/routing
步骤 3 - 创建index.php
在您项目的根目录创建文件index.php
步骤 4 - require autoload.php并使用Router
以下示例展示了如何使用路由器。
<?php require './vendor/autoload.php'; use Szenis\Routing\Router; $router = new Router(); $router->get('/{n:date}-{w:item}', function($date, $item) { return 'hello world'; }); $response = $router->resolve($_SERVER['REQUEST_URI'], $_SERVER['REQUEST_METHOD']); switch ($response['code']) { case \Szenis\Routing\Route::STATUS_NOT_FOUND: // render your 404 page here... break; case \Szenis\Routing\Route::STATUS_FOUND: // the router only resolves the route, here is an example how to execute the route. if ($response['handler'] instanceof \Closure) { echo call_user_func_array($response['handler'], $response['arguments']); } break; }
添加到您的index.php中
可选
为了调试目的,请将以下代码添加到您的index.php中
error_reporting(E_ALL); ini_set('display_errors', 1);
用法
/** * initialize the router class */ $router = new Router(); /** * Route matches the url '/' for the GET method */ $router->add('/', 'GET', function() { // the closure will be executed when route is triggerd and will return 'hello world' return 'hello world!'; }); /** * It is posible to add one or multiple wildcards in one route */ $router->add('/user/{id}', 'GET', function($id) { return $id; }); /** * It is also posible to allow mulitple methods for one route (methods should be separated with a '|') */ $router->add('/user/{id}/edit', 'GET|POST', function($id) { return 'user id: '.$id; }); /** * Or when u are using controllers in a namespace you could give the full path to a controller (controller::action) * * Since version 2.0 executing the handler is up to you. */ $router->add('/user/{id}/delete', 'DELETE', 'App\Controllers\UserController::delete'); /** * Since version 1.1 there are shortcut methods for get, post, put, patch, delete and any. * You can use them as follow */ $router->get('/example/get', function() {}); // Will match GET requests $router->post('/example/post', function() {}); // Will match POST requests $router->put('/example/put', function() {}); // Will match PUT requests $router->patch('/example/patch', function() {}); // Will match PATCH requests $router->delete('/example/delete', function() {}); // Will match DELETE requests $router->any('/example/any', function() {}); // Will match GET, POST, PUT, PATCH, DELETE requests /** * resolve the route and receive the response * * The response is an array with the following keys * - code (contains 200 if the route is found, else 404) * - handler (contains the handler, often a \Closure or full path to your controller action) * - arguments (contains the route arguments if any) */ $response = $router->resolve($_SERVER['REQUEST_URI'], $_SERVER['REQUEST_METHOD']); /** * To execute your route you have to do the following */ switch ($response['code']) { case \Szenis\Routing\Route::STATUS_NOT_FOUND: // render your 404 page here... break; case \Szenis\Routing\Route::STATUS_FOUND: // the router only resolves the route, here is an example how to execute the route. if ($response['handler'] instanceof \Closure) { echo call_user_func_array($response['handler'], $response['arguments']); } // if your handler is a full path to your function you could execute it with this: $className = substr($response['handler'], 0, strpos($response['handler'], '::')); $functionName = substr($response['handler'], strpos($response['handler'], '::') + 2); echo call_user_func_array(array((new $className), $functionName), $response['arguments']); break; }
通配符选项
以下选项存在- a:(仅字母字符)
- n:(仅数字)
- an:(仅字母数字字符)
- w:(仅字母数字、破折号和下划线)
- ?:(可选参数)-必须是URL的最后一部分
- *:(懒加载)-必须是URL的最后一部分
如何使用
// The id must be a number $router->add('/user/{n:id}', 'GET', 'App\Controllers\UserController::show'); // The id must contain either alfabetic chars or numbers $router->add('/user/{an:id}', 'GET', 'App\Controllers\UserController::show'); // Now we want everything behind docs/ in the page variable // For example when we go to the url /docs/user/edit we will receive user/edit in the page variable $router->add('/docs/{*:page}', 'GET', function($page) { // do something with $page }); // Optional parameter example $router->add('/hello/{a:name}/{?:lastname}', 'GET', function($name, $lastname = null) { // check if lastname is provided // if ($lastname) {...} })
从v0.x/v1.x升级到v2.x
- 命名空间已从
\Szenis
更改为\Szenis\Routing
$router->setNamespace()
已被删除!- RouteResolver不应用于解析路由,请使用以下代替:
$router->resolve($uri, $method);
- 路由器不再执行路由。从现在起,执行处理器的责任由您承担。在“用法”部分的底部有一个执行处理器的示例。
变更日志
v2.0.0
- 移除了'default'命名空间
- 命名空间从\Szenis更改为\Szenis\Routing
- 路由器不再自行执行可调用对象,这为您提供了更多参数注入的控制权
- RouteResolver可通过路由器调用
- 修复了bug:现在可以在一个段中拥有多个参数(/{参数1}-{参数2}/)
v1.1.0
- 为get、post、put、patch、delete和any提供了快捷函数
v1.0.0
- 更新了README
- 可能添加默认命名空间
v0.9.0
- 100%测试覆盖率
- 最低PHP版本从5.4降低到5.3
v0.8.0
- 添加了可选参数
- 添加了懒加载URL
- 改进了代码
v0.7.0
- 改进了代码
v0.6.0
- 更改了路由器的用法,请查看
用法
部分以获取更多详细信息 - 可能将闭包添加到路由器
- 现在可以找到带有查询字符串的路由器(bug修复:v0.6.1)
v0.5.0
- 移除了不必要的代码
v0.4.0
- 添加了接口并创建了一个URL工厂
v0.3.0
- 现在可以为URL通配符添加选项,有关更多信息请参阅
通配符选项
v0.2.0
- RouteResolver使用正则表达式来更快地匹配路由器