吉吉霍霍/ichi-route

PHP项目的路由库

1.7.3 2024-03-24 07:20 UTC

This package is auto-updated.

Last update: 2024-09-22 05:40:05 UTC


README

ICHI PHP ROUTER旨在成为快速、易于使用且能够保护安全漏洞的PHP路由器

许可证

本软件包根据MIT许可证开源

目录

安装

composer require jijihohococo/ichi-route

设置

根据您的服务器,在设置路由之前,您必须创建以下htaccess文件。

Apache

在您的根目录下创建 .htaccess 文件


RewriteEngine On

RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]

Nginx

在您的根目录下创建 .htacess 文件


rewrite ^/(.*)/$ /$1 redirect;

if (!-e $request_filename){
	rewrite ^(.*)$ /index.php break;
}

创建控制器

您必须为您的路由创建控制器。

首先,您需要在项目目录下创建名为 "ichi" 的文件,并在该文件中使用以下代码:

#!/usr/bin/env php
<?php

require __DIR__.'/vendor/autoload.php';

use JiJiHoHoCoCo\IchiRoute\Command\RouteCommand;


$routeCommand=new RouteCommand;
$routeCommand->run(__DIR__,$argv);

然后您可以在命令行中创建控制器

php ichi make:controller ItemController

默认文件文件夹是 "app/Controllers"。所以执行命令后,您创建的控制器将位于此默认文件文件夹中。如果您想更改默认文件夹路径,您可以在 "ichi" 文件中更改它。

$routeCommand=new RouteCommand;
$routeCommand->setPath('new_app/Controllers');
$routeCommand->run(__DIR__,$argv);

单一路由

您可以使用 "get"、"post"、"put"、"delete" 和 "head" 函数添加路由。

每个函数代表每种路由方法

您可以使用闭包函数或控制器类的函数添加路由。

使用闭包函数

use JiJiHoHoCoCo\IchiRoute\Router\Route;

$route=new Route;
$route->get('items',function(){
	echo "show items";
});

使用控制器类

$route->get('items','App\Controllers\ItemController@show');

在使用路由函数之前,您必须在 composer.json 中自动加载您的控制器文件夹。

"autoload": {
	"psr-4": {
		"App\\": "app/"
	}
}

如果您所有控制器的控制器路径相同,您可以在添加路由之前为所有路由设置基本控制器路径。

$route->setBaseControllerPath('App\Controllers');

要运行所有路由,您必须使用 "run()" 函数。

在声明系统中的所有路由之后,您必须使用 "run()" 函数。

$route->run();

运行路由函数后,路由(URL)可以运行

'items/' (GET METHOD)

PATCH方法

要创建PATCH方法,您需要__method请求,并在此处添加'PATCH'值。动作必须是'POST'。

在您的路由中

$route->patch('items','App\Controllers\ItemController@show');

对于表单数据

<form action="<?php echo route('items'); ?>" method="POST">
	<?php method('PATCH'); ?>
</form>

PUT方法

要创建PUT方法,您需要__method请求,并在此处添加'PUT'值。动作必须是'POST'。

在您的路由中

$route->put('items','App\Controllers\ItemController@show');

对于表单数据

<form action="<?php echo route('items'); ?>" method="POST">
	<?php method('PUT'); ?>
</form>

DELETE方法

要创建DELETE方法,您需要__method请求,并在此处添加'DELETE'值。动作必须是'POST'。

在您的路由中

$route->delete('items','App\Controllers\ItemController@show');

对于表单数据

<form action="<?php echo route('items'); ?>" method="POST">
	<?php method('DELETE'); ?>
</form>

使用路由

在前端调用路由

<a href="<?php echo route('items'); ?>">Items</a>

路由参数

在许多情况下,您需要创建路由参数的时间

$route->get('items/show/{id}','App\Controllers\ItemController@show');

在您的控制器类中

namespace App\Controllers;

class ItemController{

	// 'items/show/{id}' //
	public function show($id){
		echo $id;
	}
}

您也可以使用闭包函数进行

$route->get('items/show/{id}',function($id){
	echo $id;
})

运行路由函数后,路由(URL)可以运行

'items/show/1' (GET METHOD)
'items/show/2' (GET METHOD)

在前端调用路由

<a href="<?php echo route('items/show/1'); ?>" >Item 1</a> 
<a href="<?php echo route('items/show/2'); ?>" >Item 2</a> 

资源路由

您可以使用单个路由方法进行CRUD路由

$route->resource('items','App\Controllers\ItemController');

在您的控制器类中

namespace App\Controllers;

class ItemController{

	// GET METHOD //
	// 'items' //
	public function index(){

	}

	// GET METHOD //
	// 'items/create' //
	public function create(){

	}

	// POST METHOD //
	// 'items/create' //
	public function save(){

	}

	// GET METHOD //
	// 'items/{id}/edit'
	public function edit($id){

	}

	// PUT METHOD //
	// 'items/{id}/edit' //
	public function update($id){

	}

	// DELETE METHOD //
	// 'items/{id}/destroy' //
	public function destroy($id){

	}


}

根据创建控制器的说明,在终端中创建资源控制器

php ichi make:controller ItemController --resource

运行路由函数后,路由(URL)可以运行

	
	'items/' (GET METHOD) // Go to to get items' list
	'items/create' (GET METHOD) // Go to create item
	'items/create' (POST METHOD) // Create items
	'items/1/edit' (GET METHOD) // Go to update item
	'items/1/edit' (PUT METHOD) // Update item
	'items/1/destroy' (DELETE METHOD) // Delete item

根据创建控制器的说明,在终端中创建API资源控制器

php ichi make:controller ItemController --api-resource

运行路由函数后,路由(URL)可以运行

	
	'items/' (GET METHOD) // Go to to get items' list
	'items/create' (POST METHOD) // Create items
	'items/1/edit' (GET METHOD) // Go to update item
	'items/1/edit' (PUT METHOD) // Update item
	'items/1/destroy' (DELETE METHOD) // Delete item

前缀路由

您可以使用前缀路由来创建分组。

$route->group(['url_group'=>'admin'],function(){
	
	$this->get('items','App\Controllers\ItemController@getItems');
	$this->get('brands','App\Controllers\BrandController@getBrands');
});

因此以下URL可以使用:

'admin/items' (GET METHOD)
'admin/brands' (GET METHOD)

您可以在分组闭包函数中添加路由。

在声明 "url_group" 时,不要包含 '/'。

子域名路由

如果您想使用子域名,必须在声明路由之前设置主域名。

use JiJiHoHoCoCo\IchiRoute\Router\Route;

$route=new Route;
$route->setDefaultDomain('your_main_domain.com');

单个子域名

您可以使用 "domain()" 函数设置子域名路由。

您可以在 "domain()" 函数中使用所有路由函数。

您不能在分组函数中使用 domain 函数。

$route->domain('your_subdomain.com',function(){
	$this->get('items','Subdomain/ItemController@get');
});

如果您想显示子域名路由,请使用 getSubdomainRoute 函数。第一个参数是域名,第二个参数是此子域名下声明的路由。

<a href="<?php echo getSubdomainRoute('your_subdomain.com','items'); ?>" >Subdomain Items</a>

子域名参数

如果您想在子域名中使用参数

参数用大括号 "{}" 包围作为路由参数。

您必须将子域名参数传递到闭包函数或类的函数中。

类的函数

$route->domain('{subdomain}.com',function(){
	$this->get('items','Subdomain/ItemController@get');
});
namespace App\Controllers\Subdomain;

class ItemController{

	public function get($subdomain){

	}
}

闭包函数

$route->domain('{subdomain}.com',function(){
	$this->get('items',function($subdomain){

	});
})

如果您想使用多个子域名参数,在参数和字符串之间使用点 "."。

类的函数

$route->domain('{subdomain}.{person}.com',function(){
	$this->get('items','Subdomain/ItemController@get');
});
namespace App\Controllers\Subdomain;

class ItemController{

	public function get($subdomain,$person){

	}
}

闭包函数

$route->domain('{subdomain}.{person}.com',function(){
	$this->get('items',function($subdomain,$person){

	});
});

如果您想在子域名参数中使用路由参数,您必须在类的函数或闭包函数中传递子域名参数和路由参数。

类的函数

$route->domain('{subdomain}.{person}.com',function(){
	$this->get('items/{id}','Subdomain/ItemController@get');
});
namespace App\Controllers\Subdomain;

class ItemController{

	public function get($subdomain,$person,$id){

	}
}

闭包函数

$route->domain('{subdomain}.{person}.com',function(){
	$this->get('items/{id}',function($subdomain,$person,$id){

	});
});

如果您想在中间件中获取属于子域名路由的子域名参数

在您的中间件类中

namespace App\Middlewares;

use JiJiHoHoCoCo\IchiRoute\Middleware\MainMiddleware;

class TestMiddleware extends MainMiddleware{

	public function handle(){
		$subdomainParameters=$this->getDomainParameters();
	}
}

您不能像路由参数那样将子域名参数传递给中间件。

依赖注入

您可以使用控制器类进行依赖注入。

您必须根据以下格式有接口和类

您的接口和类必须被自动加载

依赖注入的类的函数将自动运行

在您的控制器类中

namespace App\Controllers;

use App\Repositories\ItemRepositoryInteface;
class ItemController{

	public $item;
	public function __construct(ItemRepositoryInteface $item){
		$this->item=$item;
	}
}

您也可以在存储库中添加另一个依赖注入。

namespace App\Repositories;

use App\Repositories\{ItemRepositoryInteface,BrandRepositoryInterface};

class ItemRepository implements ItemRepositoryInteface{

	public $brand;

	public function __construct(BrandRepositoryInterface $brand){
		$this->brand=$brand;
	}
}

中间件

您可以将中间件添加到单个路由,如下所示

$route->get('order','App\Controllers\OrderController@order',[
'App\Middlewares\OrderMiddleware'
]);

您必须声明中间件类

根据我们之前提到的,您的中间件类必须在 composer 中自动加载

namespace App\Middlewares;

use JiJiHoHoCoCo\IchiRoute\Middleware\MainMiddleware;

class OrderMiddleware extends MainMiddleware{

	public function handle(){
		//--check your business logic--//
		return $this->next();
	}
}

您必须扩展 JiJiHoHoCoCo\IchiRoute\Middleware\MainMiddleware 并添加 "handle()" 函数。在您的 "handle" 函数中,您必须始终返回 "next()" 函数。您可以在 "handle" 函数中检查您的业务交易。

创建 "ichi" 文件后,您可以通过终端创建中间件,正如我们之前在 创建控制器 中提到的

php ichi make:middleware OrderMiddleware

观察者的默认路径为 "app/Middlewares"。您也可以在 "ichi" 文件中更改此路径。

$routeCommand=new RouteCommand;
$routeCommand->setResourcePath('new_app/Middlewares');
$routeCommand->run(__DIR__,$argv);

您可以为多个中间件类添加多个中间件。

$route->get('order','App\Controllers\OrderController@order',[
	'App\Middlewares\LoginMiddleware',
	'App\Middlewares\OrderMiddleware'
]);

由于每个 "handle()" 函数中都使用了 "next()" 函数,因此这些中间件将按顺序加载。

您可以在中间件中使用您的路由参数添加参数。

$route->get('items/{id}','App\Controllers\ItemController@getItems',[
	'App\Middlewares\CheckItemMiddleware:id'
]);

在您的中间件类中

namespace App\Middlewares;

use JiJiHoHoCoCo\IchiRoute\Middleware\MainMiddleware;

class CheckItemMiddleware extends MainMiddleware{

	public function handle($id){
		//--check your business logic--//
		return $this->next();
	}

}

您可以在中间件中使用您的路由参数添加多个参数。

$route->get('items/{id}/{stock_id}',
	'App\Controllers\ItemController@getItems',[
	'App\Middlewares\CheckItemMiddleware:id,stock_id'
]);

在您的中间件类中

namespace App\Middlewares;

use JiJiHoHoCoCo\IchiRoute\Middleware\MainMiddleware;

class CheckItemMiddleware extends MainMiddleware{

	public function handle($id,$stock){
		//--check your business logic--//
		return $this->next();
	}

}

您可以在前缀路由中添加中间件,就像在单个路由和参数路由中做的那样。

$route->group(['url_group' => 'admin' , 
	'middleware' => ['App\Middlewares\CheckAdminMiddleware']
 ],function(){
 	$this->resource('items','App\Controllers\ItemController');
 });

您只能在前缀路由中添加中间件。

$route->group(['middleare' => ['App\Middlewares\CheckUserMiddleware'] ],function(){
	$this->get('order','App\Controllers\OrderController@order');
});

如果您所有中间件的路由路径都相同,您可以在添加路由之前为所有路由设置基本中间件路径。

$route->setBaseMiddlewarePath('App\Middlewares');

此库中已经编写了一些中间件。对于这些中间件,您必须完全声明它们的中间件路径。

如果您想为所有路由检查中间件

如果您没有声明基本中间件路径

$route->defaultMiddlewares([
'App\Middlewares\CheckUserMiddleware'
]);

如果您声明了基本中间件路径

$route->defaultMiddlewares([
'CheckUserMiddleware'
]);

CSRF令牌认证

您可以使用 CSRF Token 身份验证来保护创建和更新路由

在声明路由之前,您必须生成 CSRF Token。

use JiJiHoHoCoCo\IchiRoute\Router\Route;

generateCSRFToken();

$route=new Route;
$route->post('items','App\ItemController@create',[
'JiJiHoHoCoCo\IchiRoute\Middleware\CSRFMiddleware'
]);

您也可以在您的路由中添加 JiJiHoHoCoCo\IchiRoute\Middleware\CSRFMiddleware

use JiJiHoHoCoCo\IchiRoute\Router\Route;

generateCSRFToken();

$route=new Route;
$route->group(['middleare' => 
	['JiJiHoHoCoCo\IchiRoute\Middleware\CSRFMiddleware'] ],function(){
	$this->post('items','App\ItemController@create');
});

在您的前端 PHP 文件中

<form action="<?php echo route('items'); ?>" method="POST" >
	<?php csrfToken(); ?>
	<input type="text" name="name">
	<input type="submit" name="submit">
</form>

API请求认证

您可以为您的路由添加中间件,仅接受 API 请求

$route->get('items_api','App\Controllers\ItemController@getItems',[
	'JiJiHoHoCoCo\IchiRoute\Middleware\APIMiddleware'
]);

要传递 JiJiHoHoCoCo\IchiRoute\Middleware\APIMiddleware,您必须在请求该 API 路由时将 "Content-Type" 头中的值添加为 "application/json"。

CORS

您可以通过 CORS 获取来自另一个域的数据

$route->get('items_api','App\Controllers\ItemController@getItems',[
	'JiJiHoHoCoCo\IchiRoute\Middleware\CORSMiddleware'
]);

您可以使用 JiJiHoHoCoCo\IchiRoute\Setting\CORS 为您的 CORS 添加选项

 
use JiJiHoHoCoCo\IchiRoute\Setting\CORS;

CORS::setAvialableSites(['http://domain-one.com','http://domain-two.com']);
// To set Access Control Allow Origins (default is '*')

CORS::setAvailableSitesRegex(['/w3schools/']);
// To set Access Control Allow Origins according to regex

CORS::setAvialableMethods(['GET','POST']);
// To set Access Control Allow Origin Methods (default is '*')

CORS::setAvailableHeaders(['X-Custom-Header','Upgrade-Insecure-Requests']);
// To set Access Control Allow Origin Headers (default is '*')

CORS::setToAllowCredential();
// To set Access Control Allow Credentials to TRUE. (default is 'false')

CORS::setMaxAge(3600);
// To set Access Control Max Age (default is 0)

路由缓存

您可以使用以下方式缓存参数路由

  1. 数据库
  2. Redis
  3. Memcached

在添加路由之前,您必须执行以下操作

数据库缓存

您必须在数据库中运行以下SQL代码来创建 "ichi_routes" 表

CREATE TABLE IF NOT EXISTS ichi_routes( 
	id   INT AUTO_INCREMENT,
	route_key  VARCHAR(100) NOT NULL,
	route_method VARCHAR(100) NOT NULL,
	expired_time VARCHAR(100) NULL,
	PRIMARY KEY(id))

并且添加您的pdo对象,并设置过期时间(以秒为单位)

$route->setPDO($pdoObject,10000);

您也可以不设置过期时间

$route->setPDO($pdoObject);

Redis缓存

添加您的redis对象,并设置过期时间(以秒为单位)

$route->setRedis($redisObject,10000);

您也可以不设置过期时间

$route->setRedis($redisObject);

Memcached缓存

添加您的memcached对象,并设置过期时间(以秒为单位)

$route->setMemcached($memcachedObject,10000);

您也可以不设置过期时间

$route->setMemcached($memcachedObject);

自定义错误页面

您可以调用错误页面(无论它是默认的还是有自定义的)

use JiJiHoHoCoCo\IchiRoute\UI\ErrorPage;

echo ErrorPage::show();
exit();

默认错误信息是 "404 - URL未找到"。默认HTTP响应代码是 404。

您可以自定义错误信息和HTTP响应代码

use JiJiHoHoCoCo\IchiRoute\UI\ErrorPage;

echo ErrorPage::show('403 - Unauthorized Request',403);
exit();

如果您不喜欢此库提供的默认错误页面,您可以显示自己的错误页面

use JiJiHoHoCoCo\IchiRoute\UI\ErrorPage;

ErrorPage::setErrorPage('<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>

<h1>404</h1>
<p>404 URL</p>

</body>
</html>');

如果您想根据您的HTTP响应代码显示更具体的错误,您必须创建一个函数

use JiJiHoHoCoCo\IchiRoute\UI\ErrorPage;

$errorPage=function($message,$code){
		return <<<HTML
			<html>
			<meta name="viewport" content="width=device-width, initial-scale=1.0"> 
			<title>$message</title>
			<body style="background-color: white;">
			<div style="position: fixed;top:50%;left:50%;transform: translate(-50%, -50%);color:black;font-family: 'Nunito', sans-serif;">
			<p>$message</p>
			</div>
			</body>
			</html>
			HTML;
	};

ErrorPage::setErrorPage($errorPage);

在您的自定义函数中,您必须有 "$message" 和 "$code" 参数