MVC - карта маршрутизации

sfsf

Новичок
Хочу сделать карту маршрутизации
Если у вас есть готовые примеры, то скиньте пожалуйста

Вид моей карты

PHP:
$routes = array (
                    'index' => array(':p',':id'),
                    '404' => array(),
                    'catalog' => array('detail',':id',':p'),
                   'catalog' => array('index',':id',':p')
        );
собственно сейчас обрабатывает все виды ссылок

но возникла проблема

если допустим я хочу сделать ссылку вида

site.xx/123-kniga.htm

то перекинет на страницу

site.xx/404

Какие есть идеи по усовершенствовании карты маршрутизации?
 

hell0w0rd

Продвинутый новичок
Тебе нужно превращать это в регулярку:
из
PHP:
/:id.html
в
PHP:
/\/(.+).html/
А вообще это велосипед, есть готовые компоненты для такого, бери и пользуйся.
PS наверняка через некоторое время захочешь для id только цифры - тогда прийдется писать свои правила для составления регулярок, а в компоненте уже все для этого есть)
 

ksnk

прохожий
PHP:
'router.rules'=>array(
        array('#^/?seat(?:/(\d+))?($|\?.*)#',
            array('class'=>'Main', 'method'=>'do_filter', 'filter'=>'174' ,1=>'page')),
        array('#^/?furniture(?:/(\d+))?($|\?.*)#',
            array('class'=>'Main', 'method'=>'do_filter', 'filter'=>'164' ,1=>'page')),
        array('#^/?carriage(?:/(\d+))?($|\?.*)#',
            array('class'=>'Main', 'method'=>'do_filter', 'filter'=>'172' ,1=>'page')),
        array('#^/?filter/(\d+)(?:/(\d+))?($|\?.*)#',
            array('class'=>'Main', 'method'=>'do_filter', 1 => 'filter',2=>'page')),
        array('#^/?webinars(?:/(\d+))?($|\?.*)#',
            array('class'=>'Main', 'method'=>'do_list', 'filter'=>'webinar' ,1=>'page')),
        array('#^/?(\w+)/(\w+)($|\?.*)#',
            array(1 => 'class', 2 => 'method', 3 => 'query')),
        array('#^/?(?:[^\.\/]*)\.(\d+)($|\?.*)#',
            array('class'=>'Main', 'method'=>'do_video', 1 => 'xid', 2 => 'query')),
        array('#^/?(\w+)($|\?.*)#',
            array('class'=>'Main', 1 => 'method', 2 => 'query')),
    ),
Каждая строчка - правило. Первый элемент правила - регулярка. Если она подошла - правила дальше не раскручиваются. Второй элемент - описание результатов preg_match. xxx=>yyy - если xxx -строка, то свойство XXX получает значение YYY. Если xxx число - свойство yyy получает такое по по порядку значение, захваченное регуляркой. Cвойство `method` при присвоении из значения регулярки дополняется префиксом 'do_'

Довольно гибко, хотя тоже не универсально, к сожалению...
 

hell0w0rd

Продвинутый новичок
может я конечно плохо в регулярках шарю - но это жесть)
 

ksnk

прохожий
Интересно, наверное, советовать к детскому велосипеду прикрутить колесо от Мерседеса... Что-то такое здесь есть в этом... инфернальное такое... ;)
Ну, Zend я могу еще вообразить как заменитель самодельного маршрутизатора, хотя и с некоторым трудом, а вот запчасть от Симфони без самого Симфони смотрится чистым злом...

Для начала - нужно определится с задачей, решаемой роутером.
Можно просто и тупо распарсить прилетевший чпу. Если достаточно ловко и удачно генерировать ссылки, это можно даже перевесить на htaccess. На php эту задачу несложно решить за десяток-пару десятков строк. Из CMS наиболее простое решение я увидел в CI http://ellislab.com/codeigniter/user-guide/general/routing.html. Сам CI тоже очень прост, интуитивно понятен велосипедостроителю и тем привлекателен. Если бы он стартовал не в дремучие годы засилья php4, а попозже, был бы смысл советовать его использовать, а не только тырить оттуда простые решения.

Можно решать сверхзадачу полного контроля над входящими параметрами. Это уже не десяток строк, но запчасть большой цмски. Так или иначе - все цмс решают эту задачу. Наиболее далеко, imho, зашли в той же симфони -http://symfony.com/doc/2.0/book/routing.html . Конфигурация в yaml, все дела (yaml - чисто потому, что на php-массивах оно смотрится криво)... Хотя действительно универсально.

Можно заодно решить задачу генерации Url для вставляемых в шаблоны ссылок по тем же правилам, которыми парсится ЧПУ. Имеющийся в системе компонент получает способность не знать о том, какие ссылки в системе ведут на него. Такое я встречал только в Yii - http://www.yiiframework.com/doc/guide/1.1/en/topics.url. С моей точки зрения - несколько избыточная возможность, но реального опыта использования Yii у меня нет, так что ее пользу я могу просто не видеть.

мой коммент был про то, что ksnk скинул
Какой коммент? про жесть или тот, где отквочен кусок сообщения сингла?
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
ksnk
Роутинг от симфони прикручивается как раз таки на раз-два... А вот зенд - это как с пушки по молекулам, даже не по воробьям.
 

hell0w0rd

Продвинутый новичок
Что значит симфони без симфони? Вообще-то они создают по максимому не связные компоненты, юзай как хочешь)
 

ksnk

прохожий
Что значит симфони без симфони? Вообще-то они создают по максимому не связные компоненты, юзай как хочешь)
Симфони без симфони? Несвязанные копоненты? Ты серьезно? Вот кусочек кода по твоей ссылке с примером. Я его добил юзезами, которые встречаются внутри списка юзезов из примера.
PHP:
use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\Session\SessionInterface;

use Symfony\Component\Routing\Matcher\UrlMatcher;
    use Symfony\Component\Routing\Exception\MethodNotAllowedException;
    use Symfony\Component\Routing\Exception\ResourceNotFoundException;
   
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
  use Symfony\Component\Config\Resource\ResourceInterface;

use Symfony\Component\Routing\Route;
Проверить размер подключаемых файлов, просуммировать, не пренебрегая uses-ами из внутренностей этих файлов, и сравнить с объемом всего своего собственного велосипеда. Если показалось, что все в порядке - проверить, не перепутали ли местами эти числа? Если объем собственного кода покажется совсем несолидным - добавить размер картинок из админки, иначе несложно с непривычки заработать комплекс неполноценности.

Это и есть колесо от Мерседеса, прикручиваемое к детскому велосипеду. Если нет опыта строительства собственного велосипеда, то этот крик души останется непонятен. Таким людям приношу искренние извинения.

Zend в этом смысле не такой связанный...
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Код откуда-то с мануала, без use
PHP:
$locator        = new \Symfony\Component\Config\FileLocator(array(__DIR__));
$requestContext = new \Symfony\Component\Routing\RequestContext($_SERVER['REQUEST_URI']);

$router = new \Symfony\Component\Routing\Router(
	new \Symfony\Component\Routing\Loader\YamlFileLoader($locator),
	'../application/config/routes.yml',
	#array('cache_dir' => '../application/cache'),
	[],
	$requestContext
);
$x      = $router->match($_SERVER['REQUEST_URI']);
var_dump($x);
Ну и файл с роутами в YAML формате, но тут кому как удобней. Велосипед не полный, просто пример.

Собственно все зависимости легко ставятся через composer
 

ksnk

прохожий
c0dex
Проблема подключения "чужих" компонент в том, что их вполне комфортно подключать и использовать только если рядом лежит ВЕСЬ комплект сорцов. Все 10метров(в случае симфони). Никто не соберется посидеть и поковыряться в чужих исходниках, выкидывая ненужные файлы, это непроизводительно и довольно глупо. Так что в реальности совет "использовать компонент" звучит так "+10 метров грузи на сервер и пиши вот эти 10 строк в своем файле". Более применимый к реальности совет в этом случае звучал бы бросай курить, становись на лыжи Пользуйся симфони и не парься. Только вот это ли хотел услышать топикстартер? Кстати, где он?
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
ksnk
Компоненты симфони довольно независимы и 10 мегами там и не пахнет для того, чтобы запустиьт только роутинг. Это вовсе не значит, что я мог бы автору посоветовать использовать симфони или зенд.

Для нормального использования компонентов надо иметь значительный бэкграунд и уметь писать велосипеды. Можно просто подсмотреть как реализовано там и написать свое, то есть не в сорц смотреть, а в то, как происходит задание роута.
 

radioheaded

PHP нуб
И как с такой архитектурой сгенерировать url на нужный контроллер+action?

С архитектурой ТСа это сделать можно.
Да как угодно, начиная с тупого вызова нужного контроллера и экшена в колбэке. В «архитектуре» ТС я вижу только маппинг сегмента на список параметров непонятно чего (причем два ключа catalog с разными значениями слегка доставляют).

С klein можно, например, классический вариант
PHP:
$klein->respond(array('POST','GET'), '[:controller]/[:action]', $callback);
В $callback простенькие проверки на существование контроллера, на выполнимость экшена и т.д.

Вообще я просто привел пример для изучения роутинга, т.к. там, на мой взгляд, все основные моменты, использующиеся при любом роутинге, написаны довольно неплохо.
 

ksnk

прохожий
Это вовсе не значит, что я мог бы автору посоветовать использовать симфони или зенд.
Точно? А зачем тогда нужен пример использования БЕЗ примера yaml'ового конфига? Он ведь самое вкусное что в этом роутере есть.
При некотором навыке этот конфиг можно избавить от yaml, переписав на php-массивы, но получится довольно коряво. Yaml в этом смысле красавец.
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
ksnk
Там есть много вкусного и без него, ибо роуты ты волен задавать и на основе PHP файла, кому как удобно.
 
Сверху