Всем привет, пишу роутер и встал в тупик, то ли мысль не идет или я не то делаю. Описание в коде Kод : $url - Массив URL запроса ( Пример: '0' => 'blog', '1' = 'post') all_url - Полный путь URL запроса ( Пример : /blog/post ) Из функций ways долно вернуться массив : Код (Text): 'controller' => '', 'action' => '', 'key' => [ ] PHP: private function ways($url) { // Получаем массив со списоком всех роутеров $ways = include ROOT.'/core/route/ways.php'; if(empty($url[0])) { $action = '/'; } else { $action = $this->all_url; } // Если находим точное совпадение, отправляем массив if(array_key_exists($action, $ways)) { return $ways[$action]; } else { foreach ($ways as $key => $value) { if(preg_match('{id}', $key)) { // Тут мысль встала Нужно проверить запрос на совпадения ( Пример: запрос URL /category/test/test1 надо сравнить его с этим : category/{id}/{id} ) если сходиться то вернуть return массив } } } Файл ways.php PHP: <?php return [ // Главная '/' => [ 'controller' => 'home', 'action' => 'index' ], // Добавить матерьял 'add' => [ 'controller' => 'product', 'action' => 'add' ], /* * Категорий */ // Все категорий 'category' => [ 'controller' => 'category', 'action' => 'all' ], // Получаем матерьял категорий 'category/{id}/{id}' => [ 'controller' => 'category', 'action' => 'get', 'key' => [ 'category' => $url[1], 'subcategory' => $url[2] ] ], ];
Нужно чтобы код и данные гармонировали друг с другом, а не выдумывать фиг знает какой формат данных, чтобы потом чесать репу по поводу его обработки. --- Добавлено --- Нафиг вы в метод передаете компоненты пути, когда у вас ключами у роутов служат полноценные, в том числе и многокомпонентные, маски?
Простейший пример роутера: PHP: <?php //ROUTER class class router { public function getURI() { if (!empty ($_SERVER['REQUEST_URI'])) { return trim ($_SERVER['REQUEST_URI'],'/'); } //эта функция возвращает запрос из адресной строки без пробелов } public function checkRequest($request_controller,$request_action) { $file = 'controllers/'.$request_controller.'.php'; //какой контроллер и где будем искать if (!file_exists($file)) { //если не нашли класс контроллера $request_controller = 'undefine'; //делаем контроллер страницы 404 $request_action = 'no_controller'; //метод "не нашли контроллер" $request_array = array($request_controller,$request_action); return $request_array; //вернем массив с контроллером undefine.php и методом "нет контроллера" undefine.php должен быть и //показывать соответствующее сообщение } require $file; //если нашли подключим класс контроллера (лучше это делать _autoloadom) $available_methods = get_class_methods($request_controller); //посмотрим какие методы есть в нашем классе контроллера if (!in_array($request_action, $available_methods)) { //если не существует запрошенный метод $request_controller = 'undefine'; //опять 404 $request_action = 'no_action'; //только уже с методом "не нашли метода" $request_array = array($request_controller,$request_action); return $request_array; //вернем массив } $request_array = array($request_controller,$request_action); //если контроллер и метод существуют просто вернем их в массиве return $request_array; } public function run(){ $uri = $this -> getURI(); //получим запрос из адресной строки if (empty($uri)) { $uri = 'site/index';} //если пустой будем открывать страницу по умолчанию if (!preg_match('~^[0-9a-z/_]{1,55}$~',$uri)) {$uri='site/index';} //если в запросе есть символы кроме a-z, A-Z цифры 0-9 или / и _ или он //длиннее 55 символов тоже откроем страницу по умолчанию (руководствуемся правилом "Белого списка" $uri = explode('/',$uri); //превратим строку $uri в массив разбив на значения по символу / $request_controller = array_shift($uri); //положим в переменную $request_controller первый элемент массива $uri - это будет наш //контроллер $request_action = array_shift($uri); // второй элемент массива $uri положим в переменную $request_action - это будет метод который //будем вызывать $request_array = $this -> checkRequest($request_controller, $request_action); //проверим есть ли у нас такой контроллер и метод в нем. //Функция checkRequest вернет массив в котором нулевым элементом будет валидный контроллер который у нас точно есть, а первым //элементом будет метод контроллера который у нас тоже есть. $c_request_controller = $request_array[0]; // вытащим из массива контроллер $c_request_action = $request_array[1]; //и метод $controller = new $c_request_controller; //создадим экземпляр класса контроллера $controller -> $c_request_action($request_controller,$request_action,$uri); //и вызовем метод передав ему в качестве аргументов //контроллер, метод и остаток от $uri если он есть. Т.е. например запрос www.site.ru/shownews/1 вызовет контроллер site метод shownews и //передаст 1 в качестве аргумента. } //end function run } ?>
Плюс данной реализации в том что не надо писать все возможные пути в массив в файле "ways.php" и помнить о них. Есть в папке controllers запрошенный контроллер и в нем нужный метод - он будет работать. Нет - будет 404