http://qs1969.pair.com?node_id=666576

graq has asked for the wisdom of the Perl Monks concerning the following question:

I have a module that handles database connections. It is used by standard CGI scripts as well as mod_perl2 modules.

The server hosts multiple sites, set up using Apache's VirtualHost configuration.

Using SetEnv (or PerlSetEnv), polutes across to other Apache requests, as %ENV is treated much like a mass global variable for all Apache's requests under MP2

Here is an example sample of code that does not work:

package MYDBCONFIG; use Apache2::RequestUtil; my %db = ( 'production' => { 'db1' => { 'host' => 'host1', 'name' => 'dbname1', 'user' => 'user1', 'pass' => 'pass1' }, 'db2' => { 'host' => 'host2', 'name' => 'dbname2', 'user' => 'user2', 'pass' => 'pass2' }, }, 'qa' => { 'db1' => { 'host' => 'host3', 'name' => 'dbname3', 'user' => 'user3', 'pass' => 'pass3' }, }, ); our ( $MYDBCONFIG ); # Used elsewhere for other 'magical' backwards co +de compatiblity sub new() { my $class = shift; my $dbname = shift; # Sanity checks. die( "No database name supplied") unless ($dbname); if( $ENV{'MOD_PERL'} ){ my $r = Apache2::RequestUtil->request(); $MYDBCONFIG = $r->subprocess_env('MYDB'); $r->log_error(__PACKAGE__.":[MP]: MYDB: $MYDBCONFIG"); } else { $MYDBCONFIG = $ENV{'MYDB'}; print STDERR __PACKAGE__.":[notMP]: MYDB: $MYDBCONFIG"; } my $dbhash = $db{$MYDBCONFIG}{$dbname}; die( "DB '$dbname' not defined / permitted") unless $dbhash; bless $dbhash, $class; }

This then allows MP2 and scripts alike to connect via ORMs (Class::DBI & DBIx::Class) to which ever DB is appropriate

The aim being to then configure apache for www.mysite.com and qa.mysite.com to use exactly the same code, but restrict access to db2, and use a different set of data for QA (allowing them to CRUD as much as they like).

-=( Graq )=-

Replies are listed 'Best First'.
Re: mod_perl2 Apache VirtualHost ENV settings [OT?]
by perrin (Chancellor) on Feb 06, 2008 at 19:27 UTC
    When you want to set up variables that are specific to a Location, Directory, or VirtualHost, use PerlSetVar.
      This would mean doubling up on all the configs, setting SetENv for scripts and PerlSetVar for mod_perl ?

      -=( Graq )=-

        If you need to support CGI scripts that don't run under mod_perl, I would suggest you create a config file with a hash of the variables you need indexed by something like DocumentRoot that's available in $ENV for CGI scripts and accessible via the mod_perl API as well.
Re: mod_perl2 Apache VirtualHost ENV settings [OT?]
by redhotpenguin (Deacon) on Feb 06, 2008 at 19:32 UTC

    You might be better off looking at $r->servername in a PerlPostReadRequest handler or something similar, and then setting the db connect value in $r->pnotes so that you don't pollute ENV across all requests.

    Even better, run a separate apache server for qa. If you get a bug in there, you run the risk of connecting your qa site to the production database, which can have undesirable consequences. This approach also has the added bonus that you will be able to use Apache::DBI for persistent DB connections, whereas I don't think you can do that with the example you have shown.