amazephp / amazephp
AmazePHP 框架。
Requires
- php: ^8.1
- doctrine/event-manager: ^2.0
- eftec/bladeone: ^4.9
- eftec/cacheone: ^2.16
- eftec/pdoone: ^4.2
- guzzlehttp/guzzle: ^7.5
- illuminate/container: ^10.13
- monolog/monolog: ^3.3
- spatie/macroable: ^2.0
README
关于 AmazePHP
作为启动 PHP 项目的良好选择,它可以用于 Web 和 API 开发。只需一分钟就可以启动项目。它具有超高性能和非常易于使用的开发体验。没有复杂的概念,因此学习曲线最低。
特性
- 配置
- 环境变量
- 路由
- 请求
- 响应
- 控制器
- 中间件
- 外观
- 容器
- 数据库
- HTTP 客户端
- 日志记录
- 视图 & 模板
- 错误处理
- 缓存
- 会话
- Cookie
- URL 生成
- CSRF 保护
安装
composer create-project amazephp/amazephp
或使用 git clone
git clone https://github.com/w3yyb/AmazePHP.git
cd AmazePHP
composer install
运行
cd public/
php -S localhost:9080 server.php
在浏览器中打开 https://:9080
要求
php 8.1+
目录结构
应用目录
应用目录包含您应用程序的核心代码。我们将在不久的将来更详细地探索此目录;然而,您应用程序中的几乎所有类都将位于此目录中。
配置目录
配置目录,正如其名所示,包含您应用程序的所有配置文件。包括路由配置文件。
辅助目录
包含其中的辅助函数。
AmazePHP 目录
框架核心目录,包含一些库类。您也可以将您的类文件放在其中。
公开目录
公开目录包含 index.php 文件,它是所有进入您应用程序的请求的入口点,并配置自动加载。此目录还包含您的资产,例如图像、JavaScript 和 CSS。
缓存目录
缓存目录包含您的缓存文件,包括日志文件。
模板目录
模板目录包含您的 HTML 模板文件。
用法
配置
获取配置
config('app'); //will read config/app.php, app.php return an array.
config('app.url')// == config('app')['url'];
// Retrieve a default value if the configuration value does not exist...
$value = config('app.timezone', 'Asia/Seoul');
设置配置
要设置运行时的配置值,请将一个数组传递给 config 函数
config(['app.timezone' => 'America/Chicago']);
缓存
获取缓存
$value = cache('key');
设置缓存
cache(['key' => 'value'], 10);// Expires after 10 seconds
视图
模板引擎使用 BladeOne
,一个类似于 laravel blade
的模板引擎,点击此处查看 BladeOne 手册 https://github.com/EFTEC/BladeOne/wiki/BladeOne-Manual
echo view('greeting', ['name' => 'James']);
第一个参数是模板名称,即 template/greeting.blade.php
,第二个参数是传递给模板的变量。
获取环境配置
env('key');
env('key','default');
传递给 env 函数的第二个值是“默认值”。如果给定键不存在环境变量,则将返回此值。
日志记录
logger('some msg');//error log
logger('some msg','warning'); //warning log | support:emergency ,alert ,critical ,error ,warning ,notice ,info ,debug
路由
查看 config/route.php
[
['GET'],
'/',
[App\Controllers\Index::class, 'index'],
'routename',
'middleware'=>[App\Middleware\a2Middleware::class,App\Middleware\b2Middleware::class],
],
第一行是 HTTP 请求方法,支持 HEAD、GET、POST、PUT、PATCH、DELETE。 ['POST,GET']
表示同时支持 POST 和 GET。['*']
表示支持所有 HTTP 方法。
第二行表示路径,例如 /users/{uid}/posts/[{pid}][/]
:花括号内是变量参数,方括号内是可选参数,即未传递到 URL 的参数,[/]
用于删除尾随斜杠。
第三行指示 PHP 回调,支持类方法、类静态方法、匿名函数、函数等。
第四行是可选的,表示命名路由的名称。
中间件键是可选的,用于注册路由中间件。
请求
AmazePHP\Request 类提供了一种面向对象的方式,与您的应用程序正在处理的当前 HTTP 请求进行交互,以及检索与请求一起提交的输入、Cookie 和文件。
用法
$input = request()->all();
$name = request()->input('name');
$value = request()->cookie('name');
$value = request()->header('X-Header-Name');
$method = request()->method();
request()->host();
$url = request()->url();
$urlWithQueryString = request()->fullUrl();
$uri = request()->path();
if (request()->is('admin/*')) {
// ...
}
$input = request()->only(['username', 'password']);
$input = request()->except(['credit_card']);
$file = request()->file('upload');
if ($file && $file->isValid()) {
$file->move(PUBLIC_PATH.'/myfile.'.$file->getUploadExtension());
return json(['code' => 0, 'msg' => 'upload success']);
}
更多用法请参阅 AmazePHP/src/Request.php。
响应
出于性能原因,AmazePHP 不提供 Respose 类。在控制器或中间件中使用 header() 函数和 echo 或 return 来响应。
控制器
您可以将所有请求处理逻辑作为闭包定义在路由文件中,而不是这样做。您可能希望使用“控制器”类来组织这种行为。控制器可以将相关的请求处理逻辑组合成一个类。例如,一个 UserController
类可以处理所有与用户相关的传入请求,包括显示、创建、更新和删除用户。默认情况下,控制器存储在 app/Controllers
目录中。
编写控制器
在 app/Controllers
目录中,您可以编写一些控制器,例如
<?php
namespace App\Controllers;
class Index
{
public function index()
{
echo 'Hello AmazePHP!';
}
}
一旦您编写了一个控制器类和方法,您可以像这样定义一个指向控制器方法的路由
[
['GET'],
'/',
[App\Controllers\Index::class, 'index']
],
当传入请求与指定的路由 URI 匹配时,App\Controllers\Index 类上的 index 方法将被调用,并将路由参数传递给该方法。
中间件
中间件,也称为 HTTP 中间件,主要用于修改或过滤 HTTP 请求或响应。所有这些中间件都位于 app/Middleware 目录中。
中间件分为前置中间件和后置中间件。前置中间件主要用于修改 HTTP 请求。后置中间件主要用于修改 HTTP 响应。
Request->Before middleware->Actual action->After middleware->Response
定义中间件
前置中间件和后置中间件的主要区别在于代码执行的地点。在 app/Middleware 目录
定义前置中间件
创建一个名为 bMiddleware.php 的文件
<?php
namespace App\Middleware;
use AmazePHP\MiddlewareInterface;
class bMiddleware implements MiddlewareInterface {
public function process($object, \Closure $next,...$params)
{
//Perform some logic here
return $next($object);
}
}
?>
定义后置中间件
创建一个名为 aMiddleware.php 的文件
<?php
namespace App\Middleware;
use AmazePHP\MiddlewareInterface;
class aMiddleware implements MiddlewareInterface {
public function process($object, \Closure $next,...$params)
{
$response = $next($object);
//Perform some logic here
return $response;
}
}
?>
注册全局中间件
在 config/middleware.php 中,写入以下内容
return [
App\Middleware\aMiddleware::class,
App\Middleware\bMiddleware::class,
];
注册路由中间件
见路由。
外观
门面提供了一个静态调用接口,用于框架核心类库的(动态)类。允许您静态调用动态类方法。
示例
在 App\Controllers\Index 控制器中
<?php
namespace App\Controllers;
use AmazePHP\Facade\Request;
class Index
{
public function index()
{
echo Request::url();//call Request.php url method statically. Same as calling Request->url().
}
}
系统中的所有门面都放在 AmazePHP/src/Facade 目录中。
容器
容器是管理类依赖关系和执行依赖注入的强大工具。
用法
例如
<?php
namespace App\Controllers;
use AmazePHP\Request;
class Foo
{
public function bar(Request $request, $id)
{
echo $request->url();
}
}
?>
bar 方法依赖于 Request 类。您可以将 Request $request 放在 bar 参数中。框架将自动调用 Request 类,因此您可以使用 Request 类方法:例如 $request->url()
。
支持使用依赖注入的场景包括(但不仅限于)
- 控制器方法;
- 路由的闭包定义;
- 中间件执行方法;
HTTP 客户端
$response= httpGet('http://httpbin.org/get');
$response= httpGet('http://httpbin.org/get',['headername'=>'headervalue']);
$response= httpHead('http://httpbin.org/get',['headername'=>'headervalue']);
$response= httpDelete('http://httpbin.org/delete',['headername'=>'headervalue']);
$response= httpPost('http://httpbin.org/post',['senddataname'=>'senddatavalue']);
$response= httpPut('http://httpbin.org/put',['senddataname'=>'senddatavalue']);
$response= httpPatch('http://httpbin.org/patch',['senddataname'=>'senddatavalue']);
$response 是一个包含状态码、头和正文数据的数组。
函数参数如下
httpGet($url,$header = [])
httpHead($url,$header = [])
httpDelete($url,$header = [])
httpPost($url, $data, $isJson = true,$method='POST',$header = [])
httpPut($url, $data, $isJson = true,$method='PUT',$header = [])
httpPatch($url, $data, $isJson = true,$method='PATCH',$header = [])
会话
默认情况下,会话是关闭的,如果您想打开,请将 .env 文件中的 SESSION_ENABLE 更改为 true。
设置会话
session(["name" => "value"]);
获取会话
$value = session('name')
Cookie
获取 Cookie
$value = request()->cookie('name');
设置 Cookie
cookie('name','value',86400); // 86400 seconds
数据库
数据库组件使用 PdoOne
,这是 PHP 和 PDO 的数据库访问对象包装器。点击 https://github.com/EFTEC/PdoOne 了解如何使用它。
以下是如何简单使用它的示例。
选择
$results = db()->select("*")->from('users')->where("name like '%test%'")->toList();
print_r($results);
使用原始 SQL
$sql='select * from users where id=1';
$pdoStatement=db()->runRawQuery($sql,[],false); // [] are the parameters
print_r($pdoStatement->fetchAll());
插入
db()->insert("users"
,['name','email','password']
,['kevin','email@email.com','123456']);
更新
db()->update("users"
,['name'=>'Captain-Crunch','email'=>'mail@mail.com'] // set
,['id'=>6]); // where
删除
db()->delete("users"
,['id'=>6]); // where
URL
访问当前 URL
// Get the current URL without the query string...
echo url()->current();
// Get the current URL including the query string...
echo url()->full();
// Get the full URL for the previous request...
echo url()->previous();
生成 URL
echo url("/posts/{$post->id}"); // http://example.com/posts/1
命名路由的 URL
[
['GET'],
'/hello/{id}/foo/{sid}',
[new App\Foo, 'bar'],
'nameroute1'//Named Route
],
echo route('nameroute1', ['id' => 1, 'sid' => 2]);
// http://example.com/hello/1/foo/2
CSRF 保护
如果您想使用它,请先启用会话。
跨站请求伪造是一种恶意利用,其中代表未经授权的命令在代表认证用户的情况下执行。幸运的是,AmazePHP 使您的应用程序容易受到跨站请求伪造(CSRF)攻击的保护。
AmazePHP会自动为每个由应用程序管理的活跃用户会话生成一个CSRF "token"。这个token用于验证认证的用户确实是正在向应用程序发送请求的人。由于这个token存储在用户的会话中,并且每次会话重新生成时都会改变,因此恶意应用程序无法访问它。
当前会话的CSRF token可以通过csrf_token
辅助函数访问。
$token = csrf_token();
每次在您的应用程序中定义“POST”、“PUT”、“PATCH”或“DELETE”HTML表单时,都应该在表单中包含一个隐藏的CSRF _token
字段,以便CSRF保护中间件可以验证请求。为了方便,您可以使用@csrf
Blade指令生成隐藏的token输入字段。
<form method="POST" action="/profile">
@csrf
<!-- Equivalent to... -->
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
</form>
X-CSRF-TOKEN
除了检查POST参数中的CSRF token外,lib\VerifyCsrfToken
还会检查X-CSRF-TOKEN
请求头。例如,您可以将token存储在HTML meta
标签中。
<meta name="csrf-token" content="{{ csrf_token() }}">
然后,您可以指示一个库如jQuery自动将token添加到所有请求头中。这为使用传统JavaScript技术的基于AJAX的应用程序提供了简单、方便的CSRF保护。
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
X-XSRF-TOKEN
AmazePHP将当前的CSRF token存储在一个加密的XSRF-TOKEN
cookie中,该cookie包含在框架生成的每个响应中。您可以使用cookie的值来设置X-XSRF-TOKEN
请求头。
此cookie主要是为了开发者的便利而发送的,因为一些JavaScript框架和库(如Angular和Axios)会自动将它的值放在同源请求的X-XSRF-TOKEN
头中。
测试
./phpunit --bootstrap vendor/autoload.php tests
./phpunit --bootstrap vendor/autoload.php tests --display-warnings
./phpunit --bootstrap vendor/autoload.php tests --display-deprecations
基准测试
在
laravel : 2900 rps。
AmazePHP: 23000 rps。
两者都开启了调试模式,并且Laravel使用Array Session驱动程序。