1.Web交互

1.Web表单交互

当用户在网站上填写了表单后,需要将数据提交给网站服务器对数据进行处理或保存。通常表单都会通过method属性指定提交方式,当表单提交时,浏览器就会按照指定的方式发送请求。例如,当提交方式为POST时,浏览器发送POST请求,当提交方式为GET时,浏览器发送GET请求。

当PHP收到来自浏览器提交的数据后,会自动保存到超全局变量中。超全局变量是PHP预定义好的变量,可以在PHP脚本的任何位置使用。常见的超全局数组变量有6.PHP与Web页面交互 - 图1_GET等,通过POST方式提交的数据会保存到6.PHP与Web页面交互 - 图2_GET中。

  1. <?php
  2. print_r($_POST);
  3. ?>
  4. <form method="post">
  5. 用户名:<input type="text" name="username">
  6. 密码:<input type="password" name="password">
  7. <input type="submit" value="登录">
  8. </form>

在浏览器中打开,会看到var_dump()打印的$_POST是一个空数组。如果在表单中填写用户名“test”和密码“123456”后提交,会看到下图所示的结果。

6.PHP与Web页面交互 - 图3form

当表单被提交时,表单中具有name属性的元素会将用户填写的内容提交给服务器,PHP会将表单数据保存在6.PHP与Web页面交互 - 图4_POST是一个关联数组,数组的键名对应表单元素的name属性,值是用户填写的内容。因此,当要接收表单提交的用户名和密码时,可以用如下代码来实现,将上述form表单action给下方代码

  1. <?php
  2. if (isset($_POST['username']) && isset($_POST['password'])){
  3. $username = $_POST['username'];
  4. $password = $_POST['password'];
  5. }
  6. echo "你输入的用户名是:".$username;
  7. echo '<br>';
  8. echo "你输入的密码是:".$password;
  9. ?>

在上述代码中,第1行的if语句用于判断表单是否提交了用户名和密码,第2~3行用于将$_POST数组中的数据取出来,保存到变量中。若客户端没有提交用户名和密码,则if条件不满足,不进行处理。

运行结果:

  1. 你输入的用户名是:admin
  2. 你输入的密码是:123456

2.URL参数交互

当表单以GET方式提交时,会将用户填写的内容放在URL参数中进行提交。以例7-1为例,将表单的method属性删除(或将其值改为get)。

  1. <form method="get" action="receive.php">
  2. 用户名:<input type="text" name="username">
  3. 密码:<input type="password" name="password">
  4. <input type="submit" value="登录">
  5. </form>

然后提交表单,会得到如下URL。

  1. http://localhost/study/php/receive.php?username=admin&password=123456

在上述URL中,“?”后面的内容为参数信息。参数是由参数名和参数值组成的,中间使用等号“=”进行连接。多个参数之间使用“&”分隔。其中,username和password是参数名,对应表单中的name属性;admin和123456是参数值,对应用户填写的内容。receive.php代码如下:

  1. <?php
  2. if (isset($_GET['username']) && isset($_GET['password'])){
  3. $username = $_GET['username'];
  4. $password = $_GET['password'];
  5. }
  6. echo "你输入的用户名是:".$username;
  7. echo '<br>';
  8. echo "你输入的密码是:".$password;
  9. ?>

运行结果:

  1. 你输入的用户名是:admin
  2. 你输入的密码是:123456

需要注意的是,在实际开发中通常都不会使用GET方式提交表单,因为GET方式提交的数据在URL中是可见的,并且传送的数据大小有限制。GET方式更多的是用在获取信息时传递一些参数。

3.数组方式提交数据

在Web表单中,复选框是一种支持提交多个值的表单控件,在编写表单时应将其name属性设置为数组,示例代码如下。

  1. <form action="receive.php" method="post">
  2. <input type="checkbox" name="hobby[]" value="swinming">游泳
  3. <input type="checkbox" name="hobby[]" value="reading">读书
  4. <input type="checkbox" name="hobby[]" value="running">跑步
  5. <input type="submit" name="提交">
  6. </form>

当提交表单时,hobby会以数组形式提交。假设用户选中了“游泳”“跑步”后,以POST方式提交表单,则PHP收到后执行“print_r($_POST[‘hobby’]);”的打印结果如下。

  1. Array ( [0] => reading [1] => running )

从上述代码可以看出,6.PHP与Web页面交互 - 图5_POST数组中将不存在hobby元素。

4.HTML特殊字符处理

在将用户输入的内容输出到HTML中显示时,会遇到特殊字符问题。例如,用户提交一段HTML代码时,为了将代码原样显示,需要将里面的特殊字符串转换为实体字符,防止被浏览器解析。若没有对这些特殊字符进行处理,会给网站的安全带来风险。

  1. <?php
  2. if (isset($_POST['content'])) {
  3. echo $_POST['content'];
  4. exit;
  5. }
  6. ?>
  7. <form method="post">
  8. <p>留言内容</p>
  9. <textarea name="content" id="1" cols="40" rows="10"></textarea>
  10. <p><input type="submit" value="提交"></p>
  11. </form>

按照上述代码编写完成后,通过浏览器访问该文件,并在留言框中输入以下内容。

  1. <script>
  2. while(true){
  3. alert('哈哈,中招了吧');
  4. }
  5. </script>

然后单击“提交”按钮,PHP就会将这些JavaScript代码输出到HTML中,导致浏览器循环地弹出对话框,无法正常浏览网页。由于Chrome浏览器默认开启了安全审计功能,无法测试结果,使用火狐浏览器进行测试,效果如下图所示。

6.PHP与Web页面交互 - 图6

上述这种情况会导致网站出现很多安全问题,而且会使用户无法正常访问页面。为了解决这类问题,PHP提供了一些专门用于处理HTML特殊字符的函数。

函数名 说明
nl2br() 将字符串中的换行符前插入HTML换行标记
strip_tags() 从字符串中取出HTML和PHP标记
htmlspecialchars() 将字符串中的特殊字符转换为HTML实体标记
htmlspecialchars_decode() 将字符串中的HTML实体字符转换回原来的字符
urlencode() 编码URL字符串
urldecode() 解码已编码的URL字符串
http_build_query() 生成URL编码后的字符串

1.nl2br()

若在表单的textarea标记中输入多行文本,然后将文本显示在div标记中时,会遇到换行显示成空格的问题,这是因为textarea中的换行符是“\r\n”,而不是HTML中的换行标记“
”。因此,当需要正确显示换行时,需要通过nl2br()函数进行转换,示例代码如下。

  1. echo nl2br("123\n456",false);

上述代码执行后,在浏览器中可以看到123和456各占一行,HTML源代码如下。

  1. 123<br>
  2. 456

2.strip_tags()

strip_tags()函数可以去除字符串中的标记部分,通常用于读取一段HTML代码后,去除其中的HTML标记,只保留文本,示例代码如下。

  1. <?php
  2. $html = <<<'EOD'
  3. <ul><li>苹果</li><li>香蕉</li></ul>
  4. 123<test>456</test><aaa>789
  5. EOD;
  6. echo strip_tags($html);
  7. ?>

上述代码执行后,输出的HTML源代码如下。

  1. 苹果香蕉 123456789

需要注意的是,strip_tags()函数并不会验证HTML标记的有效性,如示例中的\“”和\“”标记都会被删除。

3.htmlspecialchars()和htmlspecialchars_decode()

htmlspecialchars()函数和htmlspecialchars_decode()函数分别用于转换和还原字符串中的HTML特殊字符,具体包括“&”、单引号、双引号、“<”和“>”,其中,单引号需要将函数的第2个参数设置为ENT_QUOTES常量才会进行转换,示例代码如下。

  1. <?php
  2. $html = "123<br>4'56";
  3. $html = htmlspecialchars($html,ENT_QUOTES | ENT_HTML5);
  4. echo $html,"\n";
  5. $str = htmlspecialchars_decode($html,ENT_QUOTES | ENT_HTML5);
  6. echo $str;
  7. ?>

上述代码执行后,输出的HTML源代码如下所示。

  1. 123&lt;br&gt;4&apos;56
  2. 123<br>4'56

4.urlencode()和urldecode()

urlencode()函数和urldecode()函数主要用于在HTML中输出URL参数时进行编码转换,前者用于编码,后者用于解码,具体使用示例如下。

  1. <?php
  2. $name = 'A&B C';
  3. $name = urlencode($name);
  4. echo "http://localhost/study/php/test.php?name=$name";
  5. echo '<br>';
  6. echo urldecode($name);
  7. ?>

上述代码执行后,输出的HTML源代码如下。

  1. http://localhost/study/php/test.php?name=A%26B+C
  2. A&B C

在经过URL编码后,“&”被转换为“%26”,空格被转换为“+”,从而解决了在URL参数中使用特殊字符的问题。值得一提的是,当使用$_GET接收参数时,获得的数据已经是URL解码后的结果,无需手动进行处理。

5.http_build_query()

利用http_build_query()函数可以将PHP关联数组转换为URL参数字符串,具体使用示例如下。

  1. <?php
  2. $prarms = [
  3. 'name' => 'test',
  4. 'hobby' => ['reading','running']
  5. ];
  6. $query = http_build_query($prarms);
  7. echo "http://localhost/study/php/test.php?$query";
  8. ?>

上述代码执行后,输出的HTML源代码如下。

  1. http://localhost/study/php/test.php?name=test&hobby%5B0%5D=reading&hobby%5B1%5D=running

在输出结果中,“%5B”和“%5D”分别表示“[”和“]”,即数组形式的URL参数。通过本示例可看出,使用http_build_query()函数可以很方便地将数组转换为URL参数,同时还支持多维数组。