119 строки
3.4 KiB
PHP
119 строки
3.4 KiB
PHP
<?php
|
|
|
|
namespace MyApp\Core;
|
|
|
|
use ReflectionMethod;
|
|
use ReflectionClass;
|
|
use ReflectionException;
|
|
|
|
/**
|
|
* Class Router.
|
|
*/
|
|
class Router
|
|
{
|
|
/**
|
|
* @var array
|
|
*/
|
|
private $routes = [];
|
|
|
|
public function __construct()
|
|
{
|
|
$this->getRoutesFromControllers();
|
|
$this->addRoute('/^.*$/', 'MyApp\\Controller\\ErrorsController',
|
|
'get404', ['GET']);
|
|
$this->addRoute('/^.*$/', 'MyApp\\Controller\\ErrorsController',
|
|
'post404', ['POST', 'PUT', 'DELETE']);
|
|
|
|
$this->run();
|
|
}
|
|
|
|
/**
|
|
* Get Routes from a comment on method in Controllers.
|
|
*/
|
|
private function getRoutesFromControllers()
|
|
{
|
|
/* @var \App $app */
|
|
global $app;
|
|
|
|
/* @var Config $config */
|
|
$config = $app->config;
|
|
|
|
$controllersDir = $config->getControllersDir();
|
|
$controllersNamespace = $config->getControllersNamespace();
|
|
|
|
$files = scandir($controllersDir);
|
|
foreach ($files as $file) {
|
|
$className = strstr($file, '.php', true);
|
|
$fileName = $controllersDir.$file;
|
|
if (is_file($fileName) && false !== $className) {
|
|
try {
|
|
$refClass = new ReflectionClass($controllersNamespace.$className);
|
|
$methods = $refClass->getMethods(ReflectionMethod::IS_PUBLIC);
|
|
foreach ($methods as $method) {
|
|
$tags = $app->parseTagsFromComment($method->getDocComment());
|
|
if (is_array($tags)) {
|
|
if (array_key_exists('RouteRegExp', $tags)) {
|
|
if (!array_key_exists('HttpMethod', $tags)) {
|
|
$tags['HttpMethod'] = ['GET'];
|
|
}
|
|
|
|
$this->addRoute($tags['RouteRegExp'],
|
|
$method->class, $method->name,
|
|
$tags['HttpMethod']);
|
|
}
|
|
}
|
|
}
|
|
} catch (ReflectionException $e) {
|
|
var_dump($e);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add route to array.
|
|
*
|
|
* @param string $regExp
|
|
* @param string $className
|
|
* @param string $classMethod
|
|
* @param array $httpMethods
|
|
*/
|
|
private function addRoute(
|
|
string $regExp,
|
|
string $className,
|
|
string $classMethod,
|
|
array $httpMethods
|
|
) {
|
|
foreach ($httpMethods as $httpMethod) {
|
|
$this->routes[strtoupper($httpMethod)][] = [
|
|
$regExp,
|
|
$className,
|
|
$classMethod,
|
|
];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Run parse request.
|
|
*/
|
|
private function run()
|
|
{
|
|
if (array_key_exists($_SERVER['REQUEST_METHOD'], $this->routes)) {
|
|
foreach ($this->routes[$_SERVER['REQUEST_METHOD']] as $route_array) {
|
|
if (preg_match($route_array[0], $_SERVER['REQUEST_URI'],
|
|
$matches)) {
|
|
$obj = new $route_array[1]();
|
|
$param_arr = [];
|
|
foreach ($matches as $key => $value) {
|
|
if (!is_int($key)) {
|
|
$param_arr[] = $value;
|
|
}
|
|
}
|
|
call_user_func_array([$obj, $route_array[2]], $param_arr);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|