<?php<liu21st@gmail.com>declare (strict_types = 1);
namespace think;
use think\event\HttpEnd;
use think\event\HttpRun;
use think\event\RouteLoaded;
use think\exception\Handle;
use Throwable;
class Http
{
protected $app;
protected $name;
protected $path;
protected $isBind = false;
public function __construct(App $app)
{
$this->app = $app;
$this->routePath = $this->app->getRootPath() . 'route' . DIRECTORY_SEPARATOR;
}
public function name(string $name)
{
$this->name = $name;
return $this;
}
public function getName(): string
{
return $this->name ?: '';
}
public function path(string $path)
{
if (substr($path, -1) != DIRECTORY_SEPARATOR) {
$path .= DIRECTORY_SEPARATOR;
}
$this->path = $path;
return $this;
}
public function getPath(): string
{
return $this->path ?: '';
}
public function getRoutePath(): string
{
return $this->routePath;
}
public function setRoutePath(string $path): void
{
$this->routePath = $path;
}
public function setBind(bool $bind = true)
{
$this->isBind = $bind;
return $this;
}
public function isBind(): bool
{
return $this->isBind;
}
public function run(Request $request = null): Response
{
$request = $request ?? $this->app->make('request', [], true);
$this->app->instance('request', $request);
try {
$response = $this->runWithRequest($request);
} catch (Throwable $e) {
$this->reportException($e);
$response = $this->renderException($request, $e);
}
return $response;
}
protected function initialize()
{
if (!$this->app->initialized()) {
$this->app->initialize();
}
}
protected function runWithRequest(Request $request)
{
$this->initialize();
$this->loadMiddleware();
$this->app->event->trigger(HttpRun::class);
return $this->app->middleware->pipeline()
->send($request)
->then(function ($request) {
return $this->dispatchToRoute($request);
});
}
protected function dispatchToRoute($request)
{
$withRoute = $this->app->config->get('app.with_route', true) ? function () {
$this->loadRoutes();
} : null;
return $this->app->route->dispatch($request, $withRoute);
}
protected function loadMiddleware(): void
{
if (is_file($this->app->getBasePath() . 'middleware.php')) {
$this->app->middleware->import(include $this->app->getBasePath() . 'middleware.php');
}
}
protected function loadRoutes(): void
{
$routePath = $this->getRoutePath();
if (is_dir($routePath)) {
$files = glob($routePath . '*.php');
foreach ($files as $file) {
include $file;
}
}
$this->app->event->trigger(RouteLoaded::class);
}
protected function reportException(Throwable $e)
{
$this->app->make(Handle::class)->report($e);
}
protected function renderException($request, Throwable $e)
{
return $this->app->make(Handle::class)->render($request, $e);
}
public function end(Response $response): void
{
$this->app->event->trigger(HttpEnd::class, $response);
$this->app->middleware->end($response);
$this->app->log->save();
}
}