说明

php7由于新框架须要安装swoole,只能linux环境运行,这里本机开发是win10(:debian云服务器主机上git clone 项目,再同步到本机phpstorm、修改提交;或使用win10的docker安装)。

这里docker有个bug:无法感知主机文件的热更新,所以运行加了 --rm 选项,手动热启动。

1.安装

官方提供docker方式简便快捷:
(git clone https://github.com/swoft-clou... 下载swoft到目标文件夹,如/root/tmp/dk/vuejs/swoft)

#/root/tmp/dk/vuejs/swoft 为当前swoft主机映射目录 
#启动项目的http访问,启动命令情况参考根目录的Dockerfile文件
docker run -p 18306:18306 --name swoft -v /root/tmp/dk/vuejs/swoft:/var/www/swoft --rm swoft/swoft

2.http访问请求

a.http响应

复制 .env.example 为 .env ,修改参数为调试模式;端口配置在 app/bean.php 不修改。
参考HomeController和官网说明,添加控制器 app/Http/Controller/TestController.php:

<?php  declare(strict_types=1);

namespace App\Http\Controller;

use Swoft\Context\Context;
use Swoft\Http\Message\ContentType;
use Swoft\Http\Message\Response;
use Swoft\Http\Server\Annotation\Mapping\Controller;
use Swoft\Http\Server\Annotation\Mapping\RequestMapping;
use Throwable;

/**
 * 测试类
 *
 * @Controller("/test")
 */
class TestController
{
    /** 网络地址 http://host:18306/test/a
     * @RequestMapping("/test/a")
     * @throws Throwable
     *
     * 方法注释
     */
    public function index(): Response
    {
        return Context::mustGet()->getResponse()->withContentType(ContentType::HTML)->withContent("12345");
    }
}
  • 这里请求返回:获取协程上下文->获取响应对象->包含HTML头部的字符串。
  • 注解路由:

从启动文件 bin/swoft 一直ctrl+点击下去,可以看到启动配置文件后,注解路由类的加载。

    [
        new EnvProcessor($this),
        new ConfigProcessor($this),
        new AnnotationProcessor($this),
        new BeanProcessor($this),
        new EventProcessor($this),
        new ConsoleProcessor($this),
        ]

初始化加载流程:

(new AppApplication()) ==> __construct()->$this->init() ==> $this->processors() => new [] :实例化上面4个启动类;

AnnotationRegister::load() ==> AnnotationResource()->load()..loadAnnotation()..parseAnnotation()..parseOneClassAnnotation() ==> DoctrineCommonAnnotationsAnnotationReader ,扫描注解类。

b.http中间件

参考官网,配置文件 app/bean.php 里 httpDispatcher['middlewares'] 是http请求分发时的中间件,可以在此配置出添加类名、模拟ViewMiddleware.php编写中间件。
默认已经有个空的未加入,添加到配置 app/bean.php:

'httpDispatcher'   => [
        // Add global http middleware
        'middlewares' => [
            // Allow use @View tag
            \App\Http\Middleware\ControllerMiddleware::class,
            \Swoft\View\Middleware\ViewMiddleware::class,
        ],
    ],

并修改它app/Http/Middleware/ControllerMiddleware.php:

<?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\Context\Context;
use Swoft\Http\Message\Response;
use Swoft\Http\Server\Contract\MiddlewareInterface;
use Throwable;

/**
 * Class ControllerMiddleware - The middleware of httpDispatcher
 *
 * @Bean()
 */
class ControllerMiddleware implements MiddlewareInterface
{
    /**
     * Process an incoming server request.
     *
     * @param ServerRequestInterface $request
     * @param RequestHandlerInterface $handler
     *
     * @return ResponseInterface
     * @inheritdoc
     * @throws Throwable
     */
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        /** @var Response $response */
        $status = 2;
        $date = date("Y-m-d H:i:s ");
        if ( $status == 0 ) {
            //直接处理之后的 响应
            $response = $handler->handle($request);
            var_dump($response);
            return $response->withData($date); //已完成、处理无效
            return $response;
        } elseif ( $status == 1) {
            //验证失败的 响应
            $json = ['code'=>0,'msg'=>'授权失败','time'=>$date];
            $response = Context::mustGet()->getResponse();
            return $response->withData($json);

        } elseif ( $status == 2 ) {
            $response = Context::mustGet()->getResponse();
            return $response->withData("ok")->withStatus(404);
        } else {
            $method = $request->getMethod();
            $response = Context::mustGet()->getResponse();
            return $response->withData($method);
        }
    }
}

访问浏览器,可看到响应的结果。加到启动配置 httpDispatcher 里的会在 onRequest准备返回前 加载。
withData():如果是string类型:会放到返回数组的data字段里,数组类型:原样返回。

c.RESTful API

由于swoft使用的是注解路由,请求方式也在注解中添加。
编辑器中点击 @RequestMapping() 注解,可以看到有method私有属性,公共方法getMethod() Array。

## app/Http/Controller/TestController.php:
use Swoft\Http\Server\Annotation\Mapping\RequestMethod;

    /**
     * @RequestMapping(route="/test/rs", method={RequestMethod::POST, RequestMethod::PUT})
     * @throws Throwable
     *
     * 方法注释
     */
    public function restful(): Response
    {
        //SwoftTest\Http\Server\Testing\Controller\RouteController
        //* @RequestMapping("method", method={RequestMethod::POST, RequestMethod::PUT})
        //Swoft\Devtool\Http\Controller\GenController
        //* @RequestMapping(route="preview", method=RequestMethod::POST)
        return Context::mustGet()->getResponse()->withContentType(ContentType::HTML)->withContent("hiaa");
    }
}

## app/Http/Middleware/ControllerMiddleware.php:
<?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\Context\Context;
use Swoft\Http\Message\Response;
use Swoft\Http\Server\Contract\MiddlewareInterface;
use Throwable;

/**
 * Class ControllerMiddleware - The middleware of httpDispatcher
 *
 * @Bean()
 */
class ControllerMiddleware implements MiddlewareInterface
{
    /**
     * Process an incoming server request.
     *
     * @param ServerRequestInterface $request
     * @param RequestHandlerInterface $handler
     *
     * @return ResponseInterface
     * @inheritdoc
     * @throws Throwable
     */
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        /** @var Response $response */
        $date = date("Y-m-d H:i:s ");
        $method = $request->getMethod();

        $router    = \Swoft\Bean\BeanFactory::getSingleton('httpRouter');
        $uriPath   = $request->getUriPath();
        $routeData = $router->match($uriPath, $method);
        if( $routeData[0] == \Swoft\Http\Server\Router\Router::NOT_FOUND ){
            $response = Context::mustGet()->getResponse();
            var_dump(1111111);
            return $response->withData([$method ."拒绝访问"]);
        }

        $status = 0;
        if ( $status == 0 ) {
            //直接处理之后的 响应
            $response = $handler->handle($request);
            var_dump("直接响应");
            return $response->withData($date); //已完成、处理无效
            return $response;
        } elseif ( $status == 1) {
            //验证失败的 响应
            $json = ['code'=>0,'msg'=>'授权失败','time'=>$date];
            $response = Context::mustGet()->getResponse();
            return $response->withData($json);

        } elseif ( $status == 2 ) {
            $response = Context::mustGet()->getResponse();
            return $response->withData("ok")->withStatus(404);
        } else {
            $response = Context::mustGet()->getResponse();
            return $response->withData($method);
        }
    }
}

中间件的控制官方没有手册,头大。


沧浪水
97 声望12 粉丝

引用和评论

0 条评论