From 81990de191c7a9c77e1cde69b309ac9a9a86589c Mon Sep 17 00:00:00 2001 From: Arsen Mirzaev Tatyano-Muradovich Date: Mon, 28 Feb 2022 04:22:21 +1000 Subject: [PATCH] =?UTF-8?q?=D0=9C=D0=B0=D1=80=D1=88=D1=80=D1=83=D1=82?= =?UTF-8?q?=D0=B8=D0=B7=D0=B0=D1=82=D0=BE=D1=80=20=D1=82=D0=B5=D0=BF=D0=B5?= =?UTF-8?q?=D1=80=D1=8C=20=D1=83=D0=BC=D0=B5=D0=B5=D1=82=20=D0=B2=20=D0=BF?= =?UTF-8?q?=D0=B5=D1=80=D0=B5=D0=BC=D0=B5=D0=BD=D0=BD=D1=8B=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mirzaev/minimal/system/controller.php | 8 +-- mirzaev/minimal/system/core.php | 16 ++--- mirzaev/minimal/system/model.php | 2 +- mirzaev/minimal/system/router.php | 91 ++++++++++++++++++++++----- 4 files changed, 89 insertions(+), 28 deletions(-) diff --git a/mirzaev/minimal/system/controller.php b/mirzaev/minimal/system/controller.php index f508415..aa7a9f2 100644 --- a/mirzaev/minimal/system/controller.php +++ b/mirzaev/minimal/system/controller.php @@ -50,7 +50,7 @@ class controller { match ($name) { 'model' => (function () use ($value) { - if (isset($this->model)) { + if ($this->__isset('model')) { // Свойство уже было инициализировано // Выброс исключения (неудача) @@ -72,7 +72,7 @@ class controller } })(), 'view' => (function () use ($value) { - if (isset($this->view)) { + if ($this->__isset('view')) { // Свойство уже было инициализировано // Выброс исключения (неудача) @@ -94,7 +94,7 @@ class controller } })(), 'postfix' => (function () use ($value) { - if (isset($this->postfix)) { + if ($this->__isset('postfix')) { // Свойство уже было инициализировано // Выброс исключения (неудача) @@ -132,7 +132,7 @@ class controller { return match ($name) { 'postfix' => (function () { - if (isset($this->postfix)) { + if ($this->__isset('postfix')) { // Свойство уже было инициализировано } else { // Свойство ещё не было инициализировано diff --git a/mirzaev/minimal/system/core.php b/mirzaev/minimal/system/core.php index c29b165..6a1a740 100644 --- a/mirzaev/minimal/system/core.php +++ b/mirzaev/minimal/system/core.php @@ -117,7 +117,7 @@ final class core { match ($name) { 'storage', 'db', 'database' => (function () use ($value) { - if (isset($this->storage)) { + if ($this->__isset('storage')) { // Свойство уже было инициализировано // Выброс исключения (неудача) @@ -139,7 +139,7 @@ final class core } })(), 'router' => (function () use ($value) { - if (isset($this->router)) { + if ($this->__isset('router')) { // Свойство уже было инициализировано // Выброс исключения (неудача) @@ -161,7 +161,7 @@ final class core } })(), 'controller' => (function () use ($value) { - if (isset($this->controller)) { + if ($this->__isset('controller')) { // Свойство уже было инициализировано // Выброс исключения (неудача) @@ -183,7 +183,7 @@ final class core } })(), 'model' => (function () use ($value) { - if (isset($this->model)) { + if ($this->__isset('model')) { // Свойство уже было инициализировано // Выброс исключения (неудача) @@ -205,7 +205,7 @@ final class core } })(), 'namespace' => (function () use ($value) { - if (isset($this->namespace)) { + if ($this->__isset('namespace')) { // Свойство уже было инициализировано // Выброс исключения (неудача) @@ -244,7 +244,7 @@ final class core return match ($name) { 'storage', 'db', 'database' => $this->storage ?? throw new exception("Свойство \"\$$name\" не инициализировано", 500), 'router' => (function () { - if (isset($this->router)) { + if ($this->__isset('router')) { // Свойство уже было инициализировано } else { // Свойство ещё не было инициализировано @@ -257,7 +257,7 @@ final class core return $this->router; })(), 'controller' => (function () { - if (isset($this->controller)) { + if ($this->__isset('controller')) { // Свойство уже было инициализировано } else { // Свойство ещё не было инициализировано @@ -270,7 +270,7 @@ final class core return $this->controller; })(), 'model' => (function () { - if (isset($this->model)) { + if ($this->__isset('model')) { // Свойство уже было инициализировано } else { // Свойство ещё не было инициализировано diff --git a/mirzaev/minimal/system/model.php b/mirzaev/minimal/system/model.php index 1a521b0..bf11885 100644 --- a/mirzaev/minimal/system/model.php +++ b/mirzaev/minimal/system/model.php @@ -67,7 +67,7 @@ class model { return match ($name) { 'postfix' => (function() { - if (isset($this->postfix)) { + if ($this->__isset('postfix')) { // Свойство уже было инициализировано } else { // Свойство ещё не было инициализировано diff --git a/mirzaev/minimal/system/router.php b/mirzaev/minimal/system/router.php index 01a7d08..4e9a8a1 100644 --- a/mirzaev/minimal/system/router.php +++ b/mirzaev/minimal/system/router.php @@ -56,29 +56,68 @@ final class router // Инициализация URL $url = parse_url($uri, PHP_URL_PATH); - // Сортировка массива маршрутов от большего ключа к меньшему + // Универсализация + $url = self::universalization($url); + + // Сортировка массива маршрутов от большего ключа к меньшему (кешируется) krsort($this->routes); - foreach ($this->routes as $key => $value) { + // Поиск директорий в ссылке + preg_match_all('/[^\/]+/', $url, $directories); + + // Инициализация директорий + $directories = $directories[0]; + + foreach ($this->routes as $route => $data) { // Перебор маршрутов - // Если не записан "/" в начале, то записать - $route_name = preg_replace('/^([^\/])/', '/$1', $key); - $url = preg_replace('/^([^\/])/', '/$1', $url); + // Универсализация + $route = self::universalization($route); - // Если не записан "/" в конце, то записать - $route_name = preg_replace('/([^\/])$/', '$1/', $route_name); - $url = preg_replace('/([^\/])$/', '$1/', $url); + // Поиск директорий в маршруте + preg_match_all('/[^\/]+/', $route, $data['directories']); - if (mb_stripos($route_name, $url, 0, "UTF-8") === 0 && mb_strlen($route_name, 'UTF-8') <= mb_strlen($url, 'UTF-8')) { - // Найден маршрут, а так же его длина не меньше длины запрошенного URL + // Инициализация директорий + $data['directories'] = $data['directories'][0]; - // Инициализация маршрута - $route = $value[$_SERVER["REQUEST_METHOD"] ?? 'GET']; + if (count($directories) === count($data['directories'])) { + // Совпадает количество директорий у ссылки и маршрута (вероятно эта ссылка на этот маршрут) - // Выход из цикла (успех) - break; + // Инициализация массива переменных + $vars = []; + + foreach ($data['directories'] as $index => &$directory) { + // Перебор найденных переменных + + if (preg_match('/\$([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]+)/', $directory) === 1) { + // Переменная + + // Запись в массив переменных и перезапись переменной значением из ссылки + $directory = $vars[$directory] = $directories[$index]; + } + } + + // Реиницилазция маршрута + $route = self::universalization(implode('/', $data['directories'])); + + if (mb_stripos($route, $url, 0, "UTF-8") === 0 && mb_strlen($route, 'UTF-8') <= mb_strlen($url, 'UTF-8')) { + // Найден маршрут, а так же его длина не меньше длины запрошенного URL + + // Инициализация маршрута + if (array_key_exists($_SERVER["REQUEST_METHOD"], $data)) { + // Найдены настройки для полученного типа запроса + + // Запись маршрута + $route = $data[$_SERVER["REQUEST_METHOD"]]; + } + + // Выход из цикла + break; + } } + + // Деинициализация + unset($route); } if (!empty($route)) { @@ -115,11 +154,15 @@ final class router /** * Контроллер ошибок + * + * @param core $core Ядро фреймворка + * + * @return string|null HTML-документ с ошибкой */ private function error(core $core = null): ?string { if ( - class_exists($class = (new ReflectionClass(core::class))->getNamespaceName() . '\\controllers\\errors' . $core->controller->postfix ?? (new core())->controller->postfix) && + class_exists($class = '\\' . ($core->namespace ?? (new ReflectionClass(core::class))->getNamespaceName()) . '\\controllers\\errors' . $core->controller->postfix ?? (new core())->controller->postfix) && method_exists($class, $method = 'error404') ) { // Существует контроллер ошибок и метод для обработки ошибки @@ -134,4 +177,22 @@ final class router return null; } } + + /** + * Универсализация URL + * + * @param string $url Ссылка + * + * @return string Универсализированная ссылка + */ + private function universalization(string $url): string + { + // Если не записан "/" в начале, то записать + $url = preg_replace('/^([^\/])/', '/$1', $url); + + // Если записан "/" в конце, то удалить + $url = preg_replace('/(.*)\/$/', '$1', $url); + + return $url; + } }