IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  Linux | Web development  >

PHP 例解,第 2 部分

深入研究 Webzine 编辑和发送

developerWorks
文档选项

未显示需要 JavaScript 的文档选项


级别: 初级

Erik Zolt醤 (erik@zoltan.org), 高级系统工程, EDS

2001 年 1 月 01 日

作为构建动态网页的一种语言,PHP 提供了一种简化的方法来构造复杂而功能强大的与 Web 相关的程序。 Erik 用一个原始的、现实世界的网站示例逐步说明了 PHP 的基本原理。本系列文章(共两篇)的第 2 部分介绍发送模块如何向读者呈现 一个故事菜单,并说明编辑模块如何使作者能将故事提交给 Webzine。

简介

如果您是初次接触PHP,您可能会惊喜地发现在实践中它是多么易于使用。本文旨在使您对 PHP的工作方式留下一个好的印象; 随后您就可以确定它是否适合您。


在本文的 第 1 部分,我介绍了Webzine 这个简单 PHP 应用程序的发送部分。尽管只有大约 3K的代码,但它包含了许多功能。您已试用了这个应用程序,并开始研究它的后台工作方式。我说明了应用程序如何向用户显示类别菜单并根据选择显示故事。我还使读者对PHP应用程序的工作方式以及它们从调用页接收参数的方式有了一定的了解。





回页首


故事菜单

本文是第 2部分,您首先会了解到发送模块是如何将故事菜单呈现给读者的,然后还会快速查看一下使作者能向Webzine 提交故事的编辑模块。


文件中的每个故事在主题菜单文件中都有对应的一行。我已决定将脱字符号("^")用作定界符来分隔文件中的不同项目,但您可以使用任何字符(制表符是一种通用的选择)。下面是基本的布局:

故事编号^标题^图像 URL^摘要
                

举例来说,仅包含三个故事的主题菜单文件 (TradeShow.txt)可能如下所示:

清单 1. 包含三个故事的主题菜单文件

33^Great New Products This Year^/images/proddemo.jpg^Thursday's product demo ...
12^Opening Event Well Attended^/images/opnfoto.jpg^Ticket sales to the ...
5^Trade Show Opens^/images/tradelogo.gif^The Fourth Annual Trade Show ...
                



菜单驱动程序接受这些信息并向读者提供一个故事概述。其工作方式如下:

  • 首先,驱动程序将适当的条目编号从主题菜单文件复制到数组 $stories 中。对于上面的示例, $stories[0] 包含第一行(故事编号为 33), $stories[1] 包含故事编号 12, $stories[2] 包含故事编号5。您还需要统计数组中的元素个数,并将其保存在变量 $numstories 中。
  • 下一步,驱动程序将此信息提供给用户,如下所示:

清单 2.驱动程序

for ($i=0; $i<$numstories; $i++) {
 $storyinfo = split("\^", $stories[$i]);
 $storynum = $storyinfo[0]; // 故事编号(例如 33)
 $storydesc = $storyinfo[1]; // 故事标题(例如 "Great New Products This Year")。
 $storyimg = $storyinfo[2]; // 图像 URL(例如 "/images/proddemo.jpg")。
 $dtext = $storyinfo[3]; // 故事摘要(更长的文本说明)。
 $url = "<a href=\"index.php3?topic=$topic&story=$storynum\">$storydesc</a><br>";
 if ($i<10) {
 $url = "<h2>" . $url . "</h2>";
 if ($storyimg != "") {
 $url = "<p><img align=" . ($i%2==1 ? "right" : "left")
 . " src=\"$storyimg\"></p>\n"
 . $url;
 }
 $url = "<hr>" . $url;
 } else {
 $url = "<h3>" . $url . "</h3>";
 }
 echo("$url\n");
 echo("<p>$dtext</p>\n");
}
                

split 函数将故事信息的内容从一个字符串复制到一个数组中。请注意,脱字符号前面加了一个反斜杠从而成为“转义”字符。该程序将数组节点转换为说明性更强的变量名,从而使代码更易于阅读。然后就会构造URL。 if/else 结构对前 10个故事的处理与对其他故事的处理不同。前 10 个故事有一个分隔线,使用H2 标记,并包括一张照片(如果有)。 剩余的故事使用 H3标记,没有分隔线,也没有照片。这个处理突出显示最新的故事,并保留较旧的故事供需要它们的读者访问。请注意,编号为奇数的的图像是右对齐的,而编号为偶数的图像是左对齐的。

作为本例的结束,为上面的 theTradeShow.txt 文件所生成的 HTML代码如下所示:

清单 3. 为 theTradeShow.txt 文件所生成的 HTML 代码

<hr><p><img align=left src="/images/proddemo.jpg"></p>
<h2><a href="index.php3?topic=TradeShow&story=33">Great New Products This Year</a><br></h2>
<p>Thursday's product demo included a couple of exciting new
surprises from competing firms in the industry.</p>
<hr><p><img align=right src="/images/opnfoto.jpg"></p>
<h2><a href="index.php3?topic=TradeShow&story=12">Opening Event Well Attended</a><br></h2>
<p>Ticket sales to the Trade Show opening event were
up 15% from last year's show.</p>
<hr><p><img align=left src="/images/tradelogo.gif"></p>
<h2><a href="index.php3?topic=TradeShow&story=5">Trade Show Opens</a><br></h2>
<p>The Fourth Annual Trade Show opened 10/11/2000 to an enthusiastic reception
from attendees.</p>
                





回页首


编辑页 "author.php3"

单击此处查看 index.php3的源代码。在开始下一部分之前您可能希望查看整组源代码。毕竟代码的大小还不到3K!


对编辑页的分析不会像对发送模块的分析那样详细,因为它比较长,而且我们已经讨论了许多基本概念。

为了简要说明一个 PHP 函数的基本结构,让我们看一下编辑模块中的 complain 函数。这是一个简单的函数,但它是一个很好的入门级材料。

清单 4. 一个 PHP 函数示例

//通知用户输入问题。
 function complain($problem) {
 global $status;
 if ($status != "") $status = $status . "<br>\n";
 $status = $status . $problem;
 }
                

您可以在代码中的任何地方调用这个函数。例如, complain("TheURL is too long."); 接收全局变量 $status 并将这个新的错误消息追加到其尾部,如果 $status 不为空,则在错误消息前添加一个换行符。

Prepend
prepend 函数是编辑模块中最重要的函数之一。它在文件的首行添加一个新条目。下面,我使用它将作者的新提交添加到主题菜单文件的开头。

清单 5. prepend 函数

//在一个现有文件的开头添加一行新内容。
 function prepend($file,$string) {
 // 有待改进 ? 使用数据库提高这个算法的可伸缩性。
 // 目前限制为 100 个故事。
 if (file_exists($file)) {
 $filetext = file($file);
 $lines = count($filetext);
 } else {
 $lines = 0;
 }
 if ($lines > 100) $lines = 100;
 $handle = fopen($file,"w");
 fputs ($handle, "$string\n");
 for ($i=0; $i<$lines; $i++)
 fputs ($handle, $filetext[$i]);
 fclose ($handle);
 }
                

如果文件存在,整个正文将存入 $filetext 数组中。然后统计出行数。如果文件不存在,则认为它有零行。长度限制为100 行(实际上是 101 行,因为第一行是在开始计数之前添加的)。文件打开,程序首先将当前的字符串写入文件中,然后再将剩余的行(最多100 行)写入文件中。这 100 行以后的任何内容将被丢弃。

这个函数依赖于 PHP内建的几个重要的文件处理函数。下表说明了每个函数所进行的操作。

函数说明
file_exists(string) 将字符串作为文件名,如果文件名当前存在,则返回 true。
file(string) 将字符串作为文件名,用一个数组返回文件的正文,每行分别对应一个数组元素。请注意,行终止字符将位于数组中每行的尾部。
count(array) 返回数组中的元素个数。
fopen(string, mode) 字符串是一个文件名,模式是一个字符串,例如 "w" 表示写入,"r"表示读取。打开文件,并返回一个句柄。
fputs(handle, string) 将字符串写入指定的输出文件中。必须指定一个文件句柄,而不能以字符串形式指定文件名。
fclose(handle) 关闭文件,终止输出。

Save
save 函数将作者的输入写入一个文件中。因这个函数太长,在此我不能逐行分析它,但我会强调几个有趣的语句。

$entry = "$storynum^$storytitle^$storyimg^$synopsis";
                

上面的这个语句将 $storynum$storytitle$storyimg$synopsis 变量连接起来,并用脱字符号作为分隔符。内嵌的变量替代使它比显式连接更容易且更有趣。

 prepend("Main.txt",$entry);
 $topicfile = "$subject.txt";
 prepend($topicfile,$entry);
                

$entry 变量的值被添加到主故事菜单文件和主题特定的故事菜单文件中。所以,如果变量 $subject 等于 "Politics",它就被添加到文件"Politics.txt" 中。

清单 6. “搜索并替换”语句

 // 选择性安全!将大多数 HTML 标记转换为文本。
 $storytext = eregi_replace("<", "<", $storytext);
 $storytext = eregi_replace("<b>", "<b>", $storytext);
 $storytext = eregi_replace("<i>", "<i>", $storytext);
                

对故事正文应用了许多“搜索并替换”语句;您上面看到的只是一小部分。用HTML 符号 < 替换 < 符号将防止作者在文档中输入任何有危险的 HTML标记。但是,因为我们希望为作者提供一些格式化能力,所以我们随后用 <b> 替换 <b> ,用 <i> 替换 <i> ,等等。 eregi_replace 函数不区分大小写。如要执行区分大小写的替换,则可以使用 ereg_replace (名称中不带 "i")。

初始化,设置
当运行 author.php3 时,该程序首先调用以下的代码:

清单 7. 验证语句

if ($submit == "Submit") {
 $status = "";
 if (!isset($storyimg)) $storyimg = "$subject.gif";
 validate("Subject",$subject,1);
 validate("Story Title",$storytitle,10);
 validate("Synopsis",$synopsis,50);
 validate("Story Text",$storytext,300);
 if ($status == "") {
 $status = "complete";
 save();
 }
 }
                





回页首


为何要使用 PHP

如果用户单击提交按钮调用表单(不是 "Preview Image" 按钮,尽管"Preview Image"按钮也是一个提交按钮),就会验证输入。 validate 函数检查每个域以确保它非空且足够长。(在此处添加一个最大长度特性将是一个很好的增强。)如果有问题, complain 函数(前面讨论过)就会更新全局变量 $status 。 如果没有问题,该程序就调用 save 函数以保存作者的输入。


本文旨在使您对使用 PHP编程是怎么回事有所了解,尤其是因为许多开发人员还没有完全投入到一种Web 脚本语言。我只讨论了创建这个特定应用程序所必需的 PHP特性,所以它们不只是您在实践中不会用到的理论特性。

出于多方面的考虑,PHP 是 Web应用程序开发的一个极具魅力的选择。下面是根据本例总结出的几个方面:

  • 将 PHP 和 HTML 一起集成在单个源文档中使得在现有网页中添加 PHP非常容易。这也意味着您可以用 HTML 设计一个想法的原型,然后再将 PHP添加进去。
  • 因为 PHP 的结构肯定会反映它们所生成的网页的结构,所以 PHP程序易于理解。由于同样的原因,用 PHP 进行设计也非常容易。
  • 正如您在这个应用程序中所看到的那样,文件处理函数和字符串处理函数的设计考虑到了易用性。这显然是PHP 背后的一个总体设计原则 --它不遵守某个人的编程语言理论模型;在实践中它很容易使用。
  • PHP 很容易掌握。它易于学习,入门阶段就可以写出很好的 Web应用程序。您不必面对很陡的学习曲线。在掌握基本知识以后,只要有一本手册,您就可以畅通无阻了。
  • PHP 在数据库处理方面也相当出色,但那是另一篇文章的内容。


我希望您感到使用 PHP是令人激动的。欢迎使用和修改本文所包含的源代码。



参考资料

  • 您可以参阅本文在 developerWorks 全球站点上的 英文原文.

  • 本系列文章的 第 1 部分会带您入门。

  • PHP.net 是 PHP 语言的官方主页。在这里您可以免费下载 PHP 的最新版本,还可以查看 PHP 开发的发展方向。这里还有一个常见问题解答、一个手册以及许多其他资源。

  • PHPbuilder.com 面向的是开发人员,其中包含大量的文章和代码样例、零活登记以及到 PHP 资源的链接。

  • Webmonkey 的 PHP 部分包含有关 PHP 的大量入门级文章。


关于作者

Erik Zolt 从 1990 年就开始从事专业编程。他住在马萨诸塞州的 Leominster,是一名专职远程工作者。您可以给他发送电子邮件(地址为 erik@zoltan.org)或访问他的主页(网址为 www.zoltan.org)。Erik 开着一辆 1996 年的 Saturn,车身上绘制的是梵高的 星夜。




对本文的评价

太差! (1)
需提高 (2)
一般;尚可 (3)
好文章 (4)
真棒!(5)

建议?







回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款