views:

93

answers:

1

I'm trying to use mod_rewrite to handle an unknown number of variables.

An example URL would be:

example.com/var1-var2-var3/title

I have this so far:

RewriteRule ^([^/.]+)-([^/]*)(.*)$ $3?version[]=$1&version[]=$2 [QSA,N]
RewriteRule ^([^/.]+)/?$ ?title=$1 [QSA,N]
RewriteRule ^/?$ /index.php [QSA,L]

This returns: Array ( [title] => title [version] => Array ( [0] => var1-var2 [1] => var3 ) )

I need it to return: Array ( [title] => title [version] => Array ( [0] => var1 [1] => var2 [2] => var3 ) )

+1  A: 

I don't think you can capture an arbitrary number of arguments in a single RewriteRule regex. Wouldn't it be easier to redirect to index.php?version=var-var2-var3 then in PHP do an explode() on $_POST['version']?

EDIT: You can do it for a bounded number of vars (9 is the maximum captured subgroups I believe) and then remove redundant empty entries. Messier then the simple explode() alternative in my opinion, but here you go:

# Convert up to 8 arguments.
RewriteRule ^/([^-]+)-(?:([^-]+)-)?(?:([^-]+)-)?(?:([^-]+)-)?(?:([^-]+)-)?(?:([^-]+)-)?(?:([^-]+)-)?(?:([^-]+)-)?/(.*)$ index.php?t=$9&v[]=$1&v[]=$2&v[]=$3&v[]=$4&v[]=$5&v[]=$6&v[]=$7&v[]=$8
# Strip empty ones.
RewriteRule [?&]v\[\]=$ "" [N]

You can also do a complicated loop by moving one var to the new format on each run of the rewriting engine and go on running it until you run out of vars, but I think that's more than a URL rewriting engine should be responsible for.

EDIT 2: Ok, here's the loop I mentioned:

RewriteEngine on
RewriteRule ^(.*)/([^/]+)$ $1&page=$2 [L]
RewriteRule ^([^-]+)-(.*)?$ $2&v[]=$1 [L]
RewriteRule ^(?!index\.php)([^-]+)$ /index.php?v[]=$1 [L]

It transform a sample URL as follows:

var1-var2-var3/title                             <-- Original
var1-var2-var3&page=title
var2-var3&page=title&v[]=var1
var3&page=title&v[]=var1&v[]=var2
index.php?v[]=var3&page=title&v[]=var1&v[]=var2  <-- Final
Max Shawabkeh
That could be a solution, but handling it in a RewriteRule would be simpler.
Daniel
I'm looking for something more along the lines of this http://howflow.com/tricks/apache2_mod_rewrite_google_friendly_urls Except separating all the variables except the last one with '-' instead of '/'.
Daniel
What's described on that page is exactly the "complicated loop by moving one var to the new format on each run" I mentioned. I'll edit in a version that works for your format.
Max Shawabkeh
Isn't it bad practice to do it that way?
Daniel
Not really. I would consider a simpler solution where the rewriter would just pass everything to PHP and then you break it all down in PHP a better practice, but in pure mod_rewrite this is the only way to do it for an arbitrary number of vars.
Max Shawabkeh
This solution doesn't work on my server. Isn't there a way to simply modify the solution on the website I referenced?
Daniel
I tested it on my own machine and it should work. What is the output it's producing? As for modifying the howflow.com one directly, it won't work because they rely on there being an even number of values (since they are name-value pairs) and you also need an extra title argument.
Max Shawabkeh
I get a 500 internal server error.
Daniel
Make sure you have no other rules in .htaccess that may be conflicting with these and that you set RewriteBase‎ if the URLs are not at the root of the site. Also note that I edited the rules half an hour after posting - perhaps you copied the older version. If it still doesn't work, post the last few lines of the rewrite log or at least the apache error log.
Max Shawabkeh