Forum Moderators: phranque
I know how to do a basic mod-rewrite like this:
RewriteRule ^(.*)shp/stuff/detail-nm(.*)$ $1shp/stuff/detail-nm.php?thing=$2to make:
ttp://www.mydomain.com/shp/stuff/detail-nm.php?thing=$var1[abc]into:
ttp://www.mydomain.com/shp/stuff/detail-nm/$var1[abc]
In other words can I change:
ttp://www.mydomain.com/shp/stuff/detail-nm.php?name=$simplifiedname&thing=$var1[abc]into:
ttp://www.mydomain.com/shp/stuff/$simplifiedname/$var1[abc]
I tried to figure it out following this outline:
RewriteRule currentURL rewrittenURL
I have no idea how to do the currentURL part with the asterisks, I've only previously done modrewrite with 2 back references and 1 variable in the original url, like my first example above.
The best I can come up with for the rewritten url is:
$1shp/stuff/$2$simplifiedname&thing=/$3
but I don't really think that is right either, I especially don't know where to work in the last / that should come between the variable $simplifiedname and $var1[abc]
My best guess at the whole thing (but not correct)
RewriteRule ^(.*)shp/stuff/(.*)$ $1shp/stuff/$2$simplifiedname&thing=/$3If
Any ideas? Or would this require a really complex rewrite rule?
You can use up to nine RewriteRule pattern back-references, and an additional nine back references to the pattern in a preceding RewriteCond.
However, you'll need to define the value for the $3 back-reference. $1 "copies" the value of the expression that matches in the first set of parentheses in the requested URL, $2 copies the value in the second set of parentheses, and $3 will take the value of the third set of parentheses -- but there isn't a third set in your pattern.
To simplify this problem, break it into two pieces: First, the rewriting problem, of using pieces of the original URL to build the new one, and second, the pattern-matching problem using regular expressions.
Apache mod_rewrite documentation [httpd.apache.org]
Apache URL Rewriting Guide [httpd.apache.org]
Regular Expressions Tutorial [etext.lib.virginia.edu]
It isn't clear which pieces of your URL are fixed and which are variable, so I can't presently help any further in rewriting them to the correct script call. However, your problem appears to be easily-solvable.
Jim
RewriteRule ^(.*)shp/stuff/(.*)/(.*)$ $1shp/stuff/detail-nm.php?name=$2&thing=/$3
Do I really need to use any regular expressions? (They're still a bit beyond me) Or does the second (.*) need to be replaced by some regular expression to indicate any characters?
As far as what is fixed and what isn't:
shp and stuff are directories, and are fixed
detail-nm.php is a file which is fixed
$var1[abc] is a php variable that I'll need to send to the next page (detail-nm.php)to use to further pull stuff out of the database.
$simplifiedname is a variable that will be defined on the page before detail-nm.php. Since I don't need to use it for anything again - I just want it to use in the url for seo purposes - I wonder now if I really need the 'name=' part?
Couldn't I just write it as:
RewriteRule ^(.*)shp/stuff/(.*)/(.*)$ $1shp/stuff/detail-nm.php?$2&thing=/$3
Where the original url would instead be:
ttp://www.mydomain.com/shp/stuff/detail-nm.php?$simplifiedname&thing=$var1[abc]
".*" is a regular expression, and means, "match any number of any characters." You should avoid using it, because it is a "greedy" operator. That is, it will match as many characters as possible, causing inefficient operation, and occasionally, unexpected results.
> I wonder now if I really need the 'name=' part?
That's really dependent upon your php code.
As far as I can tell, you only have two variables in the requested "simplified" URL. Taking that into account, and using more-efficient regular-expressions patterns yields:
RewriteRule ^shp/stuff/([^/]+)/([^/]+)/?$ /shp/stuff/detail-nm.php?name=$1&thing=$2
You haven't stated whether this is for use in .htaccess or in httpd.conf. For use in httpd.conf, you'll need to add a leading slash to the RewwriteRule Pattern:
RewriteRule [b]^/s[/b]hp/stuff/([^/]+)/([^/]+)/?$ /shp/stuff/detail-nm.php?name=$1&thing=$2
RewriteRule [b]^([/b][^/]+)/([^/]+)/?$ /shp/stuff/detail-nm.php?name=$1&thing=$2
Don't hide from regular expressions -- You can't write or debug mod_rewrite code without them. I suggest you analyze the code above, making reference to the tutorial link I posted, and use your familiarity with your own project as leverage to understand what regular expressions are for and how they work. Regular expressions are a powerful pattern-matching "language" used in php, perl, ssi, mod_rewrite, and other Apache modules. Some time spent getting comfortable with them will pay big dividends in your ability to administrate your site.
Have fun!
Jim
([^/]+) does sound much better!
I didn't know or at least never thought of moving the .htaccess file into a subdirectory. So then I don't need the $1 out in front?
I know I shouldn't hide from regular expressions! I guess I have a sort of regular expression phobia!
I'm going to keep working on this tonight - for as long as I can, and hopefully will be able to figure it out!
I don't think so; There is nothing there to copy into the substitution URL. The part of the URL "visible" to a RewriteRule is only the local URL-path. So if a browser requests "www.example.com/foo.html", only "foo.html" is available to a RewriteRule in .htaccess. If you place a RewriteRule into .htaccess in a subdirectory, then the name of that subdirectory gets stripped off, and is no longer available to the RewriteRule. That's why I removed in in the code intended for use in /shp/stuff.
You can put that code into the subdirectory for better execution efficiency, or keep it in your Web root directory for easier central administration -- It's a trade-off. If your site gets 10,000 hits a day, put the code in the subdirectory. If not, it's a matter of preference.
Jim
Turns out I did need one extra variable than I had originally thought.
What I need to do is change:
shp/stuff/detail-nm.php?$vara&varb&thing=$var1[abc]
into:
shp/stuff/vara/varb/$var1[abc]
I tried both with $1 in front and not:
^(.*)/shp/stuff/([^/]+)/([^/]+)/([^/]+)/?$ $1shp/stuff/detail-nm.php?$2&$3&thing=$4
I get 404 errors. I have a gut feeling that at this point there is something minor I am missing and I'm not seeing it since my eyes are all glazed over after working on the php part.
Try this, and if you get a 404 error, look at your server error logs and see where it goes wrong.
Rewrite shp/stuff/vara/varb/$var1[abc] --> shp/stuff/detail-nm.php?$vara&varb&thing=$var1[abc] :
RewriteRule ^shp/stuff/([^/]+)/([^/]+)/(.+)/?$ /shp/stuff/detail-nm.php?$1&$2&thing=$3 [L]
Breaking it down, $1 will contain vara, $2 will contain varb, and $3 will contain var1[abc] if and only if all three are present in the requested URL, are preceded by "shp/stuff/", and are separated by slashes. A trailing slash is allowed, but will be ignored if present.
If it doesn't work and you cannot review the error logs, then turn this rewrite (temporarily) into an external redirect. That way, you will see the "wrong" rewritten URL in your browser address bar:
RewriteRule ^shp/stuff/([^/]+)/([^/]+)/(.+)/?$ [b]http:[/b][b]//www.example.com[/b]/shp/stuff/detail-nm.php?$1&$2&thing=$3 [[b]R=301,[/b]L]
Jim