Tải bản đầy đủ (.pdf) (72 trang)

Perl in a Nutshell phần 8 potx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (6.47 MB, 72 trang )

Chapter 10
The CGI.pm Module

10.5 Using JavaScript Features
CGI.pm supports JavaScript scripting by allowing you to embed a JavaScript script into the HTML form
within <SCRIPT> tags, and then calling the script using the -script parameter to the start_html
method. You can then call the JavaScript functions as appropriate to the form elements.
10.4 Named Parameters 10.6 Debugging
[ Library Home | Perl in a Nutshell | Learning Perl | Learning Perl on Win32 | Programming Perl | Advanced Perl
Programming | Perl Cookbook ]
[Chapter 10] 10.5 Using JavaScript Features
[2/7/2001 10:35:34 PM]
Chapter 10
The CGI.pm Module

10.6 Debugging
A complication of writing CGI scripts is that when debugging the script, you have to wrestle with the
web server environment. CGI.pm provides support for debugging the script on the command line.
If you run the script on the command line without arguments, you will be placed into an "offline" mode,
in which name-value pairs can be entered one-by-one. When you press CTRL-D, the script runs. For
example:
% birthday
(offline mode: enter name=value pairs on standard input)
birthday=6/4/65
^D
Content-type: text/html
<P>Your birthday is 6/4/65.</P>
You can also supply the name/value parameters directly on the command line. For example:
% test birthday=6/4/65
Content-type: text/html
<P>Your birthday is 6/4/65.</P>


Multiple values can be separated by spaces (as separate arguments on the command line) or by
ampersands (as in URL-encoded syntax). In fact, you can use URL-encoded syntax on the command line.
This makes it easy to supply raw CGI input to the script for testing purposes. Just remember to protect
the ampersand from the shell.
% test 'birthday=6%2f4%2f65&name=Fred%20Flintstone'
Content-type: text/html
<P>Fred Flintstone, your birthday is 6/4/65.</P>
10.5 Using JavaScript
Features
10.7 CGI.pm Reference
[Chapter 10] 10.6 Debugging
(1 of 2) [2/7/2001 10:35:36 PM]
[ Library Home | Perl in a Nutshell | Learning Perl | Learning Perl on Win32 | Programming Perl | Advanced Perl
Programming | Perl Cookbook ]
[Chapter 10] 10.6 Debugging
(2 of 2) [2/7/2001 10:35:36 PM]
Chapter 10
The CGI.pm Module

10.7 CGI.pm Reference
The following methods are supported by CGI.pm:
accept●
append●
auth_type●
autoEscape●
button●
checkbox●
checkbox_group●
cookie●
defaults●

delete●
delete_all●
dump●
end_html●
filefield●
header●
hidden●
image_button●
import_names●
isindex●
keywords●
nph●
param●
password_field●
[Chapter 10] 10.7 CGI.pm Reference
(1 of 2) [2/7/2001 10:35:40 PM]
path_info●
path_translated●
popup_menu●
radio_group●
raw_cookie●
ReadParse●
redirect●
referer●
remote_host●
remote_user●
request_method●
reset●
save●
script_name●

scrolling_list●
self_url●
start_html●
startform●
start_multipart_form●
submit●
textarea●
textfield●
url●
use_named_parameters●
user_agent●
user_name●
10.6 Debugging 11. Web Server Programming
with mod_perl
[ Library Home | Perl in a Nutshell | Learning Perl | Learning Perl on Win32 | Programming Perl | Advanced Perl
Programming | Perl Cookbook ]
[Chapter 10] 10.7 CGI.pm Reference
(2 of 2) [2/7/2001 10:35:40 PM]
Chapter 11

11. Web Server Programming with
mod_perl
Contents:
Design of mod_perl
Installing mod_perl
mod_perl Handlers
Running CGI Scripts with mod_perl
Server-Side Includes with mod_perl
<Perl> Sections
Apache:: Modules

A common criticism of CGI is that it requires forking extra processes each time a script is executed. If
you only have a few hits an hour, or even a few hits a minute, this isn't a big deal. But for a high-traffic
site, lots of CGI scripts repeatedly spawning can have an unfortunate effect on the machine running the
web server. The CGI scripts will be slow, the web server will be slow, and other processes on the
machine will come to a crawl.
The solution to this problem is mod_perl. mod_perl, written by Doug MacEachern and distributed under
CPAN, embeds the Perl interpreter directly into the web server. The effect is that your CGI scripts are
precompiled by the server and executed without forking, thus running much more quickly and efficiently.
Furthermore, CGI efficiency is only one facet of mod_perl. Since mod_perl is a complete Apache/Perl
hybrid, other benefits to mod_perl include:
Writing server-side includes in Perl●
Embedding Perl code into the Apache configuration files●
Writing complete Apache modules in Perl●
[Chapter 11] Web Server Programming with mod_perl
(1 of 2) [2/7/2001 10:35:41 PM]
11.1 Design of mod_perl
mod_perl is not a Perl module. It is a module of the Apache server, which is currently the most
commonly used web server. With mod_perl, you can use Apache configuration directives not only to
process CGI scripts much more efficiently, but also to handle all stages in processing a server request.
mod_perl embeds a copy of the Perl interpreter into the Apache httpd executable, providing complete
access to Perl functionality within Apache. This enables a set of mod_perl-specific configuration
directives, all of which start with the string Perl*. Most of these directives are used to specify handlers
for various stages of the request, but not all. In addition, mod_perl lets you embed Perl code into your
Apache configuration files (within <Perl> </Perl> directives) and allows you to use Perl for
server-side includes.
It might occur to you that sticking a large program into another large program makes a very, very large
program. mod_perl certainly makes httpd significantly bigger. If you have limited memory capacity,
mod_perl may not be for you. There are several ways to minimize the size of Apache with mod_perl
(which you can find in the mod_perl manpage or the FAQs), ranging from fiddling with Apache
configuration directives to building Perl with reduced memory consumption.

10.7 CGI.pm Reference 11.2 Installing mod_perl
[ Library Home | Perl in a Nutshell | Learning Perl | Learning Perl on Win32 | Programming Perl | Advanced Perl
Programming | Perl Cookbook ]
[Chapter 11] Web Server Programming with mod_perl
(2 of 2) [2/7/2001 10:35:41 PM]
Chapter 11
Web Server Programming with
mod_perl

11.2 Installing mod_perl
If you already have Apache installed on your machine, you will have to rebuild it with mod_perl. You
can get the source for both Apache and mod_perl from (You can also get
mod_perl from CPAN.) If there isn't already an Apache httpd in the Apache source tree, you must build
one. Then build mod_perl as directed in the INSTALL file for the mod_perl distribution.
As we've mentioned, mod_perl allows you to hook in Perl modules as handlers for various stages of a
request. By default, however, the only callback hook that is enabled is PerlHandler, which is the one
used to process content (i.e., a CGI document). If you want to use other hooks, for example to extend
Apache's logging facilities via the PerlLogHandler directive, you'll need to specify it at build time as
directed in the INSTALL file. For example:
% perl Makefile.PL PERL_LOG=1
The mod_perl Makefile replaces the httpd in the Apache source tree with a Perl-enabled one. When you
install mod_perl, it not only installs the new httpd into your system area, it also installs several Perl
modules including Apache::Registry.
At the time of this writing, both Apache and mod_perl are being ported to Win32. However, mod_perl
will only run with the standard Perl Win32 port (not ActiveState's). The INSTALL.win32 file contains the
instructions for installing mod_perl under Win32.
11.1 Design of mod_perl 11.3 mod_perl Handlers
[ Library Home | Perl in a Nutshell | Learning Perl | Learning Perl on Win32 | Programming Perl | Advanced Perl
Programming | Perl Cookbook ]
[Chapter 11] 11.2 Installing mod_perl

[2/7/2001 10:35:42 PM]
Chapter 11
Web Server Programming with
mod_perl

11.3 mod_perl Handlers
To understand mod_perl, you should understand how the Apache server works. When Apache receives a
request, it processes it in several stages. First, it translates the URL to the associated resource (i.e.,
filename, CGI script, etc.) on the server machine. Then it checks to see if the user is authorized to access
that resource, perhaps by requesting and checking an ID and password. Once the user has passed
inspection, the server figures out what kind of data it's sending back (e.g., it decides a file ending in .html
is probably a text/html file), creates some headers, and sends those headers back to the client with
the resource itself. When all is said and done, the server makes a log entry.
At each stage of this process, Apache looks for routines to "handle" the request. Apache supplies its own
handlers; for example, one of the default handlers is cgi-script, often seen applied to /cgi-bin:
<Location /cgi-bin>

SetHandler cgi-script

</Location\>
mod_perl allows you to write your own handlers in Perl, by embedding the Perl runtime library directly
into the Apache httpd server executable. To use mod_perl for CGI (which is all that most people want to
do with it), you assign the SetHandler directive to perl-script, and then assign the
mod_perl-specific PerlHandler directive to a special Perl module called Apache::Registry.
SetHandler perl-script
PerlHandler Apache::Registry
PerlHandler is the mod_perl handler for the content retrieval stage of the transaction.
To use other handlers, you don't need to reassign SetHandler. For example, to identify a handler for
the logging stage of the request:
<Location /snoop/>

PerlLogHandler Apache::DumpHeaders
</Location\>
In order for this to work, mod_perl must have been built with the logging hooks enabled (as described in
the previous section), and the Apache::DumpHeaders module must have been installed. mod_perl looks
in Apache::DumpHeaders for a routine called handler() and executes it as the logging handler for
[Chapter 11] 11.3 mod_perl Handlers
(1 of 2) [2/7/2001 10:35:44 PM]
that resource.
The following is a list of each of the handler directives that can be enabled by mod_perl, and the stages
that each is used for. Only PerlHandler is enabled by default.
Handler Purpose
PerlAccessHandler
Access stage
PerlAuthenHandler
Authentication stage
PerlAuthzHandler
Authorization stage
PerlChildInitHandler
Child initialization stage
PerlChildExitHandler
Child termination stage
PerlCleanupHandler
Cleanup stage
PerlFixupHandler
Fixup stage
PerlHandler
Response stage
PerlHeaderParserHandler
Header-parsing stage
PerlInitHandler

Initialization
PerlLogHandler
Logging stage
PerlPostReadRequestHandler
Post-request stage
PerlTransHandler
Translation stage
PerlTypeHandler
Type-handling stage
You can write your own handlers for each of these stages. But there are also dozens of modules that you
can download from CPAN, some of which are listed at the end of this chapter.
11.2 Installing mod_perl 11.4 Running CGI Scripts
with mod_perl
[ Library Home | Perl in a Nutshell | Learning Perl | Learning Perl on Win32 | Programming Perl | Advanced Perl
Programming | Perl Cookbook ]
[Chapter 11] 11.3 mod_perl Handlers
(2 of 2) [2/7/2001 10:35:44 PM]
Chapter 11
Web Server Programming with
mod_perl

11.4 Running CGI Scripts with mod_perl
What most people want to do with mod_perl is improve CGI performance. The mod_perl installation
assumes this request by enabling the PerlHandler callback hook by default, and by installing the
Apache::Registry module. PerlHandler is the handler used for the content retrieval stage of the
server transaction. Apache::Registry is the Perl module that emulates the CGI environment so you can
use "standard" Perl CGI scripts with mod_perl without having to rewrite them (much). This is by far the
cheapest way to get improved CGI performance.
With Apache::Registry, each individual CGI program is compiled and cached the first time it is called (or
whenever it is changed), and then remains available for all subsequent instances of that CGI script. This

process avoids the costs of startup time.
Whereas most CGI scripts are kept in /cgi-bin/, scripts that use Apache::Registry are placed in a separate
directory, e.g., /perl-bin/. The access.conf Apache configuration file needs to point to this directory by
setting an alias and defining a handler for this new location.
Alias /perl-bin/ /usr/local/apache/perl-bin/
<Location /perl-bin>
SetHandler perl-script
PerlHandler Apache::Registry
PerlSendHeader On
Options ExecCGI
</Location>
Instead of using the cgi-script handler, we use the perl-script handler to give control to
mod_perl. Next, the PerlHandler directive tells mod_perl that the Apache::Registry module should
be used for serving all files in that directory. PerlSendHeader is another mod_perl-specific directive;
in this case, it tells mod_perl to send response lines and common headers - by default, none are sent. (For
NPH scripts, you'll want to turn this feature off again.) Options ExecCGI is a standard Apache
header needed to tell Apache to treat the script as a CGI script.
If you want to load Perl modules in addition to Apache::Registry, you can use the PerlModule directive:
PerlModule CGI
[Chapter 11] 11.4 Running CGI Scripts with mod_perl
(1 of 2) [2/7/2001 10:35:46 PM]
If you include this line, you shouldn't need to explicitly use CGI in each Perl CGI script anymore, as
CGI.pm will be loaded directly from the Apache server. Up to ten modules can be listed with the
PerlModule directive.
CGI scripts in the new directory should work now. However, if you have problems, the mod_perl
manpage offers some words of wisdom:
Always use strict.
"Standard" CGI scripts start with a clean slate every time. When switching to mod_perl, CGI
programmers are often surprised to learn how often they take advantage of this fact. use
strict tells you when your variables haven't been properly declared and might inherit values

from previous invocations of the script.

Don't call exit().
Calling exit() at the end of every program is a habit of many programmers. While often totally
unnecessary, it usually doesn't hurt except with mod_perl. If you're using mod_perl without
Apache::Registry, exit() kills the server process. If exit() is the last function call, you can
just remove it. If the structure of your program is such that it is called from the middle of the
script, you can just put a label at the end of the script and use goto(). There's also an
Apache->exit() call you can use if you're really attached to exit()s.
If you're using Apache::Registry, you don't have to worry about this problem. Apache::Registry is
smart enough to override all exit() calls with Apache->exit().

In addition, it is recommended that you should use a recent version of Perl and of CGI.pm. You should
scan the mod_perl documentation for the very latest compatibility news.
11.3 mod_perl Handlers 11.5 Server-Side Includes
with mod_perl
[ Library Home | Perl in a Nutshell | Learning Perl | Learning Perl on Win32 | Programming Perl | Advanced Perl
Programming | Perl Cookbook ]
[Chapter 11] 11.4 Running CGI Scripts with mod_perl
(2 of 2) [2/7/2001 10:35:46 PM]
Chapter 11
Web Server Programming with
mod_perl

11.5 Server-Side Includes with mod_perl
Server-side includes (SSI) are tags embedded directly into an HTML file that perform special functions.
They are most commonly used for running CGI scripts and displaying the result; most web page counters
are performed using SSI.
If you use mod_perl with mod_include (another Apache server module), you can embed Perl subroutines
into SSI directives. For example:

The Apache::Include module lets you include entire Apache::Registry scripts:
You could have used standard SSI to include a CGI script for the same purpose, but this way is faster. To
use mod_include with mod_perl, you need to configure mod_perl to do so at compile time.
11.4 Running CGI Scripts
with mod_perl
11.6 <Perl> Sections
[ Library Home | Perl in a Nutshell | Learning Perl | Learning Perl on Win32 | Programming Perl | Advanced Perl
Programming | Perl Cookbook ]
[Chapter 11] 11.5 Server-Side Includes with mod_perl
[2/7/2001 10:35:49 PM]
Chapter 11
Web Server Programming with
mod_perl

11.6 <Perl> Sections
With mod_perl, you can use Perl in Apache configuration files. What this means is that you can make
your Apache configuration much more flexible by using conditionals.
Any Perl code in Apache configuration files should be placed between <Perl> and </Perl>
directives. This code can define variables and lists that are used by mod_perl to assign the associated
Apache configuration directives; for example, assigning the $ServerAdmin variable will redefine the
ServerAdmin Apache configuration directive.
Suppose you share the same Apache configuration files across multiple servers, and you only want to
allow personal directories on one of them. You can use Perl directives like this:
<Perl>
if (`hostname` =~ /public/) {
$UserDir = "public.html";
} else {
$UserDir = "DISABLED";
}
1;

</Perl>
Directive blocks (such as <Location> </Location\>) can be represented as a hash. For
example:
<Perl>
$Location{"/design_dept/"} = {
DefaultType => 'image/gif',
FancyIndexing => 'On'
}
</Perl>
11.5 Server-Side Includes
with mod_perl
11.7 Apache:: Modules
[Chapter 11] 11.6 <Perl> Sections
(1 of 2) [2/7/2001 10:35:50 PM]
[ Library Home | Perl in a Nutshell | Learning Perl | Learning Perl on Win32 | Programming Perl | Advanced Perl
Programming | Perl Cookbook ]
[Chapter 11] 11.6 <Perl> Sections
(2 of 2) [2/7/2001 10:35:50 PM]
Chapter 11
Web Server Programming with
mod_perl

11.7 Apache:: Modules
Apache::Registry is the most commonly used mod_perl module. But there are many more, all available
on CPAN. The following table lists the Apache::* modules and which handler they're designed to be
used with, but you should also check the apache-modlist.html file on CPAN for the very latest listing.
PerlHandler
Apache::CallHandler Maps filenames to subroutine calls
Apache::Dir Controls directory indexing
Apache::Embperl Embeds Perl code in HTML files

Apache::ePerl Embedded Perl (ePerl) emulation
Apache::FTP Emulates an FTP proxy
Apache::GzipChain Compresses output from another handler
Apache::JavaScript Generates JavaScript code
Apache::OutputChain Chains multiple handlers via "filter" modules
Apache::PassFile Sends files via OutputChain
Apache::Registry Runs unaltered CGI scripts
Apache::RobotRules Enforces robots.txt rules
Apache::Sandwich Adds per-directory headers and footers
Apache::VhostSandwich Adds headers and footers for virtual hosts
Apache::SSI Implements server-side includes in Perl
Apache::Stage Manages a document staging directory
Apache::WDB Queries databases via DBI
PerlHeaderParserHandler
Apache::AgentDeny Denies abusive clients
[Chapter 11] 11.7 Apache:: Modules
(1 of 4) [2/7/2001 10:35:55 PM]
PerlAuthenHandler
Apache::Authen Authenticates users
Apache::AuthCookie Authenticates and authorizes users via cookies
Apache::AuthenDBI Authenticates via Perl's DBI
Apache::AuthExpire Expires authentication credentials
Apache::AuthenGSS Authenticates users with Generic Security Service
Apache::AuthenLDAP Authenticates users with LDAP
Apache::AuthNIS Authenticates users with NIS
Apache::BasicCookieAuth Accepts cookie or basic authentication credentials
Apache::DBILogin Authenticates using a backend database
Apache::DCELogin Authenticates within a DCE login context
Apache::AuthAny Authenticates with any username/password
PerlAuthzHandler

Apache::AuthCookie Authenticates and authorizes via cookies
Apache::AuthzAge Authorizes based on age
Apache::AuthzDCE Authorizes based on DFS/DCE ACL
Apache::AuthzDBI Authorizes groups via DBI
Apache::AuthNIS Authenticates and authorizes via NIS
Apache::RoleAuthz Role-based authorization
PerlAccessHandler
Apache::AccessLimitNum Limits user access by the number of requests
Apache::DayLimit Limits access based on the day of the week
Apache::RobotLimit Limits access of robots
PerlTypeHandler
Apache::AcceptLanguage Sends file types based on user's language preference
PerlTransHandler
Apache::DynaRPC Translates URIs into RPCs
Apache::Junction Mounts remote web server namespace
Apache::LowerCaseGETs Translates to lowercase URIs as needed
Apache::MsqlProxy Translates URIs into mSQL queries
Apache::ProxyPassThru Skeleton for vanilla proxy
Apache::ProxyCache Caching proxy
[Chapter 11] 11.7 Apache:: Modules
(2 of 4) [2/7/2001 10:35:55 PM]
PerlFixupHandler
Apache::HttpEquiv Converts HTML HTTP-EQUIV tags to HTTP headers
Apache::Timeit Benchmarks Perl handlers
PerlLogHandler
Apache::DumpHeaders Displays HTTP transaction headers
Apache::Traffic Logs the number of bytes transferred on a per-user basis
Apache::WatchDog Looks for problematic URIs
PerlChildInitHandler
Apache::Resource Limits resources used by httpd children

Server Configuration
Apache::ConfigLDAP
Configures server via LDAP and <Perl> sections
Apache::ConfigDBI
Configures server via DBI and <Perl> sections
Apache::ModuleConfig Interfaces to configuration API
Apache::PerlSections
Utilities for <Perl> sections
Apache::httpd_conf Methods to configure and run an httpd
Apache::src Methods for finding and reading bits of source
Database
Apache::DBI Manages persistent DBI connections.
Apache::Sybase Manages persistent DBlib connections.
Apache::Mysql Manages persistent mysql connections.
Interfaces and Integration with Various Apache C Modules
Apache::Constants Constants defined in httpd.h
Apache::Include Enables use of Apache::Registry scripts within SSI with mod_include
Apache::Global Gives access to server global variables
Apache::LogError Gives an interface to aplog_error
Apache::LogFile Gives an interface to Apache's piped logs, etc.
Apache::Mime Gives an interface to mod_mime functionality
Apache::Module Gives an interface to Apache C module structures
Apache::Options Imports Apache::Constants "options"
Apache::Scoreboard Gives an interface to scoreboard API
Apache::Servlet Gives an interface to the Java Servlet engine
[Chapter 11] 11.7 Apache:: Modules
(3 of 4) [2/7/2001 10:35:55 PM]
Apache::Sfio
Gives an interface to r->connection->client->sf*
Development and Debug Tools

Apache::Debug Provides debugging utilities to mod_perl
Apache::DProf Hooks Devel::DProf into mod_perl
Apache::FakeRequest Implements Apache methods offline
Apache::Peek Emulates Devel::Peek for mod_perl
Apache::SawAmpersand
Makes sure no one is using $&, $', or $`
Apache::StatINC
Reloads files that are used or required files when updated
Apache::Status Gets information about loaded modules
Apache::Symbol Supports symbols
Apache::test Defines handy routines for make test scripts
Miscellaneous
Apache::Byterun Runs Perl bytecode modules
Apache::Mmap Shares data via Mmap module
Apache::Persistent Stores data via IPC::, DBI, or disk
Apache::PUT Handler for the HTTP PUT method
Apache::RegistryLoader Apache::Registry startup script loader
Apache::Safe Adaptation of safecgiperl
Apache::Session Maintains client <-> httpd session/state
Apache::SIG Signal handlers for mod_perl
Apache::State Powerful state engine
11.6 <Perl> Sections V. Databases
[ Library Home | Perl in a Nutshell | Learning Perl | Learning Perl on Win32 | Programming Perl | Advanced Perl
Programming | Perl Cookbook ]
[Chapter 11] 11.7 Apache:: Modules
(4 of 4) [2/7/2001 10:35:55 PM]
Part V

Part V: Databases
Chapter 12: Databases and Perl

11.7 Apache:: Modules 12. Databases and Perl
[ Library Home | Perl in a Nutshell | Learning Perl | Learning Perl on Win32 | Programming Perl | Advanced Perl
Programming | Perl Cookbook ]
[Part V] Databases
[2/7/2001 10:35:56 PM]
Chapter 12

12. Databases and Perl
Contents:
DBM Databases and DBM Hashes
Design of DBI
DBI Methods
DBI Environment Variables
Since one of Perl's greatest strengths is working with text, a genuine concern is how to store data. Flat files
are one possibility, but don't scale very well, to say the least. Instead, you'll need to use a database.
There are two general solutions to using databases with Perl. For simple database purposes, DBM (Database
Management) will serve your needs. DBM is a library supported by many (if not all) Unix systems and many
non-Unix systems as well. If you use DBM with Perl, you can manipulate databases just like any hash.
For more elaborate databases with SQL interfaces, you can get a complete database product or shareware
equivalent (depending on your needs) and use DBI and DBD. DBI is a module that provides a consistent
interface for database solutions. A DBD is a database-specific driver that translates DBI calls as needed for
that database.
In this chapter, we'll quickly cover DBM and then talk more at length about DBI/DBD.
12.1 DBM Databases and DBM Hashes
DBM is a simple database management facility for Unix systems. It allows programs to store a collection of
key-value pairs in binary form, thus providing rudimentary database support for Perl. Practically all Unix
systems support DBM, and for those that don't, you can get Berkeley DB from />To use DBM databases in Perl, you can associate a hash with a DBM database through a process similar to
opening a file. This hash (called a DBM array) is then used to access and modify the DBM database. To
associate a DBM database with a DBM array, you can use either the dbmopen function or the tie function
with a DBM-style module. (dbmopen is actually just a front-end to tie.) For example, with dbmopen:

dbmopen(%ARRAYNAME, "dbmfilename", $mode);
or (using tie with the DB_File module):
use DB_File;
tie(%ARRAYNAME, "DB_File", "dbmfilename");
[Chapter 12] Databases and Perl
(1 of 2) [2/7/2001 10:35:59 PM]
The %ARRAYNAME parameter is a Perl hash. (If it already has values, the values are discarded.) This hash
becomes connected to the DBM database called dbmfilename. This database may be stored on disk as a
single file, or as two files called dbmfilename.dir and dbmfilename.pag, depending on the DBM
implementation.
The $mode parameter is a number that controls the permissions of the pair of files if the files need to be
created. The number is typically specified in octal. If the files already exist, this parameter has no effect. For
example:
dbmopen(%BOOKS, "bookdb", 0666); # open %BOOKS onto bookdb
This invocation associates the hash %BOOKS with the disk files bookdb.dir and bookdb.pag in the current
directory. If the files don't already exist, they are created with a mode of 0666, modified by the current
umask.
The return value from dbmopen is true if the database could be opened or created, and false otherwise, just
like the open function. If you don't want the files created, use a $mode value of undef.
Once the database is opened, anything you do to the DBM hash is immediately written to the database. See
Chapter 4, The Perl Language, for more information on hashes.
dbmopen(%BOOKS, "bookdb", 0666) || die "Can't open database bookdb!";
$BOOKS{"1-56592-286-7"} = "Perl in a Nutshell";
The DBM array stays open throughout the program. When the program termi- nates, the association is
terminated. You can also break the association in a manner similar to closing a filehandle, by using the
dbmclose function (or untie if you used tie). See Chapter 5, Function Reference, for more information
on dbmclose, dbmopen, and tie.
V. Databases 12.2 Design of DBI
[ Library Home | Perl in a Nutshell | Learning Perl | Learning Perl on Win32 | Programming Perl | Advanced Perl Programming
| Perl Cookbook ]

[Chapter 12] Databases and Perl
(2 of 2) [2/7/2001 10:35:59 PM]
Chapter 12
Databases and Perl

12.2 Design of DBI
If DBM is too primitive for your database requirements, you'll have to use a more sophisticated database
package. Options include the commercial products Oracle, Sybase, and Informix, and the
publically-available msql and mysql.
Prior to Perl Version 5 and DBI, the problem was that with all the database packages to choose from,
there was no way to universalize database support for Perl. You'd have to rebuild the Perl executable
itself against libraries that included subroutines for direct access to the database package. For example,
sybperl and oraperl are both packages for building Perl Version 4 with Sybase and Oracle calls
embedded, respectively. An application written for sybperl would not be portable to Oracle, or
vice-versa. However, since current versions of Perl support binary extension loading at runtime, database
support can now be added at runtime, which simplifies adding database interfaces to Perl programs while
keeping the size of the Perl binary to a minimum.
Support for binary extensions doesn't mean that database access has been standardized. There are still
many database extensions to Perl, each with a different API. However, they all share a strikingly similar
set of commands: connect to the database, issue queries, fetch results, and disconnect. This consistency
has made it possible to develop a standard set of methods to work with any database. DBI defines a set of
functions, variables, and conventions that provide a consistent database programming interface for Perl.
Although DBI itself is language-independent, most DBI drivers require applications to use a dialect of
SQL (structured query language) to interact with the database engine. SQL is a standard that was
developed to allow programmers to manipulate relational databases. There are many implementations of
SQL, and each database server adds nuances that deviate from the standard.
12.2.1 Database Drivers (DBDs)
The success of DBI is that it is only half of the story. The other half is a DBD, or a database driver. DBI
provides the interface and framework for the drivers, but it's the database drivers that do the real work.
Drivers implement the DBI methods for the private interface functions of the corresponding database

engine.
Unless you're developing a sophisticated database application, you probably don't care about the drivers
except that you want to install the correct one. Table 12.1 lists database servers, where you can find
them, and the DBD driver designed for it. (The freeware or shareware database servers are available for
[Chapter 12] 12.2 Design of DBI
(1 of 4) [2/7/2001 10:36:03 PM]
download, and some of the commercial servers offer evaluation copies for download.)
Table 12.1: Database Servers
Server URL DBD
DB2 DBD::DB2
Empress DBD::Empress
Fulcrum DBD::Fulcrum
Informix DBD::Informix
Ingres />:8000/postgres/index.html DBD::Ingres
miniSQL DBD::mSQL
MySQL DBD::mysql
Oracle DBD::Oracle
PostgreSQL DBD::Pg
QuickBase DBD::QBase
Solid DBD::Solid
Sybase DBD::Sybase
12.2.2 Creating a Database
Before you can open a connection to a database with DBI, you must create the database. DBI isn't able to
do this step for you, although your DBD might allow you to. For example, DBD:mSQL provides a
msqladmin function. Your DBD might also support the func method, which is used to call private
(and often non-portable) methods in the driver. You could use a one-liner like this to create the database
from the command line:
perl -MDBI -e '$db_name = q[database_name_here]; \
$result = DBD::mysql::dr->func($db_name, '_CreateDB');'
If your DBD allows to you to create databases via the API, it's likely that it will allow you to drop them,

too.
perl -MDBI -e '$db_name = q[database_name_here]; \
$result = DBD::mysql::dr->func($db_name, '_DropDB');'
[Chapter 12] 12.2 Design of DBI
(2 of 4) [2/7/2001 10:36:03 PM]
12.2.3 Database Handles and Statement Handles
DBI methods work on two different types of handles: database handles and statement handles. A
database handle is like a filehandle: connect is a DBI class method that opens a connection to a
database and returns a database handle object.
$db_handle = DBI->connect(dbi:mSQL:bookdb, undef, undef)
|| die("Connect error: $DBI::errstr");
Statement handles are another thing entirely. DBI makes a distinction between the preparation of SQL
statements and their execution, by allowing you to pre-format a statement into a statement handle. You
can prepare a statement with the prepare method, which returns a statement handle. You can then
assign a SQL statement to the statement handle via various statement handle methods, and execute it
with the execute method when you're done. (You can also prepare and execute in the same command
with the do method.)
Changes to the database are written to the database automatically if the AutoCommit attribute is turned
on. If AutoCommit is off, then use the commit method when you're ready to write the changes to the
database.
AutoCommit is only one of many attributes that can be set for both database and statement handles. For
example, if $st_handle is a statement handle, then you can set $st_handle->{NULLABLE} to
determine if the fields can contain null characters. Table 12.2 is a listing of all the attributes supported by
database handles, statement handles, or both.
Table 12.2: Attributes for Database and Statement Handles
Attributes for database handles
AutoCommit Commit any changes to the database immediately, instead of waiting for an
explicit call to commit. Default is true.
Attributes for statement handles
CursorName The name of the cursor associated with the statement handle.

NAME A reference to an array of field names.
NULLABLE A reference to an array describing whether each field can contain a null
character.
NUM_OF_FIELDS Number of fields the prepared statement will return.
NUM_OF_PARAMS Number of placeholders in the prepared statement.
Attributes common to all handles
Warn Enables warnings.
CompatMode Enables compatible behavior for a specific driver.
InactiveDestroy Destroying a handle does not close prepared statements or disconnect from the
database.
[Chapter 12] 12.2 Design of DBI
(3 of 4) [2/7/2001 10:36:03 PM]

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×