它读取 URL 路由并解析路径的值,因此可以以最快的方式手动或自动解释它(例如,实现 MVC 系统)。
与其他库不同,该库没有依赖项,并且包含在单个类中,因此它与任何 PHP 项目兼容,例如 WordPress、Laravel、Drupal、自定义 PHP 项目等。
该库基于CoC Convention over Configuration 。它减少了样板文件,但具有固定的功能。该库不允许使用自定义“路由”,但它几乎涵盖了所有情况,因此它提高了性能和可用性,同时牺牲了灵活性。
假设我们有下一个 URL http://somedomain.dom/Customer/Update/2 该库将此 URL 转换为可以处理或直接调用方法的变量。
路线.php
$ route = new RouteOne ( ' http://www.somedomain.dom ' );
$ route -> addPath ( ' api/{controller}/{action}/{id} ' );
$ route -> addPath ( ' {controller}/{action}/{id}/{idparent} ' );
$ route -> fetchPath ();
$ this -> callObjectEx ( ' cocacolacontroller{controller}Controller ' );
控制器CustomerController.php 类
namespace cocacola controller ;
class CustomerController {
public function updateAction ( $ id = null , $ idparent = null , $ event = null ) {
echo " We want to update the customer $ id " ;
}
}
假设我们进行下一个操作:
用户调用下一个网站http://somedomain.com/Customer/Insert,他想要显示一个表单来插入客户
use eftec RouteOne RouteOne ;
$ route = new RouteOne ( ' . ' , null , null ); // Create the RouteOne Class
$ route -> fetch (); // fetch all the input values (from the route, get, post and such).
$ route -> callObject ( ' somenamespace \ controller \ %sController ' ); // where it will call the class CustomerController*
或者
use eftec RouteOne RouteOne ;
$ route = new RouteOne ( ' . ' , null , null ); // Create the RouteOne Class
$ route -> fetch (); // fetch all the input values (from the route, get, post and such).
$ route -> callObjectEx ( ' somenamespace \ controller \ {controller}Controller ' ); // where it will call the class CustomerController*
此代码调用Customer类中的InsertActionGet (GET)、 InsertActionPost (POST) 或InsertAction (GET/POST) 方法
调用的方法写法如下:
class Customer {
public function insertAction ( $ id = "" , $ idparent = "" , $ event = "" ) {
// here we do our operation.
}
}
让我们假设我们要更新客户编号20 ,然后我们可以调用下一页
http://somedomain.com/Customer/Update/20
其中 20 是要编辑的客户的“$id”(可以是字符串中的数字)
如果我们想要更新企业APPL的客户编号20 ,该怎么办?
http://somedomain.com/Customer/Update/20/APPL
其中 APPL 是idparent
现在,假设我们单击某个按钮,或者执行一些操作。它可以由字段_event捕获,并由参数$event读取。该变量可以通过 GET 或 POST 发送。
http://somedomain.com/Customer/Update/20/APPL?_event=click
注意:如果使用addPath()和fetchPath(),模块会自动获取,因此不需要指定。现在,假设我们的系统是模块化的,并且我们有多个客户(内部客户、外部客户等)
$ route = new RouteOne ( ' . ' , null , true ); // true indicates it is modular.
或者
$ route = new RouteOne ( ' . ' , null ,[ ' Internal ' ]); // or we determine the module automatically. In this case, every url that starts with Internal
然后
$ route -> fetch ();
$ route -> callObject ( ' somenamespace \ %2s% \ controller \ %1sController ' );
http://somedomain.com/Internal/Customer/Update/20/APPL?_event=click
然后,第一个分支是模块的名称( Internal ),它调用类somenamespaceInternalcontrollerCustomerController
作曲家需要 eftec/ RouteOne
Linux:
vendor/bin/ RouteOne cli -init (if the binary does not work, then chage the permission to execution)
视窗:
. v endor b in r outeonecli.bat -init
它将创建文件 .htaccess 和文件route.php,并且route.php 将具有默认配置。
const BASEURL = " http://localhost " ; // Base url edit this value.
const BASEWEBNS = " eftec \ controller " ; // Base namespace (web) edit this value
const BASEAPINS = " eftec \ api " ; // Base namespace (api) edit this value
稍后,您可以在此文件中添加或编辑代码。
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
DirectoryIndex route.php
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ route.php?req=$1 [L,QSA]
</IfModule>
如果您的网络主机不允许 FollowSymlinks 选项,请尝试将其替换为 Options +SymLinksIfOwnerMatch。
重要的一行是:
RewriteRule ^(.*)$route.php?req=$1 [L,QSA] # 要调用的路由器。
server {
listen 80;
server_name localhost;
root /example.com/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.html index.htm index.php;
charset utf-8;
location / {
try_files $uri $uri/ /router.php?req=$document_uri&$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ .php$ {
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /.(?!well-known).* {
deny all;
}
}
重要的一行是:
try_files $uri $uri/ /router.php?req=$document_uri&$query_string;
server {
listen 80;
server_name localhost;
root c:/www;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.html index.htm index.php;
charset utf-8;
location / {
try_files $uri $uri/ /router.php?req=$document_uri&$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ .php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /.(?!well-known).* {
deny all;
}
}
重要的一行是:
try_files $uri $uri/ /router.php?req=$document_uri&$query_string;
其中router.php是将其用作路由器的文件。 ?req=$1 很重要,因为系统将从“req”读取路线
// router.php
$ route = new RouteOne (); // Create the RouteOne Class
$ route -> fetch (); // fetch all the input values (from the route, get, post and such).
$ route -> callObject ( ' somenamespace \ controller \ %sController ' ); // where it will call the class somenamespacecontrollerCustomerController
笔记:
如果您想使用与“req”不同的参数,则可以使用以下代码更改它:
$route->argumentName='newargument';
从 1.21 开始,可以使用自定义路径而不是预定义路径。这是推荐的方式。另一种方法仍然存在。
句法:
清除路径()
它清除所有定义的路径
句法:
addPath($path, $name = null,可调用$middleWare=null)
它添加了可以使用 fetchPath() 评估的路径
例子:
$ this -> addPath ( ' api/{controller}/{action}/{id:0} ' , ' apipath ' );
$ this -> addPath ( ' /api/{controller}/{action}/{id:0}/ ' , ' apipath ' ); // "/" at the beginner and end are trimmed.
$ this -> addPath ( ' {controller}/{action}/{id:0} ' , ' webpath ' );
$ this -> addPath ( ' {controller:root}/{action}/{id:0} ' , ' webpath ' ); // root path using default
$ this -> addPath ( ' somepath ' , ' namepath ' ,
function ( callable $ next , $ id = null , $ idparent = null , $ event = null ) {
echo " middleware n" ;
$ result = $ next ( $ id , $ idparent , $ event ); // calling the controller
echo " endmiddleware n" ;
return $ result ;
});
笔记:
路径的第一部分,位于“{”之前,用于确定将使用哪个路径。
例如“path/{controller}”和“path/{controller}/{id}”,系统会认为是相同的路径
参数字符串 $path 路径,例如“aaa/{controller}/{action:default}/{id}”
其中default是可选的默认值。
参数string|null $name (可选),路径的名称
参数callable|null $middleWare 用于中间件的可调用函数。
函数的第一个参数必须是可调用方法
接下来的参数必须是由 callObjectEx 定义的参数
(id,idparent,事件)
该路径可以从静态位置开始,但路径的其余部分必须由变量(用 {} 括起来)定义并用“/”分隔。
您还可以通过在变量名称后写入“:”来设置路径的默认值:{name:defaultvalue}
可以使用 $this->currentPath 获取该名称。如果您添加具有相同名称的名称,则会将其替换。
如果您未设置名称,则它将使用自动数字。
当您调用 $this->fetchPath() 时也会返回该名称
例子:
$ this -> addPath ( ' {controller}/{id}/{idparent} ' );
$ this -> addPath ( ' myapi/otherfolder/{controller}/{id}/{idparent} ' );
$ this -> addPath ( ' {controller:defcontroller}/{action:defaction}/{id:1}/{idparent:2} ' );
// url: /dummy/10/20 =>(controller: dummy, id=10, idparent=20)
// url: /myapi/otherfolder/dummy/10/20 =>(controller: dummy, id=10, idparent=20)
您可以定义不同的路径,但它仅使用与某些 URL 匹配的路径的第一部分。 'path/somepath/{id}' 将起作用 'path/{id}/other' 将不起作用
句法:
获取路径()
它获取先前由 addPath 定义的路径,并返回路径的名称(或编号)。如果没有找到,则返回 false
例子:
$ route = new RouteOne ( ' http://www.example.dom ' );
$ route -> addPath ( ' {controller}/{id}/{idparent} ' , ' optionalname ' );
// if the url is : http://www.example.dom/customer/1/200 then it will return
echo $ route -> fetchPath (); // optionalname
echo $ route -> controller ; // customer
echo $ route -> id ; // 1
echo $ route -> idparent ; // 200
它获取一个查询值(URL)。
注意:此查询不包含值“req”、“_event”和“_extra”
例子:
// http://localhost/..../?id=hi
$ id = $ router -> getQuery ( " id " ); // hi
$ nf = $ router -> getQuery ( " something " , " not found " ); // not found
它设置一个查询值
例子:
$ route -> setQuery ( " id " , " hi " );
$ id = $ router -> getQuery ( " id " ); // hi
语法:
获取路径()
从路由中获取值,并对值进行处理。
辛塔克斯
callObjectEx($classStructure, $throwOnError, $method, $methodGet, $methodPost,$arguments,$injectArguments)
它创建一个对象的新实例(例如,Controller 对象)并调用该方法。
注意:它是 this::callObject() 的高级版本
此方法使用 {} 替换基于以下变量的值:
标签 | 描述 |
---|---|
{控制器} | 控制器名称 |
{行动} | 目前的行动 |
{事件} | 当前事件 |
{类型} | 当前路径类型(ws,controller,front,api) |
{模块} | 当前模块(如果模块处于活动状态) |
{ID} | 当前id |
{id父} | 当前的idparent |
{类别} | 当前类别 |
{子类别} | 当前子类别 |
{子子类别} | 当前子类 |
例子:
// controller example http://somedomain/Customer/Insert/23
$ this -> callObjectEx ( ' cocacolacontroller{controller}Controller ' );
// it calls the method cocacolacontrollerCustomer::InsertAction(23,'','');
// front example: http://somedomain/product/coffee/nescafe/1
$ this -> callObjectEx ( ' cocacolacontroller{category}Controller ' // the class to call
, false // if error then it throw an error
, ' {subcategory} ' // the method to call (get, post or any other method)
, null // the method to call (method get)
, null // the method to call (method post)
,[ ' subsubcategory ' , ' id ' ] // the arguments to call the method
,[ ' arg1 ' , ' arg2 ' ]); // arguments that will be passed to the constructor of the instance
// it calls the method cocacolacontrollerproduct::coffee('nescafe','1');
使用当前路由调用对象内部的方法。
例子:
路由器:
$ databaseService = new SomeDatabaseService ();
$ route = new RouteOne ();
$ route -> callObjectEx ( ' cocacolacontroller{controller}Controller ' // the class to call
, false // if error then it throw an error
, ' {action}Action ' // the method to call (get, post or any other method)
, ' {action}Action{verb} ' // the method to call (method get)
, ' {action}Action{verb} ' // the method to call (method post)
,[ ' id ' , ' idparent ' , ' event ' ] // the arguments to call the method
,[ $ databaseService , $ route ]); // (optional)arguments that will be passed to the constructor of the instance
控制器:
namespace cocacola controller ;
class CustomerController {
protected $ databaseService ;
protected $ route ;
public function __construct ( $ databaseService , $ route ) {
// optional: injecting services
$ this -> databaseService = $ databaseService ;
$ this -> route = $ route ;
}
// any action GET or POST
public function GreenAction ( $ id = "" , $ idparent = "" , $ event = "" ) {
}
// GET only action (optional)
public function BlueActionGET ( $ id = "" , $ idparent = "" , $ event = "" ) {
// **my code goes here.**
}
// POST only action (optional)
public function YellowActionPOST ( $ id = "" , $ idparent = "" , $ event = "" ) {
// **my code goes here.**
}
// GET only action (optional)
public function RedActionGET ( $ id = "" , $ idparent = "" , $ event = "" ) {
// **my code goes here.**
}
// any action GET or POST
public function RedAction ( $ id = "" , $ idparent = "" , $ event = "" ) {
// **my code goes here.**
}
}
结果:
网址 | 方法称为 |
---|---|
http://localhost/Customer/Green (GET) | 绿色行动 |
http://localhost/Customer/Green/20/30?_event=click (GET) | GreenAction($id=20, $idparent=30, $event='点击') |
http://localhost/Customer/Green (POST) | 绿色行动 |
http://localhost/Customer/Blue (GET) | 蓝色行动GET |
http://localhost/Customer/Blue (POST) | 错误 |
http://localhost/Customer/Yellow (GET) | 错误 |
http://localhost/Customer/Yellow (POST) | 黄色动作POST |
http://localhost/Customer/Red (GET) | RedActionGET(优先于 RedAction) |
http://localhost/Customer/Red (POST) | 红色行动 |
http://localhost/客户/Orange | 错误 |
它使用控制器的当前名称调用(包含)一个 php 文件
句法:
getHeader($key, $valueIfNotFound = null)
它获取当前标头(如果有)。如果未找到该值,则返回 $valueIfNotFound。请注意,$key 始终转换为大写。
例子:
$ token = $ this -> getHeader ( ' token ' , ' TOKEN NOT FOUND ' );
句法:
getBody($jsonDeserialize = false, $asAssociative = true)
它获取请求的正文。
例子:
$ body = $ this -> getBody (); // '{"id"=>1,"name"=>john}' (as string)
$ body = $ this -> getBody ( true ); // stdClass {id=>1,name=>john}
$ body = $ this -> getBody ( true , true ); // ["id"=>1,"name"=>john]
返回当前的基本 url,无需遍历空格、参数或查询
注意:此函数依赖于 $_SERVER['SERVER_NAME'],最终用户可以修改它
它返回当前服务器,不带尾部斜杠。
$ route -> getCurrentServer (); // http://somedomain
它设置当前服务器名称。它由 getCurrentUrl() 和 getCurrentServer() 使用。
注意:如果未设置$this->setCurrentServer(),则使用$_SERVER['SERVER_NAME'],并且可以由用户修改。
$ route -> setCurrentServer ( ' localhost ' );
$ route -> setCurrentServer ( ' 127.0.0.1 ' );
$ route -> setCurrentServer ( ' domain.dom ' );
它根据类中的信息获取(完整)url。
$ route -> getUrl (); // http://somedomain/controller/action/id
$ route -> getUrl ( ' id=20 ' ); // http://somedomain/controller/action/id?id=20
$ route -> getUrl ( ' id=20 ' , true ); // http://somedomain/controller/action/id?id=20&field=20&field2=40
它根据自定义值构建一个 url
$ route -> url ( null , " Customer " , " Update " , 20 ); // Customer/Update/20
它根据自定义值构建一个 url(前面)
$ route -> url ( null , " Daily " , " Milk " , 20 ); // Daily/Milk/20
如果子域为空或与 www 不同,则重定向到 www.domain.com。
注意:它不适用于 localhost、没有 TLD (netbios) 的域或 ip 域。这是故意的。
注意:如果此代码需要重定向,则会停止代码的执行。通常必须在代码顶部调用
$ route -> alwaysWWW (); // if the domain is somedomain.dom/url, then it redirects to www.somedomain.dom/url
$ route -> alwaysWWW ( true ); // if the domain is http: somedomain.dom/url, then it redirects to https: www.somedomain.dom/url
如果页面以 http 方式加载,则会重定向到 https。
注意:它不适用于 localhost、没有 TLD (netbios) 的域或 ip 域。这是故意的。
注意:如果此代码需要重定向,则会停止代码的执行。通常必须在代码顶部调用
$ route -> alwaysHTTPS (); // http://somedomain.com ---> https://somedomain.com
$ route -> alwaysHTTPS (); // http://localhost ---> // http://localhost
$ route -> alwaysHTTPS (); // http://127.0.0.1 ---> // http://127.0.0.1
$ route -> alwaysHTTPS (); // http://mypc ---> // http://mypc
如果子域是 www(例如 www.domain.dom),那么它会重定向到裸域 domain.dom
注意:它不适用于 localhost、没有 TLD (netbios) 的域或 ip 域。这是故意的。
注意:如果此代码需要重定向,则会停止代码的执行。通常,必须在代码顶部调用
$ route -> alwaysNakedDomain (); // if the domain is www.somedomain.dom/url, then it redirects to somedomain.dom/url
$ route -> alwaysNakedDomain ( true ); // if the domain is http: www.somedomain.dom/url, then it redirects to https: somedomain.dom/url
场地 | 小路 | 描述 | 例子 |
---|---|---|---|
$参数名称 | Apache .Htaccess 和 nginx 使用的参数名称 | $this-argumentName='req'; | |
$基数 | 这是基本网址。 | $这个->基=0; | |
$类型 | 它是 url 的类型(api、ws、controller 或 front) | 回显$this->类型; // 接口 | |
$模块 | {模块} | 这是当前模块 | 回显$this->模块; |
$控制器 | {控制器} | 这是控制器。 | 回显$this->控制器; |
$行动 | {行动} | 就是这个动作。 | 回显 $this->action; |
$id | {ID} | 这是标识符 | 回显 $this->id; |
$事件 | {事件} | 这是事件(例如“单击按钮”)。 | 回声$这个->事件; |
$idparent | {id父} | 它是当前的父 ID(如果有) | 回显 $this->idparent; |
额外$ | {额外的} | 这是事件(例如“单击按钮”) | 回显 $this->额外; |
$类别 | {类别} | 当前类别。它对于“front”类型很有用 | 回声 $this->类别; |
$子类别 | {子类别} | 当前子类别。它对于“front”类型很有用 | echo $this->子类别; |
$sub子类别 | {子子类别} | 当前的子子类别。它对于“front”类型很有用 | echo $this->子子类别; |
$识别 | 它是一个关联数组,有助于识别 api 和 ws 路由。 | $this->identify=['api'=>'apiurl','ws'=>'webservices','controller'=>'']; | |
$isPostBack | 如果页面是 POST,则为 true,否则为 false。 | if ($this->isPostBack) { ... }; | |
$动词 | {动词} | 当前动词,可以是 GET、POST、PUT 和 DELETE。 | if ($this->verb) { ... }; |
例子:
$ this -> addPath ( ' portal/web/{controller}/{action:list} ' );
$ this -> fetchPath ();
var_dump ( $ this -action); // it shows the current action or the default value "list" if none.
场地 | 描述 | 例子 |
---|---|---|
$allowedVerbs | 允许使用的动词列表 | $this->allowedVerbs=['GET', 'POST', 'PUT', 'DELETE']; |
$allowedFields | 包含callObjectEx()使用的允许字段的列表 | $this->allowedFields=['控制器', '动作', '动词', '事件', '类型', '模块', 'id' , 'idparent','类别', '子类别', '子子类别']; |
设置白名单() | 它将与白名单关联的数组设置为controller 、 action 、 category 、 subcategory 、 subsubcategory和module 。 如果未设置(空默认值),则允许任何条目。 目前它仅适用于控制器和类别 | $this->setWhitelist('控制器','采购','发票','客户'); $this->setWhitelist('controller',null) // 允许任何控制器; |
将方法列入白名单允许两种操作:
例如:
// Example, value not in the whitelist: someweb.dom/customer/list
$ this -> setWhiteList ( ' controller ' ,[ ' Product ' , ' Client ' ]);
$ this -> fetch ();
var_dump ( $ this -> controller ); // null or the default value
var_dump ( $ this -> notAllowed ); // true (whitelist error)
// Example, value in the whitelist but with the wrong case: someweb.dom/customer/list
$ this -> setWhiteList ( ' controller ' ,[ ' Customer ' ]);
$ this -> fetch ();
var_dump ( $ this -> controller ); // it shows "Customer" instead of "customer"
var_dump ( $ this -> notAllowed ); // false (not error with the validation of the whitelist)
// reset whitelist for controllers
$ this -> setWhiteList ( ' controller ' , null );
RouteOne包含用于创建和初始化配置的基本 CLI。二进制RouteOne cli位于供应商/bin 文件夹中
./vendor/bin/ RouteOne cli
输入路由器并按 Enter 键。
在路由器菜单中,它将显示下一个屏幕:
待处理意味着操作正在等待执行,或者需要配置某些内容。
完成后,配置将被标记为“ok”
现在,让我们配置路径