Pretty URLs with .htaccess - php

I have a URL http://localhost/index.php?user=1. When I add this .htaccess file
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^user/(.*)$ ./index.php?user=$1
I will be now allowed to use http://localhost/user/1 link. But how about http://localhost/index.php?user=1&action=update how can I make it into http://localhost/user/1/update ?
Also how can I make this url http://localhost/user/add ?
Thanks. Sorry I am relatively new to .htaccess.

If you want to turn
http://www.yourwebsite.com/index.php?user=1&action=update
into
http://www.yourwebsite.com/user/1/update
You could use
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^user/([0-9]*)/([a-z]*)$ ./index.php?user=$1&action=$2
To see the parameters in PHP:
<?php
echo "user id:" . $_GET['user'];
echo "<br>action:" . $_GET['action'];
?>
The parenthesis in the .htaccess are groups that you can call later.
with $1, $2, etc.
The first group I added ([0-9]*) means that it will
get any numbers (1, 34, etc.).
The second group means any characters
(a, abc, update, etc.).
This is, in my opinion, a little bit more clean and secure than (.*) which basically mean almost anything is accepted.

you can write something like this:
RewriteEngine On
RewriteRule ^([^/]*)/([^/]*)$ /index.php?user=$1&action=$2 [L]

a simple way is to pass only one variabe to index.php like this
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^(.*)$ index.php?data=$1 [QSA]
and in your index.php file you do this
$data = expload("/",$_GET['data']);
$user = $data[1];
$action = $data[2];
this one works for all cases, when you try to pass many variables, it doesn't work in case you do something like this though
http://localhost/user/add/12/54/54/66
the last variable always takes the value add/12/54/54/66

Since you tagged this with PHP, I'll add a little perspective from what I did, and it may or may not help you.
You can, of course, write solely in .htaccess, being careful about order. For instance, let's say that you have:
RewriteRule ^user/([0-9]+)/update$ ./index.php?user=$1&action=update
RewriteRule ^user/([0-9]+)$ ./index.php?user=$1
Then it should, upon receiving
http://localhost/user/1/update
go to
http://localhost/index.php?user=$1&action=update
and not
http://localhost/index.php?user=$1
Now, what I did instead was push everything to index.php?q=$1
RewriteRule ^(.*)$ index.php?q=$1
Then I used index.php to handle how the query was broken up. So let's say someone enters
http://www.example.com/user/18239810/update
this would go to
http://www.example.com/index.php?q=user/18239810/update
From there, explode the query string along the first / to give user and 18239810/update.
This would tell me that I need to pass 18239810/update to the user controller. In that controller, I again explode the argument into the user id and command, and I can switch on the command to tell how to load the page, passing the user id as an argument to the update function.
Very quick and dirty example (index.php):
<?php
$getString = explode('/', $_GET['q'], 1);
$controller = $getString[0].'Controller';
require_once('/controllers/'.$controller.'.php');
$loadedController = new $controller( $getString[1] );
?>
Of course, this means that constructors all must take a string argument that will be parsed for acceptable values. You can do this with explodes and switch statements, always defaulting back to the standard front page to prevent unauthorized access based on random guessing.

For /user/add you will need to do a separate rule because you have no "middle parameter". So:
RewriteRule ^user/add$ ./index.php?action=add [L,QSA]
You can then do additional rules for URLs that contain additional parameters:
RewriteRule ^user/([0-9]+)/([A-Za-z]+)$ ./index.php?user=$1&action=$2 [L,QSA]
This will allow you to perform actions on existing users. E.g. /user/1/update

Thanks for the idea #denoise and #mogosselin. Also with #stslavik for pointing out some of the drawback of my code example.
Here's how I do it:
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^user/([0-9]*)/([a-z]*)$ ./index.php?user=$1&action=$2
RewriteRule ^user/([a-z]*)$ ./index.php?user&action=$1
by using var_dump($_GET); on the link localhost/user/1234/update I got
array (size=2)
'user' => string '1234' (length=4)
'action' => string 'update' (length=3)
while localhost/user/add
array (size=2)
'user' => string '' (length=4)
'action' => string 'update' (length=3)
which is my goal. I will just only do other stuffs under the hood with PHP.

Its simple just try this out !
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^game/([0-9]+)/([_-0-9a-zA-Z]+)/?$ index.php?user=$1&action=$2 [L,NC]
Thats it !!

Try this it is very simple:
Options +FollowSymLinks
RewriteEngine on
RewriteRule index/user/(.*)/(.*)/ index.php?user=$1&action=$2
RewriteRule index/user/(.*)/(.*) index.php?user=$1&action=$2

Related

How to change the name of the directory in url in php using htaccess?

How can I do to change the name of the url of my site which is: www.example.com/user/panel.php to www.example.com/username/panel.php where the "username" is unique for each user , And for each login would be the name of the user from database, as it is in jsfiddle.net, could they help me?
Personally I would not use .htaccess for this ( specifically )
that said most the time people do it this way
RewriteEngine On
RewriteRule ^users/([-a-zA-Z0-9_]+)/?$ index.php?user=$1 [L]
So if you had a url like
www.yoursite.com/users/someguy
Then it would pass it to apache ( and php ) as
www.yoursite.com/index.php?user=someguy
Then in PHP you could access it just using $_GET[user].
Now ignoring security concerns I may have ( you shouldn't rely on user input to tell who they are, they can lie about it) for this I would use what I call the URI method ( not URL ) a URI is an imaginary path. This is also the method employed by many MVC systems. So for this I will start with the URI
www.yoursite.com/index.php/users/someguy
Notice where the index.php is ( in the middle ). Then you do a .htaccess like this
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f #if not a real file
RewriteCond %{REQUEST_FILENAME} !-d #if not a real folder
RewriteRule ^(.*)$ index.php/$1 [L] #hide the index.php
So what this does is allow you to remove the index.php giving you a url like this
www.yoursite.com/users/someguy
Which is what we want, and looks basically the same as the first case.
Then you cam use the $_SERVER['QUERY_STRING'] supper global which will give you everything past index.php
/users/someguy
And you can split that up, route it somewhere, do whatever you need to with it. Like this
$uri = array_filter( explode('/', $_SERVER['QUERY_STRING'] ) );
//$uri = [ 'users', 'someguy' ];
Now the reason I like this more, is it's more flexible and it lets you use the query string the ?var part of the url for other stuff. ( like bookmarkable search forms ) ie. it feels less hacky because your not breaking the query parameters of a GET Request. Conversely, with the first method, if your .htaccess is sloppy you could make it were the query part of the URL is unusable on your site, and that just feels wrong to me.
It also easier to maintain, because it requires no further setup for additional pretty urls
For example:
Say you want prettyfy your product. Using the first method you would have to go back to the .htaccess add at least 1 more rule in:
RewriteEngine On
RewriteRule ^users/([-a-zA-Z0-9_]+)/?$ index.php?user=$1 [L]
RewriteRule ^products/(0-9_]+)/?$ index.php?product=$1 [L]
Possibly even more complex levels if you have product categories
RewriteRule ^produts/([-a-zA-Z0-9_]+)/(0-9_]+)/?$ index.php?category=$1&product_id=$2 [L]
After a wile you would wind up with dozens of rules in there, some of which may not be immediately clear as to what they do. Then you realize you spelled products as produts and have to start renaming things. It's just a mess later on.
Now using the second method you don't need to do any additional steps, besides routing it in your index page. You just put the url in
www.yoursite.com/products/123
And pull that stuff from the $_SERVER array with no further messing with rewrite rules.
Here is a previous answer I did that outlines how to build a basic router.
Oop php front controller issue
Make sense.

.htaccess - redirect individual urls to url with query string

I'm looking to do the opposite of a common query with .htaccess files.
I want to redirect a standard url to a url with a query string, similar to below:
test.com/directory/pagename
to:
test.com/template?id=1
I don't require pattern matching of any form, I just want to write out a separate redirect for each one. For example:
test.com/colours/red = test.com/template?id=5
test.com/colours/yellow = test.com/template?id=3
Hopefully this makes some sense.
You can use this code in your DOCUMENT_ROOT/.htaccess file:
RewriteEngine On
RewriteRule ^colours/yellow/?$ template?id=3 [L,NC,QSA]
RewriteRule ^colours/red/?$ template?id=5 [L,NC,QSA]

.htaccess writerule to remove question marks and equal mark

today i tried to create .htaccess file that replacing ? and = with / ,
test.php code:
<?php
echo $_GET['myparam'];
?>
.htaccess:
i used this writerule:
RewriteEngine On
RewriteBase /
RewriteRule ^test/myparam/([0-9]+)/?$ test.php?myparam=$1 [NC,QSA,L]
ok, i navigated to www.web.com/test.php?myparam=123
there is no redirect to www.web.com/test/myparam/123
so navigated to: www.web.com/test/myparam/123 (Manually) and the php script is worked,
i changed the myparam value to abc instead of 123 : www.web.com/test/myparam/abc
and then it redirects to 404 not found page...(the server don't know that abc is not directory when integer works when string 404)
!so what i want to do:!
www.web.com/ test .php? inttParam = 1 & strrParam = stringhere & p = 1
TO
www.web.com/ test/inttParam/1/strrParam/stringhere/p/1
and when i use $_GET['p'] it will work.
i changed the myparam value to abc instead of 123 and it didn't work
Well of course it won't work since your rule is matching only numbers in the end:
RewriteRule ^test/myparam/([0-9]+)/?$ test.php?myparam=$1 [NC,QSA,L]
change your rule to this to make it work with anything:
RewriteRule ^test/myparam/([^/]+)/?$ test.php?myparam=$1 [NC,QSA,L]
To make it recursion based generic rule to convert /test/inttParam/1/strrParam/stringhere/p/2 to /test.php?p=2&strrParam=stringhere&inttParam=1`:
RewriteRule "^(test)(?:\.php)?/([^/]+)/([^/]*)(/.*)?$" /$1.php$4?$2=$3 [NC,L,QSA]
RewriteEngine on
# do not affect files
RewriteCond %{REQUEST_URI} !(\..{2,4})$
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^(.*)$ index.php?parameter1=$1&%1 [L]
Something like that perhaps?
ok, i navigated to www.web.com/test.php?myparam=123
there is no redirect to www.web.com/test/myparam/123
I don't know if that means that you also want to make a redirection (presumably 301) from the one with GET params to the one with slashes.
If so, I would recommend to use the previous answer from anubhava and handle any 301 redirection with PHP. Actually, you can redirect with "RewriteRule" using the "R" flag, but I admit that I woundn't know how to solve this particular case.
Anyway, I think there is no need, unless old URLs with GET params were working well at SEO and you didn't wan't to lose ranking.

Build PHP page based on url

If you have a url such as the one as follows:
http://www.example.com/400x200
is it possible to create a page which echos out 400x200 when the user visits that url using php?
I know how to echo the path - that is easy enough (ltrim($_SERVER['PATH_INFO'], '/')), but do not know how to create the page dynamically.
Any help would be much appreciated, thanks in advance
The request URI (/400x200) is stored in the server superglobal: $_SERVER["REQUEST_URI"].
You need to take that and route the URI accordingly. The simplest possible scenario: in your index.php, place this code:
$uri = trim($_SERVER["REQUEST_URI"],"/");
if (preg_match("/\d+x\d/")) {
list($width,$height) = explode("x",$uri);
// some logic with the above vars, e.g. include a view script
}
What this does is check whether the URI has the format {number}x{number}, extracts both numbers and stores them in the variables $width and $height. You can then do whatever you like with the variables.
In order to make the request always point to the file containing this code, edit your .htaccess and put in something like this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
(the .htaccess code is copied from the default Zend Framework project, in case anyone asks).
You may want to look at Apache Rewrites for rewriting your URL:
http://httpd.apache.org/docs/2.0/misc/rewriteguide.html
Do not know what do You mean by creating the page dynamically but I guess that using of mod_rewrite is what You need.
In Your .htaccess file You have to create some rules that will rewrite the URL to something distinguishable by Your PHP script - like from URL
http://www.example.com/400x200
to get
http://www.example.com/index.php?param=400x200
And then You can in Your index.php script do echo $_GET['param'];...
Google something about PHP and mod_rewrite: http://www.google.com/#q=PHP+mod_rewrite
Assuming you're using Apache, this can be done using something called URL rewriting. Create a file called .htaccess in your document root, and add this:
# Turn URL rewriting on
RewriteEngine on
Options +FollowSymlinks
# Rewrite rule
RewriteRule ^(\d+x\d+)/?$ index.php?dimensions=$1 [L]
The first two lines turn the rewrite engine on, and the third line defines a RewriteRule. The first part ^(\d+x\d+)/?$ is a regular expression that the part of the URL after the domain will be matched against.
The second part index.php?dimensions=$1 is the URI that will be rewritten to. The client doesn't see this, but PHP will.
If I do a print_r($_GET) in index.php with the URL http://localhost/400x300, I get this:
Array ( [dimensions] => 400x300 )
This is from the standard $_GET superglobal array in PHP and can be used as normal. URL rewriting leaves the URL as it is in the browser, yet allows you to turn it into one usable by PHP with a query string.
To make your script a bit easier to use, you could split the expression up to get separate X and Y values:
RewriteRule ^(\d+)x(\d+)/?$ index.php?x=$1&y=$2 [L]
Which will give an array like this:
Array ( [x] => 400, [y] => 300 )
Make it a GET variable like
http://www.example.com?size=400x200
Then you can retrieve the String with
$size = $_GET['size'];
What I'd recommend you to do is to get the values based on split or explode()
$lw = $size.explode('x',$size);
$length = $lw[0];
$width = $lw[1];
//Manipulate the values accordingly like
echo $length.'x'.$width;

Easy mod_rewrite - So I'll never have to think about it again

Not sure how you'll take this question but...
Whenever I try to make my URLs look pretty I always end up messing around for too long and it's simply not worth the trouble. But the end effect is good if it were a simple task.
So what I want to do is create a method which in the end would achive something like...
index.php?do=user&username=MyUsername //This becomes...
/user/MyUsername //...that
index.php?do=page&pagename=customPage //And this becomes...
/page/customPage //...that
index.php?do=lots&where=happens&this=here //This also becomes...
/lots/happens/here //...that
index.php?do=this&and=that&that=this&and=some&more=too //And yes...
/this/that/this/some/more //This becomes this
So then I just make a nice .htacess file that I'll never have to look at again. Everything will be better in the world because we have pretty URLs and my head didn't hurt in the making.
You can use a different approach of throwing the url in a single parameter, and parse it in your application.
So the apache rewrite rule would look like:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
which will convert your urls as follows:
/user/MyUsername => index.php?q=/user/MyUsername
/page/customPage => index.php?q=/page/customPage
...
In your app, you then have a $_GET['q'] variable, which you can split by '/', and have your arguments in order. In PHP it would be something like:
$args = explode('/', $_GET['q']);
$args will be an array with 'user', 'MyUserName', etc.
This way you will not have to touch your .htaccess again, just your app logic.
For /user/MyUsername ==> index.php?do=user&username=MyUsername and /page/customPage ==>
index.php?do=page&pagename=customPage, you can use:
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)$ index.php?do=$1&$1name=$2 [L]
But I don't think you can write a catch-all rule for /lots/happens/here and /this/that/this/some/more because you need to tell mod_rewrite how to translate the two urls.
Remember, mod_rewrite has to translate /lots/happens/here into index.php?do=lots&where=happens&this=here and not the other way around.
The best approach would be to delegate your application to generate the “pretty URLs” as well as parse and interpret them and to use mod_rewrite only to rewrite the requests to your application with a rule like this one:
RewriteRule %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
This rule will rewrite all requests that can not be mapped directly to an existing file to the index.php. The originally requested URL (more exact: the URL path plus query) is then available at $_SERVER['REQUEST_URI'].

Categories