在CakePHP中使用前缀而不是扩展名

时间:2012-07-10 18:17:41

标签: cakephp routing formats prefixes

我尝试在我的应用中实现REST和parseExtension类似功能,在CakePHP 2上运行。

我希望使用http://myapp.dev/controller/action.json

,而不是像http://myapp.dev/json/controller/action这样的网址

这样做的原因是,有时候扩展看起来有点愚蠢...... {/ 1}}。

虽然这可以在自定义路线中实现,但我已经有很多自定义路线,并且由于维护原因,不希望必须在其中创建每个http://myapp.dev/controller/index/show:10/page:2.json字段的副本。

什么是理想的设置,使得任何首先使用/ json / xml / html等的url都会被视为json,xml,html等是扩展名。

虽然前缀路由看起来很理想,但它需要新方法(例如json_index,html_index等,我必须将每种格式指定为单独的前缀)。

这样做有什么好办法吗?我只想让:type改为parseExtensions方法。

1 个答案:

答案 0 :(得分:1)

您应该尝试以下方法:

Router::connect('/:ext/', array(':ext'), array('pass' => 'ext'));
Router::connect('/:ext/:controller/*', array(':ext'), array('pass' => 'ext'));
Router::connect('/:ext/:controller/:action/*', array(':ext'), array('pass' => 'ext'));

然后,路由器将在路由参数的“ext”值中传递:ext参数。添加它适用于您的所有规则!

如果您想使用传统路径工作,您需要使用自定义CakeRoute。在app文件夹中创建一个文件“/libs/routes/RestRoute.php”,将以下内容添加到其中:

class RestRoutes extends CakeRoute {
    function parse($url) {
        $params = parent::parse($url);

        if (empty($params)) {
            return false;
        }

        if(!in_array($params['ext'], Router::extensions())) {
            return false;
        }

        return $params;
    }
}

在/core/routes.php中:

App::import('Lib', 'routes/RestRoute');
Router::connect('/:ext/', array(':ext'), array('pass' => 'ext', 'routeClass' => 'RestRoute'));
Router::connect('/:ext/:controller/*', array(':ext'), array('pass' => 'ext', 'routeClass' => 'RestRoute'));
Router::connect('/:ext/:controller/:action/*', array(':ext'), array('pass' => 'ext', 'routeClass' => 'RestRoute'));

因此,当您的自定义路由无法传递网址时,它会尝试默认网址,而不使用ext参数。否则,参数的顺序不安静。

也许不是最好或更清洁的解决方案,但这是一个良好的开端。