如何使子目录中的cakePHP 2.x出现在root中(在htaccess中使用mod_rewrite)?

时间:2013-04-07 23:49:31

标签: apache .htaccess cakephp mod-rewrite cakephp-2.0

我正在开发一个位于子目录内的蛋糕应用程序(因为我需要在同一个域上的另一个应用程序旁边运行它)。我希望由蛋糕驱动的页面看起来好像是顶级。

而不是example.com/cake_dir/page...我想要example.com/page...

我认为最好的方法是在.htaccess文件中添加重写规则,所以这就是我想知道的:

  1. 这是最好的方法吗? 如果是这样的话:
  2. 这种规则的正确语法是什么?
  3. 该文件应该在哪里?域根?在cake_dir?还是在蛋糕的webroot?
  4. 如果该位置中已存在Cake的.htaccess文件之一,那么新规则是应该在[L]之前还是之后移除?
  5. 更新:更清楚地描述我正在尝试做什么

    example.com/ <--root
        /_cake   <--CakePHP installed here
            /page3
            /page4
    

    目前,访问者必须访问example.com/_cake/page3访问第3页。这很糟糕。相反,我想要这个:example.com/page3,如果蛋糕路线到example.com/_cake/page4,我希望它在浏览器中显示为example.com/page4。

    我一直在尽可能多地填写mod_rewrite知识,我认为这样做的方法是在_cake不存在时进行内部重写以显示正确的内容,并在_cake存在时进行外部重写。 / p>

    更新 以下是现有的.htaccess文件...

    .htaccess in / _cake ...

    <IfModule mod_rewrite.c>
       RewriteEngine on
       RewriteRule    ^$ app/webroot/    [L]
       RewriteRule    (.*) app/webroot/$1 [L]
    </IfModule>
    

    .htaccess / _cake / app ...

    <IfModule mod_rewrite.c>
        RewriteEngine on
        RewriteRule    ^$    webroot/    [L]
        RewriteRule    (.*) webroot/$1    [L]
    </IfModule>
    

    .htaccess / _cake / app / webroot ...

    <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{REQUEST_FILENAME} !-f
        #RewriteRule ^(.*)$ index.php #[QSA,L]
        RewriteRule ^(.*)$ index.php [QSA]
    </IfModule>
    

    更新2 我将anubhava的代码添加到根.htaccess文件中,然后还更新了/ _cake /中的.htaccess文件,如下所示(注意我必须删除[L]以便CakePHP的正常重写仍然有效) :

    # Turn mod_rewrite on
    RewriteEngine On
    RewriteBase /
    
    # external redirect from /_cake/page to /page
    RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+_cake/([^\s]+) [NC]
    RewriteRule ^ /%1 [R=302]
    
    # internal forward from /page to /_cake/page
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule (?!^_cake/)^(.*)$ /_cake/$1 [NC]
    
    
    <IfModule mod_rewrite.c>
       RewriteEngine on
       RewriteRule    ^$ app/webroot/    [L]
       RewriteRule    (.*) app/webroot/$1 [L]
    </IfModule>
    

2 个答案:

答案 0 :(得分:2)

$ DOCUMENT_ROOT / htaccess的:

Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /

# internal forward from /page to /_cake/page
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (?!^_cake/)^(.*)$ /_cake/$1 [L,NC]

$ DOCUMENT_ROOT / _cake / htaccess的:

RewriteEngine on
RewriteBase /_cake/
RewriteRule (.*) app/webroot/$1 [L]

$ DOCUMENT_ROOT / _cake /应用/ htaccess的:

RewriteEngine on
RewriteBase /_cake/app/
RewriteRule (.*) webroot/$1 [L]

$ DOCUMENT_ROOT / _cake /应用程序/根目录/ htaccess的:

RewriteEngine On
RewriteBase /_cake/app/webroot/

RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+_cake/([^\s&]*) [NC]
RewriteRule ^ /%1 [R=302,L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]

答案 1 :(得分:1)

如果您希望在有人请求http://example.com/page时实际提供/cake_dir/page提供的内容,那么您应该将这些规则添加到文档根目录(或“域”中的htaccess文件中根“):

RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/cake_dir%{REQUEST_URI} -f
RewriteRule ^(.*)$ /cake_dir/$1 [L]

浏览器地址栏中的URL将保持不变,因为没有外部重定向。这里的条件是它检查%{DOCUMENT_ROOT}/cake_dir%{REQUEST_URI}是否指向文件。该字符串基本上将文档根目录,然后是字符串“cake_dir”,然后是实际请求的文件。如果这些请求中没有一个实际指向“cake_dir”中的物理文件,您可以尝试:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /cake_dir/$1 [L]

此处,条件是请求的URI(例如/page指向现有文件或目录。它会盲目地将所有内容路由到/cake_dir目录。


若有人点击其中包含 cake_dir 的链接,重定向浏览器,那么您需要以下规则:

RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ /cake_dir/
RewriteRule ^cake_dir/(.*)$ /$1 [L,R=301]