欢迎感兴趣的开发者参与开发
Github: https://github.com/next-laboratory/simple
php >= 8.0
composer create-project next/simple
php bin/workerman.php start
swoole/workerman
server {
server_name www.domain.com;
listen 80;
location / {
proxy_http_version 1.1;
proxy_set_header Connection "keep-alive";
proxy_set_header Host $http_host;
proxy_set_header Scheme $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
if (!-f $request_filename) {
proxy_pass http://127.0.0.1:9501;
}
}
}
FPM
server {
server_name www.domain.com;
listen 80;
root /data/project/public;
index index.html index.php;
location / {
if (!-e $request_filename) {
rewrite ^/(.*)$ /index.php/$1 last;
}
}
location ~ ^(.+\.php)(.*)$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
框架提供了env和config两个函数,可以方便获取配置,如果你使用了AOP包,还可以直接使用注解将配置注入示例
class User
{
#[\Next\Config\Annotations\Config(key: 'qcloud.user.secret_key', default = '123')]
protected string $secretKey;
}
如上secretKey将会被自动注入,如果配置文件中不存在,则默认123
在app/Http/Kernel.php
的map
方法中注册路由,注册方式请参考next/routing组件文档,或者使用注解方式
#[Controller(prefix: 'index', middleware: [BasicAuthentication::class])]
class Index
{
#[GetMapping(path: '/user/{id}\.html')]
public function index(\Psr\Http\Message\ServerRequestInterface $request, $id)
{
return new \Next\Http\Message\Response(200, [], 'Hello, world!');
}
}
上面的代码定义了一个 Index 控制器,并使用 Controller 注解设置了路由的前缀为 index, 该控制器中全部方法的中间件为BasicAuthentication::class
, 并且使用GetMapping
注解定义了一个路由,path
为/user/{id}.html
, 那么实际请求的地址可以为/index/user/1.html
, 支持的注解如下,分别对应了不同的请求方法,其中RequestMapping对应的请求方法默认为GET
,POST
,HEAD
,可使用method
参数来自定义
class IntexController {
#[GetMapping(path: '/{id}')]
public functin index(ServerRequestInterface $request, $id) {
// Do something.
}
}
控制器是单例对象,和路由对应的方法支持依赖注入,并且参数名为request
的参数会被注入当前请求类,该类不是单例,对于每个请求都是独立的。路由参数会被按照参数名注入,其他有类型提示的参数也会被注入
请求可以是任何实现了Psr的ServerRequestInterface实例
请使用
App\Http\ServerRequest
,该类继承Next\Http\Message\ServerRequest
类,是实现了Psr7 ServerRequest
的请求类,并且附加了一些简单的方法,开发者可以自定义相关方法
$request->getHeaderLine($name): string
$request->head($name): string
上面两个方法会返回请求头字符串,header
方法返回值 getHeaderLine
是一样的
$request->server($name): string // 一条
$request->getServerParams(): array // 全部
获取$_SERVER
中的值
$request->isMethod($method): bool
不区分大小写的方式判断请求方式是否一致
$request->url(bool $full = false): string
返回请求的地址,$full
为true
,则返回完整地址
$request->cookie(string $name): string // 单条
$request->getCookieParams(): array // 全部
获取请求的Cookie,一般也可以直接从Header
中获取
$request->isAjax(): bool
判断当前请求是否是Ajax
请求, 注意:有部分前端框架在发送Ajax请求的时候并没有发送X_REQUESTED_WITH头,所以这个方法会返回false
$request->is(string $path): bool
判断当前请求的path
是否和给定的path
匹配,支持正则
$request->get($key = null, $default = null) // $_GET
$request->post($key = null, $default = null) // $_POST
$request->all() // $_GET + $_POST
$request->input($key = null, $default = null, ?array $from = null) // $_GET + $_POST
获取请求的参数,这些参数是通过PHP全局变量加载进来的,当$key为null的时候会返回全部参数,如果为字符串会返回单个,如果不存在返回default,如果$key是数组,则会返回多个参数,$default此时可以为数组,数组的键为参数键,数组的值为参数的默认值
例如
$request->get('a');
可以给第二个参数传入一个默认值,例如
$request->get('a','default');
获取多个参数可以使用
$request->get(['a','b']);
可以传入一个关联数组,数组的键为参数名,值为默认值,例如
$request->get(['a', 'b'], ['a' => 1]);
此时如果a
不存在,则a
的值为1
$request->getUploadedFiles();
$request->file("name");
中间件基于
Psr15
实现,在App\Http\Kernel
中的$middlewares
数组中注册的为全局的中间件,例如请求异常处理,路由服务,Session初始化,CSRF校验等等
首先需要创建一个中间件,例如
<?php
namespace App\Http\Middleware;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class Login implement MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
// 前置操作
$response = $handler->handle($request);
// 后置操作
return $response;
}
#[Controller(prefix: '/', middleware(TestMiddleware::class))]
class Index {
#[GetMapping(path: '/', middlewares: [Test2Middleware::class])]
public function index() {
// Do something.
}
}
上面的注解定义了两个中间件,控制器Index中的方法都注册了TestMiddleware
中间件,index
方法不仅包含TestMiddleware
, 还包含Test2Middleware
中间件。
Session可以使用
File
,Redis
驱动
Session配置文件如下
<?php
return [
'name' => 'NextPHP_SESSION_ID',
'handler' => [
'class' => '\Next\Session\Handlers\File',
'options' => [
'path' => env('storage_path') . 'session',
'ttl' => 3600,
]
],
'cookie_expire' => time() + 3600,
];
当前请求的session需要在中间件中创建,所以需要开启SessionMiddleware。开启后将session放入Request属性中,在控制器中使用
public function index(App\Http\ServerRequest $request)
{
$session = $request->session();
$session = $request->getAttribute(\Next\Session\Session::class);
}
你也可以自己定义session的存储位置,但是要保证协程间隔离。如果使用workerman,还可以直接使用其提供的session
$session->has($name): bool
$session->get($name)
$session->set($name, $value): bool
可以是数组或者字符串
$session->pull($name): bool
$session->remove($name): bool
$session->destory(): bool
框架继承了filp/whoops,可以很方便地查看异常情况,使用前需要添加异常处理类Next\Framework\Exceptions\Handlers\WhoopsExceptionHandler
到App/Http/Middlewares/ExceptionHandleMiddleware
中间件中
如果没有安装,需要执行下面的命令安装
composer require filp/whoops
打印变量使用了symfony/var-dumper组件,但是为了兼容多种环境,建议使用d
函数代替dump
,dd
函数。使用前需要添加异常处理类Next\Framework\Exceptions\Handlers\VarDumperAbortHandler
到App/Http/Middlewares/ExceptionHandleMiddleware
中间件中
d(mixed ...$vars)
如果你没有安装symfony/var-dumper
,需要先安装
composer require symfony/var-dumper
你可以传入多个变量,如果使用swoole/workerman,需要重启服务
特别注意:异常处理使用中间件的方式,中间件未处理的异常需要用户手动处理,所以在中间件外执行的代码不能使用d函数打印变量
推荐使用下面的扩展包
支持一下