本篇主要写了在PHP中编写web应用程序的一些技巧,包括一些表单的验证,web应用程序的安全性等。
针对服务器设置调整行为:
ini_get()函数可以检验某些脚本是否打开,如ini_get('Magic Quotes'),
ini_set()函数只是改进PHP应用程序的可移植性的一种方式,其方法是,使脚本依据服务器特有的信息采取不同的行为。
eg:
打开PHP的display_errors设置:
ini_set('display_errors',1);
检查服务器配置:
function_exists()
返回true或false,以指示某个函数是否存在于PHP安装中。
![ContractedBlock.gif](http://img.e-com-net.com/image/info8/b8d97b5613f94ed2ba791cad57d0b2ed.gif)
![ExpandedBlockStart.gif](http://img.e-com-net.com/image/info8/2f88dd3f1cd145f59c0e47b51acdbd4b.gif)
1 if(function_exists('mysql_connect')){...}
2
3 if(function_exists('mysql_real_escape_string'))
4 {
5 global $dbc;
6 $data=mysql_real_escape_string(strim($data),$dbc);
7 }
8 else
9 {
10 $data=mysql_escape_string(trim($data));
11 }
web应用程序安全性
防止多次提交:
如果正在使用会话,可使用一下方法:
1 if(isset($_SESSION['form_name']))...
把唯一标识符存储在隐藏的表单输入框中:
value="">
需要使用rand()、uniqid()和md5()这几个函数,其中,uniqid()会创建一个唯一标识符。把这个标识符输入到rand()函数中,有助于生成一个更随机的数。最后,使用md5()对返回的结果进行散列(hash),这会创建一个长度刚好为32个字符的字符串。
eg:
![ContractedBlock.gif](http://img.e-com-net.com/image/info8/b8d97b5613f94ed2ba791cad57d0b2ed.gif)
![ExpandedBlockStart.gif](http://img.e-com-net.com/image/info8/2f88dd3f1cd145f59c0e47b51acdbd4b.gif)
![ContractedBlock.gif](http://img.e-com-net.com/image/info8/b8d97b5613f94ed2ba791cad57d0b2ed.gif)
![ExpandedBlockStart.gif](http://img.e-com-net.com/image/info8/2f88dd3f1cd145f59c0e47b51acdbd4b.gif)
1 <body>
2 php
3 DEFINE('DB_USER','root');
4 DEFINE('DB_PWD','mysql');
5 DEFINE('DB_HOST','localhost');
6 DEFINE('DB_NAME','content');
7
8 $dbc=@mysql_connect(DB_HOST,DB_USER,DB_PWD) OR die ('Could not connect to MySQL:'.mysql_error());
9 @mysql_select_db(DB_NAME) or die ('Could not select the database:'.mysql_error());
10
11 function escape_data($data)
12 {
13 global $dbc;
14 if(ini_get('magic_quotes_gpc'))
15 {
16 $data=stripslashes($data);
17 }
18 return mysql_real_escape_string(trim($data),$dbc);
19 }
20 ?>
21 body>
22
23
24 ---handle_comments.php
25
26 php
27 echo 'handle';
28 require_once('connectdb.php');
29 if(!empty($_POST['name']))
30 {
31 $n=escape_data($_POST['name']);
32 }
33 else
34 {
35 echo 'You forgot to enter your name.
';
36 $n=false;
37 }
38 if(!empty($_POST['comments']))
39 {
40 $c=escape_data($_POST['comments']);
41 }
42 else
43 {
44 echo 'You forgot to enter your comments.
';
45 $c=false;
46 }
47 if(strlen($_POST['stamp'])==32)
48 {
49 $s=escape_data($_POST['stamp']);
50 }
51 else
52 {
53 echo 'You forgot to enter your stamp.
';
54 $s=false;
55 }
56 if($n && $c && $s)
57 {
58 $query="insert into urls(url,title,description) values('$n','$c','s')";
59 $result=mysql_query($query);
60 if(mysql_affected_rows()==1)
61 {
62 echo 'Thank you for your comments.
';
63 }
64 else
65 {
66 echo 'Your comments could not be added.
';
67 }
68 }
69 ?>
验证正确的表单
可以在一个接受数据处理的界面判断是否接受的数据是所期望的,这样可以避免某些刻意照成Web安全威胁的安全隐患:
例如,在上例中,我们在handle_comments.php通过post方式接受的数据有name、comments、submit、stamp,就可以定义一个数组来存储这些变量:$allowed=array('name','comments','submit','stamp'),然后把接受的数据存储在一个数组里:$received=array_keys($POST),然后比较这两个数组是否相等:if($allowed==$received) {...}
处理HTML代码
在提交界面中可能会有某些恶意用户输入一些HTML或js代码弹出恶意窗口等。为了避免这些问题,需要对获取到的数据判断是否有HTML代码,并对它进行处理。常用的有几个函数:
htmlspecialchars(),它把&、'、"、<、>转变成HTML实体格式(&、"等)
htmlentities(),它把所有使用的字符转变成它们的HTML实体格式。
strip_tags(),它删除所有所有的HTML和PHP标签。
![ContractedBlock.gif](http://img.e-com-net.com/image/info8/b8d97b5613f94ed2ba791cad57d0b2ed.gif)
![ExpandedBlockStart.gif](http://img.e-com-net.com/image/info8/2f88dd3f1cd145f59c0e47b51acdbd4b.gif)
1 function escape_data($data)
2 {
3 global $dbc;
4 if(ini_get('magic_quotes_gpc'))
5 {
6 $data=stripslashes($data);
7 }
8 return mysql_real_escape_string(trim($data),$dbc);
9 }
10 $n=escape_data(htmlspecialchars($_POST['name']));
11 $c=escape_data(htmlspecialchars($_POST['comments']));
通过类型验证数据
如果提交的变量是某种类型,则这些类型验证函数会返回true,否则返回false:
函数 |
用于检查 |
is_array() |
|
is_bool() |
|
is_float() |
|
is_int() |
|
is_null() |
|
is_numeric() |
数值,甚至是字符串,如"20" |
is_resource() |
资源,如数据库连接 |
is_scalar() |
标量(单值)变量 |
is_string() |
|
用法:
首先,可先强制接收到的数据或通过相应函数测试是否为指定的数据类型:
$quantity=(int) $_POST['quantity'];
$price=(float) $_POST['price'];
$tax=(float) $_POST['tax'];
利用javascript进行表单验证
我们可以在客户端写一个javascript代码对即将要提交的页面进行判断,根据其输入格式判断是否要提交
![ContractedBlock.gif](http://img.e-com-net.com/image/info8/b8d97b5613f94ed2ba791cad57d0b2ed.gif)
![ExpandedBlockStart.gif](http://img.e-com-net.com/image/info8/2f88dd3f1cd145f59c0e47b51acdbd4b.gif)
1 <script type="text/javascript" language="javascript">
2 function check_data(my_form)
3 {
4 var problem=false;
5 if(my_form.name.value=="")
6 {
7 alert("Enter your name.");
8 my_form.name.value="***Name";
9 my_form.name.focus();
10 problem=true;
11 }
12 if(my_form.email.value=="")
13 {
14 alert("Enter your email address.");
15 my_form.email.value="***Email Address";
16 my_form.email.focus();
17 problem=true;
18 }
19 if(my_form.url.value=="")
20 {
21 alert("Enter the URL");
22 my_form.url.value="*** URL";
23 my_form.url.focus();
24 problem=true;
25 }
26 if((my_form.url_category.selectedIndex==0) || (my_form.url_category.value==0))
27 {
28 alert("Please select a category for this URL.");
29 problem=true;
30 }
31
32 if(problem)
33 {
34 return false;
35 }
36 else
37 {
38 return true;
39 }
40 }
41 script>
42
43 <form name="url_form" action="handle_submit_url" onsubmit="return check_data(this)">
44 <fieldset><legend>Enter your information in the form below:legend>
45 <p><b>Your name:b><input type="text" name="name" size="40" maxlength="60" />p>
46 <p><b>E-mail:b><input type="text" name="email" size="40" maxlength="60">p>
47 <p><b>URL:b><input type="text" name="url" size="40" maxlength="80" />p>
48
49 <p><b>URL Category:b><select name="url_category">
50 <option value="3">Code Librariesoption>
51 <option value="6">dfsgsdfgdsoption>
52 <option value="5">sadfoption>
53 <option value="1">jyyuuyoption>
54 <option value="4">uyfgbv.option>
55 <option value="2">fgk,boption>
56 select>p>
57 fieldset>
58
59 <div align="center"><input type="submit" name="submit" value="Submit" />div>