Completed
Push — master ( 4de45c...7b702d )
by Taosikai
13:36
created

src/Jade/App.php (1 issue)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/*
4
 * This file is part of the jade/jade package.
5
 *
6
 * (c) Slince <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Jade;
13
14
use Psr\Container\ContainerInterface;
15
use Psr\Http\Message\ResponseInterface;
16
use Psr\Http\Message\ServerRequestInterface as Request;
17
use Psr\Http\Message\ServerRequestInterface;
18
use Psr\Http\Server\MiddlewareInterface;
19
use Psr\Http\Server\RequestHandlerInterface;
20
use Jade\HttpKernel\HttpKernelProvider;
21
use Jade\Routing\Collection as RouteCollection;
22
use Jade\Routing\Route;
23
use Jade\Routing\RouteBuilderTrait;
24
use Jade\Middleware\RouteMiddleware;
25
use Zend\Diactoros\ServerRequestFactory;
26
27
class App implements RequestHandlerInterface
28
{
29
    use RouteBuilderTrait;
30
31
    /**
32
     * 是否已经初始化
33
     *
34
     * @var bool
35
     */
36
    protected $booted = false;
37
38
    /**
39
     * @var ContainerInterface
40
     */
41
    protected $container;
42
43
    /**
44
     * @var RouteCollection
45
     */
46
    protected $routes;
47
48
    /**
49
     * @var array
50
     */
51
    protected $providers;
52
53
    public function __construct(ContainerInterface $container = null)
54
    {
55
        if (null === $container) {
56
            $container = new Container();
57
        }
58
        // 注册核心服务
59
        $this->container = $container;
60
        $this->container['app'] = $this;
61
        $this->register(new CoreServiceProvider());
62
        $this->routes = new RouteCollection();
63
    }
64
65
    /**
66
     * 初始化启动工作
67
     */
68
    public function boot()
69
    {
70
        if ($this->booted) {
71
            return;
72
        }
73
        $this->booted = true;
74
    }
75
76
    /**
77
     * {@inheritdoc}
78
     */
79
    public function handle(Request $request): ResponseInterface
80
    {
81
        // 启动应用
82
        $this->boot();
83
        $this->register(new HttpKernelProvider());
84
        // 请求转交给 http kernel
85
        return $this->container->get('http_kernel')->handle($request);
86
    }
87
88
    /**
89
     * 代理http kernel
90
     *
91
     * @param ServerRequestInterface $request
92
     * @param ResponseInterface $response
93
     */
94
    public function terminate(ServerRequestInterface $request, ResponseInterface $response)
95
    {
96
        $this->container->get('http_kernel')->terminate($request, $response);
97
    }
98
99
    /**
100
     * 开启服务, 监听请求
101
     */
102
    public function serve()
103
    {
104
        // 1. 创建请求
105
        $request = ServerRequestFactory::fromGlobals();
106
        // 2. 处理请求
107
        $response = $this->handle($request);
108
        // 3. 输出响应
109
        $this->terminate($request, $response);
110
    }
111
112
    /**
113
     * 注册服务提供者
114
     *
115
     * @param ServiceProviderInterface|EventProviderInterface|CommandProviderInterface $provider
116
     */
117
    public function register($provider)
118
    {
119
        // 注册服务
120
        if ($provider instanceof ServiceProviderInterface) {
121
            $provider->register($this->container);
0 ignored issues
show
$this->container of type object<Psr\Container\ContainerInterface> is not a sub-type of object<Jade\Container>. It seems like you assume a concrete implementation of the interface Psr\Container\ContainerInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
122
        }
123
        // 注册事件
124
        if ($provider instanceof EventProviderInterface) {
125
            $provider->subscribe($this->container->get('event_dispatcher'), $this->container);
126
        }
127
        $this->providers[] = $provider;
128
    }
129
130
    /**
131
     * 返回该应用对应的路由集合
132
     *
133
     * @return RouteCollection
134
     */
135
    public function getRoutes()
136
    {
137
        return $this->routes;
138
    }
139
140
    /**
141
     * 获取服务容器
142
     *
143
     * @return Container
144
     */
145
    public function getContainer(): Container
146
    {
147
        return $this->container;
148
    }
149
150
    /**
151
     * 添加一个 middleware
152
     *
153
     * @param string|MiddlewareInterface|callable $middleware
154
     * @param Route|null $route 绑定的路由
155
     */
156
    public function pipe($middleware, Route $route = null)
157
    {
158
        $middleware = $this->container->get('middleware_factory')->create($middleware);
159
        if (null !== $route) {
160
            $middleware = new RouteMiddleware($route, $middleware);
161
        }
162
        $this->container->get('middleware_pipeline')->pipe(
163
            $middleware
164
        );
165
    }
166
167
    /**
168
     * 返回全部的 provider
169
     *
170
     * @return array
171
     */
172
    public function getProviders()
173
    {
174
        return $this->providers;
175
    }
176
}