I'm having trouble writing a rule for .htaccess which will redirect HTML to PHP. I'm using 302 until I get it to work right - then I'll change to a 301. I found several postings that describe this, but I am having problems - possibly because I'm running a hosting package, and each client is in a virtual/subfolder (sorry for poor description of hosting environment).
The rule I am using is
...
RewriteEngine on
RewriteRule ^(.*).html$ $1.php [R=302]
...
When I try to go to https://dmcelebratealife.com/index.html I get a 404 message saying:
https://www.dmcelebratealife.com/var/www/vhosts/dmcelebratealife.com/public_html/index.php
I added the following and it seemed to work for me.
RewriteEngine on
RewriteRule ^(.*)\.html$ /$1.php [R=302]
This works for me and is domain-independent.
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^(?!.+\.\w{2,4})(.+)$ $1.php [L]
RewriteCond %{DOCUMENT_ROOT}/$1.html -f
RewriteRule ^(?!.+\.\w{2,4})(.+)$ $1.html [L]
The first two redirect to the php file if it exists. If it doesn't then the second two will try for an HTML file.
Note it doesn`t use a 302 as you don't want to tell the user what you are doing. This does an internal redirect.
This means that if the user types in
https://www.example.com/test
it will remain in the URL box, but the following file will be executed
https://www.example.com/test.php
Related
Since we migrated to a new server, some of our pages are broken (404). Reason is we have 2 broken rewrite rules.
What's really strange is that they work if I change folder's name.
For example this work:
RewriteRule ^anything/([a-zA-Z0-9-]+)/$ page.php?var=$1 [L]
This doesn't:
RewriteRule ^myfolder/([a-zA-Z0-9-]+)/$ page.php?var=$1 [L]
I can't even find a trick to make 301 redirects, because my original "myfolder/" virtual folder never matches.
Any ideas what's going on? I was thinking it could be a rule override or something like that (as it's hosted on a multidom solution), but i don't have such rules in my main site at the root. It drives me crazy.
Thx!
In practice you probably want to do 2 things. Disable multiviews and also bypass rules if the request is a real directory.
Options -MultiViews #turn off automatic URI matching, can cause weirdness
RewriteEngine on
#stop here if the request is a real file or directory
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^myfolder/([a-zA-Z0-9-]+)/?$ /page.php?var=$1 [L]
Alright, title is REALLY sloppy.
Here's my problem: I have a news site and when you go to the main page (domain.com) it redirects you to domain.com/news/top?geography=San_Francisco after it figures out your geography.
How do I use the .htaccess so that it goes from domain.com/news/top?geography=San_Francisco domain.com/San_Francisco/news/top ?
There are some similar questions, but I have not found one similar enough in that you're editing the URL as a furtherback subdirectory.
It should also be noted that I am using the Code Igniter framework for PHP and it normally has it as domain.com/index.php/news/top?geography=San_Francisco but I did a mod_rewrite already to get rid of the index.php. The code is as follows for that:
RewriteEngine on
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
Code I've tried:
RewriteRule ^([^/]+)/news/top$ /news/top?geography=$1 [L,QSA]
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
Before the index.php rule that you have, try adding this:
RewriteRule ^([^/]+)/news/top$ /news/top?geography=$1 [L,QSA]
You'll need to make sure the links you generate are in the form of domain.com/San_Francisco/news/top though.
But to take care of the links in the wild that still look like the old way, you have to match against the actual request:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /news/top\?geography=([^&]+)
RewriteRule ^news/top$ /%1/news/top? [L,R=301]
This will 301 redirect the browser if someone goes to the link domain.com/news/top?geography=San_Francisco and make it so the browser's address bar says this: domain.com/San_Francisco/news/top. At which point the browser will send another request for the second URL, and you use the rule above to change it back into the one with a query string.
I'm new to this modrewrite beast. I managed to get it working and I can normaly load index.php as index.html for example.
Problem is when I try to navigate to index2.html and I get error 404 error, The requested URL /index2.php was not found on this server.
I have this code in my .htaccess:
Options +FollowSymlinks
RewriteEngine on
RewriteRule ^(.*)\.html$ $1.php [nc]
I've tryed few things, but I just get caught in the loop.
Basicaly I want rewriting from PHP to HTML, but I want to see the files which are actually HTML work aswell.
My 2nd question, perhaps most important is, how good is that in SEO terms, is it just as normal or are there any downsides of using such rewrite rules?
Try adding a condition for -f
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/(.*)\.html$
RewriteCond %{DOCUMENT_ROOT}/%1.php -f
RewriteRule ^(.*)\.html$ $1.php [nc]
This checks to make sure the the file exists as a php before rewriting
As for your second question, it doesn't make a big difference either way, whether extensions are html or php. Its mainly so it appears you're serving static content.
I've tried every single example I could find, they all produce an internal server error. I have these rules set up (this works, no error):
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}/index.php !-f
RewriteRule ^((/?[^/]+)+)/?$ ?q=$1 [L]
So if it's not an existing file or an existing directory with an index.php we redirect. For instance, http://domain.com/foo/bar becomes http://domain.com/?q=foo/bar
Thing is, I want the trailing slash stripped. So take off the /? at the end of the rule. How do I make it so that http://domain.com/foo/bar/ becomes http://domain.com/foo/bar with a visible redirect first (fixing the client's URL), and only then the real, silent redirection to ?q=?
Everywhere I look I see this:
RewriteRule (.*)/$ $1 [R,L]
But it gives me a 500 error if I insert it before my rule.
If foo/bar exists as a real directory, then the server will be redirecting the client to foo/bar/ (with the trailing slash). It has to do that in order for relative URLs to work correctly on the client. If you put in a rule to rewrite that back to foo/bar with a redirect then there will be a loop. An easy way to test if that's happening is to specify a path that doesn't exist at all (I assume from your index.php detection that the directory tree actually exists). The nonexistent path won't trigger the built-in redirect.
If I setup a similar set of rules to yours (plus the suggested slash-removal rule) I can see the difference between a directory that exists and one that doesn't. The ones that don't work as expected, the ones that do cause Firefox to say This page isn't redirecting properly. IE8 says something similar. Perhaps the Apache setup you're using can detect it and turns it into the 500 error?
It looks like the simpler rewrite rule you mention at the end of your question should work. The problem is, the 500 error isn't really helpful in figuring out why it's not working. One way I've found useful in helping debug mod_rewrite errors is to enable it's logging. Add the following to your httpd.conf:
RewriteLog "/usr/local/var/apache/logs/rewrite.log"
RewriteLogLevel 3
Then try again, and look in the log to see what's going on. Once you're done, you can disable the log be setting the rewriteloglevel 0. See the mod_rewrite docs for details.
Try this rule in front of your current rule:
RewriteRule (.*)/$ /$1 [R,L]
Try these rules:
#prevent mod_dir from adding slash
DirectorySlash Off
#redirect /folder/ to /folder
RewriteCond %{THE_REQUEST} ^GET\s\S+/(\?\S+)?\s [NC]
RewriteRule ^(.*)/$ /$1 [R=301,L,QSA]
#internal redirect for directories
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^(.*)$ /$1/ [L]
I'm trying to get www.example.com and www.example.com/index.html to go to index.html, but I want all other urls e.g. www.example.com/this/is/another/link to still show www.example.com/this/is/another/link but be processed by a generic script. I've tried
RewriteEngine on
RewriteCond %{REQUEST_URI} !^index\.html$
RewriteCond %{REQUEST_URI} !^$
RewriteRule ^(.*)$ mygenericscript.php [L]
but it wont work, can someone please help?
Instead of testing what %{REQUEST_URI} is, you can instead just test if the resource exists:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* mygenericscript.php
This prevents your static resources (images, stylesheets, etc.) from being redirected if they're handled through the same directory your .htaccess is in as well.
What's probably happening now is that you're seeing an internal server error, caused by an infinite internal redirection loop when you try to access anything that isn't / or /index.html. This is because .* matches every request, and after you rewrite to mygenericscript.php the first time, the rule set is reprocessed (because of how mod_rewrite works in the context that you're using it in).
The easiest to do this is to install a 404-handler which gets executed when the server does not find a file to display.
ErrorDocument 404 /mygenericscript.php
or
ErrorDocument 404 /cgi-bin/handler.cgi
or similar should do the trick.
It is not that RewriteRule's can not be used for this, it is just that they are tricky to set up and requires in depth knowledge on how apache handles requests. It is a bit of a black art.
It appears as if you're using PHP, and you can use auto_x_file (x is either append or prepend:
http://php.net/manual/en/ini.core.php