I'm trying to get the following functionality to work in PHP without a framework. I don't want to have to worry about setting up a super complicated framework for every PHP application I do.
http://domain.com/sign_up.php
becomes
http://domain.com/sign_up/
http://domain.com/user.php?id=432
becomes
http://domain.com/user/?id=432
Or if there is a way to get that to become http://domain.com/user/432 but i'm not sure how to handle multiple $_GET variables in that scenario so that's optional.
This works pretty well so far:
RewriteRule ^sign_up/([^/]*)$ /sign_up.php?p=$1 [L]
The only problem is I have to do that for every single php file i'm using which can become a lot.
What is a universal way to do it for all php files?
UPDATES:
This one line is working perfectly:
RewriteRule ^(.*)\/$ $1.php [NC]
Only issue is it doesn't auto redirect PHP
For example, I want to 301 auto redirect:
http://domain.com/file.php
to
http://domain.com/file/
And
http://domain.com/file.php?var1=value&var2=value
to
http://domain.com/file/?var1=value&var2=value
If anyone can think of a better way to handle query string values in a more SEO friendly way that would be awesome! But otherwise this is working pretty great so far.
MORE UPDATES:
Now this is working:
http://domain.com/file/ - to -
http://domain.com/file.php
Both of those point to the same page with this htaccess code:
RewriteRule ^(.*)\/$ $1.php [NC]
However http://domain.com/file without the trailing / returns a page not found error.
Also I need to know how to auto redirect http://domain.com/file.php to http://domain.com/file/
MOSTLY WORKING HTACCESS
This .htaccess works beautifully:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !\.(php|html?|jpg|gif)$
RewriteRule ^(.*)([^/])$ http://%{HTTP_HOST}/$1$2/ [L,R=301]
RewriteRule ^(.*)\/$ $1.php [NC]
The only thing it doesn't do is auto redirect if they go directly to http://domain.com/file.php it does not redirect to http://domain.com/file/ but everything else about it is working.
Try this:
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d # not a dir
RewriteCond %{REQUEST_FILENAME} !-f # not a file
RewriteCond %{DOCUMENT_ROOT}/$1.php -f # but php exists
RewriteRule ^([^/]+)/([^/]+)?$ $1.php?p=$2 [L]
However http://domain.com/file without the trailing / returns a page not found error.
That's because your rule does not match unless there's a / at the end.
RewriteRule ^(.*)\/$ $1.php [NC]
^
You can make it optional with ? as
RewriteRule ^(.*?)/?$ $1.php [L]
Note, that / does not need a \ before it. It works with or without it.
Also I need to know how to auto redirect http://domain.com/file.php to http://domain.com/file/
# Rewrite original .php request to new URLs
RewriteCond %{THE_REQUEST} \ /([^.]+)\.php [NC]
RewriteRule ^ /%1/ [R,L]
# Resolve the new URLs to .php files
RewriteRule ^(.*?)/?$ $1.php [L]
If you get this working first, we can see what we can do about the query parameters later.
Your final htaccess could look like
# Rewrite original .php request to new URLs
RewriteCond %{THE_REQUEST} \ /([^.]+)\.php [NC]
RewriteRule ^ /%1/ [R,L]
# Force a trailing / if not a file
RewriteCond %{REQUEST_URI} !\..{3,4}$
RewriteRule ^(.*)([^/])$ http://%{HTTP_HOST}/$1$2/ [L,R=301]
# Redirect to php if not an existing dir
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ $1.php [L]
You'll probably want something like this:
RewriteEngine on
RewriteBase /
# redirect with trailing parameter
RewriteRule ^([\w]+).php?p=([\w]+)$ $1/$2/ [QSA,R=301]
# redirect bare php files
RewriteRule ^([\w]+).php$ $1/ [QSA,R=301]
# make sure it's not a request to an existing file
RewriteCond %{REQUEST_FILENAME} !-f
# make sure we have a trailing slash
RewriteRule ^(.+[^/])$ $1/ [QSA,R=301]
# internally point to the right file
RewriteRule ^([^/]+)/([^/]*)/?$ $1.php?p=$2 [QSA,L]
The [R=301] appendixes redirect the browser to the new URL with a 301, moved permanently status header. That way the browser will know where to find the right url in the future, without asking the server.
Also, sometimes an .htaccess checker is useful: http://htaccess.madewithlove.be/ Do note, the tool doesn't work with %{REQUEST_FILENAME}.
Related
I had a static HTML website. I am now using some PHP and so my pages have the .php ending. For example www.example.com/about.php
How can I redirect or 'hide' the .php ending so that the above example becomes www.example.com/about ?
I have a .htaccess file for my old website. Code below. But I don't know how to edit it so that it applies to my new .php pages.
RewriteEngine On
# add www and turn on https in same rule
RewriteCond %{HTTP_HOST} !^www\. [NC,OR]
RewriteCond %{HTTPS} !on
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://www.%1%{REQUEST_URI} [R=301,L,NE]
## hide .html extension
# To externally redirect /file.html to /file
RewriteCond %{THE_REQUEST} \s/+(.+?)\.html[\s?] [NC]
RewriteRule ^ /%1 [R=301,NE,L]
# To internally rewrite /file to /file.html
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.+?)/?$ $1.html [L]
The first bit about adding www and turn on https I'd like to keep.
The second bit about hiding .html extension needs to be changed.
The last bit I don't think I ever needed and can be deleted. I don't think I need to rewrite any internal links from /file to /file.php
Many thanks
You can use the same commands that are used for html in your present .htaccess. Simply replace html by php.
Hence,
...
## hide .html extension
# To externally redirect /file.html to /file
RewriteCond %{THE_REQUEST} \s/+(.+?)\.html[\s?] [NC]
RewriteRule ^ /%1 [R=301,NE,L]
# To internally rewrite /file to /file.html
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.+?)/?$ $1.html [L]
would become
...
## hide .php extension
# To externally redirect /file.php to /file
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC] # html --> php
RewriteRule ^ /%1 [R=301,NE,L]
# To internally rewrite /file to /file.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f # html --> php
RewriteRule ^(.+?)/?$ $1.php [L] # html --> php
in your .htaccess.
Obviously, this will disable the 'functionnality' for .html files.
It sounds like when someone visits www.example.com/about.php you have a file on your server at the root level to handle it called about.php. And if someone visits another page like www.example.com/another-page.php you would have a separate php file saved at the root level called another-page.php to handle that request.
If that's what you're trying to do, then I think you can just add one conditional statement to the htaccess file that rewrites not only .html but also .php to remove the endings, like this:
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php [NC]
But if you are doing what I think you're doing on the backend, you will still need the last part for internal file mapping. The middle part basically says, if someone externally requests www.example.com/about.php send them away with an 301 code telling them to try again at www.example.com/about instead. So browsers will kindly abide by your direction and come back with a second request to www.example.com/about. However, on the back end, your server needs to know what to do with the request to /about. If you want the file called about.php to handle it, you need to tell the server that with the following lines:
# To internally rewrite /about to /about.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+?)/?$ $1.php[L]
Here is your edited .htaccess file for completenes:
RewriteEngine On
# add www and turn on https in same rule
RewriteCond %{HTTP_HOST} !^www\. [NC,OR]
RewriteCond %{HTTPS} !on
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://www.%1%{REQUEST_URI} [R=301,L,NE]
## hide .html and .php extension
# To externally redirect /file.html to /file
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php [NC]
RewriteCond %{THE_REQUEST} \s/+(.+?)\.html[\s?] [NC]
RewriteRule ^ /%1 [R=301,NE,L]
# To internally rewrite /file to /file.html
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+?)/?$ $1.html [L]
Most php frameworks send all their traffic to one entry point, for example /index.php and work out the routing based on the url. In other words, the frameworks tell the server, don't worry about trying to route requests to the right files, just give them all to me at index.php and I'll figure it out from there. Of course, you need to have logic that determines if the url is valid, and if so grabs the right file and echos it out once found. For example, in that situation, if someone came to your site with a request to something.php your back end framework would send a 301 code saying, "sorry, try again without the php next time".
I'm trying to accomplish 2 things in my .htaccess:
Redirect all requests for (in example) www.blanklabs.com/boarddrive/faq, www.blanklabs.com/boarddrive/faq.htm, www.blanklabs.com/boarddrive/faq.html, or www.blanklabs.com/boarddrive/faq.php to www.blanklabs.com/boarddrive/faq.php
The browser's address bar should show just www.blanklabs.com/boarddrive/faq, without the extension.
Here is my current .htaccess:
RewriteEngine On
# -- new
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\.html$ $1.php [L,QSA]
On the server I have faq.html (for now), but I also tried having both faq.html and faq.php. Eventually it'll just be faq.php.
The .htaccess is clearly incorrect, since if I go to www.blanklabs.com/boarddrive/faq.html I get the correct content (from faq.html), but if I go to www.blanklabs.com/boarddrive/faq.php I get a 500 error. This happens even if I have faq.php on the server.
Any ideas what I'm doing wrong? The no-extensions is secondary, the primary goal is to redirect all requests from html to php files.
Place this code in your DOCUMENT_ROOT/.htaccess file:
RewriteEngine On
# skip POST requests
RewriteCond %{REQUEST_METHOD} POST
RewriteRule ^ - [L]
RewriteCond %{THE_REQUEST} \s/+(.+?)\.(php|html?)[\s?] [NC]
RewriteRule ^ /%1 [R=301,L,NE]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^(.+?)(\.html?)?$ /$1.php [L,QSA]
You need to redirect
/faq.htm
/faq.php
[using redirect directive]
to /faq
now just applying rewrite rule to this later condition [/faq] to
/faq.php
It should work.
I have this in my htaccess file
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
Which will allow people to access server/login.php as just server/login but how can I make it so that if server/login.php is entered into the address bar it will redirect to server/login.
My site is getting different hits rather than just for one url because of this issue, thanks for your effort and time.
You can do this with an external redirect:
RewriteRule ^(.*)\.php$ $1 [R,L]
The R-flag is a temporary redirect. If things work as you expect them to work, you can use R=301 to make it a permanent redirect. See the documentation for more information.
Edit: With your current rule, this will create an infinite loop. If you are running Apache 2.3.9 or later, use the END-flag on your internal rewrite rule. If you are unwilling or unable to use such a version of Apache, you can use the "THE_REQUEST" trick to stop an infinite loop, as this will only match if the request comes from outside:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(.*)\.php[\s\?] [NC]
RewriteRule ^ %1 [R,QSA,L]
Change your base path RewriteBase /path/
RewriteEngine on
RewriteBase /path/
RewriteCond %{THE_REQUEST} \.php
RewriteRule ^(.*)\.php$ $1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
I'm trying to remove the .php extensions from a site, which I have gotten to work. example.com/parent/child.php correctly changes to example.com/parent/child/
However, when going to example.com/parent.php it still rewrites properly but shows an index page.
I'm fairly new to .htaccess and Apache, so any help would be greatly appreciated!
Update from the comments
"My apologies, Its not letting me write the code. I grabbed it from this post:
Remove .php extension (explicitly written) for friendly URL"
RewriteEngine On
RewriteBase /
# remove enter code here.php; use THE_REQUEST to prevent infinite loops
RewriteCond %{THE_REQUEST} ^GET\ (.*)\.php\ HTTP
RewriteRule (.*)\.php$ $1 [R=301]
# remove index
RewriteRule (.*)/index$ $1/ [R=301]
# remove slash if not directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /$
RewriteRule (.*)/ $1 [R=301]
# add .php to access file, but don't redirect
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI} !/$
RewriteRule (.*) $1\.php [L]
here is my case
im not in anyway good with regexp, i avoid it like its a disease
i have gone through every result on google, now im searching on gooding "how to commit suicide and die quickly" please i really need your help
i need a the extension removed and the query string rewritten
such that www.example.com/story.php?pcord=$1 ->will look like www.example.com/story/%1
please when i mean %1 i wouldn't like pcord to resurface on the url
for instance i wantwww.example.com/story.php?pcord=4849AAS84 should look something like
www.example.com/story/4849AAS84
here is the code i have tried using but doesnt work atall, only removes the extension
Options +FollowSymLinks -MultiViews
Turn mod_rewrite on
RewriteEngine On
RewriteBase /
## hide .php extension snippet
# To externally redirect /dir/foo.php to /dir/foo
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R,L]
# To internally forward /dir/foo to /dir/foo.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^(.*?)/?$ $1.php [L]
For .htaccess
Here we're capturing the value from the Query String as %1, then we're rewriting a relative url that starts with story.php to a folder called story followed by our captured string. Then we're adding the ? to the end of the new directive to stop the default nature of mod_rewrite to perform [QSA] (Query String Append) on a string where we're not creating a new query string. To make it a permanent rewrite add the [R] flag:
#External Redirect
RewriteCond %{QUERY_STRING} pcord=([A-Za-z0-9]+)
RewriteRule ^story.php story/%1? [R=301,L]
If you need to make it magically send the var back to the original string, then you need to capture it in the reverse way. Note: Here you would NOT use the [R] flag because that tells the browser to redirect.:
#Internal Forward
RewriteRule ^story/([A-Za-z0-9]+) story.php?pcord=$1 [L]
Remember if you've already tried using the [R=301] directive, it's likely cached in your browser.
Now, in PHP you should be able to access pcord with $_GET['pcord'].
The final code for .htaccess would be this:
RewriteEngine On
RewriteBase /
#External Redirect
RewriteCond %{QUERY_STRING} pcord=([A-Za-z0-9]+)
RewriteRule ^story.php story/%1? [R=301,L]
#Internal Forward
RewriteRule ^story/([A-Za-z0-9]+) story.php?pcord=$1 [L]
RewriteCond %{REQUEST_FILENAME} !^story
RewriteCond %{REQUEST_FILENAME} \.php$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
#Create the External Redirect for all existing .php files that are not story.php
RewriteRule ^([^/]+)\.php$ $1/ [R=301,L]
#Create the internal forward that maps them back in hiding
RewriteCond %{REQUEST_FILENAME} ^([A-Za-z0-9]+)/?$
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %1\.php -f
RewriteRule ^([^/]+)/?$ $1.php [L]