ФорумПрограммированиеPHP для идиотов → Оптимизация роутера запросов

Оптимизация роутера запросов

  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 20 января 2010 г. 16:37, спустя 1 минуту 33 секунды

    вы так меня заинтересовали своими роутерами, устроить чтоли сегодня вечер опенсорца, мозг размять ..
    Сапожник без сапог
  • Абырвалг

    Сообщения: 6480 Репутация: N Группа: Джедаи

    Spritz 20 января 2010 г. 16:41, спустя 4 минуты 5 секунд


    Абырвалг, аналог Zend_Controller_Router_Route получился.

    значит я на правильном пути. По этому вопросу в зенд не смотрел, честное слово. Сам дошел)
    Гляну сегодня как там это.
  • Ewg777

    Сообщения: 510 Репутация: N Группа: Джедаи

    Spritz 20 января 2010 г. 16:41, спустя 30 секунд



    Абырвалг, аналог Zend_Controller_Router_Route получился.

    значит я на правильном пути. По этому вопросу в зенд не смотрел, честное слово. Сам дошел)
    Гляну сегодня как там это.
    http://framework.zend.com/manual/ru/zend.controller.router.html#zend.controller.router.routes.standard
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 20 января 2010 г. 16:50, спустя 8 минут 27 секунд

    дуд, давай сделаем какбы баттл. возьмем одну и ту же правдоподобную большую таблицу маршрутов где-то на 100 вариантов, синтаксис понятно будет у каждого свой, но маршруты аналогичные. роутер должен работать по одной таблице маршрутизации в обе стороны.

    прогоним тесты распознавания для
    - корня сайта
    - маршрута без переменных параметров
    - маршрута с двумя параметрами, например id и page
    - маршрута с GET-параметрами. (фиг с ними, пусть они просто игнорируются если невозможно использовать)
    - ошибочного маршрута
    ιιlllιlllι унц-унц
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 20 января 2010 г. 17:04, спустя 14 минут 19 секунд

    согласен, нет списка правил? а то на такие вещи я слабоват :)
    Сапожник без сапог
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 20 января 2010 г. 17:06, спустя 2 минуты 18 секунд

    нет. могу подготовить
    ιιlllιlllι унц-унц
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 20 января 2010 г. 17:09, спустя 2 минуты 27 секунд

    давай
    Спустя 27 сек.
    у меня на сегодня DudeMultiCurl, а то заебали просить уже =)) и видимо routers + коммерцию дохуетени фени)
    Спустя 14 сек.
    надо чаем закупиться, сутки будут длинные
    Сапожник без сапог
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 20 января 2010 г. 21:42, спустя 4 часа 33 минуты 8 секунд

    phpdude, подготовил 100 маршрутов :)
    тестируем маршруты для
    - корня сайта (не mydomain.name/, а mydomain.name/site/dir/)
    - маршрута без переменных параметров (admin/settings/announcements.html)
    - маршрута с двумя параметрами, например id и page (group/4096/video/page-17.html)
    - маршрута с GET-параметрами. (search.html?action=show_user_posts&user_id=319)
    - ошибочного маршрута (serach.html?action=show_user_posts&user_id=319)

    на выходе ид.маршрута или признак неудачи + именованные параметры со значениями
    ιιlllιlllι унц-унц
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 21 января 2010 г. 2:14, спустя 4 часа 32 минуты 7 секунд

    ебанный в рот!!! я уже 4 часа времени хуйей страдаю - батл ))))))))))))))))))
    Спустя 31 сек.
    думаю "туда ли я иду". идея прикольная, но скорость чето мне кажется будет не на высоте, хотя при кеше должна быть неебической
    Сапожник без сапог
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 22 января 2010 г. 15:42, спустя 1 день 13 часов 28 минут

    Сделал версию с двоичным поиском. Структуру кеша оставил как была в предыдущей версии. Только теперь он cоздается отсортированный. Можно было, наверное, еще поколдовать с оптимизацией данных…

    было

    foreach (…)
    {

    if (substr($request, 0, $len) != $quick)
    continue;
    if (preg_match($pattern, $request, $matches))
    {

    return $key;
    }
    }
    return FALSE;

    стало

    while ($imin <= $imax)
    {
    $i = ($imin + $imax) >> 1;

    $res = strcmp($quick, substr($request, 0, $len));
    if ($res == 0)
    {

    if (preg_match($pattern, $request, $matches))
    {

    return $key;
    }
    }
    else if ($res > 0)
    $imax = $i - 1;
    else
    $imin = $i + 1;
    }
    return FALSE;


    В архиве :
    install.php - создает файл конфигурации. хз зачем, просто привычка :)
    test_bin.php - простейший пример поиска делением по упордоченному массиву целых чисел. для понимания алгоритма.
    index.php - предыдущий роутер с перебором неотсортированного списка правил. для сравнения
    index2.php - новый роутер с двоичным поиском, что позволяет сократить количество сравнений на порядок!
    .htaccess - редиректит запросы на index2 чтобы проверялся текущий URL

    Замечание:
    Алгоритм поиска делением находит произвольный элемент. Если есть повторы, мы не знаем ЧТО именно нашли — первый подходящий элемент или десятый.
    В нашем масиве правил есть повторы начальных подстрок. Поэтому после binary search приходится делать прогон вверх и вниз :(

    Вывод:
    Если список правил короткий, нет смысла заморачиваться с binary search. Вполне подойдет поиск как в index.php

    Updated 1: исправил кое-что. загрузил новый архив
    Updated 2: http://subversion.assembla.com/svn/qb7/cuts/parse_url/
    ιιlllιlllι унц-унц
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 27 января 2010 г. 20:23, спустя 5 дней 4 часа 40 минут


    $request = Router::request();
    $route = Router::route($request);


    В $route попадает либо FALSE либо строка вроде 'topic.view' или 'topic.view.p'. Видим где два, а где три семента.
    Как это можно использовать. Один из вариантов проекции маршрут—метод:

    if ($route === FALSE) CustomController::defaultAction(); // … exit()

    $func = explode('.', $route);
    $appendix = count($func)==3 ? array_pop($func) : NULL;

    if (!is_callable($func))
    $func[1] = 'defaultAction';
    call_user_func($func, $appendix);

    Т.е. к моменту вызова call_user_func() в $func останется гарантированно два элемента. Так можно адресовать метод статического класса. Автолоадер в помощь!

    Каждый класс-контроллер, как минимум, содержит метод 'defaultAction". Это можно решить наследованием от общего предка CutstomController. В конкретном контроллере можно перекрыть его чем-то толковым.
    В defaultAction по-умолчанию можно поместить ошибку 404 или страничку "возможно вы искали …". Зависит от фантазии разработчика.
    А если в классе-контроллере определён метод из второго сегмента маршрута, то будет вызван он.
    ιιlllιlllι унц-унц
  • kostyl

    Сообщения: 5210 Репутация: N Группа: Джедаи

    Spritz 4 марта 2010 г. 2:22, спустя 35 дней 5 часов 58 минут

    а я роутер задаю динамически - в каждом экшене формирую возможные подэкшены, типа того…
  • Абырвалг

    Сообщения: 6480 Репутация: N Группа: Джедаи

    Spritz 4 марта 2010 г. 12:04, спустя 9 часов 42 минуты 25 секунд

    kostyl, не понял. Покажи на примере плз
  • Nyaah

    Сообщения: 574 Репутация: N Группа: Джедаи

    Spritz 4 марта 2010 г. 13:10, спустя 1 час 6 минут 30 секунд

    наверно что-то типа того:
    /controller/action/otherAction/params вызывает $сontroller->action($otherParams); а внутри action разбираются остальные параметры и в случае чего вызывается
    $controller->action->otherAction($params); либо $controller->action->defaultAction($params);

    Я примерно тожесамое делал, когда компоненты для жумлы писал, так как там роутер чистой воды уг, поэтому приходилось вносить логику роуэра в контроллер, но имхо, это пипец неудобно =)
    Work, buy, consume, die
  • Абырвалг

    Сообщения: 6480 Репутация: N Группа: Джедаи

    Spritz 4 марта 2010 г. 13:33, спустя 22 минуты 10 секунд

    мм. У меня так:

    	public function process()
    {
    if (Application::isActiveForm($this->getFormName())) {
    $this->checkForm();
    if ($this->errors) {
    $this->showForm();
    return;
    }
    // отэта типа экшн
    if ($this->do == 'edit') {
    $this->editSave();
    } else {
    $this->addSave();
    }
    redirect($this->getRedirectUrl());

    } else {
    // и эта типа тоже
    if ($this->do == 'edit') {
    $this->getValues();
    }
    $this->showForm();
    }
    }

Пожалуйста, авторизуйтесь, чтобы написать комментарий!