I have made a custom PHP/Sql cms with a dynamic post template called blog-post.php
I am pulling in the content like so:
http://www.example.com/news/blog-post.php?slug=sample-slug-from-database
This allows me to pull in any number of posts using the same template, pulling info from the database.
I have spent 4 hours trying to achieve the following with htaccess ..
Force a trailing slash instead of .php extension
Force blog post urls to show as:
http://www.example.com/sample-slug-from-database/
instead of
http://www.example.com/news/blog-post.php?slug=sample-slug-from-database
Any help is greatly appreciated.
Although your preferred method of URL is to redirect everything, e.g. /sample-slug-from-database/, I think it would be better to instead go with a less strict implementation, e.g. /news/sample-slug-from-database/
Either way, here's the first implementation:
# URL
# INPUT http://www.example.com/random-slug/
# OUTPUT http://www.example.com/news/blog-post.php?slug=random-slug
RewriteEngine On
RewriteRule ^(.*)\/$ news/blog-post.php?slug=$1 [L,QSA]
And the second way:
# URL
# INPUT http://www.example.com/news/random-slug/
# OUTPUT http://www.example.com/news/blog-post.php?slug=random-slug
RewriteEngine On
RewriteRule ^news\/(.*?)(\/(.*?)*)$ /news/blog-post.php?slug=$1 [L]
For anyone else struggling - this is my final code:
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1/ [R,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !/$
RewriteRule . %{REQUEST_URI}/ [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*?)/?$ $1.php [L]
RewriteEngine On
RewriteRule ^(.*)\/$ blog-post.php?slug=$1 [L,QSA]
Related
My request is quite simple. Using my current .htaccess conditions and rules as given here:
# Remove .php extension from URLS
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
# Redirect from *.php to URL without *.php
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R,L]
Problem is, when I pass a URL that contains *.php?param1=A¶m2=B as a parameter, it throws away "?param1=A¶m2=B"
For example:
I want to redirect to: "/views/users/login.php?redirect=/views/home.php?id=1"
Resulting in: "/views/users/login?redirect=/views/home", which throws away "?id=1", so now I can not access that parameter.
How do I rewrite my rules so that it keeps those parameters?
Any suggestions are welcome and much appreciated.
Update (2015-09-16):
Removing
RewriteRule ^(.*)\/index\.php$ $1 [R=301,L,NC]
As it is irrelevant.
You'll have to use urlencode to encode the URL into a parameter.
So when building the link or redirect, use:
redirect('views/user/login.php?redirect=' . urlencode('/views/home.php?id=1'))
btw: redirecting to a "controller" in a folder called "views" might be a bit confusing in a few month :)
Hello you just need to add the query append marker like so:
RewriteRule ^(.*)\/index\.php$ $1 [QSA,R=301,L,NC]
that is "QSA"
I have solved this issue (to some agree) using the following code:
# Enable rewrite mod.
RewriteEngine On
RewriteBase /
Options +FollowSymLinks -MultiViews
# Redirect URLs that contain *.php to extensionless php URLs.
RewriteCond %{THE_REQUEST} ^(.*)\.php
RewriteRule ^(.+)\.php$ $1 [R,L]
# Resolve *.php file for extensionless php URLs.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^(.*)$ $1.php [NC,L,QSA]
# Resolve /views/* for URLs that do not contain views and needs it.
RewriteCond %{REQUEST_URI} ^/applications/(.*)$ [OR]
...
RewriteCond %{REQUEST_URI} ^/home [OR]
...
RewriteRule ^(.*)$ /views/$1
# Redirect URLs that contains /views/* to viewsless URLs.
RewriteCond %{THE_REQUEST} ^(.*)/views/(.*)
RewriteRule ^views(.*)$ $1 [R,L]
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}.
I have crawled StackExchange for 3 days now and come close to finding the solution to my problem, but keep coming up short.
I am using htaccess to rewrite and redirect urls to SEO friendly urls. My htaccess currently is as follows.
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1 [L,QSA]
########################################
# REMOVE INDEX.PHP FROM THE URL
########################################
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(.*)/index\.php [NC]
RewriteRule ^ %1 [R=301,L]
##################################################
# REWRITE QUERY STRING INTO SEO FRIENDLY URL
##################################################
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+(?:index\.php)?\?page=([^\s]+)? [NC]
RewriteRule ^ /%1? [R=301,L]
Currently my links pass 1 main argument '?page=somepage'. On my users page, I have links that pass not only the page argument, but also the id of a user. That link is as follows :
?page=users&id=1
Furthermore, a user has the option to edit their own profile, so that link is like this :
?page=users&id=1&do=edit
My htaccess handles the rewrite and redirect of the url correctly, but only when the {QUERY_STRING} has just one argument that is passed.
I have played with my existing RewriteCond to look for multiple arguments in the query string and also tried changing the RewriteRule to handle multiple arguments in the query string. I was successful when dealing with 2 arguments, but my original rule (for 1 argument) broke.
How should I go about writing my RewriteCond / RewriteRule to handle urls with either 1 or or more {QUERY_STRING} arguments?
I want my urls to go from :
?page=users
?page=users&id=1
?page=users&id=1&do=edit
to this :
/users
/users/1
/users/1/edit
After tinkering with my htaccess file, I managed to find a solution to my problem. This just proves that often the answer you are searching for is the most obvious and most overlooked. The following is my updated, and working htaccess file.
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1 [L,QSA]
########################################
# REMOVE INDEX.PHP FROM THE URL
########################################
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(.*)/index\.php [NC]
RewriteRule ^ %1 [R=301,L]
##################################################
# RERWITE QUERY STRING INTO SEO FRIENDLY URL
##################################################
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+(?:index\.php)?\?page=([^\s]+)? [NC]
RewriteRule ^ /%1? [R=301]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+(?:index\.php)?\?page=([^\s]+)&id=([^\s]+)? [NC]
RewriteRule ^ /%1/%2? [R=301]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+(?:index\.php)?\?page=([^\s]+)&id=([^\s]+)&do=([^\s]+)? [NC]
RewriteRule ^ /%1/%2/%3? [R=301,L]
While this is working for my needs, I do have another question.... Is there a way to simplify my htaccess RewriteCond / RewriteRule in this file?
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.
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /domain.com/
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*?)/?$ /domain.com/$1.php [L]
am using this code for remove question mark but its not working, trying http://domain.com/details?id=71 to http://domain.com/details/id/71
Please help me where am wrong?
Thanks in advance
I'm not sure what you're trying to accomplish with the first rewrite, but for the second (the last three lines), if the incoming URI is not an actual directory or file, you want to rewrite something like details/id/71 to /details.php?id=71?
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/?$ /$1.php?$2=$3 [L]
should get you close, assuming there are always 3 fields. In a RewriteRule you don't put the domain name again.
Your code doesn't do anything remotely close to what you want. Your code simply removes the php extension when a request is made explicitly with the extension and adds it back internally. In order to make http://domain.com/details?id=71 get redirected to http://domain.com/details/id/71, you need:
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\s/+([^/]+?)(?:\.php|)\?([^=]+)=([^&\ ]+)
RewriteRule ^ /%1/%2/%3? [L,R]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/?$ /$1?$2=$3 [L]
you want this before your rules that remove the php extension
Assuming your script is called details.php, the following single rule:
RewriteRule details/(.*)/(.*)/$ /details.php?$1=$2
Should rewrite www.domain.com/details/id/71 to www.domain.com/details.php?id=71
You don't need all that other stuff to remove the .php extension.