有嘗試過各種解決方案之後,我發現,最簡單,最可靠的方法是重寫Kohana_Request_Client_Internal::execute_request
。要做到這一點,在「應用程序\類\ Kohana的\請求\客戶端\ internal.php」添加文件在您application
文件夾,然後設置其內容:
<?php defined('SYSPATH') or die('No direct script access.');
class Kohana_Request_Client_Internal extends Request_Client {
/**
* @var array
*/
protected $_previous_environment;
/**
* Processes the request, executing the controller action that handles this
* request, determined by the [Route].
*
* 1. Before the controller action is called, the [Controller::before] method
* will be called.
* 2. Next the controller action will be called.
* 3. After the controller action is called, the [Controller::after] method
* will be called.
*
* By default, the output from the controller is captured and returned, and
* no headers are sent.
*
* $request->execute();
*
* @param Request $request
* @return Response
* @throws Kohana_Exception
* @uses [Kohana::$profiling]
* @uses [Profiler]
* @deprecated passing $params to controller methods deprecated since version 3.1
* will be removed in 3.2
*/
public function execute_request(Request $request)
{
// Create the class prefix
$prefix = 'controller_';
// Directory
$directory = $request->directory();
// Controller
$controller = $request->controller();
if ($directory)
{
// Add the directory name to the class prefix
$prefix .= str_replace(array('\\', '/'), '_', trim($directory, '/')).'_';
}
if (Kohana::$profiling)
{
// Set the benchmark name
$benchmark = '"'.$request->uri().'"';
if ($request !== Request::$initial AND Request::$current)
{
// Add the parent request uri
$benchmark .= ' « "'.Request::$current->uri().'"';
}
// Start benchmarking
$benchmark = Profiler::start('Requests', $benchmark);
}
// Store the currently active request
$previous = Request::$current;
// Change the current request to this request
Request::$current = $request;
// Is this the initial request
$initial_request = ($request === Request::$initial);
try
{
if (! class_exists($prefix.$controller))
{
throw new HTTP_Exception_404('The requested URL :uri was not found on this server.',
array(':uri' => $request->uri()));
}
// Load the controller using reflection
$class = new ReflectionClass($prefix.$controller);
if ($class->isAbstract())
{
throw new Kohana_Exception('Cannot create instances of abstract :controller',
array(':controller' => $prefix.$controller));
}
// Create a new instance of the controller
$controller = $class->newInstance($request, $request->response() ? $request->response() : $request->create_response());
$class->getMethod('before')->invoke($controller);
// Determine the action to use
/* ADDED */ if (strpos($request->action(), '_') !== false) throw new HTTP_Exception_404('The requested URL :uri was not found on this server.', array(':uri' => $request->uri()));
/* MODIFIED */ $action = str_replace('-', '_', $request->action()); /* ORIGINAL: $action = $request->action(); */
$params = $request->param();
// If the action doesn't exist, it's a 404
if (! $class->hasMethod('action_'.$action))
{
throw new HTTP_Exception_404('The requested URL :uri was not found on this server.',
array(':uri' => $request->uri()));
}
$method = $class->getMethod('action_'.$action);
$method->invoke($controller);
// Execute the "after action" method
$class->getMethod('after')->invoke($controller);
}
catch (Exception $e)
{
// Restore the previous request
if ($previous instanceof Request)
{
Request::$current = $previous;
}
if (isset($benchmark))
{
// Delete the benchmark, it is invalid
Profiler::delete($benchmark);
}
// Re-throw the exception
throw $e;
}
// Restore the previous request
Request::$current = $previous;
if (isset($benchmark))
{
// Stop the benchmark
Profiler::stop($benchmark);
}
// Return the response
return $request->response();
}
} // End Kohana_Request_Client_Internal
然後加連字符的動作,例如,「controller/my-action」,創建一個名爲「my_action()」的動作。
如果用戶嘗試訪問「controller/my_action」(以避免重複的內容),此方法也會引發錯誤。
我知道一些開發人員不喜歡這種方法,但其優點是它不會重命名操作,所以如果您檢查當前操作,它會在任何地方始終稱爲「我的操作」。使用Route或lambda函數方法,動作有時稱爲「my_action」,有時稱爲「my-action」(因爲兩種方法都重命名動作)。
請注意,這隻適用於行動,而不是控制器。 '非官方Kohana 3.0 Wiki'有一個類似的解決方案,簡單地擴展Konaha_Request(http://kerkness.ca/kowiki/doku.php?id=routing:using_hyphen_in_urls),它既適用於操作也適用於控制器,但不涉及重複的內容。 – ChrisV