include "../../../lib/sabren.inc" ?>
When you run a database-driven website, it makes sense to generate pages on the fly. PHP, MySQL, and Apache let you do just that... But they don't make it pretty. How many times have you had to create a URL that looks like this:
http://www.schmoop.com/snurk.php3?snurk=23497
... when what you wanted was a URL like this:
http://www.schmoop.com/snurk/23497
...?
A while back, Tim Perdue wrote a
PHP Builder Article that walked you through modifying
Apache's access.conf
file to create user-
and search-engine friendly URLs.. Which is all well and good,
but what if you don't have access to access.conf
?
With Snurk, all you need is the ability to run custom CGI scripts,
an .htaccess
file, and a little bit of time and effort.
Right now, the Snurk method has only been tested with unix-based web hosting services that run PHP3 through CGI. If you get it working on other systems, please email snurk@sabren.com for the next version.
If there's enough interest in this, future versions of Snurk will automate some of the setup for you, but right now, Snurk consists of four very simple files, which are listed below, and must be modified by hand.
First, create a new PHP3 script, explore.php3
with the following lines:
<? print "PATH_TO_SH is: "; system ("which sh"); print "<HR>\n"; phpinfo(); ?>
When you run this script, PHP will give you all kinds of information about your environment variables and server paths. Write down the following values:
This is your database driven PHP3 file. You can call it
whatever you want, but most likely, you'll want to make
it look like a directory. In this case, our directory
is called snurk
. The goal is that whether a browser requests
snurk
, or snurk/apple
, or
snurk/234
, or snurk/whatever.php3?X=34
,
only one file will ever actually be run, and that's snurk
.
If that's the case, snurk
needs to know what page
the browser thinks it's getting. You can figure it out by putting this
chunk of code at the top of your page:
## SNURK STUFF ########################## $url_array=explode("/",$REQUEST_URI); $product = $url_array[count($url_array)-1]; # strip off extra stuff in the URL: if (strpos($product, '?')) { $snurk = substr($product, 0, strpos($product, '?')); } ## END OF SNURK STUFF ################## // the rest of your script goes here... // $snurk contains everything after "snurk" in the URL // here's a highly useful example script! print "hello, world! snurk is $snurk\n";
Actually type in the "hello, world!" stuff, or something like it - you'll use it for testing in a minute.
When you pull up snurk
in your browser,
you should actually see the above source code. That's
because Apache doesn't yet know you want to run it as
PHP. So, to fix that...
This file is the heart of PHP Snurk. It gives you a chance to trick PHP into running a specific script, instead of whichever script the browser happened to ask for.
We want to tell PHP to run snurk
. Given the
PATH_TRANSLATED you wrote down, you should be able to figure
out what snurk
's PATH_TRANSLATED would be.
Stick that and the other variables you wrote down into the file
below, and save it as phpsnurk.cgi
. (You'll
have to chmod 777
it and put it in a directory
that allows CGI, just like any other CGI script.)
#!PATH_TO_SH export PATH_TRANSLATED=PATH_TRANSLATED_FOR_SNURK SCRIPT_FILENAME
Pull this page up in your browser. If everything's working, it should say "hello, world!" and tell you that snurk is "phpsnurk.cgi". If not, something's wrong and you're on your own. :)
Future versions will allow you to have multiple PHP files all using the Snurk method, but for now, you'll have to do this once for each file. (If you know the [probably very simple!] shell scripting to make a "case" statement - send it to me... otherwise, the rest of you can wait until I look it up)..
Finally, you need to tell Apache to run phpsnurk.cgi
every time
a browser requests snurk
. Go to the directory that contains
snurk
and put the following text in your
.htaccess
file. (the path to phpsnurk.cgi
should be the relative path as the browser would see it.)
Action phpsnurk /cgi-bin/phpsnurk.cgi <Files snurk> ForceType phpsnurk </Files>
That's it! Pull up snurk/whatever
in your browser,
and snurk
will run!
Why in the bloody blue blazes of hell did you call this thing "PHP Snurk"?
Well, I was going to call it "sneaky-php", but I figured that might
raise some eyebrows with nervous web hosting sysadmins, when it's really all
pretty innocent. So instead of a sneak, it's just a snurk. Now you know.
Future Plans?
It would be nice if Snurk could handle more than one file like this
on a site.. I'm imagining a "snurk control panel" that sets up
all the files and variables for you, and lets you configure which
URLs map to which scripts. I probably won't bother, though, unless
enough people ask. (snurk@sabren.com)
Marinos J. Yannikos (mjy at pobox.com) offered a much simpler solution if your Apache has mod_rewrite installed:
> I'm using mod_rewrite to achieve the same effect: > > RewriteEngine On > RewriteBase /foo/blah > RewriteRule index.php3.* - [L] > RewriteRule ^(.*) index.php3/$1 > > If this is put in the .htaccess in a directory with local URL > /foo/blah, then all accesses like /foo/blah/1/2/3 go through > the script index.php3 (which gets the usual PATH_INFO etc.). > Works fine with php3 as a module, and probably with all other > types of scripts as well.
I got this method working with php3.cgi as well, but you have to change the last line a bit:
RewriteEngine On RewriteBase /foo/blah RewriteRule index.php3.* - [L] RewriteRule ^(.*) index.php3?fakepath=$1
Otherwise php3.cgi gives an "unable to find script" error. Thanks, Marinos!
A year later, and I finally find out that you can do this with a simple 404 page after all. (That's what I tried to begin with!) To change the error code on just about any cgi/php page, you just send a "status" header.. For example:
<?php header("status: 200"); ?>
Thanks to Phil _______ (knoebi at gmx dot net) for getting the 404 concept working. He reported that he got the following line to work, though it gave me an internal server error with apache:
<?php header("http/1.0 200 Ok"); ?>article_footer(); ?> sabren_footer(); ?>