问题
I'm working on an cake app which is inside a sub directory (because I need to run it along side another app on the same domain). I want the pages powered by cake to appear as if they'r e top level.
So instead of example.com/cake_dir/page...
I want example.com/page...
I think the best way to make this work is by adding a rewrite rule to an .htaccess file, so here's what I want to know:
- Is this the best way to do this? If so:
- What is the proper syntax for that kind of rule?
- Where should that file go? The domain root? In the cake_dir? Or in cake's webroot?
- If one of Cake's .htaccess files already exists in that location, should the new rule go before or after and should and of the
[L]
s be removed?
UPDATE: Clearer description of what I'm trying to do
example.com/ <--root
/_cake <--CakePHP installed here
/page3
/page4
Currently, visitors have to access page 3 by going to example.com/_cake/page3. This sucks. Instead I want this: example.com/page3 and if cake routes to example.com/_cake/page4 I want it to appear as example.com/page4 in the browser.
I've been cramming as much mod_rewrite knowledge as possible and I think the way to do this is to do an internal rewrote to show the correct content when the _cake is absent, and an external rewrite for when _cake IS present.
Update Here are the existing .htaccess files...
.htaccess in /_cake...
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^$ app/webroot/ [L]
RewriteRule (.*) app/webroot/$1 [L]
</IfModule>
.htaccess in /_cake/app...
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^$ webroot/ [L]
RewriteRule (.*) webroot/$1 [L]
</IfModule>
.htaccess in /_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>
Update 2 I added anubhava's code to the root .htaccess file, and then also updated the .htaccess file at /_cake/ to look like the following (notice that I had to remove the [L]s in order for CakePHP's normal rewrites to still work):
# 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>
回答1:
$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/app/.htaccess:
RewriteEngine on
RewriteBase /_cake/app/
RewriteRule (.*) webroot/$1 [L]
$DOCUMENT_ROOT/_cake/app/webroot/.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]
回答2:
If you want to make it so when someone requests http://example.com/page
they actually get served the content provided by /cake_dir/page
, then you should add these rules to the htaccess file in your document root (or "domain root"):
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/cake_dir%{REQUEST_URI} -f
RewriteRule ^(.*)$ /cake_dir/$1 [L]
The URL in the browser's address bar will remain unchanged because there is no external redirect. The condition here is that it checks if the %{DOCUMENT_ROOT}/cake_dir%{REQUEST_URI}
points to a file. That string essentially puts together the document root, then the string "cake_dir", then the actual requested file. In the case that none of these requests actually point to physical files in the "cake_dir", you can try:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /cake_dir/$1 [L]
Here, the conditions are that the requested URI (e.g. /page
) does not point to an existing file or directory. And it routes everything blindly into the /cake_dir
directory.
To redirect the browser in the event that someone clicks on a link with cake_dir in it, then you need these rules:
RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ /cake_dir/
RewriteRule ^cake_dir/(.*)$ /$1 [L,R=301]
来源:https://stackoverflow.com/questions/15869240/how-to-make-cakephp-2-x-in-sub-directory-appear-in-root-with-mod-rewrite-in-hta