В чем разница Route, Router, Request?

hell0w0rd

Продвинутый новичок
GusakovNick, ну так и приведённый класс closure умеет. Вместо ответов на вопросы ты накидываешь ещё больше информации.
а ты сравни:
PHP:
$router->map('/users/:id/edit/', array('controller' => 'SomeController', 'action' => 'someAction'), array('methods' => 'GET,PUT', 'name' => 'users_edit', 'filters' => array('id' => '(\d+)')));
$app->match('/users/{id}/edit/', array('SomeController', 'someAction'))
    ->method('GET|PUT')
    ->assert('id', '\d+')
    ->bind('users_edit');
А в silex так вообще можно сделать приятную штуку:
PHP:
$users = $app['controllers_factory'];
$users->get('/{id}', function($is){});
$users->post('/new', function(){});
$app->mount('/users', $users);
Заверни подобное в конфиги и классы и будет конфетка:)
 

Вурдалак

Продвинутый новичок
То есть ты считаешь Vladex'у становится понятнее сущность роутера?
 

Vladex

Новичок
Что такое роутер я понял, теперь я хочу понять зачем он нужен:)
Cсылка имеет вид
Так вот как мне забрать значения
module и action?
Раньше ведь запросы были
Я брал ГЕТ запрос
PHP:
$_GET['name'] = $name;
и подставлял например в запрос mysql
А как сейчас
И как использовать полученные в url параметры.
Также интересно, надо ли в современном кодинге использовать такие конструкции
PHP:
$getpage['admin'] = (int)$_GET['admin'];
И если да, то могу я получать параметры из URL методом GET и передавать на исполнение?
PHP:
echo ( $_GET['admin'] == 1 ) ? $obj->display_admin() : $obj->display_public();
 

hell0w0rd

Продвинутый новичок
Vladex
Самый первый роутинг ты создаешь перенаправляя все запросы к серверу на index.php
Дальше роут разибивается каким-то классом для роутинга и ты можешь задавать ему правила работы.
Фактически:
Создаешь роуты, сообщаешь их классу, роутер смотрит к какому роуту относится текущий запрос, реализует действия описанные в роуте.
Все что приходит на сервер - строки, так что если нужно чтобы это были числа, или объекты - нужно преобразовать. Например в silex это делается с помощью convert
 

Vladex

Новичок
А конструкцию
PHP:
$getpage['admin'] = (int)$_GET['admin'];
использовать сейчас модно или уже устарел способ?
И все таки не понял как из роутера параметры передать на фронт-контроллер.
 

hell0w0rd

Продвинутый новичок
А конструкцию
PHP:
$getpage['admin'] = (int)$_GET['admin'];
использовать сейчас модно или уже устарел способ?
И все таки не понял как из роутера параметры передать на фронт-контроллер.
Не модно. Модно расставлять валидаторы/конверторы.
http://api.symfony.com/2.0/Symfony/Component/HttpFoundation/Request.html - вот посмотри как в symfony и silex устроект request объект
 

Vladex

Новичок
Я читал что компонент HttpFoundation можно отдельно использовать.
Тот способ, о чем спросил наверное использовался раньше, когда на каждую страницу был свой файл
index.php
contact.php
mail.php
Там надо запрос перебрасывать.
А сейчас все через один файл делается.
Правильно понимаю?:)
 

hell0w0rd

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

Там надо запрос перебрасывать.
А сейчас все через один файл делается.
Правильно понимаю?:)
Да, там много у симфони компонентов которые можно использовать отдельно от фреймворка.
Почитай http://symfony-gu.ru/documentation/ru/html/book/from_flat_php_to_symfony2.html, или первоисточник. Возможно ответит на твои вопросы)
 

Vladex

Новичок
Все же хотел бы понять до конца роутинг на примере https://github.com/dannyvankooten/PHP-Router/blob/master/example.php
Имеем код
PHP:
<?php
//output all errors
error_reporting(E_ALL);
require 'Router.php';
require 'Route.php';
$router = new Router();
$router->setBasePath('/tests/Develop/PHP-Router');
$router->map('/users/:id/edit/', 'users#edit', array('methods' => 'GET', 'name' => 'users_edit', 'filters' => array('id' => '(\d+)')));
$route = $router->matchCurrentRequest();
?><h3>Current URL & HTTP method would route to: </h3>
<?php if($route) { ?>
	<strong>Target:</strong>
	<pre><?php var_dump($route->getTarget()); ?></pre>
	<strong>Name:</strong>
	<pre><?php var_dump($route->getName()); ?></pre>
	<strong>Regex:</strong>
	<pre><?php var_dump($route->getRegex()); ?></pre>
	<strong>Metod:</strong>
	<pre><?php var_dump($route->getMethods()); ?></pre>
	<strong>Url:</strong>
	<pre><?php var_dump($route->getUrl()); ?></pre>
	<strong>Parameters:</strong>
	<pre><?php var_dump($route->getParameters()); ?></pre>
<?php } else { ?>
	<pre>No route matched.</pre>
<?php } ?>
<h3>Try out these URL's.</h3>
<p><a href="<?php echo $router->generate('users_edit', array('id' => 5)); ?>"><?php echo $router->generate('users_edit', array('id' => 5)); ?></a></p>
Где мне ловить параметры для их использования?
PHP:
В этом месте?
<?php if($route) { 
 } else {
    <pre>No route matched.</pre>
 } ?>
Если тут, то как и что писать в строке $route
 

hell0w0rd

Продвинутый новичок
Какие параметры? В смысле вот это все не работает? или что?
 

fawkes

Новичок
Не совсем понятно, как работают роутеры с регулярками.
Например, если указан роут /news/:id,
PHP:
$router->set('/news/:id/', 'controller#action', array('id' => '[0-9]+'));
надо в строке найти с помощью регулярки :id, потом заменить его на выражение [0-9]+, которое указано в 3ем аргументе и получить такой роут /news/[0-9]+ (он находится в переменной $uri).
Далее подставить его в
PHP:
if(preg_match('/'.$uri.'/', $_SERVER['REQUEST_URI'])) { //@todo
}
и если совпало, тогда вызывать контроллер и действие из второго аргумента.

Я правильно понял?
 

fixxxer

К.О.
Партнер клуба
Ну по всякому делают. :) Если очень в первом приближении, то примерно как ты сказал (только сначала preg_quote, потом подстановка регулярок в плейсхолдер, потом ^ в начале регулярки).

Я делаю еще оптимизацию - извлекаю все префиксы (до первого ":"), ищу сначала совпадение префикса, а потом уже проверяю регулярки. Ну и кэширование, чтобы каждый раз карты префиксов и регулярки не генерировать.

Совсем правильно было бы строить префиксное дерево, как в nginx: http://nginx.org/ru/docs/http/ngx_http_core_module.html#location
Кстати, на highload проектах я вообще не использовал php-роутинг, а использовал nginx-конфигурацию: в location определялись nginx-переменные $controller_name и $action_name, которые через fastcgi_param передаются в php-fpm, а все, что делает роутер - это смотрит эти переменные в $_SERVER.
 

fawkes

Новичок
Ну по всякому делают
А как еще?

fixxxer написал(а):
только сначала preg_quote
PHP:
 $keywords = '/news/:id/';
        var_dump(preg_quote($keywords, '/'));
//  "\/news\/\:id\/"
а для чего это?
потом подстановка регулярок в плейсхолдер
эмм, не понял (аргумент?)
потом ^ в начале регулярки
ага, птичку забыл
Я делаю еще оптимизацию - извлекаю все префиксы (до первого ":"), ищу сначала совпадение префикса, а потом уже проверяю регулярки. Ну и кэширование, чтобы каждый раз карты префиксов и регулярки не генерировать.
обычно сформированный массив записать в json файл (сериализация, не суть)?
Совсем правильно было бы строить префиксное дерево, как в nginx: http://nginx.org/ru/docs/http/ngx_http_core_module.html#location
А примеры такого роутера есть?
 

hell0w0rd

Продвинутый новичок
Совсем правильно было бы строить префиксное дерево, как в nginx: http://nginx.org/ru/docs/http/ngx_http_core_module.html#location
Кстати, на highload проектах я вообще не использовал php-роутинг, а использовал nginx-конфигурацию: в location определялись nginx-переменные $controller_name и $action_name, которые через fastcgi_param передаются в php-fpm, а все, что делает роутер - это смотрит эти переменные в $_SERVER.
У симфони есть целый дампер, правда для апача) https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Command/RouterApacheDumperCommand.php
 

fixxxer

К.О.
Партнер клуба
Dumps all routes as Apache rewrite rules
Это не дампер, а ерунда. Правильный дампер сделает <Location> и <LocationMatch>.

Если же ты не можешь писать в httpd.conf, то у тебя shared hosting и вообще нечего с этим заморачиваться.
 
  • Like
Реакции: AmdY
Сверху