what i'm trying to accomplish is to make my urls compatible with all kinds of extra arguments.
it must be able to work with n number of slashes.so my htaccess gets everything after 127.0.0.1/store/ and sends it redirect.php as id.
as in
http://127.0.0.1/store/category/cars/show/1/page/2
or
http://127.0.0.1/store/category/cars/color/red/price/min/100
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.domain\.com$
RewriteRule ^(.*)$ http://127.0.0.1/store$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ redirect.php?id=$1 [QSA,L]
in my redirect.php i explode slashes to get the script name and its parameters
if($_GET['id']){
$param = explode('/', $_GET['id']);
$template = $param[0];
// header redirect -> go to category.php
}
this gives me
Array
(
[0] => category
[1] => electronics-computers
[2] => show
[3] => 1
[4] => page
[5] => 2
)
so far so good, then i try to redirect to the file which is category.php in this example with parameters but since the htaccess controls the traffic, it becomes infinite redirection
i thought i should add some exception to htaccess to not to interfere requests coming from redirect.php but i couldnt make it work
ps: if there is a better way of doing this please let me know
then i try to redirect to the file which is category.php in this example
Well, that's the thing, you shouldn't be redirecting that this stage. Redirecting involves sending a redirect response back to the client and the client then makes a second/new request back to the server (which results in your redirect loop).
if there is a better way of doing this please let me know
You need to route the request. Since you know that the required file is contact.php (in this example), then read this file server-side, passing all the necessary parameters and send this in the same response back to the client.
Related
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.
So basically I have a website with user profiles. I want users to be able to query a profile like this:
www.example.com/john
and that would trigger another page I've written in PHP to display that profile but WITHOUT then changing the url. I've looked at other examples on SO like this:
How do I achieve a url like www.example.com/username to redirect to www.example.com/user/profile.php?uid=10?
However this uses url rewriting which means the URL would then change. For instnace if the page is called users.php, I don't want this to happen:
user queries www.examples.com/john -> page is changed to www.examples.com/users.php?name=John
I want the url to stay as www.examples.com/john but for the server to serve up the page www.examples.com/users.php?name=John
Would I still use url rewriting to achieve this even though I don't want the url to change in the url bar? Hope someone can help, thank you!
Usually who needs this kind of feature uses Routers.
Routing is the process of taking a URI endpoint (that part of the URI which comes after the base URL) and decomposing it into parameters to determine which module, controller, and action of that controller should receive the request.
Basically you can take your url and divide it in parameters. The response it's related to the input url.
There are some good libraries in php which allows you to handle routers, for example:
Dispatch: https://github.com/noodlehaus/dispatch
Phroute: https://github.com/mrjgreen/phroute
In phroute you can solve your problem just with:
$router->get(['/user/{name}', 'username'], function($name){
//retrieve $name information
return 'Hello ' . $name;
})
Just for information, every MVC framework uses router as standard.
Using .htaccess File
RewriteEngine on
RewriteRule ^/([a-zA-Z0-9])$ /users.php?name=$1
I hope this will solve your issue, now what it will do, on the front or to the public url is like http://www.example.com/john but users.php script on your server will receive a GET parameter name which will have the value john.
Just make sure apache mod_rewrite is turned on.
With Apache's rewrite module, you can do a rewrite or a redirect.
Redirect means, send a response (status code 301, 302) to the client and ask to fetch another URL. This causes the browser's URL bar to change to the new URL. This happens, when you add the R|redirect flag to a rule, e.g.
RewriteRule ^foo$ /bar.html [R,L]
or when the target is an absolute URL containing a domain, e.g.
RewriteRule ^foo$ http://www.example.com/bar.html [L]
Rewrite on the other side, means take the request and send an answer somehow, without redirecting the client to another resource.
RewriteRule ^foo$ /bar.html [L]
This time, the client asks for foo, but the server sends the contents of bar.html without telling the client.
So, as long as you don't add the R flag, or give an absolute URL, the client's URL bar won't change, e.g.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^john$ /users.php?name=john [L]
or more general
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ /users.php?name=$1 [L]
Hello I was trying to come up with the solution to my problem, but I just was not able to. So here is my problem:
What I used was a .htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.+(.*)/(.*)$ ./index.php?mesto=$1&den=$2 [QSA,NC,L]
It will display the url well. as www.site.com/CITY/DAY for example ../Prague/30.3.2014 but i need it to be more complex.
What I need is to have additional parameters, such as Bar or Restaurant in the url for example www-site.com/Prague/30.3.2014/p/bar/restaurant and other time I might have www-site.com/Prague/30.3.2014/p/pizza/bar
That part I have no idea how to do, because I have 5 different parameters
I imagine that the raw url would look this index.php?city=Prague&day=30.3.2014&p1=0&p2=0&p3=0&p4=0&p5=0 where p1 to p5 are the parameters being active (0 not 1 yes).
I don't understand how to detect what parameters are active and how to properly display the pretty url. Could you please help me?
Use
RewriteRule ^(.*)$ ./index.php [QSA,NC,L]
This will redirect all your requests to a single index.php that parses the uri with something like this:
<?php
// Example URI: /florence/30-06-2009
// Remove first slash from REQUEST_URI
$uri = substr($_SERVER['REQUEST_URI'],1);
// Get an array with portions between slashes.
$splittedURI = explode("/", $uri);
// Here you get your city (or anything else that you want)
$city = array_unshift($splittedURI); // In example, $city = "florence"
// Remaining itens in $splittedURI are the arguments/parameters to your page
// Like this:
$date = $splittedURI[0]; // In example, $date = "30-06-2009"
?>
Remember that this is just and example, and you should do additional verifications to avoid PHP exceptions.
If you need complicated routing (and if you sure you want to create your own router instead of using a ready solution as ZF, Symfony etc.) you're better off just passing the whole request uri to a php router object. There you can as complex router logic as you need.
So basically, loose the parsing in the rewrite rule:
RewriteRule ^(.*)$ ./index.php?route=$1 [QSA,NC,L]
Then you can let the index.php create a router object that can parse the route parameter and delegate the job where it needs to.
I'd recommend reading up about existing routing solutions though.
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;
I have been trying to get my urls to be more user friendly and I have come up with this set up
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ userpage?user=$1 [NC,L]
I added this to my .htaccess but I'm now i'm confused as to how to access these urls.
in my index.php when a user logs in i have tried to redirect the user using
userpage.php?user=s2xi
but the url parses as www.foo.bar/userpage.php?user=s2xi and not www.foo.bar/s2xi
and also tried this as a check to see if user exists (is there a better way?)
if($_GET['user'] != $_SESSION['username']){
header("Location: no_user.php");
}else{
//load page
}
I am using the Smarty template engine on my site and I have my 'themes' in directories that belong to members file
www.foo.bar/users/s2xi/themes
but i want www.foo.bar/s2xi to point to the persons profile page that is viewable by everyone else and not their accounts page.
You're missing the .php in your RewriteRule, if that's verbatim - eg, userpage? => userpage.php?.
However, you're going to run into some problems with this unless you're using a framework to help you distinguish between routes. If you switched to using a separate URI format for user pages (eg /user/foo) you wouldn't have conflicts; but as it stands currently, using .htaccess to rewrite your URLs in that format could potentially cause problems with many other parts of your app.
To do it with a separate URI format, change your last .htaccess line (the RewriteRule) to:
RewriteRule ^user/(.+)/?$ userpage.php?user=$1 [NC,L]
may want to consider adding QSA as well.