What should I do with Kohana 3 to make route actio

2019-05-31 10:04发布

问题:

Consider this route in 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'
    ));

The default-emails is trying to run the action_default-emails() method which obviously doesn't and can't exist.

What part of Kohana should I extend to map that hyphen into a underscore internally?

Should I be concerned that if I do do this, then it will be accessible via both _ and - delimited routes?

Thanks.

回答1:

The simplest is to hack Kohana_Request::execute()@1112

$class->getMethod('action_'.$action)->invokeArgs($controller, $this->_params);

change to

$class->getMethod('action_'.str_replace('-', '_', $action))->invokeArgs($controller, $this->_params);

But you understand, that you have to do this patch in each next kohana version.

More harmless could be to extend 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;
    }
}

Did not check, but I bet it should work.



回答2:

My solution for Kohana 3.2 for routing hyphenated actions to the appropriate underscored method:
Extend Kohana_Route and insert this code

if($key == 'action')
{
    $params[$key] = str_replace('-','_',$value);
}
else
{
    $params[$key] = $value;
}

Full Solution: Create a file route.php in application/classes/

<?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;
    }
}


回答3:

Since Kohana 3.3 came out this method no longer works. I have found a solution that, so far, works for me.

When upgrading to 3.3, you don't need to edit the Internal.php request file. Instead, you can create a Route Filter. All you need to do is replace hyphen in the action to an underscore.

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',
    ));

This obviously only works for the methods. However, if you explore a little further, you can create a better function for the directory, controller, etc.



回答4:

An update to zerkms's method. In Kohana 3.2, you need to edit the file system/classes/kohana/request/client/internal.php line 106.

Replace:

$action = $request->action();

By:

$action = str_replace('-', '_', $request->action());

I dislike hacking frameworks but this is by far the simplest and most reliable solution. Renaming the action in the Route class can lead to all sorts of troubles, because the action will then sometime be called my_action (internally) and sometime my-action (in links).