php基础教程

 

提供给新手学习的 PHP 新手教程,是一个比较有价值的 PHP 新手教程!  

 

 

出处:风流的 CG 网络日志

 时间:Mon, 28 Aug 2006 07:24:34 +0000

作者:yufeng

地址:http:///read.php?38 

一、PHP 简介 

PHP 是一种易于学习和使用的服务器端脚本语言。只需要很少的编程知识你就能使用 PHP 建立一个真正交互的 WEB站点。本教程并不想让你完全了解这种语言,只是能使你尽快加 入开发动态 web 站点的行列。我假定你有一些 HTML(或者 HTML 编辑器)的基本知识和 一些编程思想。 

1.简介 

PHP 是能让你生成动态网页的工具之一。PHP 网页文件被当作一般 HTML 网页文件来处理 并且在编辑时你可以用编辑 HTML 的常规方法编写 PHP。 

PHP 代表:超文本预处理器(PHP: Hypertext Preprocessor)。 PHP 是完全免费的,不用花钱, 你可以从 PHP 官方站点(http://www.php.net)自由下载。PHP 遵守 GNU 公共许可(GPL),在 这一许可下诞生了许多流行的软件诸如 Linux 和 Emacs。你可以不受限制的获得源码,甚至 可以从中加进你自己需要的特色。PHP 在大多数 Unix 平台,GUN/Linux 和微软 Windows 平台上均可以运行。怎样在 Windows 环境的 PC 机器或 Unix 机器上安装 PHP 的资料可以在 PHP 官方站点上找到。安装过程很简单。  

如果你的机器解决了 2000 问题,那么 PHP 也一样没有千年虫问题! 

1.1 历史 

三年前,Rasmus Lerdorf 为了创建他的在线简历而创造了"个人主页工具"(Personal Home Page Tools)。这是一种非常简单的语言。其后越来越多的人们注意到了这种语言并对其扩展 提出了各种建议。在许多人的无私奉献下以及这种语言本身的源代码自由性质,它演变成为 一种特点丰富的语言,而且现在还在成长中。 

PHP 虽然很容易学习,但是速度上比 mod_perl(植入 web 服务器的 perl 模块)慢。现在有 了可以与mod_perl速度想媲美的被称作 Zend 的新引擎,而 PHP4 就可以充分利用这个引擎。 PHP4 还处在 BETA 测试阶段。Andy Gutmans 和 Zeev Suraki 是 Zend 的主要作者。可以去

Zend 站点(http://www.zend.com)了解更多。 

PHP 的应用在个人性质的 web 工程中增长显著。根据 Netcraft 在 1999 年 10 月的报告,有 931122 个域和 321128 个 IP 地址利用 PHP 技术。 

1.2 PHP 的先进之处 

应用 PHP 有许多好处。当然已知的不利之处在于 PHP 由于是开放源码项目,没有什么商业 支持,并且由此而带来的执行速度缓慢(直到 PHP4 之前)。但是 PHP 的邮件列表很是有用 而且除非你正在运行像Yahoo!或者 Amazon.com 这样的极受欢迎的站点,你不会感觉出PHP 的速度与其他的有什么不同。最起码我就没有感觉出来!好了,让我们来看看 PHP 有那些 优点: 

- 学习过程  

我个人更喜欢 PHP 的非常简单的学习过程。与 Java和 Perl 不同,你不必把头埋进 100 多页的 文档中努力学习才可以写出一个象样的程序。只要了解一些基本的语法和语言特色,你就可 以开始你的 PHP 编码之旅了。之后你在编码过程中如果遇到了什么麻烦,还可以再去翻阅 相关文档。 

PHP 的语法与 C,Perl,ASP 或者 JSP。对于那些对上述之一的语言较熟悉的人来说,PHP 太简单了。相反的,如果你对 PHP 了解较多,那么你对于其他几种语言的学习都很简单了。 

你只需要 30 分钟就可以将PHP 的核心语言特点全部掌握,你可能已经非常了解 HTML,甚 至你已经知道怎样用编辑设计软件或者手工来制作好看的 WEB 站点。由于 PHP 代码能够 无障碍的添加进你的站点,在你设计和维护站点的同时,你可以很轻松的加入 PHP 使得你 的站点更加具有动态特性。 

- 数据库连接 

PHP 可以编译成具有与许多数据库相连接的函数。PHP 与 MySQL 是现在绝佳的组合。你还 可以自己编写外围的函数取间接存取数据库。通过这样的途径当你更换使用的数据库时,可 以轻松的更改编码以适应这样的变化。PHPLIB就是最常用的可以提供一般事务需要的一系 列基库。 

- 可扩展性 

就像前面说的那样,PHP 已经进入了一个高速发展的时期。对于一个非程序员来说为 PHP 扩展附加功能可能会比较难,但是对于一个 PHP 程序员来说并不困难。 

- 面向对象编程 

PHP 提供了类和对象。基于 web 的编程工作非常需要面向对象编程能力。PHP 支持构造器、

提取类等。 

- 可伸缩性 

传统上网页的交互作用是通过 CGI 来实现的。CGI 程序的伸缩性不很理想,因为它为每一 个正在运行的 CGI 程序开一个独立进程。解决方法就是将经常用来编写 CGI 程序的语言的 解释器编译进你的 web 服务器(比如 mod_perl,JSP)。PHP 就可以以这种方式安装,虽然很少 有人愿意这样以 CGI 方式安装它。内嵌的 PHP 可以具有更高的可伸缩性。 

- 更多特点 

PHP 的开发者们为了更适合 web 编程,开发了许多外围的流行基库,这些库包含了更易用 的层。你可以利用 PHP 连接包括 Oracle,MS-Access,Mysql 在内的大部分数据库。你可以 在苍蝇上画图,编写程序下载或者显示 e-mail。你甚至可以完成网络相关的功能。最好的是, 你可以选择你的 PHP 安装版本需要哪些功能。引用 Nissan 的 Xterra 的话来说就是 PHP 可以 做到你想让它做到的一切而且无所不能! 

1.3 竞争对手:ASP,mod_perl,JSP 

我当然不清楚 ASP/JSP 能做些什么。不过明确的是编写那样的代码有多简单,购买它们会 有多昂贵以及它们需要多么昂贵和强大的硬件。如果你有什么中立的观点(比如说没有被 SUN 和 Microsoft 的百万美金所影响),请顺便通知我。 

据我所知,JSP 基于 Java,因此 Java 程序员可以轻松开始编码。ASP 只是一个一般的引擎, 具有支持多种语言的能力,不过默认的并且是最常用的还是 VBScript。 

mod_perl 与 Perl 一样强大,只是更快一些。 

二、PHP 入门 

PHP 站点的在线教程已经很棒了。在那里还有一些其他教程的链接。而本文的该部分将让 你对 PHP 熟悉一点。我不可能做到没有任何遗漏,我的目的只在于能让你迅速开始你的 PHP 编程。 

2.1 首要条件 

你首先必须要有一个正在工作着的支持PHP的web服务器。我假定在你的服务器上所有PHP 文件的扩展名为.php3。 

2.2 PHP 的安装 

生成一个名为 test.php3 的文件,含有以下内容: <? phpinfo(); ?> 然后在你的浏览器中打开此文件。看看这个页面你就知道你的 PHP 安装使用的选项了。

 2.3 语法 

就像前面提到的一样,你可以混合编写你的 PHP 代码和 HTML 代码。因此你必须有办法将 两者区别开来。以下就是你可以采用的几种方法。你可以选用其中一种你最适应的并且就这 样坚持这种方法! 

从 HTML 中分离 

以下是可以使用的方法:

<? . . . ?> <?php . . . ?> <script language="php"> . . . </script> <% . . . %> 

语句 

与 Perl 和 C 一样,在 PHP 中用(;)来分隔语句。那些从 HTML 中分离出来的标志也表示 语句的结束。 

注释 

PHP 支持 C,C++和 Unix 风格的注释方式: 

/* C,C++风格多行注释 */ // C++风格单行注释 # Unix 风格单行注释 

Hello,World! 

通过我们已经学过的知识,你可以编写一个最简单的程序输出一个也许是程序世界中最有名 的词语:

 <HTML>

 <HEAD>

 <TITLE>

<? echo "Hello World!"; ?>

 </TITLE>

</HEAD>

<BODY> <H1> First PHP page </H1>

<HR> <? // Single line C++ style comment /* printing the message */

echo "Hello World!"; # Unix style single line comment ?>

 </BODY>

 </HTML> 

2.4 数据类型 

PHP 支持整数、浮点数、字符串、数组和对象。变量类型通常不由程序员决定而由 PHP 运 行过程决定(真是好的解脱!)。但是类型也可以被函数 cast 或者 settype()明确的设定。 

数值 

数值类型可以是整数或是浮点数。你可以用以下的语句来为一个数值赋值: $a = 1234; # 十进制数 $a = -123; # 负数 $a = 0123; # 八进制数 (等于十进制数的 83) $a = 0x12; # 十六进制数(等于十进制数的 18) $a = 1.234; # 浮点数"双精度数" $a = 1.2e3; # 双精度数的指数形式 

字符串 

字符串可以由单引号或双引号引出的字段定义。注意不同的是被单引号引出的字符串是以字 面定义的,而双引号引出的字符串可以被扩展。反斜杠(&#92;)可以被用来分割某些特殊 字符。举例如下: $first = ‘Hello‘; $second = "World"; $full1 = "$first $second"; # 产生 Hello World $full2 = ‘$first $second‘;# 产生 $first $second 

可以将字符和数字利用运算符号连接起来。字符被转化成数字,利用其最初位置。在 PHP 手册中有详细的例子。 

数组与哈希表 

数组与哈希表以同样的方法被支持。怎样运用取决于你怎样定义它们。你可以用 list()或者 array()来定义它们,也可以直接为数组赋值。数组的索引从0 开始。虽然我在这里没有说明,

但是你一样可以轻易的使用多维数组。 

// 一个包含两个元素的数组 $a&#91;0&#93; = "first"; $a&#91;1&#93; = "second"; $a&#91;&#93; = "third"; // 添加数组元素的简单方法 // 现在$a&#91;2&#93;被赋值为"third" echo count($a); // 打印出 3,因为该是数组有 3 个元素 // 用一个语句定义一个数组并赋值 $myphonebook = array ( "sbabu" => "5348", "keith" => "4829", "carole" => "4533" ); // 噢,忘了教长吧,让我们添加一个元素 $myphonebook&#91;"dean"&#93; = "5397"; // 你定义的 carale 元素错了,让我们更正它 $myphonebook&#91;"carole"&#93; => "4522" // 我还没有告诉你怎样使用数组的相似支持方式吗?让我们看一看 echo "$myphonebook&#91;0&#93;"; // sbabu echo "$myphonebook&#91;1&#93;"; // 5348 

其他一些对数组或哈希表有用的函数包括 sort(),next(),prev()和 each()。 

对象 

使用 new 语句产生一个对象:

 class foo { function do_foo () { echo "Doing foo."; } } $bar = new foo; $bar->do_foo(); 

改变变量类型 

在 PHP 手册中提到:"PHP 不支持(也不需要)直接在声明变量时定义变量类型;变量类型 将根据其被应用的情况决定。如果你为变量 var 赋值为一个字符串,那么它变成了一个字符 串。如果你又为它赋了整数值,那么它就变成了整数。" $foo = "0"; // $foo 是字符串(ASCII 48) $foo++; // $foo 是字符串"1" (ASCII 49)

$foo += 1; // $foo 现在是整数(2) $foo = $foo + 1.3; // $foo 是一个双精度数(3.3) $foo = 5 + "10 Little Piggies"; // $foo 是一个整数(15) $foo = 5 + "10 Small Pigs"; // $foo 是一个整数(15) 

如果想要强行转换变量类型,可以使用与 C 语言相同的函数 settype()。 

2.5 变量与常量 

可能你已经注意到,变量都有一个美元符号($)的前缀。所有变量都是局部变量,为了使 得定义的函数中可以使用外部变量,使用 global 语句。而你要将该变量的作用范围限制在该 函数之内,使用 static 语句。 $g_var = 1 ; // 全局范围 function test() { global $g_var; // 这样就可以声明全局变量了 } 

更先进一些的是变量的变量表示。请参考 PHP 手册。这在有时会显得很有用。 

PHP 内置了许多已定义的变量。你也可以用 define 函数定义你自己的常量,比如 define("CONSTANT","value")。 

2.6 运算符 

PHP 具有 C,C++和 Java 中的通常见到的运算符。这些运算符的优先权也是一致的。赋值同 样使用"="。 

算术和字符 

以下只有一种运算符是有关字符的: $a + $b :加 $a - $b :减 $a * $b :乘 $a / $b :除 $a % $b :取模(余数) $a . $b :字符串连接 

逻辑和比较 

逻辑运算符有: $a &#124;&#124; $b :或 $a or $b :或 $a && $b :与

$a and $b :与 $a xor $b :异或 (当$a 或$b 为 true 时为 true,两者一样时为 false) ! $a :非 比较运算符有: $a == $b :相等 $a != $b :不等 $a < $b :小于 $a <= $b :小于等于 $a > $b :大于 $a >= $b :大于等于 与 C 一样 PHP 也有三重运算符(?:)。位操作符在 PHP 同样存在。 

优先权 

就和 C 以及 Java 一样! 

2.7 控制流程结构 

PHP 有着与 C 一样的流程控制。我将在下面大概介绍。 

if, else, elseif, if(): endif 

if (表达式一)

{ . . . }

elseif (表达式二)

 { . . . }

else { . . . }

 // 或者像 Python 一样 if (表达式一) : . . . . . .

elseif (表达式二) : . . .

else : . . .

endif ; 

Loops. while, do..while, for 

while (表达式)

 { . . . }

do

{ . . . }

while (表达式);

for (表达式一; 表达式二; 表达式三)

 { . . . } //或者像 Python 一样 while (expr) : . . . endwhile ; 

switch 

switch 是对多重 if-elseif-else 结构的最好的替换:

 switch ($i)

 {

case 0: print "i equals 0";

case 1: print "i equals 1";

case 2: print "i equals 2"; } 

break, continue 

break 中断当前的循环控制结构。 continue 被用来跳出剩下的当前循环并继续执行下一次循环。 

require, include 

就像 C 中的#include 预处理一样。你在 require 中指定的那个文件将替代其在主文件中的位 置。在有条件的引用文件时,可以使用 include()。这样就使得你可以将复杂的 PHP 文件分 割成多个文件并且在不同需要时分别引用它们。 

2.8 函数 

你可以像以下的例子一样定义自己的函数。函数的返回值可以是任何数据类型: function foo (变量名一, 变量名二, . . . , 变量名 n) { echo "Example function.&#92;n"; return $retval; } 所有 PHP 代码都可以出现在函数定义中,甚至包括对其他函数和类的定义。函数必须在引 用之前定义。 

2.9 类 

利用类模型建立类。可以参考 PHP 手册中对类的详细解释。 class Employee { var $empno; // 员工人数 var $empnm; // 员工姓名 

function add_employee($in_num, $in_name)

{

 $this->empno = $in_num;

 $this->empnm = $in_name;

function show()

 {

echo "$this->empno, $this->empnm";

 return;

function changenm($in_name)

 {

 $this->empnm = $in_name;

}

$sbabu = new Employee;

$sbabu->add_employee(10,"sbabu");

$sbabu->changenm("babu"); 

$sbabu->show(); 

三、从实例入手 

 PHP 的许多特点与其他软件或者工具有关。利用迄今为止我们所学到的 PHP 知识,我们可 以试着建立一个简单交互的网站。利用这一过程我们又可以学到不少东西。好吧,我们现在 开始专注于一个典型个人网站的建设。 

3.1 计划一个站点 一般一个个人站点包括一个欢迎页面、一个留言本页面、一个书签链接页面、一个计数器、 联系信息,甚至还有照片集和一些音乐文件等等。让我们从一个标题页面、一个联系信息页 面和一个简历页面开始。我们同样需要标准的通用的页面头部和底部。 

标题页面--front.html  

这里我们有一个非常简单的 html 文件: <HTML> <HEAD> <TITLE> 我的个人主页--欢迎 </TITLE> </HEAD> <BODY> <H1> 我的个人主页 </H1> <H2> 欢迎 </H2> <HR> <P> 欢迎来我的寒舍,虽然这里现在暂时还没有什么。 </P> <P> 不过我希望马上就可以多起来。 </P> <HR> <P ALIGN="CENTER"> <SMALL> <I> Copyright ? 我自己,1999 </I> </SMALL> </P> </BODY> </HTML> 

联系信息页面--count.html

 同样我们又有了一个简单页面: <HTML> <HEAD> <TITLE> 我的个人主页--联系信息 </TITLE> </HEAD> <BODY> <H1> 我的个人主页 </H1> <H2> 联系信息 </H2> <HR> <P> 你可以通过 1-800-PHP-INFO 联系我 </P> <HR> <P ALIGN="CENTER"> <SMALL> <I> Copyright ? 我自己,1999 </I> </SMALL> </P> </BODY> </HTML>  

3.2 HTML 到 PHP 

从上面你可以看出,每个页面有相同的头部和底部。像上面那样每个页面都写入相同的信息 在工作量少的时候还可以,但是想象一下当有 100 多页面且你需要全部更改其头部或底部时 你要花费多大精力?一页一页的手工更改是一件多么冗长无趣的事情啊!所以我们应该为这 些页面编写 PHP 的头部和底部文件,之后我们只要在每个 HTML 页面中引用它们就行了。 我们将把这些 include 文件放在一个叫 include 的子目录下。下面我们就把这些站点的通用内 容写进文件中。 

全站通用变量设定:common.inc <? // 全站通用变量 $MyEmail = "[email protected]"; $MyEmailLink = "<a href=&#92;"mailto:$MyEmail&#92;">$MyEmail</a>"; $MyName = "PHP Talk";

$MySiteName = $MyName."‘s Home Page"; ?> 

通用页面头部:header.inc <? // 定义通用页面头部 ?> <HTML> <HEAD> <TITLE> <? echo "$MySiteName - $title"; ?> </TITLE> </HEAD> <BODY> <H1> <? echo "$MySiteName"; ?> </H1> <H2> <? echo "$title"; ?> </H2> <HR> 

通用页面底部:footer.inc <? // 通用页面底部 ?> <HR> <P ALIGN="CENTER"> <SMALL> <I> Copyright ? by <? echo "$MyName ($MyEmailLink)"; ?> , 1999 </I> </SMALL> </P> </BODY> </HTML> 

新的页面 front.php3: <? include("include/common.inc"); $title = "Welcome"; include("include/header.inc"); ?> <P>

欢迎来我的寒舍,虽然这里现在暂时还没有什么。 </P> <P> 不过我希望马上就可以多起来。 </P> <? include("include/footer.inc"); ?> 

新的 cont.php3: <? include("include/common.inc"); $title = "Contact Information"; include("include/header.inc"); ?> <P> 你可以通过 1-800-PHP-INFO 联系我 </P> <? include("include/footer.inc"); ?> 

现在你就可以猜出这样安排的好处了。如果你想改动页面的头部或者底部,你只需要改动相 应的文件就可以了。如果你要修改你的 e-mail 地址甚至你的名字,只要修改 common.inc 文 件就行了。另外值得注意的是你可以把具有任何文件名或者文件扩展名的文件包含进你的文 件中,你甚至可以包含其他站点上的文件。 

3.3 计数器 

让我们在首页上加上一个计数器。这个例子已经被讲过多次了,但是还是有利于演示怎样读 写文件以及创建自己的函数。counter.inc 包含以下代码: <? /* &#124;&#124; 一个简单的计数器 */ function get_hitcount($counter_file) { /* 将计数器归零 这样如果计数器还未被使用,初始值将是 1 你当然也可以把初始值设成 20000 来骗人咯 */ $count=0; // 如果存放计数器文件已经存在,读取其中的内容 if ( file_exists($counter_file) )

{ $fp=fopen($counter_file,"r"); // 我们只取了前 20 位,希望你的站点不要太受欢迎啊 $count=0+fgets($fp,20); // 由于函数 fgets()返回字符串,我们可以通过加 0 的方法将其自动转换为整数 fclose($fp); // 对文件操作完毕 } // 增加一次计数值 $count++; // 将新的计数值写入文件 $fp=fopen($counter_file,"w"); fputs($fp,$count); fclose($fp); # 返回计数值 return ($count); } ?> 然后我们更改 front.php3 文件以显示这个计数器: <? include("include/counter.inc"); // 我把计数值放在文件 counter.txt 中,读出并输出 printf ("<CENTER><B>%06d</B></CENTER> <BR> &#92;n", get_hitcount("counter.txt")); include("include/footer.inc"); ?> 看看我们的新 front.php3 

3.4 反馈表单 

让我们再添加一个反馈表单以便你的浏览者填写并 e-mail 给你。举例来说我们用一种很简 单的方法实现它,我们只需要两个页面:一个为浏览者提供输入表单;一个获得表单数据并 处理、mail 给你。 

PHP 中获取表单数据是很简单的。当一个表单被发送后,表单中所包含的各个元素被赋上 了相应的值,而这样就可以像引用一般变量一样使用了。 <FORM name="myform" ACTION="process_form.php3" METHOD="POST"> <INPUT TYPE="TEXT" NAME="mytext" VALUE="Some Value"> </FORM> 

在 process_form.php3 中,变量$mytext 就被赋予了输入的值--非常简单!同样的,你可以从 列表框、多选框、单选框、按钮等表单元素中取得变量值。你唯一要做的就是为表单中的每 一个元素取名以便将来可以引用。 

根据这个方法,我们可以生成一个简单的包含三个元素的表单:姓名、e-mail 地址和留言。 当浏览者发送表单后,处理该表单的 PHP 页面(sendfdbk.php3)读取数据,检查姓名是否 为空,最后将数据 mail 给你。 

表单:form.php3 <? include("include/common.inc"); $title = "Feedback"; include("include/header.inc"); ?> <P> <FORM ACTION="sendfdbk.php3" METHOD="POST"> <INPUT TYPE="text" NAME="name" value="Your name" SIZE="20" MAXLENGTH="30"> <INPUT TYPE="text" MAXLENGTH="40" WIDTH="20" value="Your Email" NAME="email"> <BR> <TEXTAREA ROWS="7" COLS="40" NAME="comment"> Your feedback on my home page. </TEXTAREA> <BR> <INPUT TYPE="submit" VALUE="Send Feedback!"> </FORM> </P> <? include("include/footer.inc"); ?> 

处理表单:sendfdbk.php3 <? include("include/common.inc"); $title = "Feedback"; include("include/header.inc"); if ( $name == "" ) { // 现在我很讨厌匿名的留言! echo "Duh ? How come you are anonymous?"; } elseif ($name == "Your name") { // 这个浏览者真是不想透露姓名啊! echo "Hello ? <B>Your name</B> is supposed to be replaced with your actual name!</B>"; } else

{ // 输出一段礼貌的感谢语 echo " Hello, $name. <BR> Thank you for your feedback. It is greatly appreciated. <BR> Thanking you <BR> $MyName <BR> $MyEmailLink "; // 最后 mail 出去 mail($MyEmail, "Feedback."," Name : $name E-mail : $email Comment : $comment "); } include("include/footer.inc"); ?> 

3.5 简单的站内搜索引擎 

PHP 可以调用外部程序。在 Unix 环境下我们可以利用程序 grep 实现一个简单的搜索引擎。 我们可以做的稍微复杂一些:使用一个页面既输出一个表单供用户输入搜索字串又输出查询 结果。 <? include("include/common.inc"); $title = "Search"; include("include/header.inc"); ?> <P> <FORM ACTION="<? echo "$PHP_SELF"; ?>" METHOD="POST"> <INPUT TYPE="text" NAME="searchstr" value="<? echo "$searchstr"; ?>" SIZE="20" MAXLENGTH="30"> <INPUT TYPE="submit" VALUE="Search!"> </FORM> </P> <? if ( ! empty($searchstr) ) { // empty()用来检查查询字串是否为空 // 如果不为空,调用 grep 查询

echo "<HR>&#92;n"; // 调用 grep 对所有文件进行大小写非敏感模式的查询 $cmdstr = "grep -i $searchstr *"; $fp = popen( $cmdstr, "r" ); // 执行命令并输出管道 $myresult = array(); // 存储查询结果 while( $buffer = fgetss ($fp, 4096)) { // grep 返回这样格式: 文件名:匹配字串出现行数 // 因此我们利用函数 split()分离处理数据 list($fname, $fline) = split(":",$buffer, 2); // 我们只输出第一次匹配的结果 if ( !defined($myresult&#91;$fname&#93;)) $myresult&#91;$fname&#93; = $fline; } // 现在我们将结果存储在数组中,下面就可以处理并输出了 if ( count($myresult) ) { echo "<OL>&#92;n"; while(list($fname,$fline) = each($myresult)) echo "<LI> <A HREF=&#92;"$fname&#92;">$fname</A> : $fline </LI>&#92;n"; echo "</OL>&#92;n"; } else { // 如果没有查询结果 echo "Sorry. Search on <B>$searchstr</B> returned no results.<BR>&#92;n"; } pclose($fp); } ?> <? include("include/footer.inc"); ?>  

注释: 

PHP_SELF 是 PHP 内建的变量。包含当前文件名。 fgets()按行读取文件,最多 4096(指定)字符长度。 fgetss()与 fgets()相似,只是解析输出的 HTML 标记。 split()有一个参数是 2,因为我们只需要把输出分成两部分。另外需要省略":"。 each()是一个数组操作函数,用来更方便的遍历整个数组。

popen()、pclose()与 fopen()、fclose()的功能很相似,只是增加了管道处理。 请注意以上的代码并不是实现一个搜索引擎的好办法。这只是有助于我们更好学习 PHP 而 举出的一个例子而已。理想的情况是你应该建立一个包含关键字的数据库然后进行搜索  

四、与数据库链接 

通过 PHP 你可以轻松的连接到数据库,请求数据并将其显示在你的 web 站点中,甚至修改 数据库中的数据。MySQL 是一种很流行的数据库,并且在互联网中有许多有关 PHP 与 MySQL 的教程。MySQL 是免费的,这一点也许就吸引了不少人。由于其广泛应用,我就 不想在这里赘述 MySQL 的使用方法了。Oracle 被大量在企业应用中采用,因此我们就利用 Oracle 来介绍 PHP 与数据库的连接。我们当然不会提及 Oracle 数据库的设计原理,原因是 这已经超出了我们的讨论范围。 PHP 提供了两套函数与 Oracle 连接,分别是 ORA_和 OCI 函数。其中 ORA_函数略显陈旧。 OCI 函数更新据说更好一些。两者的使用语法几乎相差无几。如前所述,你的 PHP 安装选 项应该可以支持两者的使用。 想获得更多有关在Microsoft Windows 平台上安装支持PHP3 的 Apache服务器的知识以及更 多有关 Oracle 数据库的知识,请查阅以下 URL:www.csoft.net/~vsbabu/articles/oraphp.html。 

4.1 连接 

<? if ($conn=Ora_Logon("user@TNSNAME","password")) { echo "<B>SUCCESS ! Connected to database<B>&#92;n"; } else { echo "<B>Failed :-( Could not connect to database<B>&#92;n"; } Ora_Logoff($conn); phpinfo(); ?> 以上代码使用 TNSNAME(在你的 tnsnames.ora 文件中指明)定义的 Oracle 数据库名称、用 户名称和密码连接数据库。在成功连接的基础上,ora_logon 函数返回一个非零的连接 ID 并 储存在变量$conn 中。 

4.2 查询 

假设与数据库已经连接就绪,下面我们就来实际的应用对数据库的查询。下面的代码演示了 一个连接并查询的典型例子: <? /* * 连接数据库并执行查询

*/ function printoraerr($in_cur) { // 检查 Oracle 是否出错 // 如果存在错误则显示 // 当指针被激活时每次请求 Oracle 后调用该函数 if(ora_errorcode($in_cur)) echo "Oracle code - ".ora_error($in_cur)."&#92;n"; return; } /** 主程序 */ if (!($conn=ora_logon("user@TNSNAME","password"))) { echo "Connection to database failed&#92;n"; exit; } echo "Connected as connection - <b>$conn</b><br>&#92;n"; echo "Opening cursor ...<br>&#92;n"; $cursor=ora_open($conn); printoraerr($cursor); echo "Opened cursor - <b>$cursor</b><br>&#92;n"; $qry="select user,sysdate from dual"; echo "Parsing the query <b>$qry</b> ...<br>&#92;n"; ora_parse($cursor,$qry,0); printoraerr($cursor); echo "Query parsed <br>&#92;n"; echo "Executing cursor ...<br>&#92;n"; ora_exec($cursor); printoraerr($cursor); echo "Executed cursor<br>&#92;n"; echo "Fetching cursor ...<br>&#92;n"; while(ora_fetch($cursor)) { $user=ora_getcolumn($cursor,0); printoraerr($cursor); $sysdate=ora_getcolumn($cursor,1); printoraerr($cursor); echo " row = <B>$user, $sysdate </B><br>&#92;n"; } echo "Fetched all records<br>&#92;n"; echo "Closing cursor ...<br>&#92;n"; ora_close($cursor); echo "Closed cursor<br>&#92;n"; echo "Logging off from oracle... <br>&#92;n"; ora_logoff($conn); echo "Logged off from oracle <br>&#92;n"; ?> (译者注:以上代码段缺少注释,请读者参考 PHP Manual 的 Oracle 数据库函数部分) 

4.3 显示结果 

以下代码演示了怎样查询数据库并将结果输出: <? function printoraerr($in_cur, $conn) { // 检查 Oracle 是否出错 // 如果存在错误则显示 // 当指针被激活时每次请求 Oracle 后调用该函数 // If it encountered an error, we exit immediately if(ora_errorcode($in_cur)) { echo "Oracle code - ".ora_error($in_cur)."<br>n"; ora_logoff($conn); exit; } return; } 

function exequery($w_qry,$conn) { $cursor=ora_open($conn); printoraerr($cursor,$conn); ora_parse($cursor,$w_qry,0); printoraerr($cursor,$conn); ora_exec($cursor); printoraerr($cursor,$conn); $numrows=0; $w_numcols=ora_numcols($cursor); // 显示头部 echo " <TABLE WIDTH=&#92;"100%&#92;" BORDER=&#92;"0&#92;" CELLSPACING=&#92;"1&#92;" CELLPADDING=&#92;"2&#92;"> <TR>&#92;n"; for ($i=0;$i<$w_numcols;$i++) { $align=(ora_columntype($cursor,$i)=="NUMBER")?"RIGHT":"LEFT"; echo "&#92;t<TH VALIGN=TOP ALIGN=$align>".ora_columnname($cursor,$i)."</TH>&#92;n"; } echo "</TR>&#92;n"; while(ora_fetch($cursor)) { echo "<TR>&#92;n"; for ($i=0;$i<$w_numcols;$i++) { $align=(ora_columntype($cursor,$i)=="NUMBER")?"RIGHT":"LEFT";

if(ora_columntype($cursor,$i)=="LONG") echo "<TD VALIGN=TOP ALIGN=$align><PRE>". ora_getcolumn($cursor,$i)."</PRE></TD>&#92;n"; else echo "<TD VALIGN=TOP ALIGN=$align>".ora_getcolumn($cursor,$i)."</TD>&#92;n"; printoraerr($cursor,$conn); } $numrows++; echo "</TR>&#92;n"; } if ($numrows==0) echo "<TR><TD COLSPAN=&#92;"$w_numcols&#92;"><B>Query returned no records </B></TD></TR>&#92;n"; else { echo "<TR>&#92;n"; echo "<TH COLSPAN=&#92;"".($w_numcols-1)."&#92;" ALIGN=RIGHT>Count</TH>&#92;n"; echo "<TH ALIGN=RIGHT>$numrows</TH>&#92;n"; echo "</TR>&#92;n"; } echo "</TABLE>&#92;n"; ora_close($cursor); return; } 

// 主程序 if(!($conn=ora_logon("user@SID","password"))) { echo "Error: Cannot connect to database&#92;n"; exit; } $qry="SELECT deptno &#92;"Dept&#92;" ,empno &#92;"Emp&#92;" ,empnm &#92;"Name&#92;" ,salary &#92;"Salary&#92;" FROM employee ORDER BY 1,2"; exequery($qry); ora_logoff($conn); ?> (译者注:以上代码段缺少注释,请读者参考 PHP Manual 的 Oracle 数据库函数部分)

 4.4 基于 HTTP 的 Oracle 登录 

将以下代码加在 PHP 页面代码之前以确认 Oracle 登录。注意你必须正确设定$ SID。 <? if(!isset($PHP_AUTH_USER)) { Header("WWW-authenticate: basic realm=&#92;"$SID&#92;""); Header("HTTP/1.0 401 Unauthorized"); $title="Login Instructions"; echo "<blockquote> You are not authorized to enter the site </blockquote> &#92;n"; exit; } else { if (!($conn=ora_logon("$PHP_AUTH_USER@$SID",$PHP_AUTH_PW))) { Header("WWW-authenticate: basic realm=&#92;"$SID&#92;""); Header("HTTP/1.0 401 Unauthorized"); $title="Login Instructions"; echo "<blockquote> You are not authorised to enter the site </blockquote> &#92;n"; exit; } } ?> 

五、其它功能  

5.1 生成图像 

PHP 可以操作处理图像。如果你已经安装了 GD 库,你甚至可以利用 PHP 生成图像。 <? Header("Content-type: image/gif"); $string=implode($argv," "); $im = imagecreatefromgif("images/button1.gif"); $orange = ImageColorAllocate($im, 220, 210, 60); $px = (imagesx($im)-7.5*strlen($string))/2; ImageString($im,3,$px,9,$string,$orange); ImageGif($im); ImageDestroy($im);

?> (译者注:以上代码段缺少注释,请读者参考 PHP Manual 的图像处理函数部分) 这段代码在其他页面中通过以下标记<img src="button.php3?text">调用,然后以上的那段 button.php3 代码取得text 值并在另外取得的图像文件中加上该值--在以上的代码中该图像文 件是 images/button1.gif--最后输出到浏览器。假如你想在表单域中使用图像按钮,但是又不 希望在每次按钮上的文字改变后不得不重新生成新的图像,就可以利用这样简单的方法动态 生成图像文件。 

5.2 Cookies 

PHP 支持基于 HTTP 的 cookies。在需要时你可以像使用一般变量一样方便的使用 cookie。 Cookies 是浏览器保存于客户端的一些信息片段,由此你可以知道是否一台特定 PC 上的任 何人都访问过你的站点,浏览者者在你的站点上的踪迹等等。使用 cookies 的典型例子就是 对浏览者偏好的甄别。Cookies 由函数 setcookie()设定。与输出 HTTP 标头的函数 header() 一样,setcookie()必须在任何实际内容杯输出到浏览器之前调用。以下是一个简单例子: <? if (empty($VisitedBefore)) { // 如果没有设定 cookie,为 cookie 赋上当前时间值 // 函数中的最后一个参数声明了该 cookie 保存的时间 // 在这个例子中是 1 年 // time()函数返回自 1970 年 1 月 1 日以来的以秒数计的时间 SetCookie("VisitedBefore",time(), time()+(60*60*24*365)); } else { // 欢迎浏览者再次光临 echo "Hello there, welcome back<BR>"; // 读取 cookie 并判断 if ( (time() - $VisitedBefore) >= "(60*60*24*7)" ) echo "Why did you take a week to come back. You should be here more often!? "; } ?> 

5.3 基于 HTTP 验证 

基于 HTTP 验证当 PHP 以 CGI 模式运行时不能实现。我们可以使用函数 header()发送 HTTP 标头强制验证,客户端浏览器则弹出供输入用户名和密码的对话框。这两个变量被储存在 $PHP_AUTH_USER 和$PHP_AUTH_PW 中,你可以使用这两个变量验证合法并允许进入。 以下的例子通过用户名称/密码对为 tnc/nature 的验证一名用户的登录: <? if(!isset($PHP_AUTH_USER)) { Header("WWW-Authenticate: Basic realm=&#92;"My Realm&#92;"");

Header("HTTP/1.0 401 Unauthorized"); echo "Text to send if user hits Cancel button&#92;n"; exit; } else { if ( !($PHP_AUTH_USER=="tnc" && $PHP_AUTH_PW=="nature") ) { // 如果是错误的用户名称/密码对,强制再验证 Header("WWW-Authenticate: Basic realm=&#92;"My Realm&#92;""); Header("HTTP/1.0 401 Unauthorized"); echo "ERROR : $PHP_AUTH_USER/$PHP_AUTH_PW is invalid."; exit; } else { echo "Welcome tnc!"; } ?> 事实上再实际引用中不大可能如上面使用代码段明显的用户名称/密码对,而是利用数据库 或者加密的密码文件存取它们。 

5.4 文件上传 

你可以利用PHP 实现文件的功能,注意客户端的浏览器应该是Netscape3 以上或者 IE3 以上。 以下就是该功能的简单演示: ( upload.html ): <HTML> <HEAD> <TITLE>Upload Your File</TITLE> </HEAD> <BODY> <FORM ACTION="receiver.php3" ENCTYPE="multipart/form-data" METHOD=POST> <INPUT TYPE="HIDDEN" NAME="MAX_FILE_SIZE" VALUE="2000000"> <INPUT TYPE="FILE" NAME="uploadfile" SIZE="24" MAXLENGTH="80"> <BR><BR> <INPUT TYPE="SUBMIT" VALUE="Upload File!" NAME="sendit"> <INPUT TYPE="SUBMIT" VALUE="Cancel" NAME="cancelit"><BR> </FORM>

<I><FONT SIZE="2">(You may notice a slight delay while we upload your file.)</FONT></I> </BODY> </HTML> 

下面是处理上传的文件: ( receiver.php3 ): <? function do_upload () { global $uploadfile, $uploadfile_size; global $local_file, $error_msg; if ( $uploadfile == "none" ) { $error_msg = "You did not specify a file for uploading."; return; } if ( $uploadfile_size > 2000000 ) { $error_msg = "Sorry, your file is too large."; return; } $the_time = time (); // 你需要对以下目录有写权限 $upload_dir = "/local/uploads"; $local_file = "$upload_dir/$the_time"; if ( file_exists ( ‘$local_file‘ ) ) { $seq = 1; while ( file_exists ( "$upload_dir/$the_time$seq" ) ) { $seq++; } $local_file = "$upload_dir/$the_time$seq"; }; rename ( $uploadfile, $local_file ); display_page (); } function display_page () { // 这里是你的页面内容 } <HTML> <HEAD> <TITLE>php3 Receiving Script</TITLE> </HEAD> <BODY>

<? if ( $error_msg ) { echo "<B>$error_msg</B><BR><BR>"; } if ( $sendit ) { do_upload (); } elseif ( $cancelit ) { header ( "Location: $some_other_script" ); exit; } else { some_other_func (); } ?> </BODY> </HTML> 

5.5 常用函数 

我们简单来看看一些常用的函数。 

数组  

array - 生成数组 count - 数组元素个数 sort - 数组排序,另有其他几种排序函数可供使用 list - 列出数组元素 each - 返回下一个 key/value 对 current - 返回当前数组元素 next,prev - 传回当前数组元素前后指针   

日期和时间 

checkdate - 验证日期/时间格式 date - 生成日期/时间格式 time - 当前时间信息 strftime - 格式化日期/时间 

目录、文件系统

 chdir - 改变目录 dir - 目录类别 opendir, readdir, closedir - 开启、读取、关闭目录 fopen, fclose - 开启、关闭文件 fgets, fgetss - 逐行读取内容 file - 将整个文件读入一个数组变量中 

正则表达式 

ereg - 匹配正则表达式 eregi - 大小写非敏感匹配正则表达式 ereg_replace -匹配正则表达式并替换 eregi_replace -大小写非敏感匹配正则表达式并替换 split - 依规则切开字符串并以数组形势存储   

字符串 

AddSlashes - 加上斜杠后使用字符串 echo - 输出一个或多个字符串 join, implode - 将数组元素合并为字符串 htmlentities, htmlspecialchars - 将 HTML 特殊字符转换为 HTML 标记形式 split - 依规则切开字符串并以数组形势存储 5.6 扩展我们的范例主页 

我们将使用以上提到的一些函数和思想为我们的范例主页添加更多的动态内容。我们可以在 每个页面的顶部加上导航栏,同时使得当前页自动的不被链接显示;同时还可以添加一个用 户验证表单以便上传音乐、图像等文件并自动更新页面。 

导航栏 

实际上就是在 footer.inc 文件中加上一段代码。假设你的web 站点中所有后缀为.php3 的文件 都会出现在导航栏中,以下就是被存为 include/navbar.inc 的代码: <? /* 输出该导航栏,链接所有除当前页的站内.php3 文件 */ # 读取目录 $d = dir("./"); echo "<P ALIGN=&#92;"CENTER&#92;"> &#124; &#92;n"; while($entry = $d->read()) { // 忽略无文件情况 if ( !is_file($entry) )

continue; /* 将文件名与扩展名分开。由于.是正则表达式特殊字符,应该用&#92;引出 */ list($filenm, $fileext) = split("&#92;.",$entry, 2); // 忽略非.php3 文件情况 if( $fileext != "php3" ) continue; /* 现在我们已经把.php3 文件都选出,下面搜寻文件中的第一行(标题) 类似$title="something"; 并将以上标题内容分开,用作链接文字 */ $linknm = ""; $fp=fopen($entry,"r"); while($buffer=fgets($fp, 4096)) { $buffer = trim($buffer); // 我们已经把每个文件的标题放在文件的第一行以便搜索 // 但是当你改变变量名称时可能会带来大麻烦 if (ereg("title *= *&#92;"", $buffer)) { /* 我们已经取得了标题内容并可以在此基础上 进行去除空格等处理。 必须以 PHP 代码方式处理,比如$title = "blah blah" */ eval($buffer); // 然后将链接文字显示为标题文字 $linknm = $title; break; } } fclose($fp); if ( $entry == basename($PHP_SELF) ) echo "$linknm"; else echo "<A HREF=&#92;"$entry&#92;">$linknm</A>"; echo " &#124; "; } $d->close(); echo " </P>&#92;n"; ?> 

照片收藏夹 

我们将引用基于 HTTP 的验证、文件系统函数和文件上传功能维护放置图像文件的目录。 同时我们需要建立一个可以列出在该目录下所有照片的页面。 

文件上传

<? include("include/common.inc"); // 我们在这里再做一次用户验证 if(!isset($PHP_AUTH_USER)) { Header("WWW-Authenticate: Basic realm=&#92;"$MySiteName&#92;""); Header("HTTP/1.0 401 Unauthorized"); echo "Sorry, you are not authorized to upload files&#92;n"; exit; } else { if ( !($PHP_AUTH_USER==$MyName && $PHP_AUTH_PW==$MyPassword ) ) { // 如果是错误的用户名称/密码对,强制再次认证 Header("WWW-Authenticate: Basic realm=&#92;"My Realm&#92;""); Header("HTTP/1.0 401 Unauthorized"); echo "ERROR : $PHP_AUTH_USER/$PHP_AUTH_PW is invalid.<P>"; exit; } } if ( $cancelit ) { // 当浏览者按下"取消"按钮则转向首页面 header ( "Location: front_2.php3" ); exit; } function do_upload () { global $userfile, $userfile_size, $userfile_name, $userfile_type; global $local_file, $error_msg; global $HTTP_REFERER; if ( $userfile == "none" ) { $error_msg = "You did not specify a file for uploading."; return; } if ( $userfile_size > 2000000 ) { $error_msg = "Sorry, your file is too large."; return; } // Wherever you have write permission below... $upload_dir = "photos"; $local_file = "$upload_dir/$userfile_name"; if ( file_exists ( $local_file ) ) {

$error_msg = "Sorry, a file with that name already exists"; return; }; // 你还可以由此检查文件名称/类型对以确定是何种文件:gif,jpg,mp3… rename($userfile, $local_file); echo "The file is uploaded<BR>&#92;n"; echo "<A HREF=&#92;"$HTTP_REFERER&#92;">Go Back</A><BR>&#92;n"; } $title = "Upload File"; include("include/header.inc"); if (empty($userfile) &#124;&#124; $userfile=="none") { // 输出以下表单 ?> <FORM ACTION="<? echo "$PHP_SELF"; ?>" ENCTYPE="multipart/form-data" METHOD=POST> <INPUT TYPE="HIDDEN" NAME="MAX_FILE_SIZE" VALUE="2000000"> <INPUT TYPE="FILE" NAME="userfile" SIZE="24" MAXLENGTH="80"> <BR><BR> <INPUT TYPE="SUBMIT" VALUE="Upload File!" NAME="sendit"> <INPUT TYPE="SUBMIT" VALUE="Cancel" NAME="cancelit"><BR> </FORM> <I><FONT SIZE="2">(You may notice a slight delay while we upload your file.)</FONT></I> <? } else { if ( $error_msg ) { echo "<B>$error_msg</B><BR><BR>"; } if ( $sendit ) { do_upload (); } } include("include/footer.inc"); ?> 

照片图库  

<? include("include/common.inc"); $title = "Gallery"; include("include/header.inc"); ?> <P> Here are some of our family photos. This PHP script can really be made better, by splitting into multiple pages.

</P> <? $d = dir("photos"); while($entry = $d->read()) { if (is_file("photos/$entry")) echo "<IMG SRC=&#92;"photos/$entry&#92;">&#92;n"; } $d->close(); ?> <? include("include/footer.inc"); ?> 

另外,你可以在文件上传的表单中加上一个输入元素去描述该上传的文件。这个元素将被存 储在文件中,然后被以上的照片图库的那段代码所读出并显示出来。 

六、网络资源 

你可以通过 web 上的众多资源更多的了解 PHP3。许多邮件列表和书籍对你都非常有用。 

6.1 站点 

PHP 的爆炸性流行使得一夜之间出现了很多基于 PHP 的站点,其中不少站点有在线教程、 范例代码、技巧和提示等内容。  

国内 http://www.phpuser.com - PHP 中文用户,也就是这里了 http://www.phpx.com - 中国 PHP 联盟 http://www.phpsite.net - PHP 专门站 http://www.phpchina.com - PHP CHINA http://www.cpcw.com/netschool/homepage/cgi/ - 电脑报网页陶吧 国外 http://www.php.net/ - PHP 官方站点 http://www.devshed.com/ - 极好的教程 http://px.sklar.com - 代码交换 http://www.phpbuilder.com/ - 教程、专栏和邮件列表档案 http://www.weberdev.com/ - 文章和代码 http://www.phpwizard.net/ - 提示与技巧 http://www.iometrics.com/php/phplist.php3/ - IOMetrics scripts 的档案 http://www.e-gineer.com/phpkb/ - PHP 知识库 

6.2 邮件列表

 你可以在 PHP 官方站点的"支持"栏目内登记获得以下的邮件列表。值得注意的是这些都是 高流量流表,一般每天会有 100 份 e-mail。  

[email protected] - 主要的列表 [email protected] - 主要针对开发者 [email protected] - 本站的邮件列表,与论坛相通 

6.3 引人注目的工程 

一些基于 PHP 的工程已经发展得比较完善。其中一些更出色更引人注目的是: 

http:// phplib.netuse.de - PHPLib,一整套 PHP 函数库

http://www.phorum.org - Phorum 是一个很完善的 BBS 系统 http://www.fishcartsql.org - FishCartSQL 是一个电子商务解决方案 http://www.midgard-project.org - Midgard 是一个网络应用开发平台     

Generated by Bo-blog 2.0.2 sp2

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。