Page is a not externally linkable
StupidScript - 6:05 pm on Jul 20, 2010 (gmt 0)
Thanks to Jim Morgan, here's code that works for me on Fedora 13 Linux, running Apache 2.2, PHP 5.3 and MySQL 5.1.47:
Using Apache's RewriteEngine, PHP and MySQL to produce clean URIs from dynamic content.
Concept:
- Articles are stored in a database
- Page request is an alias of that resource
- Requested alias is checked against database table
- Leaving the alias in the browser address bar, display dynamic resource
This takes an aliased URI like:
http://www.example.com/article/this-is-an-article
And grabs this actual URI from the server:
http://www.example.com/index.php?article=11
It leaves the original URI in the browser's address bar, so the visitor/search engine doesn't know any different.
Note: All visible links should be aliases. In other words, there should be NO links with queries in them. Every request is looked up in the alias table. Static pages are not re-mapped.
Table 'url_alias':
id int(11) primary key auto_increment
rid int(11)
type varchar(10)
alias varchar(128)
Sample table data:
id = 11;
rid = 11;
type = 'article';
alias = 'this-is-an-article';
httpd.conf (sever config, not Directory or Virtual):
# start mod_rewrite
RewriteEngine on
# find processing script here
RewriteMap newurl prg://var/www/cgi-bin/cleanurls.php
# enable lock file while rewriting (protection against collisions)
RewriteLock /var/lock/map.newurl.lock
# if RewriteRule matches, check for specific case
RewriteCond %{REQUEST_URI} ^/article.*
# any URI matches, and is then tested by the RewriteCond, above
RewriteRule ^/(.*) ${newurl:$1} [L]
/var/www/cgi-bin/cleanurls.php (chmod 755, apache user)(first line is NOT a comment! It's a 'bang'):
#!/usr/bin/php
<?php
# PHP/MySQL db connection
include '/path/to/db_connect.php';
# this program cannot die ... TO DO: graceful error handling needed
set_time_limit(0);
# assign STDIN to handler
$keyboard = fopen("php://stdin","r");
# always
while (1) {
# read STDIN to variable from handler
$line = fgets($keyboard);
# check for string '/chars/chars/' in URI
if (preg_match('/(.*)\/(.*)/', $line, $igot)) {
# grab pieces for resolving dynamic resource from db table ('article' and '11')
# matches 'alias' string, so that must be unique!
$getalias = mysql_query("select type, rid from url_alias where type = '$igot[1]' && alias = '$igot[2]'");
while($row=mysql_fetch_array($getalias)) {
$atype = $row['type'];
$arid = $row['rid'];
}
# print dynamic resource reference to STDOUT (does not refresh URI in address bar)
print "/index.php?$atype=$arid\n";
}
else {
# did not match '/chars/chars/', so just use the original URI (i.e. 'about.html')
print "$line\n";
}
}
?>