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

📄 ch20.htm

📁 prrl 5 programs codes in the book
💻 HTM
📖 第 1 页 / 共 5 页
字号:

data file.

<P>

While the program in Listing 20.5 works well, there are several

things that can improve it:

<UL>

<LI>Error Handling-instead of simply dying, the program could

generate an error page that indicates the problem.

<LI>Field Validation-blank fields should be checked for and warned

against.

<LI>Guest book display-visitors should be able to see the Guest

book without needing to add an entry.

</UL>

<P>

The CGI program in Listing 20.6 implements these new features.

If you add <TT>?display</TT> to the

URL of the script, the script will simply display the entries

in the data file. If you add <TT>?add</TT>

to the URL of the script, it will redirect the client browser

to the <TT>addgest.htm</TT> Web page.

If no additional information is passed with the URL, the script

will assume that it has been invoked from a form and will read

the form information. After saving the information, the Guestbook

page will be displayed.

<P>

A debugging routine called <TT>printENV()</TT>

has been added to this listing. If you have trouble getting the

script to work, you can call the <TT>printENV()</TT>

routine in order to display all of the environment variables and

any form information that was read. Place the call to <TT>printENV()</TT>

right before the <TT>&lt;/BODY&gt;</TT>

tag of a Web page. The <TT>displayError()</TT>

fuNCtion calls the <TT>printENV()</TT>

fuNCtion so that the error can have as much information as possible

when a problem arises.

<P>

<IMG SRC="pseudo.gif" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/pseudo.gif" BORDER=1 ALIGN=RIGHT><p>

<BLOCKQUOTE>

<I>Turn on the warning option.<BR>

Turn on the strict pragma.<BR>

Declare a hash variable to hold the HTML form field data.<BR>

Get the local time and pretend that it is one of the form fields.

<BR>

Get the data from the form.<BR>

Was the program was invoked with added URL information?<BR>

if the display command was used, display the Guest book.<BR>

if the add command was use, redirect to the Add Entry page.<BR>

otherwise display an error page.<BR>

If no extra URL information, check for blank fields.<BR>

if blank fields, display an error page.<BR>

Save the form data.<BR>

Display the Guest book.    <BR>

Exit the program.<BR>

Define the </I><TT><I>displayError()</I></TT><I>

fuNCtion.<BR>

Display an error page with a specified error message.<BR>

Define the </I><TT><I>displayPage()</I></TT><I>

fuNCtion.<BR>

Read all of the entries into a hash.<BR>

Display the Guest book.<BR>

Define the </I><TT><I>readFormData()</I></TT><I>

fuNCtion.<BR>

Declare local variables for a file name and a hash refereNCe.

<BR>

Open the file for reading.<BR>

Iterate over the lines of the file.<BR>

Split the line into four variables using ~ as demlimiter.<BR>

Create a hash entry to hold the Guest book information.<BR>

Close the file.<BR>

Define the </I><TT><I>getFormData()</I></TT><I>

fuNCtion.<BR>

Declare a local variable to hold the refereNCe to the input field

hash.<BR>

Initialize a buffer.<BR>

If the </I><TT><I>GET</I></TT><I>

method is used, copy the form information into the buffer.<BR>

If the </I><TT><I>POST</I></TT><I>

method is used, read the form information into the buffer.<BR>

Iterate over the array returned by the </I><TT><I>split()</I></TT><I>

fuNCtion.<BR>

Decode both the input field name and value.<BR>

Compress multiple </I><TT><I>&lt;P&gt;</I></TT><I>

tags into one.<BR>

Convert </I><TT><I>&lt;</I></TT><I>

into </I><TT><I>&amp;lt;</I></TT><I>

and </I><TT><I>&gt;</I></TT><I> into

</I><TT><I>&amp;gt;</I></TT><I> stopping

HTML tags from interpretation.<BR>

Turn back on the bold and italic HTML tags.<BR>

Remove unneded carriage returns.<BR>

Convert two newlines into a HTML paragraph tag.<BR>

Convert single newlines into spaces.<BR>

Create an entry in the input field hash variable.<BR>

Define the </I><TT><I>decodeURL()</I></TT><I>

fuNCtion.<BR>

Get the eNCoded string from the parameter array.<BR>

Translate all plus signs into spaces.<BR>

Convert character coded as hexadecimal digits into regular characters.

<BR>

Return the decoded string.<BR>

Define the </I><TT><I>zeroFill()</I></TT><I>

fuNCtion-turns &quot;1&quot; into &quot;01&quot;.<BR>

Declare a local variable to hold the number to be filled.<BR>

Declare a local variable to hold the string length that is needed.

<BR>

Find differeNCe between current string length and needed length.

<BR>

If the string is big enough (like &quot;12&quot;) then return

it.<BR>

If the string is too big, prefix it with some zeroes.<BR>

Define the </I><TT><I>saveFormData()</I></TT><I>

fuNCtion.<BR>

Declare two local variables to hold the hash and file name.<BR>

Open the file for appending.<BR>

Store the contents of the hash in the data file.<BR>

Close the file.</I>

</BLOCKQUOTE>

<HR>

<BLOCKQUOTE>

<B>Listing 20.6&nbsp;&nbsp;20LST06.PL-A More AdvaNCed Guestbook

<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<PRE>

#! /user/bin/perl -w

#use strict;



    my(%fields);

    my($sec, $min, $hour, $mday, $mon, $year) = (localtime(time))[0..5];

    my($dataFile) = &quot;data/gestbook.dat&quot;;



    $mon  = zeroFill($mon, 2);

    $hour = zeroFill($hour, 2);

    $min  = zeroFill($min, 2);

    $sec  = zeroFill($sec, 2);

    $fields{'timestamp'} = &quot;$mon/$mday/$year, $hour:$min:$sec&quot;;



    getFormData(\%fields);



    if ($ENV{'QUERY_STRING'}) {

        if ($ENV{'QUERY_STRING'} eq 'display') {

            displayPage();

        }

        elsif ($ENV{'QUERY_STRING'} eq 'add') {

            print(&quot;Location: /addgest.htm\n\n&quot;);

        }

        else {

            displayError(&quot;Unknown Command: &lt;B&gt;$ENV{'QUERY_STRING'}&lt;/B&gt;&quot;);

        }

    }

    else {

        if (length($fields{'name'}) == 0) {

            displayError(&quot;Please fill the name field,&lt;BR&gt;\n&quot;);

        }

if (length($fields{'comments'}) == 0) {

            displayError(&quot;Please fill the comments field,&lt;BR&gt;\n&quot;);

        }

        saveFormData(\%fields, $dataFile);

        displayPage();

    }



    exit(0);



sub displayError {

    print(&quot;Content-type: text/html\n\n&quot;);

    print(&quot;&lt;HTML&gt;\n&quot;);

    print(&quot;&lt;HEAD&gt;&lt;TITLE&gt;Guestbook Error&lt;/TITLE&gt;&lt;/HEAD&gt;\n&quot;);

    print(&quot;&lt;H1&gt;Guestbook&lt;/H1&gt;\n&quot;);

    print(&quot;&lt;HR&gt;\n&quot;);

    print(&quot;@_&lt;BR&gt;\n&quot;);

    print(&quot;&lt;HR&gt;\n&quot;);

    printENV();

    print(&quot;&lt;/BODY&gt;\n&quot;);

    print(&quot;&lt;/HTML&gt;\n&quot;);

    exit(0);

}



        

sub displayPage {

    my(%entries);



    readFormData($dataFile, \%entries);



    print(&quot;Content-type: text/html\n\n&quot;);

    print(&quot;&lt;HTML&gt;\n&quot;);

    print(&quot;&lt;HEAD&gt;&lt;TITLE&gt;Guestbook&lt;/TITLE&gt;&lt;/HEAD&gt;\n&quot;);

    print(&quot;&lt;TABLE&gt;&lt;TR&gt;&lt;TD VALIGN=top&gt;&lt;H1&gt;Guestbook&lt;/H1&gt;&lt;/TD&gt;\n&quot;);



    print(&quot;&lt;TD VALIGN=top&gt;&lt;UL&gt;&lt;LI&gt;&lt;A HREF=\&quot;/cgi-bin/gestbook.pl?add\&quot;&gt;Add an Entry&lt;/A&gt;\n&quot;);

    print(&quot;&lt;LI&gt;&lt;A HREF=\&quot;/cgi-bin/gestbook.pl?display\&quot;&gt;Refresh&lt;/A&gt;&lt;/UL&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TABLE&gt;\n&quot;);

    print(&quot;&lt;HR&gt;\n&quot;);



    foreach (sort(keys(%entries))) {

        my($arrayRef) = $entries{$_};

        my($timestamp, $name, $email, $comments) = ($_, @{$arrayRef});



        print(&quot;$timestamp: &lt;B&gt;$name&lt;/B&gt; &lt;A HREF=mailto:$email&gt;$email&lt;/A&gt;\n&quot;);

        print(&quot;&lt;OL&gt;$comments&lt;/OL&gt;\n&quot;);

        print(&quot;&lt;HR&gt;\n&quot;);

    }

    print(&quot;&lt;/BODY&gt;\n&quot;);

    print(&quot;&lt;/HTML&gt;\n&quot;);

}



sub readFormData {

    my($file)    = shift;

    my($hashRef) = shift;



    open(FILE, &quot;&lt;$file&quot;) or displayError(&quot;Unable to open Guestbook data file.&quot;);

    while (&lt;FILE&gt;) {

        my($timestamp, $name, $email, $comments) = split(/~/, $_);



        $hashRef-&gt;{$timestamp} = [ $name, $email, $comments ];

    }

    close(FILE);

}



sub getFormData {

    my($hashRef) = shift;

    my($buffer) = &quot;&quot;;



    if ($ENV{'REQUEST_METHOD'} eq &quot;GET&quot;) {

        $buffer = $ENV{'QUERY_STRING'};

    }

    

   else {

        read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});

    }



    foreach (split(/&amp;/, $buffer)) {

        my($key, $value) = split(/=/, $_);

        $key   = decodeURL($key);

        $value = decodeURL($value);



        $value =~ s/(&lt;P&gt;\s*)+/&lt;P&gt;/g;   # compress multiple &lt;P&gt; tags.

        $value =~ s/&lt;/&amp;lt;/g;           # turn off all HTML tags.

        $value =~ s/&gt;/&amp;gt;/g;

        $value =~ s/&amp;lt;b&amp;gt;/&lt;b&gt;/ig;    # turn on the bold tag.

        $value =~ s!&amp;lt;/b&amp;gt;!&lt;/b&gt;!ig;

        $value =~ s/&amp;lt;i&amp;gt;/&lt;b&gt;/ig;    # turn on the italic tag.

        $value =~ s!&amp;lt;/i&amp;gt;!&lt;/b&gt;!ig;

        $value =~ s!\cM!!g;            # Remove unneeded carriage returns.

        $value =~ s!\n\n!&lt;P&gt;!g;        # Convert 2 newlines into paragraph.

        $value =~ s!\n! !g;            # convert newline into space.

        %{$hashRef}-&gt;{$key} = $value;

    }

}



sub decodeURL {

    $_ = shift;

    tr/+/ /;

    s/%(..)/pack('c', hex($1))/eg;

    return($_);

}



sub zeroFill {

    my($temp) = shift;

    my($len)  = shift;

    my($diff) = $len - length($temp);



    return($temp) if $diff &lt;= 0;

    return(('0' x $diff) . $temp);

}



sub saveFormData {

    my($hashRef) = shift;

    my($file)    = shift;



    open(FILE, &quot;&gt;&gt;$file&quot;) or die(&quot;Unable to open Guestbook data file.&quot;);

    print FILE (&quot;$hashRef-&gt;{'timestamp'}~&quot;);

    print FILE (&quot;$hashRef-&gt;{'name'}~&quot;);

    print FILE (&quot;$hashRef-&gt;{'email'}~&quot;);

    print FILE (&quot;$hashRef-&gt;{'comments'}&quot;);

    print FILE (&quot;\n&quot;);

    

close(FILE);

}



sub printENV {

    print &quot;The Environment report&lt;BR&gt;\n&quot;;

    print &quot;----------------------&lt;BR&gt;&lt;PRE&gt;\n&quot;;

    print &quot;REQUEST_METHOD:  *$ENV{'REQUEST_METHOD'}*\n&quot;;

    print &quot;SCRIPT_NAME:     *$ENV{'SCRIPT_NAME'}*\n&quot;;

    print &quot;QUERY_STRING:    *$ENV{'QUERY_STRING'}*\n&quot;;

    print &quot;PATH_INFO:       *$ENV{'PATH_INFO'}*\n&quot;;

    print &quot;PATH_TRANSLATED: *$ENV{'PATH_TRANSLATED'}*&lt;/PRE&gt;\n&quot;;



    if ($ENV{'REQUEST_METHOD'} eq 'POST') {

        print &quot;CONTENT_TYPE:    $ENV{'CONTENT_TYPE'}&lt;BR&gt;\n&quot;;

        print &quot;CONTENT_FILE:    $ENV{'CONTENT_FILE'}&lt;BR&gt;\n&quot;;

        print &quot;CONTENT_LENGTH:  $ENV{'CONTENT_LENGTH'}&lt;BR&gt;\n&quot;;

    }

    print(&quot;&lt;BR&gt;&quot;);



    foreach (sort(keys(%ENV))) {

        print(&quot;$_: $ENV{$_}&lt;BR&gt;\n&quot;);

    }

    print(&quot;&lt;BR&gt;&quot;);



     foreach (sort(keys(%fields))) {

        print(&quot;$_: $fields{$_}&lt;BR&gt;\n&quot;);

    }

    print(&quot;&lt;BR&gt;&quot;);

}

</PRE>

</BLOCKQUOTE>

<HR>

<P>

One of the major changes between Listing 20.5 and Listing 20.6

is in the <TT>readFormData()</TT>

fuNCtion. Instead of actually printing the Guest book data, the

fuNCtion now creates hash entries for it. This change was done

so that an error page could be generated if the data file could

not be opened. Otherwise, the error message would have appeared

it the middle of the Guest book page-leading to confusion on the

part of vistors.

<P>

A table was used to add two hypertext links to the top of t

⌨️ 快捷键说明

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