Navid, The path info technique is moderately well known. I thought I'd seen an account of it at phpwizard.net, and I would have given you the link, but when I looked just now I couldn't find it. Anyway, this is roughly how it goes:-
Background ======== You can add all kinds of stuff at the end of a url pointing to your php script and the php still gets run e.g. http://www.mysite.net/myscript.php/this/and/thatand_the_other will still cause myscript.php to be run. Anything appearing after the path name is know as the path info and is available in a pre-defined global variable $PATH_INFO, (at least with Apache). In this example $PATH_INFO would be "/this/and/thatand_the_other", (note the / at the front). Basic Technique =========== So you can use PATH_INFO to communicate with your script from a link without using a GET string e.g. instead of : /myscript.php?search=findthis, you could just have /myscript.php/findthis. With the first, "GET" syntax, php automatically sets $search to "findthis". If you use the second, path info syntax instead, then you have to do a bit more work to get the value into the variable you want. In this case, you would do something like: list($null,$search) = explode('/',$PATH_INFO); >From this line on, it's exactly as if $search was set from the GET information. (The $null variable is simply there to "use up" the empty variable that explode assigns for what appears before the first /, it is only necessary because I use list() syntax to do all the work of unpacking and assignment in one line. list($search) = explode('/',substr($PATH_INFO,1)); would be an alternative that avoids this dummy variable.) You can pass any number of parameters, but your script needs to know what variables need to be set and in what order, which it doesn't have to do with the GET, since the names of the variables are passed as well as their values on a GET. For example, I've had urls that look like something like this: /product.php/cookers/range/belling as a replacement for /product.php?section_code=cookers&type_code=range&manufacturer_code=belling To unpack the PATH_INFO version in this case, I use the following code: list($null,$section_code,$type_code,$manufacturer_code) = explode('/',$PATH_INFO); That's about all there is to it. Eliminating the .php ============= There is a further refinement that I like, which is to get rid of the .php on the end of the script name. So instead of /myscript.php/this you have just /myscript/this, or in my last example : /product/cookers/range/belling. To achieve this you need to tell your web-server that it should treat files with no extension as if they were php files. If you run Apache, you need the following directive in the configuration file. DefaultType application/x-httpd-php (Don't assume I've got the syntax exactly right, check it!) You can set it across your whole server, just some virtual servers or individual directories. This tells Apache that if a file has no "type" i.e. no extension, treat it as php. The Advantages =========== Why bother using PATH_INFO, since it is extra work? 1. Elegant URLs Like you, I much prefer elegant urls. My reasoning is that the "location" of a page has an extremely prominent position within any browser, so it ought to be made as attractive, straightforward and unfrightening for the user as possible. It's as much a part of the design as the rest of the page. Whenever I see horrendous urls, (and some of the supposedly most professional sites are the worst), I get a bad taste in my mouth. I immediately assume that if the location of the page has such unnecessary geekery, there is probably a lot more unnecessary geekery to follow on the body of the page... 2. Search Engines An often quoted reason for using PATH_INFO is that search engines will not follow links which include GET data, whereas they will always follow PATH_INFO based links since there is no way they can distinguish them from "real" static links. In principle, this means that you can get every page of search results indexed and treated as if it were an individual static page by the search engine. You just need "hidden" path info based links on your pages that point to searches for "all" or various sub-sets of the possible results. But search engine placing is a black art, so don't take my word for it ;) 3. Usability Another point, is PATH_INFO urls are generally easy to remember/bookmark/manage, since they have a simpler format and will always use less characters than the GET version. They are, for example, much more likely to be fully visible in the browser's message toolbar during hovers over links. 4. Multi-Output Services There is a more subtle long-term advantage in eliminating the GET portion of your urls. Pure "PATH_INFO" urls are inherently more standards compliant than urls with GET information. They are significantly more likely to fit in with non-html urls, e.g. satisfying wap or xml requests for "data" from a "service" without changing the "addressing" of the service. You could publish the fact that urls of the form mysite/product/cookers/range/belling always return information about Belling range cookers, with the form in which the data is returned, html, wml, xml or whatever just depending on the request type. The basic address of the data is the same, regardless of the format requested. Before anyone jumps on my back for suggesting GET syntax is non-standard, let me point out that it's always going to be true that an "address" format with only one delimiter i.e. '/', is going to be more easily ported than an address format with four i.e. /, ?, = and &. 5. Advanced Techniques There are loads of simple but powerful techniques you can invent if you combine PATH_INFO with the DefaultType technique. For instance, you could take an existing static site and turn it into a fully dynamic php site with minimal changes. You might want to add standard headers/footers to turn a framed into a frameless site, or to add sophisticated database controlled user access control, all without changing any of the static pages or their cross-links. How? Well you rename the static site's directories and then put php scripts in with the old name of the directory. Then all requests for pages within the original directory are immediately routed to the php script. That script can then use PATH_INFO to find what page was actually requested, read in the html of the static page, manipulate it, e.g. "including" new headers/footers, and then return the modified html just as if it was the original static page! It's a lot less work than modifying all the static pages, and a lot more friendly if you want the page contents to be maintained by html designers with no php skills. General Problems ============ 1. Caching If you are using PATH_INFO, you should watch out for caching issues. I'm not quite sure how it works, (can anyone help explain?), but it seems that browsers and other cache-ers (e.g. proxy server caches), try and make sure they do not cache dynamic pages e.g. search results. I suspect that they identify dynamic pages by POST requests or presence of GET information, neither of which are there if you use PATH_INFO. I believe that means you can end up with users getting out of date results if they follow a PATH_INFO link at a later date. The results will be served up from cache instead of being re-generated. There's a pretty simple failsafe solution. You just have to make sure you send out explicit headers to prevent cache-ing e.g. insert the following php, (or call a function with this code), at the top of every script. header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . "GMT"); header("Cache-Control: no-cache,must-revalidate"); header("Pragma: no-cache"); 2. Invisible php One regret I have about developing sites which fully use these techniques, is that it can end up being completely impossible for anyone, including the robots that collect tool-usage data, to know that the site uses php. If I was using asp, perl, ColdFusion, Oracle, etc. I would consider that desirable ;). But it does seem a bit unfair on php that it can be so good that ends up completely invisible! I don't know how many people are using this technique, (how can anyone tell?), but it's even possible that this is part of the reason why php sites are, apparently, not growing as fast relative to other technologies as they used to. Sample Site ======== http://tandridge.cpfc.co.uk uses PATH_INFO quite a bit. In particular, it has php scripts which produce dynamic images, (try the "League Tables" and "Cup Competitions" options). These dynamic image scripts receive their control information i.e. where to find the data to display, via PATH_INFO. That makes it easy to change the image displayed without reloading the page. There's a little bit of Javascript that runs when the user changes their selection to tweak the image url (location), and change the image-generating scripts "parameters". By the way, if anyone is interested in bits of this site's code for another sports results site, let me know and I'll see if the client will let me release some or all of the code. It took me more than a month's work, and, IMHO, it has some semi-cute features. It'd be a shame if it was only ever used for a few hundred London youth soccer teams, when it could be easily converted to handle league/cup fixtures and results for basketball, baseball, ice-hockey or whatever Another of my sites that's pretty much path info throughout, but which you'll probably find more entertaining is http://super10.lycos.co.uk, an online gaming site. There are free games, (flash based), and real money to be won if you sign up for the prize games, so even though the techniques are less obvious, (most of it runs in windows without location bars), you might find it more interesting! Hope this helps. If you, or anyone else, find these notes useful, please drop me a mail and I'll think about putting a proper article somewhere or other. George mailto::[EMAIL PROTECTED] Navid Yar wrote: > George, > > Good point. I actually like your idea a lot. I have never thought about > using $SCRIPT_NAME. > > You also mentioned using "$PATH_INFO to implement elegant (and > search-engine safe) urls..." below. Can you give me a couple of examples > of how I might do this? I always hated the GET strings at the end of the > url. Sometimes I redirect a user to the same page two times just to get > rid of the trailing GET string. I know that's a bad way of doing it, but > it was a temporary thing until I could find a way around it. I would > really appreciate your help on this one. Thanks... > > Navid > > -----Original Message----- > From: George Whiffen [mailto:[EMAIL PROTECTED]] > Sent: Monday, February 18, 2002 7:09 AM > To: Navid Yar > Subject: Re: [PHP] form submission error trapping > > Navid, > > $SCRIPT_NAME is sometimes a safer alternative than $PHP_SELF. > > The difference is that $PHP_SELF includes $PATH_INFO while $SCRIPT_NAME > is > just the name of the actual script running. > http://www.php.net/manual/en/language.variables.predefined.php > > This becomes particularly important if you use $PATH_INFO to implement > elegant (and search-engine safe) urls e.g. /search/products/myproduct > rather > than /search.php?category=products&key=myproduct. > > George > > Navid Yar wrote: > > > Simply, to send a form to itself, you can use a special variable > called > > $PHP_SELF. Here's an example of how to use it: > > > > if ($somevalue) { > > header("Location: $PHP_SELF"); > > } else { > > execute some other code... > > } > > > > Here, if $somevalue holds true, it will call itself and reload the > same > > script/file. This code is not very useful at all, but it gets the > point > > across. If you wanted to pass GET variables to this, then you could > > easily say: > > > > header("Location: $PHP_SELF?var=value&var2=value2&var3=value3"); > > > > ...and so on. You can also use this approach with Sessions if you > wanted > > to turn the values back over to the form page, assuming you had two > > pages: one for the form, and one for form checking and entry into a > > database. There are several ways to check forms, whether you want it > on > > one page or span it out to several pages. You just need to be creative > > in what tools are avaiable to you. Here is an example of how you can > > pass session values: > > > > header("Location: some_file.php?<?=SID?>"); > > > > Here, whatever variables you've registered in session_register() will > be > > passed to the php page you specify, in this case some_file.php. Hope > > this helps. Have fun, and happy coding. :) -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php