Ik snap niet precies wat je wil bereiken denk ik. Het standaard trailing slash probleem staat gewoon in de
manual en ziet er zo uit:
code:
1
2
3
4
| RewriteEngine on
RewriteBase /~quux/
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.+[^/])$ $1/ [R] |
Als het gaat om het verwerken van een virtueel URL dan doe ik het eigenlijk altijd met behulp van multiviews. Onderstaand een object om multiviews URL te behandelen. Nadeel van multiviews is dat ze pas te behandelen zijn vanuit een daadwerkelijke script-aanroep. /pagina/foo/bar/ is vanuit pagina.php prima om te zetten in $arg1=foo $arg2=bar. Om de boel netjes te laten werken bij een aanroep als domein.nl/virtualdir/virtualdir2 komt er een rewriterule kijken.
Gegeven dat a) multiviews aan staan; en b) pathinfo wordt doorgegeven door Apache werkt het volgende.
code:
1
2
3
4
5
6
| #.htaccess
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index/$1 |
Dit zorgt ervoor dat elk request naar een niet bestaand bestand wordt vertaald naar een request naar index(.php) met daar achter de pathinfo.
In index.php kun je een (/de) instantie aanroepen van onderstaande urlHandler klasse. Deze heeft vervolgens een property uriArgs die een array entry bevat voor elk deel van het url, waarbij een deel wordt gescheiden door een '/'.
Met een index.php die er zo uit ziet:
PHP:
1
2
3
4
| $URL = &URLhandler::getInstance();
foreach($URL->uriArgs as $param) {
echo '<li>' .$param;
} |
Levert een request naar domein/foo/bar(/) dan:
De klasse is niet heel kort, maar als cadeautje levert ie ook een 'baseUri' property om je stylesheets goed te includen, en een methode om veelzeggende keys aan je uriArgs te hangen:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
| /**
* urlHandler class for convenient handling of multiviews urls
* requires PHP >= 4.1.0
*/
class urlHandler {
var $baseUri;
var $uriArgs = array();
/**
* Constructor
* Compares the requested url with the path to the script to determine the
* input parameters that will be stored in array $uriArgs.
* Also, the string $baseUri will be filled with the full www path to the
* directory that contains script. This value can be used to solve the
* problem of breaking relative paths in pages that use multiviews urls.
*/
function urlHandler() {
$docRoot = rtrim($_SERVER["DOCUMENT_ROOT"], '/');
$httpHost = rtrim($_SERVER["HTTP_HOST"], '/');
//relative uri to scriptfile
$relScriptFile = substr($_SERVER["SCRIPT_FILENAME"], strlen($docRoot));
//strip GET requests from request uri
$reqUri = ($getPos = strpos($_SERVER["REQUEST_URI"], '?')) ? substr($_SERVER["REQUEST_URI"],0,$getPos) : $_SERVER["REQUEST_URI"];
//find all parts of the requesturi
$reqUriParts = explode('/', rtrim(urldecode($reqUri),'/') );
//extract uri args when set
$sliceOffset = substr_count($relScriptFile, '/');
if ($sliceOffset < count($reqUriParts)) {
$this->uriArgs = array_slice($reqUriParts, $sliceOffset);
}
//if the first part of the requesturi is the filename (or a multiviews derivate) then it's no input parameter
$scriptPathParts = pathinfo($_SERVER["SCRIPT_FILENAME"]);
$scriptIsFirstArg = ( $this->uriArgs[0] == $scriptPathParts['basename']
|| $this->uriArgs[0] == basename($_SERVER["SCRIPT_FILENAME"], '.' .$scriptPathParts['extension']) );
if ($scriptIsFirstArg) {
array_shift($this->uriArgs);
}
//set baseuri
$scriptDir = substr($relScriptFile, 0, strrpos($relScriptFile,'/')+1);
$this->baseUri = 'http://' .$httpHost .$scriptDir;
}
/** singleton object **/
function &getInstance() {
static $instance;
if (!isset($instance)) { $instance = new urlHandler(); }
return $instance;
}
/**
* creates associative entries in the uriArgs array from the arguments
* passed on to this function
* Input: can be either a single array with strings or multiple strings
* returns: the uriArgs array
*/
function associateWithUriArgs() {
$keys = func_get_args();
if (is_array($keys[0])) {
$keys = $keys[0];
}
foreach ($keys as $key => $value) {
if (isset($this->uriArgs[$key])) {
$this->uriArgs[$value] = $this->uriArgs[$key];
}
}
return $this->uriArgs;
}
} |