我已经用 CakePHP 2.2.1 成功地实现了这一点。这很丑,很长,违反规则,但它有效!:D
文件:/app/webroot/.htaccess
RewriteEngine On
RewriteRule ^dev/(.*)$ $1 //my hack
// /dev/orders/create => /orders/create
// /dev/css/main.css => /css/main.css
// This only changes the url for the next rule
// Cake would have still parsed /dev/orders/create
// but this is needed for the sake of static files in app/webroot
//cake native rewrite
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
文件:bootstrap.php
$url = (!empty($_SERVER['REQUEST_URI'])) ? $_SERVER['REQUEST_URI'] : '';
//$url is still /dev/orders/create, despite the rewrites
Configure::write('App.dev', false);
//we use this to check if we're in "dev" mode
//anywhere in the app, just call:
// if ( Configure::read('App.dev') ) ...
//check if URL starts with /dev
if (preg_match('|^/dev|', $url)){
/* the most important thing is to trick CakePHP
into thinking it's on a /dev/ subfolder on the server
this preserves all the routing as it
should be, not making it prefixed route */
Configure::write('App.base', '/dev');
Configure::write('App.dev', true);
//this changes /dev/orders/create to /orders/create
//for Cake's Route parser
$_SERVER['REQUEST_URI'] = preg_replace('|/dev|', '', $_SERVER['REQUEST_URI']);
}
?>
至此,我们已经拥有了让 CakePHP 在 /dev/ 下显示站点的完整副本所需的一切。Cake 执行所有默认操作+视图,所有链接都按预期工作(只要您对 URL 使用帮助程序),所有静态文件都得到服务。所有应用程序路径和常量保持不变。
现在来看看一些方法魔法:
<?php
//file: AppController.php
public function invokeAction(CakeRequest $request) {
if (Configure::read('App.dev')) {
$new_action = 'dev'.$request->params['action'];
if (method_exists($this, $new_action)){
$request->params['action'] = $new_action;
}
}
return parent::invokeAction($request);
}
?>
所有这些使我们能够:
- 在 /dev/ 上拥有站点的完整工作别名,其中包括路由、前缀、静态文件、数据库连接等。
- 使用名称前面的“dev”覆盖 ACTION。
- 有一个用于“dev”或“not dev”的开关(App.dev 配置)
例如:
<?php
//OrdersController.php
//gets called on /admin/orders/view
public function admin_view(){}
//gets called on /dev/admin/orders/view
public function devadmin_view(){
//views have to be defined manually for DEV actions
$this->render('devadmin_view');
}
//gets called on /admin/orders/add
// AND /dev/admin/orders/add
public function admin_add() {}
?>