⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch10.htm

📁 CGI programming is the hottest stuff to look out for in this book
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<h4>Your entry has been added to the address book</h4>
<BR>
&lt;A HREF=&quot;add.html&quot;&gt;Go&lt;/a&gt; back to the form
to add another user.<BR>
&lt;/body&gt;&lt;/html&gt;<BR>
EOF</FONT></TT>
</BLOCKQUOTE>
<P>
In effect, this CGI script simply appends the new entry to the
database. The first snag becomes file locking. If someone else
is modifying the database at exactly the same time, one of the
changes will be lost or the entire database will become corrupted.
To circumvent this, we use a lock file to tell if someone else
is writing to the database. This is far from the most elegant
solution, and most systems provide a <TT><FONT FACE="Courier">flock()</FONT></TT>
function to more effectively lock the file from simultaneous access.
Secondly, the ID number of the entry must be determined. In this
case, we can assume that the entries will be sequentially numbered
and that the last entry will have the last ID number. So we simply
read the last line of the database, grab the ID number from that,
and then increment it to obtain the new ID number.
<P>
Now that anyone can add entries to the address book, it may become
necessary to delete or modify entries. To do that, however, there
must be some way for the user to indicate the desired entry to
modify or delete. Instead of creating a whole new form for this,
we can add this functionality to our existing search CGI. If the
user's search returns exactly one result, a line can be added
to the HTML result page offering the option to modify or delete
this entry. (This could be done for more than one result fairly
easily, but we will stick with one for brevity's sake.) This can
be done by changing the following lines at the bottom of the search
CGI:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">print &lt;&lt;EOH;<BR>
&lt;/pre&gt;&lt;br&gt;<BR>
Thank you for using my address book.<BR>
&lt;A HREF=&quot;addrbk.html&quot;&gt;Go&lt;/a&gt; back to the
form to make another search.<BR>
&lt;/body&gt;&lt;/html&gt;<BR>
EOH</FONT></TT>
</BLOCKQUOTE>
<P>
to:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">print &quot;&lt;/pre&gt;&lt;br&gt;\nThank
you for using my address book.\n&quot;;<BR>
print &quot;&lt;A HREF=\&quot;addrbk.html\&quot;&gt;Go&lt;/a&gt;
back to the form to make another search.&lt;br&gt;\n&quot;;<BR>
if ($#results == 0) {<BR>
print &quot;&lt;A HREF=\&quot;change.cgi?a=d&amp;n=$result[0]\&quot;&gt;Delete&lt;/a&gt;
this entry.&lt;br&gt;\n&quot;;<BR>
print &quot;&lt;A HREF=\&quot;change.cgi?a=c&amp;n=$result[0]\&quot;&gt;Modify&lt;/a&gt;
this entry.&lt;br&gt;\n&quot;;<BR>
}<BR>
print &quot;&lt;/body&gt;&lt;/html&gt;\n&quot;;</FONT></TT>
</BLOCKQUOTE>
<P>
The added lines print links to a new CGI program, passing two
values: a parameter indicating whether a deletion or a modification
is wanted, and the ID number of the entry to delete or modify.
<P>
Because our database is delimited, we will have to regenerate
the entire database to make a change, as shown in Listing 10.2.
<HR>
<BLOCKQUOTE>
<B>Listing 10.2. Outputting an ASCII database.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">#!/bin/perl<BR>
<BR>
require cgi_head; # Set up CGI environment<BR>
<BR>
while ( -e &quot;datalock&quot; ) { sleep 1; } # Wait while someone
else is<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#
modifying database.<BR>
system (&quot;touch datalock&quot;); # Lock the database.<BR>
<BR>
# Load database<BR>
open (DAT, &quot;database.txt&quot;) || die &quot;Can't open the
database: $! !.\n&quot;;<BR>
$maxn = 0; # A counter for the number of entries.<BR>
while (&lt;DAT&gt;) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;chop;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;@field = split(/:/); # Split the line
into the data fields.<BR>
&nbsp;&nbsp;&nbsp;&nbsp;$n = $field[0]; # First field is an id
number<BR>
&nbsp;&nbsp;&nbsp;&nbsp;$add[$n]{'name'} = $field[1]; # Then the
name<BR>
&nbsp;&nbsp;&nbsp;&nbsp;$add[$n]{'phone'} = $field[2]; # The phone
number<BR>
&nbsp;&nbsp;&nbsp;&nbsp;$add[$n]{'street'} = $field[3]; # The
street address<BR>
&nbsp;&nbsp;&nbsp;&nbsp;$add[$n]{'city'} = $field[4]; # The city
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;$add[$n]{'state'} = $field[5]; # The state
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;$add[$n]{'zip'} = $field[6]; # The Zip
Code<BR>
&nbsp;&nbsp;&nbsp;&nbsp;$add[$n]{'line'} = $_ . &quot;\n&quot;;
# The entire line<BR>
}<BR>
$maxn = $n;<BR>
<BR>
close DAT;<BR>
<BR>
open (DAT, &quot;&gt;database.txt&quot;); # Open database for
writing.<BR>
if ($FORM{'a'} eq &quot;d&quot;) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#
If a deletion is being requested,<BR>
&nbsp;&nbsp;&nbsp;&nbsp;for ($I = 0; $I &lt;= $maxn; $I++) {&nbsp;&nbsp;&nbsp;#print
all entries except the<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unless ($I ==
$FORM{'n'}) { # one to be deleted.<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print
DAT $add[$I]{'line'};<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
&nbsp;&nbsp;&nbsp;&nbsp;# Print a message then exit.<BR>
&nbsp;&nbsp;&nbsp;&nbsp;print &lt;&lt;EOP;<BR>
&lt;HTML&gt;&lt;HEAD&gt;&lt;TITLE&gt;Request successful&lt;/title&gt;&lt;/head&gt;
<BR>
&lt;BODY&gt;<BR>
&lt;H3&gt;The selected entry has been deleted.&lt;/h3&gt;<BR>
&lt;A HREF=&quot;addrbk.html&quot;&gt;Go&lt;/a&gt; back to make
another search.<BR>
&lt;/body&gt;&lt;/html&gt;<BR>
EOP<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;close DAT;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;system (&quot;rm datalock&quot;);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;die;<BR>
} elsif ($FORM{'a'} eq &quot;c&quot;) {<BR>
<BR>
# If the user wants to modify the entry, things become a bit trickier.
<BR>
# We must first print out a form, similar to the original form,
to allow<BR>
# the user to change the values of the entry.<BR>
&nbsp;&nbsp;&nbsp;&nbsp;$n = $FORM{'n'}; # Put the entry to be
changed in an easier to type<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#
variable.<BR>
&nbsp;&nbsp;&nbsp;&nbsp;print &lt;&lt;EOF;<BR>
&lt;HTML&gt;&lt;HEAD&gt;&lt;TITLE&gt;Entry Modification&lt;/title&gt;&lt;/head&gt;
<BR>
&lt;BODY&gt;<BR>
&lt;h4&gt;Make the desired changes in the form below.&lt;/h4&gt;
<BR>
&lt;FORM ACTION=&quot;change.cgi&quot; METHOD=&quot;POST&quot;&gt;
<BR>
&lt;INPUT TYPE=HIDDEN NAME=&quot;a&quot; VALUE=&quot;m&quot;&gt;
<BR>
&lt;INPUT TYPE=HIDDEN NAME=&quot;n&quot; VALUE=&quot;$n&quot;&gt;
<BR>
Name: &lt;INPUT SIZE=45 NAME=&quot;name&quot; VALUE=&quot;$add[$n]{'name'}&quot;&gt;&lt;br&gt;
<BR>
Phone: &lt;INPUT SIZE=45 NAME=&quot;phone&quot; VALUE=&quot;$add[$n]{'phone'}&quot;&gt;&lt;br&gt;
<BR>
Street: &lt;INPUT SIZE=45 NAME=&quot;street&quot; VALUE=&quot;$add[$n]{'street'}&quot;&gt;&lt;br&gt;
<BR>
City: &lt;INPUT SIZE=20 NAME=&quot;city&quot; VALUE=&quot;$add[$n]{'city'}&quot;&gt;
<BR>
State: &lt;INPUT SIZE=3 NAME=&quot;state&quot; VALUE=&quot;$add[$n]{'state'}&quot;&gt;
<BR>
Zip: &lt;INPUT SIZE=6 NAME=&quot;zip&quot; VALUE=&quot;$add[$n]{'zip'}&quot;&gt;
<BR>
&lt;br&gt;&lt;br&gt;<BR>
&lt;INPUT TYPE=SUBMIT VALUE=&quot;&nbsp;&nbsp;Modify Entry&nbsp;&nbsp;&quot;&gt;
<BR>
&lt;INPUT TYPE=RESET VALUE=&quot;&nbsp;&nbsp;Reset Form&nbsp;&nbsp;&quot;&gt;
<BR>
&lt;/form&gt;&lt;/body&gt;&lt;/html&gt;<BR>
EOF<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;# This form adds two hidden fields, telling
this CGI which entry to<BR>
&nbsp;&nbsp;&nbsp;&nbsp;# modify.<BR>
&nbsp;&nbsp;&nbsp;&nbsp;for ($I = 0; $I &lt;= $maxn; $I++) { print
DAT $add[$I]{'line'}; }<BR>
&nbsp;&nbsp;&nbsp;&nbsp;close DAT;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;system (&quot;rm datalock&quot;);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;die;<BR>
<BR>
} elsif ($FORM{'a'} = &quot;m&quot;) {<BR>
# Make the change on the modified entry.<BR>
&nbsp;&nbsp;&nbsp;&nbsp;$n = $FORM{'n'}; # Copy the entry to be
changed into a more<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
# typeable variable.<BR>
&nbsp;&nbsp;&nbsp;&nbsp;# Assign the modified values to the entry.
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;$add[$n]{'name'} = $FORM{'name'};<BR>
&nbsp;&nbsp;&nbsp;&nbsp;$add[$n]{'phone'} = $FORM{'phone'};<BR>
&nbsp;&nbsp;&nbsp;&nbsp;$add[$n]{'street'} = $FORM{'street'};
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;$add[$n]{'city'} = $FORM{'city'};<BR>
&nbsp;&nbsp;&nbsp;&nbsp;$add[$n]{'state'} = $FORM{'state'};<BR>
&nbsp;&nbsp;&nbsp;&nbsp;$add[$n]{'zip'} = $FORM{'zip'};<BR>
&nbsp;&nbsp;&nbsp;&nbsp;$add[$n]{'line'} =<BR>
&quot;$n:$add[$n]{'name'}:$add[$n]{'phone'}:$add[$n]{'street'}:$add[$n]{'city'}:$add[$n]{'state'}:
<BR>
&Acirc;$add[$n]{'zip'}\n&quot;;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;for ($I = 0; $I &lt;= $maxn; $i++) { print
DAT $add[$i]{'line'}; }<BR>
&nbsp;&nbsp;&nbsp;&nbsp;close DAT;<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;print &lt;&lt;EOE;<BR>
&lt;HTML&gt;&lt;HEAD&gt;&lt;TITLE&gt;Modification successful&lt;/title&gt;&lt;/head&gt;
<BR>
&lt;BODY&gt;<BR>
&lt;H4&gt;The requested entry has been modified.&lt;/H4&gt;<BR>
&lt;A HREF=&quot;addrbk.html&quot;&gt;Go&lt;/a&gt; back to the
form to make another search.<BR>
&lt;/body&gt;&lt;//html&gt;<BR>
EOE<BR>
&nbsp;&nbsp;&nbsp;&nbsp;system (&quot;rm datalock&quot;);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;die;<BR>
} else { die; } # This should never be reached.</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
Now we have a complete address book system in which entries can
be added, deleted, modified, and searched in any number of categories.
As it is, though, this address book is lacking in several important
areas:
<UL>
<LI><FONT COLOR=#000000>Clean Code</FONT>-For readability's sake,
the code in this example is rather naive. There are several sections
that could be optimized, and the entire thing could benefit from
a more object-oriented approach. Object orientation is one of
the most important things to strive for when developing a CGI
program (or any program designed for use on the Internet). Unless
your code must be proprietary, there is a good chance that it
will travel far and wide across the Web and will be used by many
different people in many different ways. A modular approach allows
people to reuse portions of the code that are useful to them and
makes understanding the structure of the program much easier.
<LI><FONT COLOR=#000000>User Interface</FONT>-The HTML pages generated
by these CGI scripts are Spartan to the extreme. A well-thought-out
design can make your CGI more pleasant to use, encouraging people
to come back. It is important, however, not to take it too far.
If your database is for business or academic purposes, the Web
pages should reflect that. Also make sure (especially if you are
in an academic environment) that your scripts are usable by as
many people as possible. Many people are still connecting to the
Internet through modems 14.4 Kbps and slower. Large graphics,
Java applets, or other needless bells and whistles can make your
page worthless to a large potential audience. And if at all possible,
make the page usable from a line-mode browser such as Lynx. Such
browsers are the last refuge for people with very slow connections,
and are the only means of access for the visually impaired and
other physically challenged people.
<LI><FONT COLOR=#000000>Functionality</FONT>-While it's important
not to make your CGI programs too complicated to use, it helps
to anticipate the needs of your users and to include as much functionality
as possible. In our address book, for example, a better search
engine would greatly improve its usefulness. As it stands, the
script returns only entries that match exactly with database entries.
If the scripts could do substring matching, a person could search
for all entries with a common last name or all people who have
the same telephone prefix. With Perl's pattern matching and regular
expression capabilities, this would not be a difficult addition.
</UL>
<H2><A NAME="WebIndexing"><FONT SIZE=5 COLOR=#FF0000>Web Indexing</FONT></A>
</H2>
<P>
Somewhere between small text databases and large database servers
are databases that contain information about the Web itself. Such
databases provide for users the capability to search for information
on a site without having to look at every page by hand. The most
common modus operandi of a Web index is as follows: A user enters

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -