Chapter 11 Web Server Programming withAs we've mentioned, mod_perl allows you to hook in Perl modules as handlers for various stages of a request.. Apache::Registry is the Perl module th
Trang 1Chapter 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 formwithin <SCRIPT> tags, and then calling the script using the -script parameter to the start_htmlmethod You can then call the JavaScript functions as appropriate to the form elements
[ 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
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch10_05.htm [2/7/2001 10:35:34 PM]
Trang 2Chapter 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 theweb 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 Forexample:
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 protectthe ampersand from the shell
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch10_06.htm (1 of 2) [2/7/2001 10:35:36 PM]
Trang 3[ Library Home | Perl in a Nutshell | Learning Perl | Learning Perl on Win32 | Programming Perl | Advanced Perl Programming | Perl Cookbook ]
[Chapter 10] 10.6 Debugging
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch10_06.htm (2 of 2) [2/7/2001 10:35:36 PM]
Trang 4Chapter 10 The CGI.pm Module
Trang 6Running 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 Ifyou only have a few hits an hour, or even a few hits a minute, this isn't a big deal But for a high-trafficsite, lots of CGI scripts repeatedly spawning can have an unfortunate effect on the machine running theweb 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 areprecompiled 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
Trang 711.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 forserver-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
[ 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
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch11_01.htm (2 of 2) [2/7/2001 10:35:41 PM]
Trang 8Chapter 11 Web Server Programming with
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 oneused to process content (i.e., a CGI document) If you want to use other hooks, for example to extendApache'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.
[ 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
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch11_02.htm [2/7/2001 10:35:42 PM]
Trang 9Chapter 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 accessthat 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 withthe 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 ownhandlers; for example, one of the default handlers is cgi-script, often seen applied to /cgi-bin:
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 forthe logging stage of the request:
Trang 10that 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
PerlAccessHandler Access stage
PerlAuthenHandler Authentication stage
PerlAuthzHandler Authorization stage
PerlChildInitHandler Child initialization stage
PerlChildExitHandler Child termination stage
PerlCleanupHandler Cleanup stage
PerlFixupHandler Fixup stage
PerlHeaderParserHandler Header-parsing stage
PerlInitHandler Initialization
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 youcan download from CPAN, some of which are listed at the end of this chapter
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
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch11_03.htm (2 of 2) [2/7/2001 10:35:44 PM]
Trang 11Chapter 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 theApache::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 (orwhenever it is changed), and then remains available for all subsequent instances of that CGI script Thisprocess 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/
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
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch11_04.htm (1 of 2) [2/7/2001 10:35:46 PM]
Trang 12If you include this line, you shouldn't need to explicitly use CGI in each Perl CGI script anymore, asCGI.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 valuesfrom 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 canjust remove it If the structure of your program is such that it is called from the middle of thescript, 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 issmart 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.
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
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch11_04.htm (2 of 2) [2/7/2001 10:35:46 PM]
Trang 13Chapter 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 countersare 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
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch11_05.htm [2/7/2001 10:35:49 PM]
Trang 14Chapter 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 theServerAdmin Apache configuration directive
Suppose you share the same Apache configuration files across multiple servers, and you only want toallow personal directories on one of them You can use Perl directives like this:
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch11_06.htm (1 of 2) [2/7/2001 10:35:50 PM]
Trang 15[ 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
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch11_06.htm (2 of 2) [2/7/2001 10:35:50 PM]
Trang 16Chapter 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::Embperl Embeds Perl code in HTML files
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
PerlHeaderParserHandler
Apache::AgentDeny Denies abusive clients
[Chapter 11] 11.7 Apache:: Modules
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch11_07.htm (1 of 4) [2/7/2001 10:35:55 PM]
Trang 17Apache::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::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
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch11_07.htm (2 of 4) [2/7/2001 10:35:55 PM]
Trang 18Apache::HttpEquiv Converts HTML HTTP-EQUIV tags to HTTP headers
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::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
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch11_07.htm (3 of 4) [2/7/2001 10:35:55 PM]
Trang 19Apache::Sfio Gives an interface to r->connection->client->sf*
Development and Debug Tools
Apache::Debug Provides debugging utilities to mod_perl
Apache::FakeRequest Implements Apache methods offline
Apache::SawAmpersand Makes sure no one is using $&, $', or $`
Apache::StatINC Reloads files that are used or required files when updatedApache::Status Gets information about loaded modules
Apache::test Defines handy routines for make test scripts
Miscellaneous
Apache::Byterun Runs Perl bytecode modules
Apache::Persistent Stores data via IPC::, DBI, or disk
Apache::RegistryLoader Apache::Registry startup script loader
Apache::Session Maintains client <-> httpd session/state
[ 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
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch11_07.htm (4 of 4) [2/7/2001 10:35:55 PM]
Trang 20Part V
Part V: Databases
Chapter 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
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/part05.htm [2/7/2001 10:35:56 PM]
Trang 21DBI Environment Variables
Since one of Perl's greatest strengths is working with text, a genuine concern is how to store data Flat filesare 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 (DatabaseManagement) will serve your needs DBM is a library supported by many (if not all) Unix systems and manynon-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 sharewareequivalent (depending on your needs) and use DBI and DBD DBI is a module that provides a consistentinterface for database solutions A DBD is a database-specific driver that translates DBI calls as needed forthat 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 ofkey-value pairs in binary form, thus providing rudimentary database support for Perl Practically all Unixsystems support DBM, and for those that don't, you can get Berkeley DB from http://www.sleepycat.com/db
To use DBM databases in Perl, you can associate a hash with a DBM database through a process similar toopening a file This hash (called a DBM array) is then used to access and modify the DBM database Toassociate a DBM database with a DBM array, you can use either the dbmopen function or the tie functionwith 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
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch12_01.htm (1 of 2) [2/7/2001 10:35:59 PM]
Trang 22The %ARRAYNAME parameter is a Perl hash (If it already has values, the values are discarded.) This hashbecomes 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 becreated The number is typically specified in octal If the files already exist, this parameter has no effect Forexample:
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, justlike 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
[ Library Home | Perl in a Nutshell | Learning Perl | Learning Perl on Win32 | Programming Perl | Advanced Perl Programming
| Perl Cookbook ]
[Chapter 12] Databases and Perl
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch12_01.htm (2 of 2) [2/7/2001 10:35:59 PM]
Trang 23Chapter 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 databasepackage 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 executableitself 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, databasesupport can now be added at runtime, which simplifies adding database interfaces to Perl programs whilekeeping the size of the Perl binary to a minimum
Support for binary extensions doesn't mean that database access has been standardized There are stillmany database extensions to Perl, each with a different API However, they all share a strikingly similarset of commands: connect to the database, issue queries, fetch results, and disconnect This consistencyhas made it possible to develop a standard set of methods to work with any database DBI defines a set offunctions, 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 ofSQL (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 ofSQL, 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 DBIprovides 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 databaseengine
Unless you're developing a sophisticated database application, you probably don't care about the driversexcept that you want to install the correct one Table 12.1 lists database servers, where you can findthem, and the DBD driver designed for it (The freeware or shareware database servers are available for[Chapter 12] 12.2 Design of DBI
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch12_02.htm (1 of 4) [2/7/2001 10:36:03 PM]
Trang 24download, and some of the commercial servers offer evaluation copies for download.)
Table 12.1: Database Servers
DB2 http://www.software.ibm.com/data/db2/ DBD::DB2
Ingres http://www.cai.com/products/ingres.htm
http://epoch.cs.berkeley.edu:8000/postgres/index.html DBD::Ingres
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 databasefrom 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
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch12_02.htm (2 of 4) [2/7/2001 10:36:03 PM]
Trang 2512.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 SQLstatements and their execution, by allowing you to pre-format a statement into a statement handle Youcan prepare a statement with the prepare method, which returns a statement handle You can thenassign a SQL statement to the statement handle via various statement handle methods, and execute itwith the execute method when you're done (You can also prepare and execute in the same commandwith 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 thedatabase
AutoCommit is only one of many attributes that can be set for both database and statement handles Forexample, if $st_handle is a statement handle, then you can set $st_handle->{NULLABLE} todetermine if the fields can contain null characters Table 12.2 is a listing of all the attributes supported bydatabase 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
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
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
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch12_02.htm (3 of 4) [2/7/2001 10:36:03 PM]
Trang 26PrintError Errors generate warnings.
RaiseError Errors raise exceptions
ChopBlanks Truncate trailing space characters in fixed-width character fields
LongReadLen Controls the maximum length of long data
LongTruncOk Controls whether fetching long data that has been truncated should fail
12.2.4 Placeholders database and statement handles
Many database drivers allow you to use question marks as placeholders in SQL statements, and then bindvalues to the placeholders before executing them This enables you to prepare a single statement withplaceholders and then reuse it for each row of the database For example, the prepare statement mightread:
$st_handle = $db_handle->prepare(q{
insert into books (isbn, title) values (?, ?)
}) || die db_handle->errstr;
And a subsequent execute statement might read:
$st_handle->execute("1-56592-286-7", "Perl in a Nutshell")
|| die $db_handle->errstr;
12.1 DBM Databases and
DBM Hashes
12.3 DBI Methods
[ Library Home | Perl in a Nutshell | Learning Perl | Learning Perl on Win32 | Programming Perl | Advanced Perl
Programming | Perl Cookbook ]
[Chapter 12] 12.2 Design of DBI
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch12_02.htm (4 of 4) [2/7/2001 10:36:03 PM]
Trang 27Chapter 12 Databases and Perl
Trang 29Chapter 12 Databases and Perl
12.4 DBI Environment Variables
The following environment variables are defined for use with DBI:
Appends trace information to the specified file; the trace level is set to 2
[ Library Home | Perl in a Nutshell | Learning Perl | Learning Perl on Win32 | Programming Perl | Advanced Perl
Programming | Perl Cookbook ]
[Chapter 12] 12.4 DBI Environment Variables
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch12_04.htm [2/7/2001 10:36:08 PM]
Trang 30Part VI
Part VI: Network Programming
Chapter 13: Sockets
Chapter 14: Email Connectivity
Chapter 15: Usenet News
Trang 31Chapter 13
13 Sockets
Contents:
Built-in Socket Functions
The IO::Socket Module
Why build networking functionality into your Perl scripts? You might want to access your email
remotely, or write a simple script that updates files on a FTP site You might want to check up on youremployees with a program that searches for Usenet postings that came from your site You might want tocheck a web site for any recent changes, or even write your own home-grown web server The network isthe computer these days, and Perl makes network applications easy
Perl programmers have their choice of modules for doing common tasks with network protocols; Chapter
14, Email Connectivity, through Chapter 17, The LWP Library, cover the modules for writing email,news, FTP, and web applications in Perl If you can do what you want with the available modules, you'reencouraged to jump to those chapters and skip this one However, there will be times that you'll have towrestle with sockets directly, and that's where this chapter comes in
Sockets are the underlying mechanism for networking on the Internet With sockets, one application (a
server) sits on a port waiting for connections Another application (the client) connects to that port and
says hello; then the client and server have a chat Their actual conversation is done with whatever
protocol they choose - for example, a web client and server would use HTTP, an email server would usePOP3 and SMTP, etc But at the most basic level, you might say that all network programming comesdown to opening a socket, reading and writing data, and closing the socket again
You can work with sockets in Perl at various levels At the lowest level, Perl's built-in functions includesocket routines similar to the system calls in C of the same name To make these routines easier to use,the Socket module in the standard library imports common definitions and constants specific to yoursystem's networking capabilities Finally, the IO::Socket module provides an object interface to the
socket functions through a standard set of methods and options for constructing both client and servercommunications programs
Sockets provide a connection between systems or applications They can be set up to handle streamingdata or discrete data packets Streaming data continually comes and goes over a connection A transportprotocol like TCP (Transmission Control Protocol) is used to process streaming data so that all of thedata is properly received and ordered Packet-oriented communication sends data across the network in[Chapter 13] Sockets
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch13_01.htm (1 of 5) [2/7/2001 10:36:15 PM]
Trang 32discrete chunks The message-oriented protocol UDP (User Datagram Protocol) works on this type ofconnection Although streaming sockets using TCP are widely used for applications, UDP sockets alsohave their uses.
Sockets exist in one of two address domains: the Internet domain and the Unix domain Sockets that areused for Internet connections require the careful binding and assignment of the proper type of addressdictated by the Internet Protocol (IP) These sockets are referred to as Internet-domain sockets
Sockets in the Unix domain create connections between applications either on the same machine orwithin a LAN The addressing scheme is less complicated, often just providing the name of the targetprocess
In Perl, sockets are attached to a filehandle after they have been created Communication over the
connection is then handled by standard Perl I/O functions
13.1 Built-in Socket Functions
Perl provides built-in support for sockets The following functions are defined specifically for socketprogramming For full descriptions and syntax, see Chapter 5, Function Reference
Writes data to a filehandle
shutdown (or close)
Terminates a network connection
Regular functions that read and write filehandles can also be used for sockets, i.e., write, print,printf, and the diamond input operator, <>
[Chapter 13] Sockets
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch13_01.htm (2 of 5) [2/7/2001 10:36:15 PM]
Trang 33The socket functions tend to use hard-coded values for some parameters, which severely hurt portability.Perl solves this problem with a module called Socket, included in the standard library Use this modulefor any socket applications that you build with the built-in functions (i.e., use Socket) The module
loads the socket.h header file, which enables the built-in functions to use the constants and names
specific to your system's network programming, as well as additional functions for dealing with addressand protocol names
The next few sections describe Perl socket programming using a combination of the built-in functionstogether with the Socket module After that, we describe the use of the IO::Socket module
use Socket;
socket(SH, PF_INET, SOCK_STREAM, getprotobyname('tcp')) || die $!;The PF_INET argument indicates that the socket will connect to addresses in the Internet domain (i.e.,
IP addresses) Sockets with a Unix domain address use PF_UNIX
Because this is a streaming connection using TCP, we specify SOCK_STREAM for the second argument.The alternative would be to specify SOCK_DGRAM for a packet-based UDP connection
The third argument indicates the protocol used for the connection Each protocol has a number assigned
to it by the system; that number is passed to socket as the third argument In the scalar context,
getprotobyname returns the protocol number
Finally, if the socket call fails, the program will die, printing the error message found in $!
13.1.2 Client Connections
On the client side, the next step is to make a connection with a server at a particular port and host To dothis, the client uses the connect call connect requires the socket filehandle as its first argument Thesecond argument is a data structure containing the port and hostname that together specify the address.The Socket package provides the sockaddr_in function to create this structure for Internet addressesand the sockaddr_un function for Unix domain addresses
The sockaddr_in function takes a port number for its first argument and a 32-bit IP address for thesecond argument The 32-bit address is formed from the inet_aton function found in the Socket
package This function takes either a hostname (e.g., www.oreilly.com) or a dotted-decimal string (e.g.,207.54.2.25), and it returns the corresponding 32-bit structure
Continuing with the previous example, a call to connect could look like this:
my $dest = sockaddr_in (80, inet_aton('www.oreilly.com'));
connect (SH, $dest) || die $!;
[Chapter 13] Sockets
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch13_01.htm (3 of 5) [2/7/2001 10:36:15 PM]
Trang 34This call attempts to establish a network connection to the specified server and port If successful, itreturns true Otherwise, it returns false and dies with the error in $!.
Assuming that the connect call has completed successfully and a connection has been established,there are a number of functions we can use to write to and read from the file handle For example, thesend function sends data to a socket:
socket(FH, PF_INET, SOCK_STREAM, $proto) || die $!;
The filehandle $FH is the generic filehandle for the socket This filehandle only receives requests fromclients; each specific connection is passed to a different filehandle by accept, where the rest of thecommunication occurs
A server-side socket must be bound to a port on the local machine by passing a port and an address datastructure to the bind function via sockaddr_in The Socket module provides identifiers for commonlocal addresses, such as localhost and the broadcast address Here we use INADDR_ANY, which allowsthe system to pick the appropriate address for the machine:
my $sin = sockaddr_in (80, INADDR_ANY);
bind (FH, $sin) || die $!;
The listen function tells the operating system that the server is ready to accept incoming networkconnections on the port The first argument is the socket filehandle The second argument gives a queuelength, in case multiple clients are connecting to the port at the same time This number indicates how[Chapter 13] Sockets
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch13_01.htm (4 of 5) [2/7/2001 10:36:15 PM]
Trang 35many clients can wait for an accept at one time.
listen (FH, $length);
The accept function completes a connection after a client requests and assigns a new filehandle
specific to that connection The new filehandle is given as the first argument to accept, and the genericsocket filehandle is given as the second:
accept (NEW, FH) || die $!;
Now the server can read and write to the filehandle NEW for its communication with the client
13.1.4 Socket Module Functions
The following functions are imported from the Socket module for use in socket applications:
[ Library Home | Perl in a Nutshell | Learning Perl | Learning Perl on Win32 | Programming Perl | Advanced Perl
Programming | Perl Cookbook ]
[Chapter 13] Sockets
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch13_01.htm (5 of 5) [2/7/2001 10:36:15 PM]
Trang 36Chapter 13 Sockets
13.2 The IO::Socket Module
The IO::Socket module included in the core Perl distribution provides an object-oriented approach tosocket programming This module provides a convenient way to handle the large number of options youhave to deal with, and it handles the laborious task of forming addresses IO::Socket is built upon theSocket module provided in the standard library It inherits from IO::Handle, which supports a class offilehandle objects for much of the IO library The following IO::Socket functions are simply frontendsfor the corresponding built-in functions and use the same syntax:
peername (same as getpeername)
sockname (same as getsockname)
The accept function in IO::Socket is slightly different from the equivalent function, however, and isdescribed later in the chapter
IO:Socket contains two subclasses: INET and UNIX The INET subclass is used to create and manipulateInternet-domain sockets, such as the ones used in the examples The UNIX subclass creates Unix domainsockets
13.2.1 Client-Side Sockets
IO::Socket greatly simplifies the implementation of a socket for client communications The followingexample creates an Internet-domain socket (using the INET subclass) and attempts to connect to thespecified server:
use IO::Socket;
$sock = new IO::Socket::INET (PeerAddr => 'www.ora.com',
PeerPort => 80,
Proto => 'tcp');
die "$!" unless $sock;
IO::Socket::INET::new creates an object containing a socket filehandle and connects it to the[Chapter 13] 13.2 The IO::Socket Module
http://www.crypto.nc1uw1aoi420d85w1sos.de/documents/oreilly/perl/perlnut/ch13_02.htm (1 of 4) [2/7/2001 10:36:18 PM]