问题
Is it possible to use mod_rewrite to write an htaccess rule that takes a url parameter value (for example: id=1, where 'id' is the parameter, and '1' is the parameter value), query a database with the parameter value specified, and then write the value returned from the query as a part of the url of the requested page?
I know the basics of mod_rewrite, for example rewriting a url that appears like:
www.example.com/item.php?id=1
to the following:
www.example.com/item/1
An example of what I would require is writing the following url:
www.example.com/item.php?id=1
to this:
www.example.com/item/name-of-item-based-on-id-specified-in-original-url
However I have no idea if what I am looking to do is possible using mod_rewrite.
If anyone has a solution to this problem I'd be very grateful if you could help me. If what I am trying to do is not possible using htaccess and mod_rewrite, can someone please point me in the direction of how I may go about solving this problem?
回答1:
It's possible, but you need to use a RewriteMap to define a mapping that you can use within a RewriteRule
.
Apache version 2.2 doesn't have direct database access so you'll need to write a script that does the actual query then return the result. You can define this map using the "External Rewriting Program".
So if you have a script that takes "cats" from stdin, then queries the database, and returns "1", you'd define it like so:
RewriteMap item_lookup prg:/path/to/item_lookup.php
That directive has to be in your server or vhost config, it can't be in an htaccess file. But you can use the mapping in an htaccess file:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /item.php?id=${item_lookup:$1} [L]
So this takes the URI /cats
and rewrites that to /item.php?id=1
.
If you are using apache 2.4, then you can take advantage of the "DBD" map. You can insert a query right into the map definition, bypassing having to use an external script. You'd use it in the same way.
RewriteMap item_lookup "fastdbd:SELECT id FROM items WHERE name = %s"
Then use it in the same way:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /item.php?id=${item_lookup:$1} [L]
Without using a DBD/FastDBD query, I think you're honestly better off just doing the database lookup from item.php
, since you'd be duplicating all of that work in a second external script anyways. Just add something like:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^item/([0-9]+)$ /item.php?id=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([A-Za-z0-9-]+)$ /item.php?name=$1 [L]
And in your item.php
script, check for both id and name. If you have a name, do the database lookup in order to turn that into an id. It's much easier to manage, you don't need to have server/vhost config access, and you're not complicating matters by using a rewrite map.
来源:https://stackoverflow.com/questions/18621538/is-it-possible-to-query-a-database-using-a-value-passed-in-a-url-and-write-the