Swoft2.x 小白学习笔记 (一) ---控制器
Swoft通过官方文档进行学习,这里不做介绍,直接上手。
涉及到Swoft方面:(配置、注意的坑)
1、控制器(路由、验证器、中间件)
4、协程简单实现
5、RPC实现
准备: 1、先安装php各种扩充,有的扩充不兼容需要禁用
2、先安装 swoftcli,能让修改代码重新启动,生效。https://www.swoft.org/docs/2.x/zh-CN/tool/swoftcli/index.html
一、Http/Https服务控制器
1、配置,在 /app/bean.php中
'httpServer' => [ 'class' => HttpServer::class, 'port' => 18306, 'listener' => [ ], 'process' => [ ], 'on' => [ ], // 'type' => SWOOLE_SOCK_TCP | SWOOLE_SSL, //支持https,必须安装OpenSSL扩充 /* @see HttpServer::$setting */ 'setting' => [0 'worker_num' => 4, //支持https,签名文件 // 'ssl_cert_file' => '/my/certs/2288803_www.domain.com.pem', // 'ssl_key_file' => '/my/certs/2288803_www.domain.com.key', ] ],
2、新建控制器,在 /app/Http/Controller/文件夹下新建文件 IndexController.php
/**
* Class IndexController
* @package App\Http\Controller
* @Controller(prefix="/apidemo")
*/
class IndexController{
/**
* @RequestMapping("index",method={RequestMethod::GET})
* @throws \Swoft\Exception\SwoftException
*/
public function index(){
$res = Context()->getResponse();
$data = ['name'=>'Swoft2.0.2222'];
return $res->withData($data);
}
/**
* @RequestMapping("index_v2")
* @throws \Swoft\Exception\SwoftException
*/
public function indexV2(){
$res = Context()->getResponse();
$data = ['name'=>'Swoft2.0.2222'];
return $res->withData($data);
}
}
注意事项:1、Swoft路径全部使用注解方式进行。注解必须使用 /** 开始,不能少或者多 * ,只能是两个* ,不然会报错。 2、如果有其他注释,不能出现@符合,如下: /** * * //路径解析
* //将此注解应用于 Action 上,则作用域仅为当前的 Action @Middleware 用于配置单个中间件 @Middlebrows 用于配置一组 Middleware
* * @RequestMapping("demo_middle")
*/
会报错,蓝色部分是你的注释,其中 @Middleware 不能加@符号,不然会报错。
3、路由访问是通过 @Controller(prefix="/apidemo") 中的prefix + 类中每个方法的@RequestMapping("index") 参数:url/apidemo/index 进行访问当前控制器的方法。
4、如果有多个方法的路由相同,会以最后一个为准,覆盖之前的。
详细路由查看:https://www.swoft.org/docs/2.x/zh-CN/http-server/route.html
3、启动 swoftcli run -c http:start -b bin/swoft
浏览器访问 http://127.0.0.1:18306/apidemo/index
二:验证器:https://www.swoft.org/docs/2.x/zh-CN/validator/index.html
1、安装组件 composer require swoft/validator
2、配置
'httpDispatcher' => [ // Add global http middleware 'afterMiddlewares' => [ \Swoft\Http\Server\Middleware\ValidatorMiddleware::class ] ],
3、在文件夹 /app/Validator/下新建文件DemoValidator.php
<?php declare(strict_types=1); namespace App\Validator; use Swoft\Validator\Annotation\Mapping\Validator; use Swoft\Validator\Contract\ValidatorInterface; use Swoft\Validator\Exception\ValidatorException; /** * Class DemoValidator * * @since 2.0 * * @Validator(name="demoValidator") //给验证器取个名字 */ class DemoValidator implements ValidatorInterface { /** * @return array * @throws ValidatorException */ public function validate(array $data, array $params): array { $start = $data['start'] ?? null; $end = $data['end'] ?? null; if ($start === null && $end === null) { throw new ValidatorException('Start time and end time cannot be empty'); } if ($start > $end) { throw new ValidatorException('Start cannot be greater than the end time'); } return $data; } }
4、使用。在前面新建的控制器中
/** * 访问: http://127.0.0.1:18306/apidemo/valida_v2?start=4&end=2
* * @RequestMapping("valida_v2") //路由 * @Validate(validator="demoValidator",type=ValidateType::GET) //使用验证器,默认是post验证,加上type修改验证请求方式 * @throws \Swoft\Exception\SwoftException */ public function validaV2Controller(){ $res = context()->getResponse(); $data = ['name'=>'Swoft2.0.2222']; return $res->withData($data); }
访问: http://127.0.0.1:18306/apidemo/valida_v2?start=4&end=8 ,不加参数或者end比start值大都会抛出异常
三、中间件:https://www.swoft.org/docs/2.x/zh-CN/http-server/middleware.html
1、定义,在文件夹 /app/Http/Middleware/ 下新建文件DemoMiddleware.php
只需要实现了 Swoft\Http\Server\Contract\MiddlewareInterface 接口均为一个合法的中间件,其中 process() 方法为该中间件逻辑处理方法
<?php declare(strict_types=1); namespace App\Http\Middleware; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; use Swoft\Bean\Annotation\Mapping\Bean; use Swoft\Http\Server\Contract\MiddlewareInterface; /**
* //中间件必须实现 MiddlewareInterface 接口 * @Bean() */ class DemoMiddleware implements MiddlewareInterface{ /** * @return ResponseInterface * @inheritdoc * @throws \Swoft\Exception\SwoftException */ public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { // TODO: Implement process() method. $path = $request->getUri()->getPath(); var_dump($path); $request = $handler->handle($request); return $request; }
2、全局使用,当中间件需要全局使用时,直接在bean中配置。否则使用步骤3.
'httpDispatcher' => [ // Add global http middleware 'middlewares' => [ \App\Http\Middleware\FavIconMiddleware::class, \App\Http\Middleware\DemoMiddleware::class //添加新的中间件,添加后会让所有控制器都会默认使用该控制器 ], 'afterMiddlewares' => [ \Swoft\Http\Server\Middleware\ValidatorMiddleware::class ] ],
3、不进行全局使用时,在需要的地方进行注解使用。在前面创建的控制器中。
use App\Http\Middleware\DemoMiddleware; //先在类最上面引用
/** * * //中间间测试用 * //当将此注解应用于 Controller 上,则作用域为整个 Controller * //将此注解应用于 Action 上,则作用域仅为当前的 Action Middleware 用于配置单个中间件 Middlebrows 显而易见的是用于配置一组 Middleware,按照定义顺序依次执行 * * @RequestMapping("demo_middle") * * @Middleware(DemoMiddleware::class) //通过注解加入中间件,只有当前路由会使用到该中间件 */ public function demoMiddle(){ return "dddd"; }
参考文档 :
源码解析:https://www.jianshu.com/p/2f679e0b4d58