OCDev
OCDev

Reputation: 2369

mod_rewrite for dynamically mapping SEO friendly links directly to individual files, without routing via front controller

I'm looking for an SEO friendly url rewrite rule that would work for any common PHP site that doesn't have a front controller. It would map the SEO friendly url directly to the PHP file that is found to exist on the server and convert the remaining URL branches to standard URL parameters.

For example:

/folder1/folder2/folder3/page/var1/val1/var2/val2/var3/val3

would map to:

/folder1/folder2/folder3/page.php?var1=val1&var2=val2&var3=val3

Now, here's the tricky part. Since the rewrite rules need to be completely agnostic to all the names of folders, pages, and variables, it would need to base the rewrite of the URL parameters on the exact location along link where can be found a file that exists along the path. For instance, consider if the following file happened to exist (hypothetically) off the document root: /folder1/folder2.php
In this case, the following remapping would be legitimate and acceptable:
/folder1/folder2.php?folder3=page&var1=val1&var2=val2&var3=val3

This would be the ultimate rewrite rule for many traditional websites that have already been built that want their URLs and parameters to instantly become URL-friendly.

The only examples that I have found involve mapping everything to work with a single front controller or otherwise hard-coded files in the rule that are expected to exist rather than have mod_rewrite detect their existence dynamically. They're related, but not flexible for any file that is found to exist:

Upvotes: 0

Views: 503

Answers (1)

Gumbo
Gumbo

Reputation: 655189

The Apache web server does already know such a concept:

  • MultiViews:

    The effect of MultiViews is as follows: if the server receives a request for /some/dir/foo, if /some/dir has MultiViews enabled, and /some/dir/foo does not exist, then the server reads the directory looking for files named foo.*, and effectively fakes up a type map which names all those files, assigning them the same media types and content-encodings it would have if the client had asked for one of them by name. It then chooses the best match to the client's requirements.

  • Path Info:

    This directive controls whether requests that contain trailing pathname information that follows an actual filename (or non-existent file in an existing directory) will be accepted or rejected. The trailing pathname information can be made available to scripts in the PATH_INFO environment variable.

    For example, assume the location /test/ points to a directory that contains only the single file here.html. Then requests for /test/here.html/more and /test/nothere.html/more both collect /more as PATH_INFO.

All you then need to adjust is to take the path info part and parse it.

Besides that, if you really want to implement that behavior with mod_rewrite, try this:

RewriteCond %{DOCUMENT_ROOT}/$0.php !-f
RewriteRule ^(.+)/([^/]+)/([^/]+)$ /$1?$2=$3 [N,QSA]
RewriteCond %{DOCUMENT_ROOT}/$0.php -f
RewriteRule .+ /$0.php [L]

Upvotes: 1

Related Questions