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

📄 ch15_02.htm

📁 用perl编写CGI的好书。本书从解释CGI和底层HTTP协议如何工作开始
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<?label 15.2. Perl Coding Techniques?><html><head><title>Perl Coding Techniques (CGI Programming with Perl)</title><link href="../style/style1.css" type="text/css" rel="stylesheet" /><meta name="DC.Creator" content="Scott Guelich, Gunther Birznieks and Shishir Gundavaram" /><meta scheme="MIME" content="text/xml" name="DC.Format" /><meta content="en-US" name="DC.Language" /><meta content="O'Reilly & Associates, Inc." name="DC.Publisher" /><meta scheme="ISBN" name="DC.Source" content="1565924193L" /><meta name="DC.Subject.Keyword" content="stuff" /><meta name="DC.Title" content="CGI Programming with Perl" /><meta content="Text.Monograph" name="DC.Type" /></head><body bgcolor="#ffffff"><img src="gifs/smbanner.gif" alt="Book Home" usemap="#banner-map" border="0" /><map name="banner-map"><area alt="CGI Programming with Perl" href="index.htm" coords="0,0,466,65" shape="rect" /><area alt="Search this book" href="jobjects/fsearch.htm" coords="467,0,514,18" shape="rect" /></map><div class="navbar"><table border="0" width="515"><tr><td width="172" valign="top" align="left"><a href="ch15_01.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0" /></a></td><td width="171" valign="top" align="center"><a href="index.htm">CGI Programming with Perl</a></td><td width="172" valign="top" align="right"><a href="ch15_03.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0" /></a></td></tr></table></div><hr align="left" width="515" /><h2 class="sect1">15.2. Perl Coding Techniques</h2><p>In this <a name="INDEX-2961" /> <a name="INDEX-2,962" /> <a name="INDEX-2,963" /> <a name="INDEX-2,964" />section, we'll discuss<a name="INDEX-2965" />programming techniques that will helpus develop stable, bug-free applications. These techniques are easyto use, and using them can help you avoid bugs in the first place:</p><ul><li><p>Always <tt class="literal">use</tt> <tt class="literal">strict</tt>.</p></li><li><p>Check the status of system calls.</p></li><li><p>Verify that each file <tt class="function">open</tt> is successful.</p></li><li><p>Trap <tt class="function">die.</tt></p></li><li><p>Lock files.</p></li><li><p>Unbuffer the output stream when necessary.</p></li><li><p>Use <em class="emphasis">binmode</em> when necessary.</p></li></ul><p>Let's review each of these in detail.</p><a name="ch15-6-fm2xml" /><div class="sect2"><h3 class="sect2">15.2.1. Use strict</h3><p>You should use the <tt class="literal">strict</tt><a name="INDEX-2966" /> <a name="INDEX-2,967" /><a name="INDEX-2968" />pragma for any Perl script more than a few lines long, and for allCGI scripts. Simply place the following line at the top of yourscript:</p><blockquote><pre class="code">use strict;</pre></blockquote><p>If an import list is not specified, <tt class="literal">strict</tt>generates errors if you use symbolic references, bareword identifiersas subroutines, or use variables that are not localized, fullyqualified, or pre-defined using the <tt class="literal">vars</tt> argument.</p><p>Here are two snippets of code, one which will compile successfullyunder <tt class="literal">strict</tt>, and the other which will causeerrors:</p><blockquote><pre class="code">use strict;$id = 2000;$field = \$id;print $$field;        ## Success, will print 2000$field = "id";print $$field;        ## Error!</pre></blockquote><p><a name="INDEX-2969" /><a name="INDEX-2970" />Symbolic references are names ofvariables, used to get at the underlying object. In the secondsnippet above, we are trying to get at the value of<tt class="literal">$id</tt> indirectly. As a result, Perl will generate anerror like the following:</p><blockquote><pre class="code">Can't use string ("id") as a SCALAR ref while "strict refs" in use ...</pre></blockquote><p>Now, let's look at <a name="INDEX-2971" /><a name="INDEX-2972" />bareword subroutines. Take thefollowing example:</p><blockquote><pre class="code">use strict "subs";greeting;...sub greeting{    print "Hello Friend!";}</pre></blockquote><p>When Perl looks at the second line, it doesn't know what it is.It could be a string in a void context or it could be a subroutine orfunction call. When we run this code, Perl will generate thefollowing error:</p><blockquote><pre class="code">Bareword "greeting" not allowed while "strict subs" in use at simple line 3.Execution of simple aborted due to compilation errors.</pre></blockquote><p>We can solve this in one of several ways. We can create a prototype,declare <em class="emphasis">greeting</em> as a subroutine with the<tt class="literal">subs</tt> module, use the <tt class="literal">&amp;</tt>prefix, or pass an <a name="INDEX-2973" /><a name="INDEX-2974" />empty list, like so:</p><blockquote><pre class="code">sub greeting;              ## prototypeuse subs qw (greeting);    ## use subs&amp;greeting;                 ## &amp; prefixgreeting(  );                ## null list</pre></blockquote><p>This forces us to be clear about the use of subroutines in ourapplications.</p><p>The last restriction that <tt class="literal">strict</tt> imposes on usinvolves<a name="INDEX-2975" /><a name="INDEX-2976" />variable declaration. You haveprobably run across source code where you're not sure if acertain variable is <a name="INDEX-2977" /> <a name="INDEX-2,978" />global, or local to a function orsubroutine. By using the <tt class="literal">vars</tt> argument with<tt class="literal">strict</tt>, we can eliminate this guessing.</p><p>Here's a trivial example:</p><blockquote><pre class="code">use strict "vars";$soda = "Coke";</pre></blockquote><p>Since we haven't told Perl what <tt class="literal">$soda</tt> is, itwill complain with the following error:</p><blockquote><pre class="code">Global symbol "$soda" requires explicit package name at simple line 3.Execution of simple aborted due to compilation errors.</pre></blockquote><p>We can solve this problem by using a <a name="INDEX-2979" /><a name="INDEX-2980" />fully qualified variable name,declaring the variable using the <tt class="literal">vars</tt> module, orlocalizing it with <em class="emphasis">my</em>, like so:</p><blockquote><pre class="code">$main::soda = "Coke";    ## Fully qualifieduse vars qw ($soda);     ## Declare using vars modulemy $soda;                ## Localize</pre></blockquote><p>As you can see, the <tt class="literal">strict</tt> module imposes a veryrigid environment for developing applications. But, that's avery nice and powerful feature, because it helps us track down avariety of bugs. In addition, the module allows for great flexibilityas well. For example, if we know that a certain piece of code worksfine, but will fail under <tt class="literal">strict</tt>, we can turncertain <a name="INDEX-2981" /> <a name="INDEX-2,982" />restrictions off, like so:</p><blockquote><pre class="code">## code that passes strict...{    no strict;    ## or no strict "vars";        ## code that will not pass strict}</pre></blockquote><p>All code within the block, delimited by braces, will have norestrictions.</p><p>With this type of flexibility and control, there is no reason why youshould not be using <tt class="literal">strict</tt> to help you developcleaner, bug-free <a name="INDEX-2983" /> <a name="INDEX-2,984" /> <a name="INDEX-2,985" />applications.</p></div><a name="ch15-7-fm2xml" /><div class="sect2"><h3 class="sect2">15.2.2. Check Status of System Calls</h3><p>Before we <a name="INDEX-2986" /> <a name="INDEX-2,987" /> <a name="INDEX-2,988" />discuss anything in this section,here's a mantra to<a name="INDEX-2989" />code by:</p><blockquote class="simplelist"><p>"Always check the return value of all the system <a name="INDEX-2990" /><a name="INDEX-2,991" />commands, including <tt class="function">open</tt>, <tt class="function">eval</tt>, and <tt class="function">system</tt>."</p></blockquote><p>Since web servers are typically configured to run as<em class="emphasis">nobody</em>, or a user with minimal accessprivileges, we must be very careful when performing any file orsystem I/O. Take, for example, the following code:</p><blockquote><pre class="code">#!/usr/bin/perl -wTprint "Content-type: text/html\n\n";...open FILE, "/usr/local/apache/data/recipes.txt";while (&lt;FILE&gt;) {    s/^\s*$/&lt;P&gt;/, next if (/^\s*$/);    s/\n/&lt;BR&gt;/;    ...}close FILE;</pre></blockquote><p>If the <em class="emphasis">/usr/local/apache/data</em> directory is notworld readable, then the<em class="emphasis">open</em><a name="INDEX-2992" /><a name="INDEX-2993" /> command will fail, and we will end upwith no output. This isn't really desirable, since the userwill have no idea what happened.</p><p>A solution to this problem is to check the status of<em class="emphasis">open</em>:</p><blockquote><pre class="code">...open FILE, "/usr/local/apache/data/recipes.txt"    or error ( $q, "Sorry, I can't access the recipe data!" );print "Content-type: text/html\n\n";...</pre></blockquote><p>If the <em class="emphasis">open</em> fails, we call a custom<em class="emphasis">error</em> function to return a nicely formatted HTMLdocument and exit.</p><p>You need to follow the same process when creating or updating files,as well. In order for a CGI application to write to a file, it has tohave write permissions on the file, as well as the directories inwhich the file resides.</p><p>Some of the more commonly used <a name="INDEX-2994" />system functions include:<em class="emphasis">open</em>, <em class="emphasis">close</em>,<em class="emphasis">flock</em>, <em class="emphasis">eval,</em> and<em class="emphasis">system</em>. You should make it a habit to check thereturn value of such functions, so you can take preventative action.</p></div><a name="ch15-8-fm2xml" /><div class="sect2"><h3 class="sect2">15.2.3. Is It Open?</h3><p>In various examples throughout the book, we've used the<em class="emphasis">open</em><a name="INDEX-2995" /><a name="INDEX-2996" /> function to create pipes to

⌨️ 快捷键说明

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