Рассмотрим этот маршрут в bootstrap.php
…
Route::set('crud', 'staff/<controller>(/<action>(/<id>))', array( 'controller' => '(activities|users|default-emails)', 'action' => '(new|view|modify|delete)', 'id' => '\d+' ))->defaults(array( 'directory' => 'staff', 'action' => 'view' ));
поRoute::set('crud', 'staff/<controller>(/<action>(/<id>))', array( 'controller' => '(activities|users|default-emails)', 'action' => '(new|view|modify|delete)', 'id' => '\d+' ))->defaults(array( 'directory' => 'staff', 'action' => 'view' ));
action_default-emails()
default-emails
пытается запустить метод action_default-emails()
который, очевидно, не существует и не может существовать.
Какую часть Коханы я должен распространять, чтобы отобразить этот дефис внутри подчеркивания внутри?
Должен ли я быть обеспокоен тем, что если я это сделаю, тогда он будет доступен через оба маршрута с разделителями и разделителями?
Благодарю.
Самый простой Kohana_Request::execute()@1112
взломать Kohana_Request::execute()@1112
$class->getMethod('action_'.$action)->invokeArgs($controller, $this->_params);
изменить на
$class->getMethod('action_'.str_replace('-', '_', $action))->invokeArgs($controller, $this->_params);
Но вы понимаете, что вам нужно сделать этот патч в каждой следующей версии kohana.
Более безопасным может быть расширение Kohana_Route::matches()
class Route extends Kohana_Route { public function matches($uri) { $matches = parent::matches($uri); if (isset($matches['action'])) { $matches['action'] = str_replace('-', '_', $matches['action']; } return $matches; } }
Не проверял, но держу пари, что он должен работать.
Мое решение для Kohana 3.2 для маршрутизации переносимых действий на соответствующий подчеркнутый метод:
Расширьте Kohana_Route и вставьте этот код
if($key == 'action') { $params[$key] = str_replace('-','_',$value); } else { $params[$key] = $value; }
Полное: Создайте файл route.php в приложении / классах /
<?php defined('SYSPATH') or die('No direct script access.'); class Route extends Kohana_Route { public function matches($uri) { if ($this->_callback) { $closure = $this->_callback; $params = call_user_func($closure, $uri); if ( ! is_array($params)) return FALSE; } else { if ( ! preg_match($this->_route_regex, $uri, $matches)) return FALSE; $params = array(); foreach ($matches as $key => $value) { if (is_int($key)) { // Skip all unnamed keys continue; } // Set the value for all matched keys if($key == 'action') { $params[$key] = str_replace('-','_',$value); } else { $params[$key] = $value; } } } foreach ($this->_defaults as $key => $value) { if ( ! isset($params[$key]) OR $params[$key] === '') { // Set default values for any key that was not matched $params[$key] = $value; } } return $params; } }
Поскольку Kohana 3.3 вышел, этот метод больше не работает. Я нашел решение, которое до сих пор работает для меня.
При обновлении до 3.3 вам не нужно редактировать файл запроса Internal.php. Вместо этого вы можете создать фильтр маршрутов. Все, что вам нужно сделать, это заменить дефис в действии на подчеркивание.
Route::set('default', '(<controller>(/<action>(/<id>)))') ->filter(function($route, $params, $request) { // Replacing the hyphens for underscores. $params['action'] = str_replace('-', '_', $params['action']); return $params; // Returning an array will replace the parameters. }) ->defaults(array( 'controller' => 'welcome', 'action' => 'index', ));
поRoute::set('default', '(<controller>(/<action>(/<id>)))') ->filter(function($route, $params, $request) { // Replacing the hyphens for underscores. $params['action'] = str_replace('-', '_', $params['action']); return $params; // Returning an array will replace the parameters. }) ->defaults(array( 'controller' => 'welcome', 'action' => 'index', ));
Это, очевидно, работает только для методов. Однако, если вы изучите немного дальше, вы можете создать лучшую функцию для каталога, контроллера и т. Д.
Обновление метода zerkms. В Kohana 3.2 вам необходимо отредактировать строку файловой system/classes/kohana/request/client/internal.php
106 .
Заменить:
$action = $request->action();
От:
$action = str_replace('-', '_', $request->action());
Мне не нравятся хакерские рамки, но это, безусловно, самое простое и надежное решение. Переименование действия в классе Route может привести к разным проблемам, потому что действие затем будет называться my_action (внутренне) и иногда my-action (в ссылках).