I have a Drupal website that I'm migrating to a custom php cms.
I have two types of drupal links:
node/123
title-of-my-link
With the new custom version, and after a database import, I've got:
content.php?id=852
I'm resolving this with an Apache rewrite rule that sends everything to a php file that does a mysql query and forward everything.
Here's my process:
RewriteRule ^.*$ ./reenvio.php
//I get the part of the url that I need to and put it inside an $urlString variable, extracting just what is after the forwardslash symbol.
$x = $conectarDB->prepare("
SELECT id, alias1, alias2
FROM contenidos
WHERE alias1 = ? OR alias2 = ?
");
$x->bindParam(1, $urlString);
$x->bindParam(2, $urlString);
$x->execute();
$urlDrupal = $x->fetch(PDO::FETCH_ASSOC);
$alias1 = strtolower($urlDrupal["alias1"]);
$alias2 = strtolower($urlDrupal["alias2"]);
//Then I do forward everything according to the id that I've found in the database that corresponds to the alias:
//I get the variables for the server first
$http = $_SERVER['REQUEST_SCHEME'];
$sitio = $_SERVER['HTTP_HOST'];
$id = $urlDrupal["contenidoID"];
$reenvioA = $http.'://'.$sitio.'/contenido.php?id='.$id;
//and I do sent the user to the unfriendly link
header('Location: '.$reenvioA);
exit();
My question being:
When having a lot of RewriteRules
that conform to the same pattern, you can use RewriteMap
. RewriteMap
supports lookup from a variety of sources, one being SQL with the use of mod_dbd
. However, if all your content has been already migrated and it's basically a static lookup, you can dump all your rules to a file and use another map type to avoid the dbd
dependency.
A RewriteMap
can only be defined in the VirtualHost
context. If you don't have access to the main configuration this will not work for you.
First define your Map
in the VirtualHost
config and configure dbd
if necessary (step omitted):
RewriteMap drupalmap "dbd:SELECT id FROM contenidos WHERE alias1 = %s OR alias2 = %s"
A lookup map takes a Pattern and a Substitution, just like RewriteRule
, so if you go with a file-backed map you can just dump the result of SELECT alias1, id FROM contenidos UNION SELECT alias2, id FROM contenidos
. The format is quite straightforward, but you have examples in the docs.
Then change the RewriteRule
:
RewriteCond ${drupalmap:%1} >"" # Apply the rule if there is a result
RewriteRule ^(.*)$ contenido.php?id=${drupalmap:$1}
If you don't have access to the main server config, and your mapping doesn't have any logic, the "dirty" solution can be to dump all mappings to RewriteRule
and paste them in .htaccess
so you end up with a bunch of
RewriteRule ^node/123$ contenido.php?id=852
RewriteRule ^title-of-my-link$ contenido.php?id=852
...
You can do this with a little script and the query suggested before but if you have a lot of rules this might have performance implications.