di-zatech / burp
一个简单的PHP路由器,与查询字符串和uri-segments一起工作,laravel过滤器系统
Requires
- php: >=5.4.0
- illuminate/support: ^5.0|^6.0|^7.0|^8.0|^9.0|^10.0
This package is auto-updated.
Last update: 2024-09-25 16:53:26 UTC
README
一个简单的php 路由器,可以与 "URI","查询字符串" 或两者同时工作。
它还包含一个简单的 事件监听器 实现(用于触发或队列应用程序事件)。
您可以在您首选的框架中使用Burp(包括laravel),它并不试图成为唯一的路由器,它只是检查您的URL然后触发或队列事件。
为什么
理念是拥有一个“一站式”的路由器、过滤器、事件监听器。
这是一种构建事件驱动的控件和定义灵活的“语义”应用程序URL的方法
Burp可以为受 uri-segments、查询字符串 或两者驱动的控件供电,而无需拥有经典的控制器。
安装
使用composer安装,添加 "zofe/burp": "3.0.*"
如果您正在使用laravel,请将服务提供者在config/app.php中添加
'providers' => array(
...
'Zofe\Burp\BurpServiceProvider',
)
用法
Burp类似于任何其他PHP路由器,但它也可以作为过滤器使用。
您需要了解的两个主要区别是
-
路由规则可以是 严格 或 非严格(这意味着:“精确匹配”或“部分匹配”,即非严格规则可以匹配一些uri-segment或一些查询字符串参数)
-
规则是非阻塞的,这意味着单个HTTP请求可以触发多个路由
示例
<?php //catch /user/2 (GET) Burp::get('^/user/(\d+)$', null, array('as'=>'user.show', function($id) { //show user $id })); //catch /user (POST) Burp::post('^/user$', null, array('as'=>'user.create', function() { //create new user })); //catch /user/2 (PATCH) Burp::patch('^/user/(\d+)$', null, array('as'=>'user.update', function($id) { //save changes for user $id })); //catch /welcome (on any http method: GET, POST, ...) Burp::any('^/welcome/(\w+)$', null, function($username) { //say welcome $username! })); //catch /something?apikey=xxxx Burp::get(null, 'apikey=(\w+)', array('as'=>'key', function($key) { //check api key in query string.. })); //will return: /currenturi?apikey=asda Burp::linkRoute('key','asda') Burp::dispatch();
重要
- 要定义“严格规则”,您必须使用正则表达式的界定符 ^ 和 $
- 要定义“参数”,您必须使用括号,就像正则表达式原子一样
绑定控制器
您可以使用'uses'键将路由绑定到某个 class@method
<?php //catch /user/2 (GET) and bind it to UserController class on show method Burp::get('^/user/(\d+)$', null, array('as'=>'user.show', 'uses'=>'UsersController@show'));
用法 - 前端控制器完整示例
如果您需要“独立”上下文中的Burp,您需要一个前端控制器。
您可以从这个 .htaccess开始(大多数应用程序框架已经有了类似的东西)
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
然后您需要包含burp,这是将Burp作为独立路由器的一种方式
<?php #index.php require_once __DIR__ . '/vendor/autoload.php'; use Zofe\Burp\Burp; //widget routing - fired when url is for example: /something/pg/2 Burp::get('pg/(\d+)', null, array('as'=>'page', function($page) { echo "current page is page: $page<br>"; })); //widget routing - fired when url is for example: /something?ord=-title Burp::get(null, 'ord=(-?)(\w+)', array('as'=>'orderby', function($direction, $field) { $direction = ($direction == '-') ? "descending" : "ascending"; echo "current sorting is on : $field ($direction)<br>"; }))->remove('page'); //strict route - fired when uri is "/" or "/pg/2", but not when is "/something/pag/2" ... Burp::get('^/{page?}$', null, array('as'=>'home', function() { echo '<hr>'; echo '<a href="'.Burp::linkRoute('page',1).'">page 1</a><br>'; echo '<a href="'.Burp::linkRoute('page',2).'">page 2</a><br>'; echo '<a href="'.Burp::linkRoute('orderby',array('','title')).'">sort title up</a><br>'; echo '<a href="'.Burp::linkRoute('orderby',array('-','label')).'">sort label down</a><br>'; echo '<hr>'; })); //404 route - fired only if there are defined strict routes (i.e.: ^/$ or ^.*$) //but all uncatched Burp::missing(function() { header("HTTP/1.0 404 Not Found"); echo '404 - Resource Not Found'; die; }); //where all began Burp::dispatch();
模式
您还可以声明和使用模式
Burp::pattern('number', '(\d+)'); Burp::pattern('page', 'pg/(\d+)'); Burp::pattern('slug', '([a-z0-9-]+)'); Burp::get('articles/{page?}',... Burp::get('article/{slug}',...
重要:您必须使用括号来定义原子/s
用法 - 在laravel中
这个片段应该让您了解您可以使用Burp来
“定义跨laravel路由的行为”。
此URL: /article/list?ord=-title
将触发“sort”事件。
此URL: /article/list/pg/2?ord=title
将触发“sort”和“page”事件。
此外,如您所知,laravel分页“原生的”只与类似此的 /articles/list?page=1
一起工作
但是在这个示例中,对于这个控制器,它将通过段来工作
/articles/list/pg/x
(无需创建自定义分页类)。
<?php #in your laravel routes.php add Route::pattern('pg', 'pg/(\d+)'); Route::get('/articles/list/{pg?}', array('as'=>'art','uses'=>'ArticleController@getList')); //define some general purpose events on uri-segments Burp::pattern('pg', 'pg/(\d+)'); Burp::get('{pg}', null, array('as'=>'page', function($page) { \Event::queue('page', array($page)); })); //define some general purpose events on query-string Burp::get(null, 'ord=(-?)(\w+)', array('as'=>'orderby', function($direction, $field) { $direction = ($direction == '-') ? "DESC" : "ASC"; \Event::queue('sort', array($direction, $field)); }))->remove('page'); Burp::dispatch(); #in your controller class ArticleController extends BaseController { public function __construct() { //starting from a clean query builder $this->articles = new Article; //listen for burp defined events \Event::listen('sort', array($this, 'sort')); \Event::listen('page', array($this, 'page')); //flush queued events \Event::flush('sort'); \Event::flush('page'); } public function sort($direction, $field) { $this->articles = $this->articles->orderBy($field, $direction); } public function page($page) { \Paginator::setCurrentPage($page); } public function getList() { //paginate $articles = $this->articles->paginate(20); //fix links to use custom defined pagination-uri (instead classic 'page=?') $links = $articles->links(); $links = preg_replace('@href="(.*\?page=(\d+))"@U', 'href="'.Burp::linkRoute('page', '$2').'"', $links); return view('articles.list', compact('articles','links')); } }
现在您也可以自由更改您的URL-语义在您的路由器中,例如从查询字符串切换到uri-segments或反之亦然。
您还可以将事件和常见行为移动到基控制器中,然后扩展此控制器