分类:
2008-05-29 22:29:27
PHP简介
正如我们在前面提到的,PHP是一个服务器端的脚本语言。这个概念可能很难理解,特别是如果你以前只用过HTML和javascript来设计过网页时更是如此。一个服务器端的脚本程序与javascript在许多地方有点相像,两者都允许你在Web页面的HTML中插入一些程序(脚本)。其结果就是,这些脚本使你可以控制在浏览器窗口内会显示什么,这显然要比直接使用HTML要来得灵活得多。
javascript和PHP的关键的不同点是:当Web浏览器解释javascript时,包含这个脚本的Web页面已经被下载了,而对于象PHP这样的服务器端脚本程序来说,解释的工作是由服务器在将页面发出到浏览器之前完全的。解释工作完成后,Web页面中的PHP的代码将由脚本运行的结果所代替,浏览者看到的完全是标准的HTML文件。脚本是完全由服务器来处理的。这也就是它的命名的由来:服务器端脚本程序。
让我们再回头看看我们在第一章里建立的示例today.php:
Today's date (according to this Web server) is |
这个程序中的绝大多数是采用HTML格式的。只有在中间的行是用PHP写的。 表示“结束PHP代码”。Web服务器在将这个Web页面发送到请求它的浏览器之前会对这个两个标识符之前的所有内容进行处理,并将其转换成标准的HTML代码。浏览器接受到的页面将是这样的:
Today's date (according to this Web server) is |
请注意,现在所有的PHP代码都没有被显示。它们被相应的标准的HTML所取代,能过这个例子,我们可以看到服务器端脚本的几个优势:
不存在浏览器兼容的问题。PHP脚本仅仅是由Web服务器来解释的,所以我们不必担心你使用的语言是否能被你的访问者的浏览器所支持。
可以访问服务器端的资源。在上面的例子中,我们在Web页面中放置了Web服务器的日期。而当我们使用的是javascript,要实现同样的功能,我们只能显示Web浏览器在上面运行的计算机的日期。这个例子还对于使用服务器端的资源还不是十分典型的,事实上我们可以很方便地插入一些其他的信息,而这些信息只能通过运行在服务器上的脚本来调用,例如,运行在Web服务器上的MySQL数据库中存储的信息。
简化了客户端的装载。javascript会明显降低Web页面的显示速度,因为在显示这个Web页面之前,浏览器首先得运行javascript脚本。而对于服务器端脚本来说,这种负担将由Web服务器独自承担。
基本的语法和命令
对于任何一个用过C、C++、Java、javascript、Perl或其他源自C的语言的人,PHP的语法都会让你觉得非常熟悉。一个PHP脚本包含一系列的命令(语句),Web服务器必须依次处理这些指令。与上面提到的其他语言一样,PHP语句也总是以分号(;)结束。
这是一个典型的PHP语句:
echo("This is a test!"); |
这个语句调用了一个叫echo的内置函数,并传递给它这么一个字符串:“This is a test! ”。内置函数你可以理解为“不需要另外的说明PHP就能知道该怎么做”的事情。PHP有很多的内置函数,我们可以利用它们来做许多事,从发送e-mail到处理存储在数据库中的不同类型的数据都是它们的管辖范围。echo函数只是简单地将传递给它的文本插入到HTML页面的当前位置。你可以看看下面这个例子:
echo("This is a test!"); |
如果你给这段代码起名为test.php(或者test.php3,如果你的Web主机还没有将.php文件配置为PHP脚本),并将它放置到你的Web服务器上,浏览器看到的将是这样的一页:
This is a test! |
请注意,包含HTML标识符(和)在内的所有文本都被正确地显示了出来。
你也许会感到疑惑,我们为什么要在这里使用括号和引号。引号在PHP中是用来标志字符串的开始和结束。括号有双重作用,首先,它指出echo是一个你想要调用的函数,其次,它标志了这个函数的参数的开始和结束。通过参数,你可以指挥你的函数去干什么。对于echo函数,我们只需要给它一个字符串,用来在页面上显示,但是我们将会看到有些函数有几个参数(在这种情况下,我们用逗号分开各个参数)。即使对于没有参数的函数,我们仍需要有括号,只不过在括号中间我们不必输入任何内容。
变量和运算符
PHP中的变量与许多其它程序中的变量一样。当还未被初始化时,变量仅仅是一个假想的容器的名字,其中可以存放任何数值。下面的语句建立了一个叫$testvariable(在PHP中所有的变量都以一个美元符开始)并将其赋值为3:
$testvariable = 3; |
PHP是一个“宽松类型”的语言,这就是说,一个变量可以包含任何类型的数据(数字、字符串或者其他类型),在它的存活期内其类型可以自由地转换。所以如果在上面的语句后再出现这样的语句,这就意味着给我们的已经存在的$testvariable变量重新赋了一个值。这个变量从一个数值变量变成了一个字符串变量:
$testvariable = "Three"; |
在上面的两个语句中我们用到的等于号被称之“赋值运算符”,它是用来给一个变量赋值的。另外,我们还有一些执行数学运算的运算符:
$testvariable = 1 + 1; //变量赋值为2。 $testvariable = 1 - 1; //变量赋值为0。 $testvariable = 2 * 2; //变量赋值为4。 $testvariable = 2 / 2; //变量赋值为1。 |
上面的各行的最后都有一个注释。注释是通过插入解释性的文字来说明我们的代码的用途,同时它也会通知PHP解释程序忽略对这部分语句的解释。注释以//开始并在同一行内结束。如果你熟悉在其他语言中的/* */风格的注释,在PHP中你也可以这样用。在我们这个教程中,我们会经常使用注释来对程序作出解释。
现在回到我们上面的四个语句,四个运算符分别被用来完成加、减、乘、除的运算。另外,还有一个运行符是用来连接字符串的:
//给变量赋值为"Hi there!". $testvariable = "Hi " . "there!"; |
变量可以被应用在很多使用实际数值的地方。你可以看看下面的例子:
$var1 = "PHP"; //将$var1赋值为"PHP" $var2 = 5; //将$var2赋值为5 $var3 = $var2 + 1; //将$var3赋值为6 $var2 = $var1; //将$var2赋值为"PHP" echo($var1); //输出"PHP" echo($var2); //输出"PHP" echo($var3); //输出6 echo($var1 . " rules!"); //输出"PHP rules!" echo("$var1 rules!"); //输出"PHP rules!" echo('$var1 rules!'); //输出'$var1 rules!' |
请特别注意最后的两行,你可以直接在一个字符串中包含一个变量名,如果你用双引号将其括起来,将会用该变量的值代替变量名。而最后一行证明,如果你使用的是单引号,是不会作这种转换的。
用户交互和表单
对于许多我们感兴趣的PHP应用来说,最基本的功能是实现与浏览这个页面的用户的交互。如果你熟悉javascript,你可能会习惯于这么一种事务处理的模式,那就是对用户的许多行动直接作出反应(例如将鼠标移动到页面上的一个连接)。而对于PHP这样的服务器端脚本程序而言,它用来实现与用户交互的活动范围要小得多,与用户的交互仅仅发生在用户向服务器发出请求以及服务器用一个动态页面作出回应之间。
用户与PHP实现交互的关键是理解用户对一个新Web页面发出的请求中可能包含的发出信息。我们将会看到,PHP使得这个工作极为简单。
最简单的方法是使用“URL查询字符串”在页面请求中发出信息。如果你曾经看到过一个在文件名后包含问号的URL,那就是采用的这种技术。让我们来看一个简单的例子。建立一个标准的HTML文件(不一定使用.php扩展名,在这个文件中将不包含任何PHP代码),并在其中加入以下连接:
Hi, I'm Kevin! |
这是指向一个叫welcome.php的文件的连接,但是在连接这个文件的同时,我们还在页面请求中传递了一个变量。这个变量是被作为“查询字符串”的一部分传递的,它位于URL的问号后面。这个变量的名字是name,它的值是Kevin。也就是说,我们建立了一个连接,这个连接装载welcome.php并告知这个文件中包含的PHP代码:name等于Kevin。
要清楚这么做对我们有什么好处,我们需要看看welcome.php。 同样地将其作为一个新的HTML文件来建立,但是这一次要记得使用.php 扩展名,这会告诉Web服务器在这个文件中有一些PHP代码需要解释。如果你的Web服务器还不接受.php作为PHP文件的扩展名,你可能需要将其改名为welcome.php3(在这种情况下,你也需要相应调整上面的代码中的连接)。在这个新文件中,输入以下内容:
echo("Welcome to our Web site, $name!"); ?> |
现在,如果你用第一个文件中连接去装载第二个文件,你会看到这一页显示“Welcome to our Web site, Kevin!”,这个通过URL的查询字符串传递过来的变量的值被自动地赋予了一个叫$name的变量,我们在一段文本中显示了这个传递过来的变量。
如果你需要的话,你也可以通过查询字符串传递几个变量。让我们看看这个例子的稍微复杂一点的版本。将HTML文件中的连接改变为:
Hi, I'm Kevin Yank! |
这一次,我们传递了两个变量:firstname和lastname。这些变量在查询字符串中被&符号分开。你可以传递更多的变量,只要你将每一个name=value对以&符号分开。
如前所述,我们可以在我们的welcome.php文件中使用这两个变量的值:
echo("Welcome to our Web site, $firstname $lastname!"); ?> |
虽然看上去一切都好了,但是我们仍没有达到我们真正地与用户交互的目的,我们的用户应该能够输入任意的信息,并将它交给PHP来处理。接着我们的个性化欢迎页面的例子,我们想要让我们的用户任意地输入他(或她)的名字并将其显示到信息中,要让用户输入数据,我们需要用到HTML的表单。这儿是表单的代码:
除了在这里你可以任意输入你的名字以外,这个表单所起的效果和我们上面的第二个连接(在查询字符串中使用firstname=Kevin&lastname=Yank)完全一样。当你按提交按钮(标志为“GO”)时,浏览器会装载welcome.php并自动为你在查询字符串中添加变量和它们的值。变量名就是在INPUT TYPE=TEXT标识中的NAME属性,变量值就是用户输入的相应的内容。
INPUT TYPE=TEXT标识中的METHOD属性是用来告诉浏览器如何在请求中发送变量名及变量值的。GET(就是我们在上面使用的)表示在查询字符串中传递变量,但是还有另外一种选择。将变量显示在查询字符串中并不总是令我们满意的--甚至有的时候在技术上就是不可行的。如果在你的表单中包含了一个TEXTAREA标识用来让用户输入大量的文本,这部分文本也显示在查询字符串中实在是太长了,而且会超过浏览器所能支持的URL的最大长度。另外一种方法可以允许浏览器隐藏地传递信息。这种方法的代码和我们上面看到的表单的代码几乎一样,只是我们将表单的方法从GET变成了POST:
这个表单和我们之前的那个在功能上完全一样。唯一的不同是当用户在按“GO”按钮时所装载页面的URL将没有一个查询字符串。一方面,这可以让你通过表单提交大量的数据或者是敏感的数据(例如密码),而不在一个查询字符串中显示出来。另一方面,如果用户将提交表单生成的结果页添加到收藏夹,这个收藏夹是没有用的,因为它不包含提交的数据。另外,附带说一下,象AltaVista这样的搜索引擎总是利用查询字符串来提交查询条件,其主要原因就是为了便于用户将查询结果页添加到收藏夹中,以便在将来进行同样的搜索,因为搜索条件是包含在URL之中的。
这儿讲了利用表单来实现用户与PHP的交互的基本的原理。在以后的例子中,我们将讨论一些更高级的问题和技术。
控制语句
在我们之前看到的PHP的代码的例子中,要么是只有一个单独的向Web页面输出文本语句;要么是一系列的依次执行的语句。如果你用其他语言编写过程序,你应该知道,实际上很少有这么简单的程序。和任何其他的编程语言一样,PHP也提供了很方便地处理脚本中的“控制流”的方法。就是说,PHP中包含了一些特殊的语句,通过这些语句你可是不受依次执行的顺序的束缚。这种语句被称之为“控制语句”。不理解?不要担心!有一些例子会很好地帮助你。
最基本最常用到的控制语句是if-else语句。它的结构是这样的:
if ( //如果 } else { //(可选)如果 } |
这个控制语可以让我们告诉PHP根据一些条件的真假来决定相应地执行哪一组语句。如果你不觉得我这么做有点空虚,我们可以将我们刚才建立的welcome.php文件修改为:
if ( $name == "Kevin" ) { echo("Welcome, oh glorious leader!"); } else { echo("Welcome, $name!"); } |
现在,如果传递给这个页面的name变量的值是Kevin,将显示一个特殊的信息。否则,将显示一个包含输入的name的普通的信息。
需要指出的是,在这个结构中,“else子句”(它指出了if-else结构中条件为假时执行的内容)是可选的。对于上面的例子,如果我们的目的是当适当的名字被输入时,显示特殊的信息,否则就什么也不显示。这段代码应该是这样的:
if ( $name == "Kevin" ) { echo("Welcome, oh glorious leader!"); } |
在上面条件中所使用的==是用比较两个值是否相等的运算符。要特别记住的是在这儿你需要输入两个等号。如果你输入的是一个等号,你实际上使用的是前面我们讨论过的赋值运算符,你将不再是对两个变量的值进行比较,而是给变量赋了一个新值(这个操作会附带地返回一个true)。这样做的结果不仅仅是导致这个条件永远是true,它还可能改变我们所要检查的变量的值,这可能会导致很多问题。
防止发生这种错误有一种安全的做法,那就是象下面这样颠倒用来比较的变量和常量的位置:
if ( "Kevin" == $name ) { |
这样做的效果是完全相同的,但是当你忘了第二个等号时,我们来看看会发生什么情况。PHP会试图将变量($name)的值插入常量("Kevin")中。因为你不能改变常量的值,PHP会中断并提示一个错误信息,这将立即提示你忘了第二个等于号!
条件可以比单个的比较是否相等来得更复杂。回忆我们修改的welcome.php3,它是可以同时获取firstname和lastname的。如果我们想要为某个特定的人显示一个特殊的信息,我们可以同时比较这两个变量:
if ( "Kevin" == $firstname and "Yank" == $lastname ) { echo("Welcome, oh glorious leader!"); } |
只有$firstname的值是Kevin,而且$lastname的值是Yank时这个条件才会返回真。and的意义就是只有两个比较都为真时,整个条件才会返回真。还有一个符号是or,这使得两个比较中至少有一个为真时,整个条件就返回真。如果你对javascript和C中的运算符(&&(and)和||(or))熟悉的话,你也可以在PHP中同样地使用它们。
在下面我们将看到一些更复杂的比较。现在,我们只需要对if-else语句有个基本的理解就可以了。
另一个常用的PHP控制语句是while循环。if-else语句使我们可以根据条件选择是否执行一组语句,while循环使我们可以根据条件来决定重复执行一组语句多少次。while循环的基本格式应该是这样的:
while ( |
这和一个没有else子句的if-else 语句非常相象。不同点在于当条件为真时语句执行完后,将不再是接着执行结束符(})后面的语句,而是再次检查条件。如果这个条件仍为真。将会重复执行语句,直到条件不再为真时为止。当这个条件首次返回假时(不管是第几次检查它),将会跳转执行循环后面的语句(在结束符后面)。
这样的循环可以用来处理一个事物的较长的列表(例如存储在数据库中的笑话),下面我们举了一个简单的例子:计数到10。
$count = 1; while ( $count <= 10 ) { echo("$count "); $count++; } |
我知道这段语句可能看上去挺恐怖,但是我们可以一行行地来看它。第一行定义了一个叫$count的变量并将其赋值为1。第二行是while循环的开始,条件是$count小于或等于(<=)10。第三行和第四行是while循环的循环体,当条件为真时,我们将重复执行它。第三行简单地输出了一$count的值,并在其后加了一个空格。第四行将$count的值加一($count++是$count = $count + 1的缩写--两者的意义是完全一样的)。
现在我们可以看看这段程序是如何执行的了。当第一次检查条件时,$count的值是1,所以条件为真。$count的值(1)被输出,接着$count被赋予了一个新值2。当第二次检查条件时条件仍为真,所以2 被输出,并赋了一个新值3 。这个过程被继续下去,输出了3 ,4 ,5 ,6 ,7 ,8 ,9 直到10 。最后,$count被赋予值11,条件为假,循环结束。最终的结果是输出了这样一个字符串“1 2 3 4 5 6 7 8 9 10”。
在这个例子的条件中我们使用了一个新的运算符:<= (小于或等于)。其他用于数值比较的运算符还有>=(大于或等于),<(小于),>(大于)和!=(不等于)。最后一个也可以使用于字符串比较中。
多用途的页面
如果你想在你建立的网站的每一个网页的顶端都显示访问者的姓名。使用我们前面的自动显示欢迎信息的例子,我们已经基本上成功了一半。现在我们只要对我们示例解决这几个问题就行了:
我们需要在站点的每一个页面都显示,而不是仅仅在一个页面上。
我们无法控制在我们的站点上那一个页面会首先显示。
第一个问题的解决不是太困难的。当我们在一个页面上获得了用户名这个变量后,我们可以在任何请求中通过将其添加到一个查询字符串来传递这个变量:
A link |
请注意我们在HTML标识符的中间嵌入了PHP的代码。实际上这是非常常用的。我们已经对echo这个函数很熟悉,但是我们还不熟悉urlencode函数。这个函数的功能是将字符串中一些特殊的字符(例如空格)转换成特定的编码,以使它们能够在查询字符串中显示。例如,如果$name变量的值是"Kevin Yank",其中的空格在查询字符串中不允许存在,urlencode的输出将是Kevin+Yank,在newpage.php中建立$name时,值将会被自动转换回来。
Ok,现在已经可以将用户名传递给我们站点的第一个连接了。现在我们所需要的就是在其第一次出现时,要能获得它的值。在我们上面的例子中,我们已经做了一个HTML页面用来处理获得用户名的表单。而问题是我们不能强迫用户在每一次访问我们的站点时都从这个页面开始。
解决方案是在我们站点的每一个页面都检查是否指定了一个用户名,如果需要,应该提求用户输入用户名。这意味着我们站点上的每一个页面都必须能显示用户名,在未指定用户名时,应提示用户输入。如果你现在就想到了使用if-else语句,那证明你的学习能力真的不错!
我们的“多功能页面”应该根据不同的条件显示完全不同的内容,这个页面的源程序将会是这样的:
) { ?> |
这段程序初看上去很混乱,但是事实上这仍然是普通的if-else语句,只不过在其中插入了HTML代码,而不是我们之前使用的PHP语句。这个例子说明了PHP的一个很大的优点:你可以自由地选择在什么时候进行或退出“PHP模式”。你可以将看成是返回到“普通的HTML模式”的命令。这样上面的例子就变得很容易理解了。
if-else语句还有另外的一种格式,使用这种格式将使你的程序更易读懂。如果使用这种格式,我们的“多功能页面”的源程序将是这样的:
): ?> |
Ok,现在我们已经有了所有我们需要的工具,让我们看看我们的站点中的一个样页:
|
在上面的程序中出现了两个新的东西,但是理解它们应该不是太困难的。首先,我们在条件中使用了一个新的函数:isset。当变量已经被赋值(在我们这里也就是指提供了用户名),该函数将返回(输出)一个逻辑真;当变量没有被赋值(在我们这里也就是指没有提供用户名),该函数将返回(输出)一个逻辑假。第二个新东西是在指定FORM标志中的ACTION属性中使用了$PHP_SELF变量。这个变量是自动产生的系统变量之一。具体地说,$PHP_SELF总是被设置成当前页面的URL。当一个表单在提交时指向同一个页面时,这给我们提供一个简单的做法。只不过这时的$name变量已经被赋值了。
将这一段加到你的网站上的所有网页上后,不管访问者第一次访问的是什么网页,都会被提示输入用户名。只有在输入了用户名并按了“GO”,才能到达他们真正想要访问的网页。输入的用户名会被通过每个连接中的查询字符串传递到之后的各个页面,这样就可以确保只要求访问者输入一次用户名。
结语
在这一章内,我们介绍了PHP的所有的基本语法:语句、变量、运算符以及控制语句。我们的例子是非常的简单。但是事实上PHP的强大功能在于它内置的数百个函数,利用这些函数你可以访问MySQL数据库中的数据来发送邮件,可以通过动态产生的图象来建立PDF文件,你还可以做其他的很多事情。