hacker has asked for the wisdom of the Perl Monks concerning the following question:
When building sites for mod_perl, using the non-module approach and Apache::Registry, Apache::StatINC, and Apache::DBI, there seem to be several types of approaches. I've been reading everything I can get my hands on, including cgi_to_mod_perl, everything at perl.apache.org, the mod_perl mailing list archives, and others. Here's what I've seen so far, and am not yet sure what the best approach is:
use strict; use warnings; use diagnostics; use HTTP::Module; use Some::Module; my ($dbuser, # database username $dbpass, # password for db $dbhost, # host for the database $dbport, # db connection port $dbname, # name of the database used $dbh, # DBI handle $foo, # for foo $bar, # for bar $baz, # for baz %quux, # quux hash ); $dbuser = 'nobody'; $dbpass = 'NobodyPassword'; $dbport = '3306'; $dbhost = 'localhost'; $dbh = DBI->connect('DBI:mysql:$dbname:$dbhost:$dbport', $dbuser, $dbpass, {RaiseError => 1}); &init(); # initialize basic environment &print_header(); # CGI.pm basic header/content-type &top_of_page(); # print top menubars, logos, etc. &middle_of_page(); # main content, DBI results, etc. &bottom_of_page(); # bottom cleanup HTML, copyright, etc. &end_content(); # finish HTML, close handles if (!$vars{action} || $vars{action} eq "home") { # if the user hits the main page, or clicks 'home' # from the menubar, show the basic HTML content, no # sections &left_content(); &right_content(); } sub init { # ... } sub print_header { my $query = new CGI; %vars = $query->Vars(); # ... } sub top_of_page { # ... } sub middle_of_page { # ... $dbh = DBI->connect(..); # prepare, execute and print query results # wrapped in HTML elements } sub left_content { # Only shown when the user is on the main page # (no $vars{action} parsed) or they have # selected 'home' from the HTML menu displayed. # ... } sub right_content { # ..compliment to the 'left_content' sub above # ... } sub bottom_of_page { # ... } sub end_content { # ... }
This approach seems to model the 'quick' migration from static CGI to mod_perl-based CGI. The second approach I've seen is something like:
sub init { use strict; use warnings; use diagnostics; use HTTP::Module; use Some::Module; } sub print_header { my $query = new CGI; %vars = $query->Vars(); # ... } sub top_of_page { # ... } sub middle_of_page { # ... my ($dbuser, # database username $dbpass, # password for db $dbhost, # host for the database $dbport, # db connection port $dbname, # name of the database used $dbh, # DBI handle ); $dbuser = 'nobody'; $dbpass = 'NobodyPassword'; $dbport = '3306'; $dbhost = 'localhost'; $dbh = DBI->connect('DBI:mysql:$dbname:$dbhost:$dbport' +, $dbuser, $dbpass, {RaiseError => 1}); } sub left_content { if (!$vars{action} || $vars{action} eq "home") { # print the generic left content here } # ... } sub right_content { if (!$vars{action} || $vars{action} eq "home") { # print the generic right content here } # ... } sub bottom_of_page { # ... } sub end_content { # ... }
The second approach is the 'top-down' approach, where all the subroutines are executed in sequential order, not called from the top. This requires that the 'logic' be inside each sub, instead of a 'decision-tree' at the top to determine when to execute a sub or not.
I recognize that the first approach is going to throw more warnings from mod_perl because this is all wrapped in a subroutine under Apache::Registry, but in the latter case, there is increased redundancy/points of failure. I'm trying to figure out why (in my case) variables hold their value across requests, and this may help me solve that.
In designing this type of website, is it preferable to restrict as many globals as possible? Or compartmentalize them at the top, reducing redundancy, but increasing the "caching" factor of globals? One example of this is a simple my $dbh = DBI->connect definition to declare $dbuser, $dbpass, $dbport and so on. If that is global, all subs can use it, if it's local, it must be replicated in each sub that uses it.
I'm curious to see what the various implications of using each approach is. In my problem code, everything is local, except the module calls and the initialization of things like $dbh and friends, and I still have a problem with "caching" of those locals and variables retaining their values. I think it may have something to do with using 'Design 1' above, and not 'Design 2'.
Comments?
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: mod_perl with Apache::Registry with CGI.pm design considerations
by perrin (Chancellor) on Jun 13, 2002 at 20:11 UTC | |
Re: mod_perl with Apache::Registry with CGI.pm design considerations
by dsheroh (Monsignor) on Jun 14, 2002 at 18:41 UTC | |
Re: mod_perl with Apache::Registry with CGI.pm design considerations
by BigJoe (Curate) on Jun 14, 2002 at 12:42 UTC | |
by hacker (Priest) on Jun 14, 2002 at 14:03 UTC | |
by Anonymous Monk on Nov 13, 2002 at 14:11 UTC | |
by perrin (Chancellor) on Jun 14, 2002 at 14:32 UTC |