htaccess redirect fails with multiple URL parameters - php

I've got the following htaccess file:
RewriteEngine On
RewriteBase /
# Redirect to remove .php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
# Redirect to "page" for dynamic pages
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ page?url=/$1 [L]
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1%{REQUEST_URI} [R=301,QSA,NC,L]
This allows my custom CMS to use dynamic URLs (http://example.com/some-page, for example) and redirect it to http://example.com/page?url=some-page so that the CMS can render the content. It all works great - until someone adds a URL like http://example.com/something/else. When I spit out the url parameter with: print $_GET['url']; I get /something/else.php/else.
So it seems like the remove .php directive is getting lost and the second parameter is getting duplicated? Thanks for any help.

Have it this way:
Options -MultiViews
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,NE,L]
RewriteCond %{ENV:REDIRECT_STATUS} =200
RewriteRule ^ - [L]
# Redirect to remove .php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([^/]+)/?$ $1.php [L]
# Redirect to "page" for dynamic pages
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule !^page\.php$ page.php?url=%{REQUEST_URI} [L,NC,QSA]
Here are changes:
Keep redirect rule before rewrite rules otherwise when www is removed from a URL then your internal URL will be exposed.
Use page.php in target instead of page to avoid another rewrite rule execution.
Use [L] flag in .php adding rule.
Addition of Options -MultiViews

Related

Redirect users with friendly urls htaccess php

I need a hand to redirect and write nice urls for my product requests.
So for any request like
https://www.domain.com.au/pages/product.php?product=PRODUCTNAME
Redirect and rewrite to
https://www.domain.com.au/pages/product/PRODUCTNAME
I actually have:
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
RewriteCond %{SERVER_PORT} 80
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
# Add trailing slash to url
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/|#(.*))$
RewriteRule ^(.*)$ $1/ [R=301,L]
# Remove .php-extension from url
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^([^\.]+)/$ $1.php
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC]
RewriteRule ^ /%1/ [R=301,NE,L]
# End of Apache Rewrite Rules
So it goes to:
https://www.domain.com.au/pages/product/?product=PRODUCTNAME
That, for pages like about.php etc it's fine as you may realize.
Thanks ahead!
You can use the following to shorten your Product URLs :
Put the following at top of your /root/. htaccess file.
RewriteEngine On
#redirect /pages/product.php?product=name to /pages/product/name
RewriteCond %{THE_REQUEST} /pages/product\.php\?product=([^\s]+) [NC]
RewriteRule ^ /pages/product/%1? [L,R=301]
#Rewrite the new URL to the old one
#load the contents from the OLD URL
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^pages/product/([^/]+)/?$ /pages/product.php?product=$1 [L]

Show correct URL without extension & redirect if URL is incorrect

I've added a bounty of 50 to this question. I'm trying to make it so that:
all website pages show www.example.com/page/ - instead of /page. My current code below is only successful for www.example.com/page
How can the .htaccess code be corrected to achieve this?
Also, changing the canonical URL meta tags from www.mysite.com/page to www.example.com/page/ - will www.example.com/page/ show up in search engines instead of /page ?
The current .htaccess code is:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTP_HOST} ^ example.com [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]
Note that the first rewriting conditions just forward to www. and https, so the only part that might need editing might just be:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]
So all I want to do it simply add a '/'. A wordpress blog (presumably PHP files rather than HTML) that achieves my wants on the same website (it's at www.example.com/blog/) has htaccess code being:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
</IfModule>
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
</IfModule>
# END WordPress
I'm not sure how this works but I'd love to learn more about .htaccess and redirects, but nothing much seems to be on the web for beginners. I've also read this post. It also must be https (not sure why but blog posts also can have a http link, whereas other pages redirect to https).
The website also has a blog (php files) on it with its own htaccess file, installed under example.com/blog/ - the htaccess code is the default wordpress one:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
</IfModule>
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
</IfModule>
# END WordPress
Have your .htaccess as this in site root:
RewriteEngine On
# force www
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
# force https
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
# remove .php or .html extensions
RewriteCond %{THE_REQUEST} \s/+(.+?)\.(?:html|php)[\s?] [NC]
RewriteRule ^ /%1 [R=301,NE,L]
# add trailing slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule [^/]$ %{REQUEST_URI}/ [L,R=301,NE]
# add .html extension
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.+?)/?$ $1.html [L]
# add .html extension
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ $1.php [L]
For issues with relative paths for css/js/images add this just below <head> section of your page's HTML:
<base href="/" />
This works for me, the top one is excluding .php from the URL and the bottom one excludes .html from the URL.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [NC,L]
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.*)$ $1.html [NC,L]

How to remove .php extension the pro way

I have created my first Php solution but have trouble removing the .php extension from the URL. It works in the root but not in sub-folders?
Eg www.domain.com/index.php reached from www.domain.com/index (or www.domain.com/)
Then it gets tricky.
For example. www.domain.com/en/europe/bikes/racer-bike.php will not differ from www.domain.com/en/bikes/racer-bike without ending up on www.domain.com/en/bikes/ and on index.php
My .htaccess file looks like this:
Options -MultiViews
RewriteEngine on
RewriteBase /
# Remove .php-extension from url
RewriteCond %{REQUEST_URI} ^/(.*).php$
RewriteRule ^(.*)$ %1 [L,QSA]
# Add trailing slash to url
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/|#(.*))$
RewriteRule ^(.*)$ $1/ [R=301,L]
# SSL
RewriteCond %{HTTP_HOST} ^domain.com$
RewriteRule ^(.*)$ http://www.domain.com$1 [R=301]
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^/?(.*)$ https://%{SERVER_NAME}/$1 [L,R=301,QSA]
I Try it and it works:
My dirs structure
/
index.php
/sub
file.php
And my htaccess like this:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^/([^\/]*)$
RewriteRule ^([^\/]*)$ $1.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ([A-Za-z]+)/(.*)$ [NC]
RewriteCond %{DOCUMENT_ROOT}/%1 -d
RewriteRule ^([A-Za-z]+)/(.*)$ $1/$2.php [NC,L,QSA]
Try it
You are doing it wrong ... Mostly you do not make php files for each uri (route). You should not remove php extension you should direct all uri's to index.php and use some router to define how to handle each request. or you can just use some framework to do that like laravel or symfony etc.

htaccess redirect domain with query string to subdomain with excludes

We have moved our site to a subdomain while on the main domain we have a new site with new url's. What we are trying to do is having the old url's redirect to the subdomain while the excluding the new url's.
here's examples of the old url's:
http://www.domain.co.il/index.php?dir=app_admin&page=ip_stat&op=list&pos=0
should be redirected to:
http://sub.domain.co.il/index.php?dir=app_admin&page=ip_stat&op=list&pos=0
While the new site url's (do not contain php) and the homepage should not be effected.
This is what our htaccess looks like:
It does redirect the url's to the sub, but does not exclude the new pages and redirect them to the subdomain home (sub.domain.com)
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{REQUEST_URI} !contact(|$)
RewriteCond %{REQUEST_URI} !about(|$)
RewriteCond %{REQUEST_URI} index\.php
RewriteRule ^(.*)$ http://sub.domain.com [R=301,L]
Hopefully someone can help us get this right, we get many 404 in our gwt now :/
Thanks for any help !
Fix some regex and reorder your rules:
RewriteEngine on
RewriteBase /
RewriteCond %{THE_REQUEST} !/(contact|about) [NC]
RewriteCond %{THE_REQUEST} !\.(jpe?g|gif|bmp|png|tiff|css|js) [NC]
RewriteRule ^(.+)$ http://sub.domain.com/$1 [R=301,L,NE]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
Also test this in a new browser to avoid old browser cache.
Here's the full code for the site.
The way things are set up is that the new site is being called from a folder named "main" while the old site is being called from the root directory.
So we actually have 2 htaccess.
Here's the root htaccess code:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^/([^.]+)\.php
RewriteRule ^(.*)$ http://sub.domain.com/$1 [L,R=301]
RewriteCond %{HTTP_HOST} www.domain.com$
RewriteCond %{REQUEST_URI} !^/main
RewriteRule ^(.*)$ /main/$1 [L]
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule .* - [L]
RewriteRule ^admin$ index.php?dir=app_misc&page=login [L]
RewriteRule ^admin/$ index.php?dir=app_misc&page=login [L]
RewriteRule ^sitemap.xml$ sitemap.php [L]
RewriteRule ^robots.txt$ robots.php [L]
RewriteRule ^adv$ adv/index.php [L]
RewriteRule ^adv/$ adv/index.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^/(([0-9]+)_([^/]+)|([0-9]+))$
RewriteRule (.*) /404.php?a=%{REQUEST_URI} [L]
and the htaccess in the "main" folder:
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_URI} !(contact|about) [NC]
RewriteRule ^(.*)$ http://sub.domain.com/$1 [R=301,L,NE]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L]
I've tested on few browsers and in incognito mode as well
Thanks
Instead of excluding urls which caused necessary css & js files to redirect as well, I solved it by creating a redirect that effect only url's with php.
RewriteCond %{THE_REQUEST} ([^.]+)\.php [NC]
RewriteRule ^(.*)$ http://sub.domain.com/$1 [R=301,L,NE]

rewriting www to non-www and index.php CI

I am using CodeIgnter, as for a result all my links are like base.com/index.php/home/index or www.base.com/index.php/home/index.
I would like to display them only as base.com/home/index if possible.I have tried looking over the internet,got the rewrite in htacces from both of them as:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$0 [PT,L]
RewriteCond %{HTTP_HOST} ^domain\.com\$ [OR]
RewriteCond %{HTTP_HOST} ^www\.domain\.com\$
RewriteRule ^/?$ "http\:\/\/domain\.com\/" [R=301,L]
and
RewriteEngine on
RewriteCond %{HTTP_HOST} !^domain\.com$ [NC]
RewriteRule ^(.*)$ http://domain.com/$1 [R=301,L]
put them separately,they work.But toghether they don't do what i need them to do.
Anyone knowing the solution?Thanks.
For CI, you want something like your first set of rules, but without the redirect. But the redirect needs to happen before the routing happes, so try:
RewriteEngine On
# redirect www to non-www
RewriteCond %{HTTP_HOST} ^www\.base\.com$ [NC]
RewriteRule ^(.*)$ http://base.com/$1 [L,R=301]
# redirect direct requests to /index.php to remove it
RewriteCond %{THE_REQUEST} \ /index\.php/?([^\?\ ]*)
RewriteRule ^ http://base.com/%1 [L,R=301]
# internally route to /index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [PT,L]

Categories