Контент


[Ko3.2] Работа метода Request->uri()

В версии 3.2 разработчики поменяли поведение метода Request->uri() (#3690). В 3.0-3.1 этот метод позволял получить «соседний» URI с применением небольших изменений, например:

// пусть текущий адрес: /articles/page1/
// мы хотим получить ссылку /articles/page2/
$uri = $this->request->uri(array('page' => 2));

В 3.2+ этот номер уже не прокатит. Сейчас $this->request->uri() игнорирует переданные параметры, и возвращает текущий URI. Разработчики предлагают использовать $this->request->route(), что в принципе логично. Однако есть небольшое НО — этот метод не подставляет текущие параметры объекта Request, он просто о них не знает. Т.е. нам надо передавать туда все параметры явно, а это очень большая конструкция:

$uri = $this->request->uri(
    array('page' => 2) +
    $this->request->param() +
    array(
        'directory' => $this->request->directory(),
        'controller' => $this->request->controller(),
        'action' => $this->request->action(),
    )
);

Помните, что $this->request->param() вернет не все сегменты. Значения directory/controller/action хранятся в отдельных свойствах и имеют свои методы-геттеры.

Громоздко, ага. Давайте воспользуемся возможностями Каскадной Файловой Системы Kohana и сделаем мир удобнее:

1. Копируем файл SYSPATH/classes/request.php в APPPATH/classes/.
2. Добавляем туда новое содержимое метода uri():

public function uri(array $params = null) 
{
    if ($params === NULL)
    {
        return parent::uri();
    }
 
    $params += $this->_params + array(
        'directory'   => $this->_directory,
        'controller'  => $this->_controller,
        'action'      => $this->_action,
    );
 
     return $this->_route->uri($params);
}

Вуаля! Теперь можно использовать $this->request->uri() как для получения текущего URI, так и для быстрого reverse-routing на базе текущих параметров:

$uri = $this->request->uri(); // текущий адрес
$uri = $this->request->uri(array('action' => 'test')); // меняем в URI текущий экшен на action_test()

Обратите внимание, что новый метод uri() применяет ВСЕ текущие значения объекта Request. Таким образом, если мы меняем только экшен, то все остальные параметры останутся прежними, в том числе и те, которые в роуте шли после экшена. Например, при текущем адресе foo/bar/123, вызов $this->request->uri(array('action' => 'baz')) вернет строку ‘foo/baz/123‘, а не ‘foo/baz‘.

Содержимое файла request.php выложил на гитхаб: https://gist.github.com/2773591.

Google Bookmarks Digg Reddit del.icio.us Ma.gnolia Technorati Slashdot Yahoo My Web News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru Mister Wong

Опубликовано в знаете ли вы.

Теги: , , , , .


Комментарии (7)

Будьте в курсе обсуждения, подпишитесь на RSS ленту комментариев к этой записи.

  1. rex пишет:

    дада, помнится мне я нехило получил проблем, когда обновился до 3.2 — тогда то и родилась поделка, которая это реализовывала — правда в виде отдельного класса и ряда статических методов.

    Я думаю, следовало бы упомянуть еще тот факт, что именно uri лучше всего использовать с хелперами HTML, Form. А то народ путает (или не знает) и получает непонятные вещи при переносе приложения в подпапку DOCUMENT_ROOT-а.

  2. biakaveron пишет:

    Думаю, многим было бы интересно поглядеть эту «поделку». Есть возможность ее выложить?

  3. rex пишет:

    вот тут можно глянуть. Действовал по принципу дешево и сердито, теперь же хочу перенести данную логику в класс Request..

  4. Spider пишет:

    Да, супер, что тут сказать… Меня самого очень обломало это «усовершенствование». Т.е. разработчики убрали из ядра такую полезную возможность, а мы теперь должны в каждом своём проекте дописывать это обрано. Отлично!

  5. Spider пишет:

    И ещё мне очень не нравится, что они никак не хотят исправлять очевидные баги, сообщения о которых висят уже по году и более. Например, некорректное кодирование символов в функции URL::site() и Route::url()

  6. biakaveron пишет:

    @Spider
    Мы уже обсуждали исправления багов в комментах к одной из предыдущих статей. Мое мнение такое — если тикет переведен в unsheduled, то надо периодически этот тикет АПить. Ну или отправить Pull Request — это сильно ускоряет работу над тикетом. Есть ощущение, что в последнее время у разработчиков не слишком много свободного времени для разработки.

  7. Spider пишет:

    Согласен, пулл реквесты надо делать, Kohana всё-таки позиционируется как community-driven framework



Можно включить подсветку кода: <code><pre lang="">...</pre></code>
Разрешены некоторые HTML теги

или используйте trackback.