它讀取 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”
現在,讓我們配置路徑