My project is beginning to get a bit messy and I'd like to clean it up with the .htaccess file.
Right now it's set up to redirect to 'page1.html' or 'page1.php' when I call 'page1'.
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*?)/?$ $1.php [NC,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html [NC,L]
But what I want is when I redirect to 'page1' it opens '/page1/page1.html' or '/page1/page1.php'.
I believe it should be achievable with htaccess but I don't have any experience in it so I'm not completely sure.
Thanks in advance :)
I think you can find your answer in this link (maybe the title doesn't seem to be relevant, but surely it is): https://www.digitalocean.com/community/tutorials/how-to-set-up-mod_rewrite-for-apache-on-centos-7
As the link above mentions, you can use the following to do this (this is used for aliasing a file):
RewriteEngine on
RewriteRule ^page1$ /page1/page1.html [NC]
Hope I've understood what you exactly mean.
Assuming you're trying to do this dynamically, you'd want something like this:
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^([^/]+)/?$ $1/$1.php [NC,L]
Problem is that the server has no way of knowing whether it should serve page1.php or page1.html. You'd be better of routing your traffic into a php bootstrapper that does something like check if a file exists and do one or the other if that's your end game.
If you want to maybe just condense your code but still have a bit of bloat to handle which pages go to html vs php, you could do something like this
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(page1|page2|page5)/?$ $1/$1.php [NC,L]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(page3|page4|page6)/?$ $1/$1.html [NC,L]
That would at least allow you to have just two blocks where you can put each page together.
Related
I want to add another language to my website (an app written in PHP 7).
I found out, good SEO practices say that every page on my site should be accessible from differend URLs, depending on the language.
Currently my .htaccess looks something like this:
RewriteEngine on
Options +FollowSymLinks
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([a-zA-z0-9-]+)$ $1.php [NC,L]
So when user types in (or clicks a link) http://example.com/contact they get page contact.php (if exists).
What I want to achieve is, to redirect http://example.com/en/contact to the very same file contact.php, but with $_GET argument and still redirecting /contact to contact.php (without this argument). I thought that would be:
... everything from above code sample and then:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^en/([a-zA-z0-9-]+)$ $1.php?lang=en [NC,L]
But it doesn't work. Any ideas why and how to make this work?
Last condition checks that en/file.php exists, which is never the case. That's why the rule is never met. Either you remove it (but it will be applied even on nonexistent files) or you use this workaround by rewriting the faulty condition
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f
RewriteRule ^en/([^/]+)$ /$1.php?lang=en [NC,L]
To be more complete, you can also redirect users that try to access /contact.php?lang=en directly (better for SEO). Here is how your final htaccess should look like
RewriteEngine On
# if url is /file.php?lang=en and file exists then redirect to /en/file
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{THE_REQUEST} \s/([^/\s\?&]+)\.php\?lang=en\s [NC]
RewriteRule ^ /en/%1? [R=301,L]
# if url is /en/file and /file.php exists then internally rewrite to /file.php?lang=en
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f
RewriteRule ^en/([^/]+)$ /$1.php?lang=en [NC,L]
Note: the above code is specific to en language, but you can easily adapt it to multiple languages
So, I have this code in .htaccess:
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
Every file loses its extension (/index.php -> /index etc) and that works perfectly fine. But later on, I started working with admin panel and I'm using some GET parameters there. For example, problematic URL look like:
example.com/admin?cat=1
As far as I know, RewriteRule gets only string after RewriteBase and is not catching GET parameters, right? So why when I try to go to this URL it rewrites it to this?
http://example.com/C:/OpenServer/domains/example.com/admin/1/
There is also this line in .htaccess(but doesn't look like there is problem with it):
RewriteRule ^admin/(.*)$ admin.php?cat=$1
As answered here, you have to add [QSA] at the end of your RewriteRule line:
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [QSA]
Google search query that lead me to that answer: htaccess pass parameters
I have a URL:
domain.com/abc/hotel_detail.php?id=2
And I want to do a URL re-write to make it look like this :
domain.com/abc/hotel_detail/2
My current .htaccess looks like this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteCond %{QUERY_STRING} ^id=20$
RewriteRule ^abc/hotel_detail/([0-9]+)$ ^abc/hotel_detail.php?id=$1 [L]
The first part contains code for removing the extension(.php) from pages.
When I try to open this link domain.com/abc/hotel_detail/2 , it gives me object not found error.
Can Someone please tell me whats wrong with the code?
Remove this line:
RewriteCond %{QUERY_STRING} ^id=20$
Changing your file to:
RewriteEngine On
RewriteRule ^abc/hotel_detail/([0-9]+)$ ^abc/hotel_detail.php?id=$1 [R]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,R]
should work. I removed RewriteCond %{QUERY_STRING} ^id=20
Your first rewritecond and rule was overwriting the second one, switching them around should fix it.
I think this should work
RewriteRule ^abc/hotel_detail/([0-9]*)$ abc/hotel_detail.php?id=$1 [L]
([0-9]*) miltiply sign.
and the ^ for the real link
I am trying to find a better solution to solve the issue. I am not using any framework like silex, Yii, etc. Thus I do not have the general routing handling mechanism provided by these frameworks. My URL patterns are like
routing.php
routing.php?action=create
routing.php?action=list&id=1
and the resulting URL I want to have are
/routing
/routing/create
/routing/list/1
I have some very basic understanding of .htaccess, below is my current foundings
RewriteEngine On
RewriteBase /name/
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
These codes work well to put any .php to /something. However, I am stuck to continue to generate a general solution for getting /routing/create and /routing/list/1 . I appreciate for any helps.
Have your .htaccess like this:
RewriteEngine On
RewriteBase /name/
RewriteCond %{DOCUMENT_ROOT}/name/$1.php -f
RewriteRule ^([^/]+)/([^/]+)/?$ $.php1?action=$2 [L,NC,QSA]
RewriteCond %{DOCUMENT_ROOT}/name/$1.php -f
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/?$ $1.php?action=$2&id=$3 [L,NC,QSA]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]
I hate to ask this question because it's been asked a million times, but the answers never seem satisfactory, and most of the threads seem abandoned without an accepted answer.
Here's exactly what I need to do (bad urls are intentional due to low karma):
http://example.com/file.php redirects to http://example.com/file/
http://example.com/file must also redirect to http://example.com/file/
http://example.com/asdfsadf and http://examplecom/file/asdfasdf must go to the 404 page
Here's the htaccess magic I cobbled together from posts here and elsewhere. It seems to work (unlike most of the abandoned threads on the topic, where there's always some strange behavior).
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^([^/]+)/$ $1.php
RewriteRule ^([^/]+)/([^/]+)/$ /$1/$2.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ /$1/ [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^/]+/)*[^.#?\ ]+\.php([#?][^\ ]*)?\ HTTP/
RewriteRule ^(([^/]+/)*[^.]+)\.php http://example.com/$1 [R=301,L]
Like I said, as far as I can tell, this works fine, even with subdirectories. Can any more knowledgeable folks tell me if I'm missing something. Could it be improved or shortened?
For what it's worth, I'm also removing the www:
RewriteCond %{HTTP_HOST} ^www.example.com$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]
It seems to work fine. It is included after the other parts. Is this the best order?
Thanks everyone, I hope we can get a good, reliable answer for this out there because there's a lot of bad ones.
Oh, I have the answer to this one!
This little rewrite snippet to go in .htaccess will remove the extension from any file you specify in its url.
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
RewriteBase /
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://yourdomain.com/$1/ [L,R=301]
Just paste it at the bottom of your .htaccess file in your root directory. The file is hidden so make sure 'show hidden files' is enabled in your ftp. ETA: last 3 lines should add a trailing slash to all files at yourcomain.com Do't forget to replace youdomain.com correctly.
That will remove the '.php' from all your urls to php files! ^_^
Hope I helped