Using Non-Hardcoded Configuration Module Names - Perl
Now that you have mod_perl installed, you can move on to learning how to use it. This article will run you through some basic Perl concepts to start with.
You have just seen how to use a configuration module for configurationcentralization and an easy access to the information stored in thismodule. However, there is somewhat of a chicken-and-egg problem--howto let your other modules know the name of this file? Hardcoding thename is brittle--if you have only a single project it should be fine,but if you have more projects which use different configurations andyou will want to reuse their code you will have to find all instancesof the hardcoded name and replace it.
Another solution could be to have the same name for a configurationmodule, like My::Config but putting a different copy of it intodifferent locations. But this won't work under mod_perl because of thenamespace collision. You cannot load different modules which uses thesame name, only the first one will be loaded.
Luckily, there is another solution which allows us to stay flexible.PerlSetVar comes to rescue. Just like with environment variables,you can set server's global Perl variables which can be retrieved fromany module and script. Those statements are placed into thehttpd.conf file. For example
Now I require() the file where the above configuration will be used.
PerlRequire /home/httpd/perl/startup.pl
In the startup.pl I might have the following code:
# retrieve the configuration module path
use Apache:
my $s = Apache->server;
my $base_dir = $s->dir_config('FooBaseDir') || '';
my $config_module = $s->dir_config('FooConfigModule') || '';
die "FooBaseDir and FooConfigModule aren't set in httpd.conf"
unless $base_dir and $config_module;
# build the real path to the config module
my $path = "$base_dir/$config_module";
$path =~ s|::|/|;
$path .= ".pm";
# I have something like "/home/httpd/foo/Foo/Config.pm"
# now I can pull in the configuration module
require $path;
Now I know the module name and it's loaded, so for example if I needto use some variables stored in this module to open a databaseconnection, I will do:
Apache::DBI->connect_on_init
("DBI:mysql:${$config_module.'::DB_NAME'}::${$config_module.'::SERVER'}",
${$config_module.'::USER'},
${$config_module.'::USER_PASSWD'},
{
PrintError => 1, # warn() on errors
RaiseError => 0, # don't die on error
AutoCommit => 1, # commit executes immediately
}
);
Where variable like:
${$config_module.'::USER'}
In my example are really:
$Foo::Config::USER
If you want to access these variable from within your code at the runtime, instead accessing to the server object $c, use the requestobject $r:
my $r = shift;
my $base_dir = $r->dir_config('FooBaseDir') || '';
my $config_module = $r->dir_config('FooConfigModule') || '';