3.1 PHP的Web编程基础
本节将讲述最基本的PHP Web编程知识,诸如获取表单数据、处理表单数据、PHP中的Session和上传文件等。
3.1.1 HTTP协议原理
网络上的计算机之间要进行通信,就必须遵守一定的规则,这种通信规则就是网络协议。协议保证网络上各种不同的计算机之间能够理解彼此传递的消息,如同语言不通的人可以通过翻译来理解对方所说的话。现在互联网使用的是TCP/IP协议,浏览WWW使用的是HTTP协议(超文本传输协议,HyperText Transfer Protocol),此协议建立在TCP/IP协议之上。
图3-1 HTTP请求/响应
浏览网页的过程其实就是一系列请求/响应的过程。HTTP协议定义了这个请求/响应过程中请求和响应的格式,及维护HTTP链接的内容。
用户使用浏览器浏览一个Web站点,首先通过一个网址向网络中的某台计算机(即服务器)发出请求,请求浏览某个页面;服务器在找到这个页面后,在响应中返回相应页面的内容。图3-1展现了这个请求/响应过程。
3.1.2 创建HTML表单
HTML中使用标签<form>和</form>创建一个表单。<form>的主要属性是action和method。
·action属性:用来指定表单数据被提交后,处理这些数据的程序的地址。如下HTML代码表示当表单提交后,表单的数据将被传到文件login.php,由login.php来处理传入的数据。
<form action= ”login.php ”>
·method属性:指定用何种HTTP方式传递数据。
传递数据的方式有两种,POST方式和GET方式。POST方式将表单数据放在HTTP数据的正文部分传递。GET方式将表单数据加到action所指的地址之后传递。
说明 当表单被提交时,表单元素的value属性所对应的值将会被传送。对于文本框的value属性,其值就是用户输入的数据。
3.1.3 访问和获取HTML表单数据
在PHP中,可以通过两个预定义变量很方便地获取HTML表单数据。这两个预定义变量即$_GET和$_POST。它们都是PHP的自动全局变量,可以直接在PHP程序中使用。
·变量$_GET是表单数据组成的数组,它由HTTP的GET方法传递的表单数据组成。表单元素的名称就是数组的“索引”。这就是说,通过表单元素的名称(即name属性的值),就可以获得该表单元素的值。例如某表单中有一个文本输入框,名称为“user_name”,那么在PHP程序中,就可以通过$_GET['user_name']获取文本框中用户输入的值。
·变量$_POST的用法和$_GET类似。通过HTTP的POST方法获取的表单数据,都将存放在该变量中,该变量也是一个数组。
下面通过一个实例,介绍变量$_POST的使用,变量$_GET的用法与之类似。
(1)创建如代码3-1所示的HTML文档。
代码3-1 一个含有表单的HTML文档3-1.html
01 <html> 02 <head> 03 <title>3-1</title> 04 </head> 05 06 <body> 071 <form name="form1" method="POST" action="3-2.php"> 08 输入姓名:<input name="user_name" type="text"><br/><br/> 09 选择性别:<input name="gender" type="radio" value="male"> 男 <input name="gender" type="radio" 10 value="female"> 女<br/><br/> 11 兴趣与爱好:<input name="hobby" type="checkbox" value="reading"> 阅读 <input name="hobby" 12 type="checkbox" value="travel"> 旅游 <input name="hobby" type="checkbox" value="sport"> 运动 <input 13 name="hobby" type="checkbox" value="internet"> 上网<br/><br/> 14 选择职业: 15 <select name="occup"> 16 <option value="engineer"> 工程师</option> 17 <option value="teache"> 教师</option> 18 <option value="doctor"> 医生</option> 19 <option value="other"> 其他</option> 20 </select><br/><br/> 21 <input type="submit" value=" 提交数据"> 22 </form> 23 24 </body> 25 </html>
【代码解析】该HTML文档定义了一个表单,其中的第07行的method="POST"表示用POST方法传送表单数据,action="3-2.php"表示将表单提交给3-2.php处理。在表单中定义的元素有名称为user_name的文本框、名称为gender的radio按钮、名称为hobby的checkbox多选框、名称为occup的下拉列表框。当表单提交时,表单元素的值由POST方式交由当前目录下的3-2.php处理。
(2)接下来编写3-2.php,该程序先获取表单提交的数据,然后将这些数据向浏览器输出,完整的代码如代码3-2所示。
代码3-2 获取表单数据3-2.php
01 <?php 02 // 通过$_POST 全局变量,获取文本框user_name 的值,并赋给变量$user_name 03 $user_name = $_POST['user_name']; 04 $gender = $_POST['gender']; // 获取性别 05 $hobby = $_POST['hobby']; // 获取爱好 06 $prof = $_POST['occup']; // 获取职业 07 08 echo " 用户名:".$user_name."<br/>"; 09 echo " 性别:".$gender."<br/>"; 10 echo " 爱好:".$hobby."<br/>"; 11 echo " 职业:".$prof."<br/>"; 12 ?>
【代码解析】读者重点掌握的就是第03~06行中$_POST的使用,表示索引都是用[],不是用(),这里请不要混淆。
(3)这是个很简单的获取表单数据并且输出的PHP程序。如果在3-1.html页面填写的数据和所做的选择如图3-2所示,那么3-2.php将输出如图3-3所示的结果。
图3-2 含有表单的HTML文档
图3-3 表单数据输出的结果
从上面的结果图示可以看出,PHP输出的值就是HTML表单元素的value属性所赋的值,这些值是当表单提交时传给全局变量$_POST的。表单中每个元素的值都将以元素的name属性的值作为索引存入数组变量$_POST中。在PHP程序中,通过访问$_POST数组来获取HTML表单元素的值。
3.1.4 用PHP处理表单数据
在文档3-1.html中,对于表单中的“爱好”多选框,只选择了“阅读”一项。如果做了多个选择,再提交表单,3-2.php输出的结果就有所不同。例如,对3-1.html的多选框,做如图3-4所示的选择。在HTML文档中,对于多选框occup选择了“阅读”、“旅游”、“上网”3项。提交表单后,将看到如图3-5所示的结果。
图3-4 HTML表单中的多选框
图3-5 PHP输出表单数据结果
从图3-5可以看出,所选择的3个checkbox中,只有最后1个的值被输出了,其他两个选项的值没有被输出,这并不是所期望的结果。之所以出现这种情况,是因为多选按钮元素checkbox的名称都为“hobby”,而PHP要求,如果表单元素同名,就必须以数组方式命名,并为其value属性赋值,这样PHP才能正确取值。
因此,首先修改3-1.html的中表单元素checkbox的名称,以数组方式命名checkbox元素,即在原来的名称“hobby”后加上“[]”,修改后的代码如下。
兴趣与爱好:<input name="hobby[]" type="checkbox" value="reading"> 阅读 <input name="hobby[]" type="checkbox" value="travel"> 旅游 <input name="hobby[]" type="checkbox" value="sport"> 运动 <input name="hobby[]" type="checkbox" value="internet"> 上网<br/><br/>
在3-2.php中通过$_POST['hobby'][0]访问3-1.html中第1个checkbox的值,通过$_POST[‘hobby’][1]访问3-1.html中第2个checkbox的值,以此类推。修改后的代码如下。
$hobby = $_POST['hobby'][0]." 、".$_POST['hobby'][1]." 、 ".$_POST['hobby'][2]." 、 ".$_POST['hobby'][3];
像这样修改HTML文档和PHP程序之后,再次多选“爱好”项,就会看到所选项的值都被输出,如图3-6所示。
提示 因为$_POST是一个数组变量,所以,除了使用类似$_POST['hobby'][0]的方法获取同名checkbox元素的值之外,还可以使用另外一种专门用于操作数组的方法,这个方法会在第4章讲述数组处理时介绍。
3.1.5 用PHP验证表单数据有效性
在实际开发应用中,PHP程序往往要对用户提交的数据做验证,以保证程序的执行安全和数据的完整、有效。
本小节将在前两小节程序的基础上加入对提交数据的验证,只有在用户完全提交有效的数据后,程序才会向浏览器输出数据,否则将会向用户输出提示信息。对代码3-2做一些修改,使之成为代码3-3,并按名称3-3.php保存在测试目录下。对代码3-1所示的HTML文档做修改,将表单提交到3-3.php。
代码3-3 用PHP验证数据3-3.php
01 <?php 02 $user_name = $_POST['user_name']; 03 $gender = $_POST['gender']; 04 $hobby = $_POST['hobby'][0]." 、".$_POST['hobby'][1]." 、 ".$_POST['hobby'][2]." 、 ".$_POST['hobby'][3]; 05 $prof = $_POST['occup']; 06 07 // 当用户名为空,即没有输入用户名时,则输出一个提示信息,并中断程序的执行 08 if($user_name == "") // 用户名如果为空 09 { 10 echo " 请返回输入用户名!"; 11 exit; //exit 语句将使程序立即中断,不再向下执行 12 } 13 14 if($gender == "") // 如果没有选择性别 15 { 16 echo " 请返回选择性别!"; 17 exit; 18 } 19 20 if($hobby == "") // 如果没有选择爱好 21 { 22 echo " 请返回选择兴趣与爱好!"; 23 exit; 24 } 25 26 echo " 用户名:".$user_name."<br/>"; 27 echo " 性别:".$gender."<br/>"; 28 echo " 爱好:".$hobby."<br/>"; 29 echo " 职业:".$prof."<br/>"; 30 ?>
【代码解析】第02~05行首先获取表单传过来的数据,然后通过if语句来判断数据是否为空,如果为空,通过echo给出提示,然后调用exit退出程序。如果没有填写用户名便提交表单,程序就会输出一个提示信息“请返回输入用户名!”,实际效果如图3-7所示。
这个程序只对用户的输入值是否为空做了判断。事实上,数据的验证情况远远要比这多,比这复杂,如要求输入的数据只能是数字、限制输入内容的长度等。随着学习的深入,这些内容将会所有讲述。
图3-6 PHP处理多选按钮元素的输出
图3-7 用PHP做数据验证
3.1.6 PHP中的session
session是Web开发中最常见的概念,也是最常用的功能之一。简单地说,session是指用户进入网站到浏览器关闭的这段时间(或过程)。
HTTP是面向无连接(或无状态)的协议。这意味着,在HTTP中,一个完整的请求/响应过程结束之后,客户端(即浏览器)和服务器端的链接就已中断。此时,如果用户再从当前页面访问其他页面,即向服务器端发出请求,服务器端并不知道此请求是哪个用户发起的,因此也就无法得知用户的浏览状态。这样就遇到一个问题:当前页面中的某个数据(或变量),无法在接下来访问的页面中使用。而在实际的Web开发中,经常要在页面之间传递数据,而且不同的访问用户传递的数据是不同的。虽然解决这个问题的办法有很多,但通过session解决这个问题会更加方便、快速、有效。通过session记录用户的有关信息,以供用户以此身份向服务器端发起请求时,服务器能够根据session做出正确的判断,区分不同用户的请求。
在PHP中使用session,就是通过注册一些session全局变量,在不同页面的程序中使用这些变量。这样就可以通过session完成用户身份验证、程序状态和页面之间的数据传递等功能。
一般使用类似$_SESSION['session_name']=session_value的代码注册一个session变量,其用法也和$_POST、$_GET类似。另外,在使用session的页面中需要使用sesssion_star()函数,它表示开始或返回一个已经存在的session。这个函数要在浏览器有任何输出之前调用,也就是说,它往往是使用session的程序的第一行代码。
下面通过一个实例来介绍session的使用。这个实例中有两个PHP程序,在第1个程序中定义一些session变量,如代码3-4所示,然后通过第1个页面中的链接请求第2个PHP程序。在第2个程序中输出通过session前一个页面定义的session变量,如代码3-5所示。
代码3-4 在PHP程序中注册session变量3-4.php
01 <?php 02 session_start(); // 使用session 前必须调用该函数 03 04 $_SESSION['user'] = 'KingKong'; // 注册一个session 变量,变量的值为“KingKong ” 05 $_SESSION['explain']=' 这是3-4.php 的session 变量'; 06 echo ' 这个页面已经通过session 保存了一些变量'; 07 echo '<br/><a href="3-5.php"> 进入3-5.php</a> 查看这些变量值'; 08 ?>
代码3-5 在PHP程序中取得session变量的值3-5.php
09 <?php 10 session_start(); 11 echo $_SESSION['user']."<br/>"; 12 echo $_SESSION['explain']."<br/>"; 13 echo '<a href="3-4.php"> 返回3-4.php</a>'; 14 ?>
【代码解析】代码第04~05行注册了两个session变量,然后通过第11~12行进行读取和输出。
访问3-4.php,然后通过该页面的“进入3-5.php”的链接,访问3-5.php,可以看到如图3-8所示的结果。程序3-5.php通过session取得了在3-4.php中注册的session变量,实现了数据的跨页面传递。
说明 上述传递session变量功能的实现,是基于客户端浏览器支持cookie的。cookie是由服务器端产生的并且保存在客户端的一些文件,里面存放了一些用户信息和数据。有关cookie的知识会在第8章介绍。因为PHP的session机制的是通过cookie实现的,所以,如果浏览器不支持cookie,那么上述的示例程序就无法看到预期的效果。
3.1.7 PHP中的文件上传处理
在Web开发中经常会遇到从客户端上传文件到服务器端的问题。通常,文件上传使用的是HTTP的POST方式,使用POST方式传递文件到服务器端。要完成文件上传处理,首先要定义HTML表单的enctype属性为"multipart/form-data",代码如下。
<form enctype="multipart/form-data" action="somefile.php" method="POST">
只有这样的表单,才能确保文件可以提交并上传。其中,somefile.php要替换为一个可以处理文件上传的真实PHP文件。代码3-6是一个支持文件上传的表单示例,该表单将一个文件提交至3-7.php进行处理,稍后完成3-7.php程序。
代码3-6 支持文件上传的HTML表单3-6.html
01 <html> 02 <head><title>3-6 支持文件上传的表单</title></head> 03 <body> 04 05 <!-- 表单的enctype 属性必须指定为multipart/form-data --> 06 <form enctype="multipart/form-data" action="3-7.php" method="POST"> 07 <!-- input 的type 属性指定为file ,name 属性的值将会在PHP 程序的$_FILES 数组中用到--> 08 上传此文件: <input name="myfile" type="file" /> 09 <input type="submit" value=" 提交上传" /> 10 </form> 11 12 </body> 13 </html>
【代码解析】代码第06行使用enctype指定了multipart/form-data属性。第08行是一个HTML控件input,其类型为file,表示这是一个文件上传控件。
浏览3-6.html,可以看到如图3-9所示的效果,该页面会生成一个“浏览”按钮,通过它可以选择客户端文件。
图3-8 在PHP中使用session变量
图3-9 支持文件上传到表单
在PHP程序中使用全局变量$_FILES处理文件上传,$_FILES是一个数组,包含了要上传的文件的信息。下面以上述HTML表单为例,介绍$_FILES数组的内容。
·$_FILES['myfile']['name']表示客户端文件的原始名称,即要上传的文件的文件名。其中,myfile就是在代码3-6中定义的input元素的name属性的值<input name="myfile"type="file"/>。
·$_FILES['myfile']['type']表示上传文件的类型,例如“image/gif”。
·$_FILES['myfile']['size']表示已上传文件的大小,单位为字节。
·$_FILES['myfile']['tmp_name']表示文件上传后,在服务器端存储的临时文件名。
·$_FILES['myfile']['error']表示和文件上传的相关错误信息。
文件提交后,一般会被存储到服务器的默认临时目录中,可以通过修改php.ini中的upload_tmp_dir项,修改为其他路径。使用函数move_uploaded_file()将上传的文件移到指定的目录下。该函数的原型如下。
move_uploaded_file (filename, destination)
第1个参数filename指合法的上传文件,第2个参数destination是移动后的目标文件。如果上传的文件不合法,或由于某种原因无法移动文件,该函数会返回FALSE。
代码3-7是处理文件上传的一个示例PHP程序,代码3-6所示的HTML文档中的文件提交后,将由3-7.php来处理。
注意 一定要先在DOCUMENT_ROOT指定的目录下新建一个文件夹upload。
代码3-7 处理文件上传的PHP程序3-7.php
01 <?php 02 // 将文件移至服务器的根目录的upload 目录下,upload 目录要事先建立好 03 $upload_path = $_SERVER['DOCUMENT_ROOT']."/upload/"; 04 $dest_file = $upload_path.basename($_FILES['myfile']['name']); 05 06 // 将临时文件移至目标文件夹 07 if(move_uploaded_file($_FILES['myfile']['tmp_name'],$dest_file)) 08 { 09 echo " 文件已上传至服务器根目录的upload 目录下"; 10 } 11 else 12 { 13 echo " 文件上传时发生了一个错误".$_FILES['myfile']['error']; 14 } 15 ?>
【代码解析】代码3-7首先定义一个存放上传文件的目录,然后通过函数move_uploaded_file()将临时文件移至这个目录下。浏览3-6.html文档,选择一个要上传的文件,如图3-10所示,单击“提交上传”按钮,如果上传成功,会显示上传成功的信息,如图3-11所示。
图3-10 选择一个要上传的文件
图3-11 文件上传成功
转到服务器根目录的upload目录下,将会看到刚刚上传的文件“read.txt”,如图3-12所示。
图3-12 上传的文件在服务器中的位置
共有条评论 网友评论