开发者

.htaccess rewrite file uri to either file-name.html or file-name.php - whichever exists

OBJECTIVE: To cause the browser to rewrite to file-name.php, if it exists; else return file-name.html - whether the visitor has typed the url as any one of the following:

  1. http://mydomain.com/file-name
  2. http://mydomain.com/file-name.html
  3. http://mydomain.com/file-name.php

Had good success with the following rules in my .htaccess file at root:

# REWRITE FILE URI TO file.php IF EXISTS
Options Indexes +FollowSymLinks +MultiViews
Options +ExecCGI
RewriteEngine on
RewriteBase /
# parse out basename, but remember the fact
RewriteRule ^(.*).html$ $1 [C,E=WasHTML:yes]
# rewrite to document.php if exists
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [S=1]
# else reverse the previous basename cutout
RewriteCond %{ENV:WasHTML} ^yes$
RewriteRule ^(.*)$ $1.html

However, I have since installed WP at root, alongside pre-existing website, and these rules are no longer working.

WHAT DOES WORK: file-name is rewritten to either file-name.html or file-name.php - whichever file exists.

WHAT DOES NOT WORK: file-name.html is not rewritten to file-name.php even when there is no file-name.html and file-name.php is there. Also, file-name.php is not rewritten to file-name.html when there is no file-name.php but there is file-name.html.

The entire .htaccess as it is now:

# BEGIN WP MULTISITE RULES
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]

# uploaded files
RewriteRule ^([_0-9a-zA-Z-]+/)?files/(.+) wp-includes/ms-files.php?file=$2 [L]

# add a trailing slash to /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule  ^[_0-9a-zA-Z-]+/(wp-(content|admin|includes).*) $1 [L]
RewriteRule  ^[_0-9a-zA-Z-]+/(.*\.php)$ $1 [L]
Rew开发者_开发知识库riteRule . index.php [L]
# END WP MULTISITE RULES

# REWRITE FILE URI TO file.php IF EXISTS
Options Indexes +FollowSymLinks +MultiViews
Options +ExecCGI
RewriteEngine on
RewriteBase /
# parse out basename, but remember the fact
RewriteRule ^(.*).html$ $1 [C,E=WasHTML:yes]
# rewrite to document.phtml if exists
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [S=1]
# else reverse the previous basename cutout
RewriteCond %{ENV:WasHTML} ^yes$
RewriteRule ^(.*)$ $1.html

Any advices?


Quick overview tells that your original rules most likely will never get reached as WP rules should intercept all requests.

This line RewriteRule ^ - [L] with those conditions will abort rewriting for any already existing files or folders, while this line RewriteRule . index.php [L] will intercept/redirect all requests to index.php.

If you move your rules above WordPress one, then it will work again.


To rewrite request for non-existing .php file to .html file use this rule:

# rewrite non-existing .php file to existing .html
RewriteCond %{DOCUMENT_ROOT}/$1.php !-f
RewriteCond %{DOCUMENT_ROOT}/$1.html -f
RewriteRule ^(.+)\.php$ $1.html [L,PT]

Place it below your rules (but above WP). The rule will check if .php files does not exist and rewrite will only occurs if .html file is present. If both files are unavailable then nothing will happen.

Keep in mind that because of these checks and the fact that rule is on the top of rewrite chain, this rule will be evaluated for every request to .php file (even WP pages) which may put extra pressure on very busy server. Ideally you would like to have proper URLs in first place so there will be no need for such manipulations.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜