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

📄 ch06_04.htm

📁 用perl编写CGI的好书。本书从解释CGI和底层HTTP协议如何工作开始
💻 HTM
📖 第 1 页 / 共 4 页
字号:
variables. They can also contain Perl control structures. Instead ofusing Embperl's meta-commands as control structures, we couldhave used Perl's <tt class="function">foreach</tt> loop instead ofEmbperl's to create the table in our previous example:</p><blockquote><pre class="code">[# Output a row for each environment variable #]  [* foreach $varname ( sort keys %ENV ) { *]    &lt;TR&gt;      &lt;TD&gt;&lt;B&gt;[+ $varname +]&lt;/B&gt;&lt;/TD&gt;      &lt;TD&gt;[+ $ENV{$varname} +]&lt;/TD&gt;    &lt;/TR&gt;  [* } *]</pre></blockquote><p>The difference is brackets versus meta-command blocks. Note that codewithin <tt class="literal">[*</tt> and <tt class="literal">*]</tt> must end witha semicolon or a curly bracket, and these blocks are evaluated eveninside Embperl comment blocks (see below). These bracket pairs wereintroduced in Embperl 1.2.</p></dd><dt><b><tt class="literal">[#</tt>  ... <tt class="literal">#]</tt></b></dt><dd><p>These brackets are used for<a name="INDEX-1433" />comments. Embperl ignoresand strips anything between these bracket pairs so the contents donot end up in the output sent to the client. These can also be usedto remove large sections of HTML or code during testing, butunfortunately this does not work for code within <tt class="literal">[* ...*]</tt>, since these blocks are evaluated first. These bracketpairs were introduced in Embperl 1.2.</p></dd></dl><p>Because blocks begin with <tt class="literal">[</tt> in Embperl, you mustuse <tt class="literal">[[</tt> if you need to output the [ character inyour HTML. There is no need to escape <tt class="literal">]</tt> or<a name="INDEX-1434" /> <a name="INDEX-1,435" />other characters. Also, Embperl ties STDOUTto its output stream so you can use <tt class="function">print</tt> withinEmbperl blocks and it will behave correctly.</p></div><a name="ch06-73315" /><div class="sect3"><h3 class="sect3">6.4.2.2. Variable scope</h3><p>Each block of code within a set of bracket pairs is evaluated as aseparate block within Perl. This means that each one has a separate<a name="INDEX-1436" /><a name="INDEX-1437" />variablescope. If you declare a <a name="INDEX-1438" />lexical variable (a variable declaredwith <tt class="function">my</tt>) in one block, it will not be visible inanother block. In other words, this will not work:</p><blockquote><pre class="code">[- my $time = localtime -]&lt;P&gt;The time is: [+ $time +].&lt;/P&gt;</pre></blockquote><p>The result is roughly analogous to the following in Perl:</p><blockquote><pre class="code">&amp;{sub { my $time = localtime }};print "&lt;P&gt;The time is: " . &amp;{sub { $time }} . ".&lt;/P&gt;";</pre></blockquote><p>Similarly, <a name="INDEX-1439" /><a name="INDEX-1440" />pragmas that depend on scope suchas <tt class="literal">use strict</tt> will only affect the current blockof code. To enable the strict pragma globally, you must use the<tt class="literal">var</tt> meta-command (see <a href="ch06_04.htm#ch06-63926">Table 6-6</a>).</p><p>The <tt class="literal">[* ... *]</tt> blocks are a little different. Theyall share a common scope so local variables (variables declared with<tt class="function">local</tt>) can be shared between them. However,lexical variables still can not. This does not mean that you shouldentirely abandon declaring your variables with<tt class="function">my</tt> in Embperl.</p><p>Lexical variables are still useful as <a name="INDEX-1441" />temporary variables that you only needwithin a particular block. Using lexical variables for temporaryvariables is more efficient than using <a name="INDEX-1442" /> <a name="INDEX-1,443" />globalvariables because they are reclaimed by Perl as soon as thesurrounding block ends. Otherwise, they persist until the end of theHTTP request. Under CGI, of course, all global variables are cleanedup at the end of the request because <tt class="command">perl</tt> exits.However, even when running under <em class="emphasis">mod_perl</em>, bydefault Embperl undefines all global variables created within thescope of your pages at the end of each HTTP request.</p></div><a name="ch06-63352" /><div class="sect3"><h3 class="sect3">6.4.2.3. Meta-commands</h3><p><a name="INDEX-1444" /><a name="INDEX-1445" /><a name="INDEX-1446" />Embperl offers several meta-commands forcreating control structures plus other miscellaneous functions shownin <a href="ch06_04.htm#ch06-63926">Table 6-6</a>. The parentheses shown with some ofthe control structures are optional in Embperl, but including themcan make these commands clearer and look more like Perl'scorresponding control structures.</p><a name="ch06-63926" /><h4 class="objtitle">Table 6-6. Embperl's Meta-commands </h4><table border="1"><tr><th><p>Meta-command</p></th><th><p>Description</p></th></tr><tr><td><blockquote><pre class="code">[$ foreach $loop_var ( list ) $]</pre></blockquote></td><td><p>Similar to Perl's <tt class="function">foreach</tt> controlstructure, except <em class="emphasis">$loop_var</em> is required.</p></td></tr><tr><td><blockquote><pre class="code">[$ endforeach $]</pre></blockquote></td><td><p>Indicates the end of a <em class="emphasis">foreach</em> loop.</p></td></tr><tr><td><blockquote><pre class="code">[$ while ( expr ) $]</pre></blockquote></td><td><p>Similar to Perl's <tt class="function">while</tt> control structure.</p></td></tr><tr><td><blockquote><pre class="code">[$ endwhile $]</pre></blockquote></td><td><p>Indicates the end of a <em class="emphasis">while</em> loop.</p></td></tr><tr><td><blockquote><pre class="code">[$ do $]</pre></blockquote></td><td><p>Indicates the beginning of an <em class="emphasis">until</em> loop.</p></td></tr><tr><td><blockquote><pre class="code">[$ until ( expr ) $]</pre></blockquote></td><td><p>Similar to Perl's <tt class="function">until</tt> control structure.</p></td></tr><tr><td><blockquote><pre class="code">[$ if ( expr ) $]</pre></blockquote></td><td><p>Similar to Perl's <tt class="function">if</tt> control structure.</p></td></tr><tr><td><blockquote><pre class="code">[$ elsif ( expr ) $]</pre></blockquote></td><td><p>Similar to Perl's <tt class="function">elsif</tt> control structure.</p></td></tr><tr><td><blockquote><pre class="code">[$ else $]</pre></blockquote></td><td><p>Similar to Perl's <tt class="function">else</tt> control structure.</p></td></tr><tr><td><blockquote><pre class="code">[$ endif $]</pre></blockquote></td><td><p>Indicates the end of an <em class="emphasis">if</em> conditional.</p></td></tr><tr><td><blockquote><pre class="code">[$ sub subname $]</pre></blockquote></td><td><p>This allows you to treat a section containing both HTML and Embperlblocks as a subroutine that can be called as a normal Perl subroutineor via Embperl's <tt class="function">Execute</tt> function.</p></td></tr><tr><td><blockquote><pre class="code">[$ endsub $]</pre></blockquote></td><td><p>Indicates the end of a <em class="emphasis">sub</em> body.</p></td></tr><tr><td><blockquote><pre class="code">[$ var $var1 @var2 %var3 ... $]</pre></blockquote></td><td><p>This command is equivalent to the following in a Perl script:</p><blockquote><pre class="code">use strict;use vars qw( $var1 @var2 %var3 ... );</pre></blockquote><p>Your pages will be more efficient if you use this, especially whenrunning with <em class="emphasis">mod_perl</em>. Remember, however, thatif you do, you must declare every variable here that is sharedbetween Embperl blocks because of the scope restriction (see <a href="ch06_04.htm#ch06-73315">Section 6.4.2.2, "Variable scope"</a>, earlier).</p></td></tr><tr><td><blockquote><pre class="code">[$ hidden [ %input %used ] $]</pre></blockquote></td><td><p>This generates hidden fields for all elements in the first hash thatare not in the second hash. Both hashes are optional, and onetypically uses Embperl's default, which are<tt class="literal">%fdat</tt> and <tt class="literal">%idat</tt>.<tt class="literal">%fdat</tt> contains the name and values of the fieldsthe user submitted, and <tt class="literal">%idat</tt> contains the namesand values of the fields that have been used as elements in thecurrent form (see <a href="ch06_04.htm#ch06-15817">Section 6.4.4, "Global Variables"</a>, later).</p></td></tr></table></div></div><a name="ch06-16-fm2xml" /><div class="sect2"><h3 class="sect2">6.4.3. HTML Logic</h3><p><a name="INDEX-1447" /><a name="INDEX-1448" />Embperl monitors and responds to HTML as itis output. You can have it construct<a name="INDEX-1449" />tables and prefillform elements for you automatically.</p><a name="ch06-17-fm2xml" /><div class="sect3"><h3 class="sect3">6.4.3.1. Tables</h3><p>If you use the <tt class="literal">$row</tt>, <tt class="literal">$col</tt>, or<tt class="literal">$cnt</tt> variables in code within a table, Embperlwill loop over the contents of the table, dynamically build the tablefor you, and set these variables to the current row index, thecurrent column index, and the number of cells output, respectively,with each iteration. Embperl interprets the variables as follows:</p><ul><li><p>If <tt class="literal">$row</tt> is present, everything between&lt;TABLE&gt; and &lt;/TABLE&gt; is repeated until the expressioncontaining <tt class="literal">$row</tt> is undefined.<a name="INDEX-1450" />Rows consistingentirely of &lt;TH&gt; ... &lt;/TH&gt; cells are considered headersand are not repeated.</p></li><li><p>If <tt class="literal">$col</tt> is present, everything between &lt;TR&gt;and &lt;/TR&gt; is repeated until the expression containing<tt class="literal">$col</tt> is undefined.</p></li><li><p><tt class="literal">$cnt</tt> is used in the same manner for either rows orcolumns if it is present and <tt class="literal">$row</tt> or<tt class="literal">$col</tt> are not.</p></li></ul><p>Let's look at an example. Because <tt class="literal">$row</tt> and<tt class="literal">$col</tt> are set to the index of the current row andcolumn, they are typically used as<a name="INDEX-1451" /><a name="INDEX-1452" />array indices whenbuilding tables, as shown here:</p><blockquote><pre class="code">[- @sports = ( [ "Windsurfing", "Summer",   "Water"    ],               [ "Skiing",      "Winter",   "Mountain" ],               [ "Biking",      "All Year", "Hills"    ],               [ "Camping",     "All Year", "Desert"   ] ); -]&lt;TABLE&gt;  &lt;TR&gt;    &lt;TH&gt;Sport&lt;/TH&gt;    &lt;TH&gt;Season&lt;/TH&gt;    &lt;TH&gt;Terrain&lt;/TH&gt;  &lt;/TR&gt;  &lt;TR&gt;    &lt;TD&gt;[+ $sports[$row][$col] +]&lt;/TD&gt;  &lt;/TR&gt;&lt;/TABLE&gt;</pre></blockquote><p>The previous code will create the following table:</p><blockquote><pre class="code">&lt;TABLE&gt;  &lt;TR&gt;    &lt;TH&gt;Sport&lt;/TH&gt;    &lt;TH&gt;Season&lt;/TH&gt;    &lt;TH&gt;Terrain&lt;/TH&gt;  &lt;/TR&gt;  &lt;TR&gt;    &lt;TD&gt;Windsurfing&lt;/TD&gt;    &lt;TD&gt;Summer&lt;/TD&gt;    &lt;TD&gt;Water&lt;/TD&gt;  &lt;/TR&gt;  &lt;TR&gt;    &lt;TD&gt;Skiing&lt;/TD&gt;    &lt;TD&gt;Winter&lt;/TD&gt;    &lt;TD&gt;Mountain&lt;/TD&gt;  &lt;/TR&gt;  &lt;TR&gt;    &lt;TD&gt;Biking&lt;/TD&gt;    &lt;TD&gt;All Year&lt;/TD&gt;    &lt;TD&gt;Hills&lt;/TD&gt;  &lt;/TR&gt;  &lt;TR&gt;    &lt;TD&gt;Camping&lt;/TD&gt;    &lt;TD&gt;All Year&lt;/TD&gt;    &lt;TD&gt;Desert&lt;/TD&gt;  &lt;/TR&gt;&lt;/TABLE&gt;</pre></blockquote></div><a name="ch06-18-fm2xml" /><div class="sect3"><h3 class="sect3">6.4.3.2. List elements</h3><p>If you use <tt class="literal">$row</tt> within a<a name="INDEX-1453" /><a name="INDEX-1454" />list or select menu, Embperl willrepeat each element until <tt class="literal">$row</tt> is undefined, justas it does with tables. For select menus, Embperl will alsoautomatically check options that match name and value pairs in<tt class="literal">%fdat</tt> and add names and values to<tt class="literal">%idat</tt> (see below).</p></div><a name="ch06-19-fm2xml" /><div class="sect3"><h3 class="sect3">6.4.3.3. Form input elements</h3><p>Outputting <a name="INDEX-1455" /><a name="INDEX-1456" /> <a name="INDEX-1,457" />input and<a name="INDEX-1458" />

⌨️ 快捷键说明

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