URL rewriting advice please - php

I would like to make my urls more seo friendly and for example change this:
http://www.chillisource.co.uk/product?&cat=Grocery&q=Daves%20Gourmet&page=1&prod=B0000DID5R&prodName=Daves_Insanity_Sauce
to something nice like this:
http://www.chillisource.co.uk/product/Daves_Gourmet/Daves_Insanity_Sauce
What is the best way of going about doing this? I've had a look at doing this with the htaccess file but this seems very complicated.
Thanks in advance

Ben Paton, there is in fact a very easy way out. CMSes like Wordpress tend to use it instead of messing around with regular expressions.
The .htaccess side
First of, you use an .htacess with the content below:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
Let me explain what it does (line by line):
if the apache module named mod_rewrite exists..
turn the module on
let it be known that we will rewrite anything starting after the
domain name (to only rewrite some directories, use RewriteBase
/subdir/)
if the requested path does not exist as a file...
and it doesn't even exist as a directory...
"redirect" request to the index.php file
close our module condition
The above is just a quick explanation. You don't really need it to use this.
What we did, is that we told Apache that all requests that would end up as 404s to pass them to the index.php file, where we can process the request manually.
The PHP side
On the PHP side, inside index.php, you simply have to parse the original URL. This URL is passed in the $_SERVER variable as $_SERVER['REDIRECT_URL'].
The best part, if there was no redirection, this variable is not set!
So, our code would end up like:
if ( isset( $_SERVER['REDIRECT_URL'] ) ) {
$url = explode('/', $_SERVER['REDIRECT_URL'] );
switch($url[0]){
case 'home': // eg: /home/
break;
case 'about': // eg: /about/
break;
case 'images': // eg: /images/
switch( $url[1] ){
case '2010': // eg: /images/2010/
break;
case '2011': // eg: /images/2011/
break;
}
break;
}
}
Easy Integration
I nearly forgot to mention this, but, thanks to the way it works, you can even end up not changing your existing code at all!
Less talk, more examples. Let's say your code looked like:
<?php
$page = get_page($_GET['id']);
echo '<h1>'. $page->title .'</h1>';
echo '<div>'. $page->content .'</div>';
?>
Which worked with urls like:
index.php?id=5
You can make it work with SEO URLs as well as keep it with your old system at the same time. Firstly, make sure the .htaccess contains the code I wrote in the one above.
Next, add the following code at the very start of your file:
if ( isset( $_SERVER['REDIRECT_URL'] ) ) {
$url = explode('/', $_SERVER['REDIRECT_URL'] );
$_GET['id'] = $url[0];
}
What are we doing here? Before going on two your own code, we are basically finding IDs and information from the old URL and feeding it to PHP's $_GET variable.
We are essentially fooling your code to think the request had those variables!
The only remaining hurdle to find all those pesky <a/> tags and replace their href accordingly, but that's a different story. :)

It's called a mod_rewrite, here is a tutorial:
http://www.workingwith.me.uk/articles/scripting/mod_rewrite

What about using the PATH_INFO environment variable?
$path=explode("/",getenv("PATH_INFO"));
echo($path[0]."; ".$path[1] /* ... */);
Will output
product; Daves_Gourmet; Daves_insanity_Sauce
The transition from using $_GET to using PATH_INFO environment is a good programming exercise. I think you cannot just do the task with configuration.

try some thing like this
RewriteRule ^/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+) /$1.php?id1=$2&id2=$3 [QSA]
then use $_GET to get the parameter values...

I'll have to add: in your original url, there's a 'prod' key, which seems to consist of an ID.
Make sure that, when switching to rewritten urls, you no longer solely depend upon a unique id, because that won't be visible in the url.
Now, you can use the ID to make a distinction between 2 products with the same name, but in case of rewriting urls and no longer requiring ID in the url, you need to make sure 1 product name can not be used multiple times for different products.
Likewise, I see the 'cat'-key not being present in the desired output url, same applies as described above.
Disregarding the above-described "problems", the rewrite should roughtly look like:
RewriteRule ^/product/(.*?)/(.*?)$ /product?&cat=Grocery&q=$1&page=1&prod=B0000DID5R&prodName=$2
The q & prodName will receive the underscored value, rather than %20, so also that will require some patching.
As you can see, I didn't touch the id & category, it'll be up to you to figure out how to handle that.

Related

How to make a URL link like this http://stackoverflow.com/questions/tagged/php [duplicate]

When you edit a question on stackoverflow.com, you will be redirected to a URL like this:
https://stackoverflow.com/posts/1807421/edit
But usually, it should be
https://stackoverflow.com/posts/1807491/edit.php
or
https://stackoverflow.com/posts/edit.php?id=1807491
How was
https://stackoverflow.com/posts/1807421/edit
created?
I know that Stackoverflow.com was not created by using PHP, but I am wondering how to achieve this in PHP?
With apache and PHP, you might perform one of your examples using a mod_rewrite rule in your apache config as follows:
RewriteEngine On
RewriteRule ^/posts/(\d+)/edit /posts/edit.php?id=$1
This looks for URLs of the "clean" form, and then rewrites them so that they are internally redirected to a particular PHP script.
Quite often rules like this are used to route all requests into a common controller script, which might do something like instantiate a "PostsController" class and ask it to handle an edit request. This is a common feature of most PHP application frameworks.
It's called routing. Take a look at tutorials on the subject.
If you use a framework such as cake php it should be built in.
As #mr-euro stated you can use mod_rewrite but front controller is a far better solution.
You force every request to index.php and you write your application controlling in index.php.
You use Apache's .htaccess/mod_rewrite, and optionally a PHP file, which is the approach I like to take myself.
For the .htaccess, something like this:
RewriteEngine On
RewriteRule ^(.*)$ index.php
Then in your PHP file, you can do something like this:
The following should get everything after the first slash.
$url = $_SERVER['REQUEST_URI'];
You can then use explode to turn it into an array.
$split = explode('/', $url);
Now you can use the array to determine what to load:
if ($split[1] == 'home')
{
// display homepage
}
The array is starting from 1 since 0 will usually be empty.
It's indeed done by mod_rewrite, or with multiviews. But i prefer mod_rewrite.
First: you create a .htaccessfile with these contents:
RewriteEngine On
RewriteRule ^posts/([0-9])/(edit|delete)$ /index.php?page=posts&postId=$1&action=$2
Obvious, mod_rewrite must be enabled by your hostingprovider ;)
Using mod_rewrite this can be achieved very easily.
I am poor at this but i do know you can redirect urls using apache mod_rewrite and by touching config files. From what i remember htaccess can be used to redirect. Then internally when the user hits
http://stackoverflow.com/posts/1807421/edit it can use your page http://stackoverflow.com/edit.php?p=1807421 instead or whatever you want.
You could use htaccess + write an URI parser class.

How do I make clean url?

I want to make the clean url for my site. How do I change htaccess file. My original Link that
This is my original link
**http://www.tangailbazar.com/adview_details.php?ID=9014&show=Hot%20and%20Cool%20Water%20Filter**
I want to make it like this
http://www.tangailbazar.com/Hot-and-Cool-Water-Filter
My code is here.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule /^(.*) adview_details.php?show=$1 [PT,QSA]
My post link from where i get the value like this
View Details
In adview_details page I have written the code
<?php
$id=$_GET['ID'];
$id1=$_GET['show'];
?>
<?php
$SQL="select * from tb_classified where sl='$id' and title='$id1'";
$obj->sql($SQL);
while($row = mysql_fetch_array($obj->result))
{
echo $row['title'];
echo $row['description'];
}
?>
You are looking for an Apache mod called mod_rewrite. Specifically (from the documentation):
If, on the other hand, you wish to pass the requested URI as a query string argument to index.php, you can replace that RewriteRule with:
RewriteRule (.*) adview_details.php?show=$1 [PT,QSA]
Note that these rulesets can be used in a .htaccess file, as well as in a block.
<?php
$title = str_replace(' ', '-', $row['title'])
?>
View Details
Output URL http://www.tangailbazar.com/Hot-and-Cool-Water-Filter
but this will not work, why? because you can not make a url with a condition, while for the request to mysql need two conditions.
maybe you should change your url into http://www.tangailbazar.com/1/Hot-and-Cool-Water-Filter
If you follow my advice you should change the code. htaccess becomes
RewriteRule ([0-9]?)/([a-zA-Z_-]+) adview_details.php?ID=$1&show=$2 [PT,QSA]
and the URL that you should use
View Details
First what draws my attention is that your regular URL is not as clean to start with. I would advise you to remove the spaces and change them for hyphens—if possible. URL are also case insensitive so there is actually no use for uppercase characters, but using them is personal preference though it makes them less readable and when rewriting it's an extra process to change them.
When rewriting a URL, you should think of your URL as parts. There is the domain which is divided in: subdomain (www), domain-name (tangailbazar) and the top-level domain (com). After the domain begins the cleaning up (you can also do a lot of rewriting on the domain, but in your case you will not).
To keep your rewrite process clear and simple (because URL rewriting with mod_rewrite can give massive headaches) you want every part of a rewritten URL (between slashes) to translate to a parameter in the raw URL. So in your case: ID=9014&show=Hot and Cool Water Filter are two parameters that should be used in your clean URL. When rewriting the URL you would pick the value of key (parameter) ID and show and use them in your clean URL. In your case you need the ID parameter in the clean URL otherwise you can never not load your destination URL.
RewriteRule ^.+/(.+)/(.+)+$ adview_details.php?ID=$1&show=$2 [L]
This rule will change the request for:
www.tangailbazar.com/9014/Hot%20and%20Cool%20Water%20Filter
into:
www.tangailbazar.com/adview_details.php?ID=9014&show=Hot%20and%20Cool%20Water%20Filter
This is the best you can do in this case, otherwise you will have to change some things about the structure of the destination URL.
An important thing you need to get hold of is that the name URL rewriting is misleading, you actually don't rewrite anything, you translate the requested URL from the browser into the URL where you're page is located. So it's more of a 'URL translate' then a 'URL rewrite'. In creating user friendly URL's you most of the time are removing the parameter keys (show=) and file extension (.php) from the URL to make them more readable.
You will always need to use the dynamic parts in your URL and you can clean the static parts.
I hope this will help you solve your problem or at least make some things clear on rewriting URL's.
Good luck!
httpd.apache.org/docs/current/mod/mod_rewrite.html
www.regexr.com

Safe routing in my own framework using PHP - how

As almost every programmer, I'm writing my own PHP framework for educational purposes. And now I'm looking at the problem with parsing URLs for MVC routing.
Framework will use friendly URLs everywhere. But the question is how to parse them in front controller. For example the link /foo/bar/aaa/bbb may mean "Call the controller's foo action bar and pass parameter aaa with value bbb. But in case someone installs a framework into the subdirectory of the domain root, the directory part should be stripped before determining controller name and action name. And I'm looking for a way to do it safely.
Also I would like to support a fallback case if URL rewriting is not supported on the server.
On different systems different sets of $_SERVER variables are defined. For example, on my local machine from the set of PATH_INFO, REQUEST_URI, REQUEST_URL, ORIG_REQUEST_URI, SCRIPT_NAME, PHP_SELF only REQUEST_URI, SCRIPT_NAME and PHP_SELF are defined. I wonder, if I can rely on them.
Mature frameworks like Symfony or ZF have some compicated algorithms of parsing URLs (at least it seemed to be so). So, I can't just take a part from there for mine.
Two workarounds:
Add config variable with url / instalation directory to your application, and strip it from $_SERVER['REQUEST_URI']
Make apache rewrite it to get variable
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php?myrequest=$1 [QSA,L]
I'm currently doing the same research. But everything I see is so complicated that I'll most probably continue using mod_rewrite anyway. After all you end up with the same thing rather you use SEF with PHP or mod_rewrite with apache. Anyway I'll be monitoring this topic.. it's interesting :)
Hope the php gurus around here have some more info about this :)
Edit:
It really depends on what you want to do. For my needs I hardcoded most of the pages so they looked SEF. But something like the example below should work as well.
RewriteEngine on
RewriteRule ^/posts/([A-Za-z0-9_\-]+)/([A-Za-z0-9_\-]+)\.html$ posts.php?$1=$2 [NC]
With this example above:
http://localhost/posts/view/23
http://localhost/posts/delete/23
is equal to:
http://localhost/posts.php?view=23
http://localhost/posts.php?delete=23
It really depends on what exactly you're doing :)
The example above should be working but I haven't tested them.
I usually use the following for determining an application base URL path, assuming all your requests always goes through the same gateway script:
$base = dirname($_SERVER['PHP_SELF']);
For your second question, if you want to check if mod_rewrite is enabled, you can use:
if (in_array('mod_rewrite', apache_get_modules())) {
// rewrite is enabled
}
However, it doesn't necessarily means that RewriteEngine is enabled, so you probably should use an extra condition:
if (in_array('mod_rewrite', apache_get_modules()) &&
preg_match('/RewriteEngine +On/i', file_get_contents('/path/to/.htaccess'))) {
// rewrite is enabled and active
}
Maybe you could take PHP_SELF and remove the first n chars where n is the length of SCRIPT_NAME.
Edit: Oops... seems like you can just take PHP_SELF: http://php.about.com/od/learnphp/qt/_SERVER_PHP.htm

what is the best way to do that name?get=

ok assume i have php page
has this name name.php?get= and has get varible named get
ok
how i can make it appear like that name?get=
If you are using apache, mod_rewrite is one way to go. There is a whole bunch of mod_rewrite tricks here.
I'd seriously reconsider before using (or overusing) mod_rewrite.
In almost all of my projects I use a simple mod rewrite in the .htaccess:
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^.*$ ./
AddHandler php5-script .php
This tells the server to forward all pages to / (index.php) unless a file otherwise exists.
In the root directory I have a folder called "views" with all of the pages that I use. E.g. the file used for /home would actually be /views/home.php. However, in the index.php I have a script that parses the user's url, checks for the file, and includes that.
$page = substr($_SERVER['REQUEST_URI'], 1);
if(!$page) :
header("Location: /home");
if(file_exists("views/$page.php")) :
include "views/$page.php";
else :
include "views/$page.php";
endif;
This creates a variable called $page that stores the value of everything in the URL after the domain name. I use a substr() function on the Request URI to get rid of the trailing forward slash (/) on the URL.
If the variable is empty, for example if the user is simply at http://example.com or http://example.com/ then it forwards them to /home, where the script then checks for the home.php file inside of the views folder. If that file exists, it includes it, and displays it to the user.
Else, the script will simply include the 404 page telling the user that the file doesn't exist.
Hopefully this helps you, and if you need any further explanation I'd be happy to help!
I think you're wanting to re-write the URL client-side, which would include mod_rewrite.
In the route of your website, create a file called .htaccess and place the following code in it:
RewriteEngine on
RewriteRule ^name?get=(.*) /name.php?get=$1
Now when you type http://www.example.com/name?get=something, it will actually map to http://www.example.com/name.php?get=something transparently for you.
As far as i could understand your question, you can not strip the file extension because otherwise it will not run. In other words, you can not change:
name.php?get=
into
name?get=
But if you mean to create links with query string values that you can put them in hyperlinks in this way:
Click here !!
If you're looking to create links using a variable '$get', then you can create the link like this:
<a href="name.php?get=$get>Link</a>
Or if you want to get the value of the query string variable, you can use this:
$get = $_GET['get']

How To rewrite a url with PHP?

Let' say for example one of my members is to http://www.example.com/members/893674.php. How do I let them customize there url so it can be for example, http://www.example.com/myname
I guess what I want is for my members to have there own customized url. Is there a better way to do this by reorganizing my files.
You could use a Front Controller, it's a common solution for making custom URLs and is used in all languages, not just PHP. Here's a guide: http://www.oreillynet.com/pub/a/php/2004/07/08/front_controller.html
Essentially you would create an index.php file that is called for every URL, its job is to parse the URL and determine which code to run base on the URL's contents. So, on your site your URLs would be something like: http://www.example.com/index.php/myname or http://www.example.com/index.php/about-us or http://www.example.com/index.php/contact-us and so on. index.php is called for ALL URLs.
You can remove index.php from the URL using mod_rewrite, see here: http://www.wil-linssen.com/expressionengine-removing-indexphp/
Add a re-write rule to point everything to index.php. Then inside of your index.php, parse the url and grab myname. Lookup a path to myname in somekinda table and include that path
RewriteEngine on
RewriteRule ^.*$ index.php [L,QSA]
index.php:
$myname = $_SERVER['REQUEST_URI'];
$myname = ltrim($myname, '/'); //strip leading slash if need be.
$realpath = LookupNameToPath($myname);
include($realpath);
create a new file and change it name to (.htaccess) and put this apache commands (just for example) into it :
Options +FollowSymLinks
RewriteEngine on
RewriteRule ^profile/([0-9]*)$ members.php?id=$1
You must create a rewrite rule that point from http://www.example.com/myname to something like http://www.example.com/user.php?uname=myname.
In '.htaccess':
RewriteEngine on
RewriteRule ^/(.*)$ /user.php?uname=$1
# SourceURL TargetURL
Then you create a 'user.php', that load user information from 'uname' GET variable.
See from your question, you may already have user page based on user id (i.e., '893674.php') so you make redirect it there.
But I do not suggest it as redirect will change the URL on the location bar.
Another way (if you already have '893674.php') is to include it.
The best way though, is to show the information of the user (or whatever you do with it) right in that page.
For example:
<?phg
vat $UName = $_GET['uname'];
var $User = new User($UName);
$User->showInfo();
?>
you need apache’s mod_rewrite for that. with php alone you won’t have any luck.
see: http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html

Categories