`
isiqi
  • 浏览: 16071181 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

php5.2 中新的输入检查函数

阅读更多
在PHP 5.2最新版本中,在对输入检查的函数方面,多了新的功能,默认是开启的,减少了很多写代码的工作量
,在IBM DW的http://www.ibm.com/developerworks/cn/opensource/os-php-v522/index.html上有很好的介绍,下面笔记并补充之


过滤扩展功能有两种过滤器:Sanitizing 和 Logical。

Sanitizing 过滤器只是允许或禁止字符串中的字符并将清理后的字符串作为结果返回。无论您将哪种数据格式传入这些函数,它们将始终返回字符串。对于特定类型的使用,这是至关重要的,因为您可以阻止用户发送不适当的输入并导致异常结果。例如,用户可以发现文本块的输入被返回到以下页面上并且要利用那些返回信息。如果清理输入,则将删除输入的所有危险部分。

Logical 过滤器将对变量执行测试并根据测试提供 true 或 false 结果。然后您可以使用结果来决定如何处理数据或获得用户的地址。这种过滤器的简单示例是验证年龄。逻辑测试还可以针对类似 Perl 的正则表达式进行测试。
<?php

echo "You are " . filter_var($_GET['1'], FILTER_SANITIZE_STRING) . ".<br>\n";
echo "Your favorite color is " . filter_var($_GET['2'], FILTER_SANITIZE_STRING) .
".<br>\n";
echo "The airspeed of an unladen swallow is " . filter_var($_GET['3'], FILTER_SANITIZE_STRING)
. ".<br>\n";
?>
filter_var() 函数来清理输入并使其有效并且安全。在这种情况下,使用选项 FILTER_SANITIZE_STRING,该选项将获取输入、删除所有 HTML 标记并选择性地编码或删除特定字符。

由于它将除去 HTML 标记,因此尝试运行 JavaScript 将失败,并且从脚本中获得更适当的结果。

再补充些

PHP: indicates the earliest version of PHP that supports the function.

Function Description PHP
filter_has_var() Checks if a variable of a specified input type exist 5
filter_id() Returns the ID number of a specified filter 5
filter_input() Get input from outside the script and filter it 5
filter_input_array() Get multiple inputs from outside the script and filters them 5
filter_list() Returns an array of all supported filters 5
filter_var_array() Get multiple variables and filter them 5
filter_var() Get a variable and filter it 5


PHP Filters

ID Name Description
FILTER_CALLBACK Call a user-defined function to filter data
FILTER_SANITIZE_STRING Strip tags, optionally strip or encode special characters
FILTER_SANITIZE_STRIPPED Alias of "string" filter
FILTER_SANITIZE_ENCODED URL-encode string, optionally strip or encode special characters
FILTER_SANITIZE_SPECIAL_CHARS HTML-escape '"<>& and characters with ASCII value less than 32
FILTER_SANITIZE_EMAIL Remove all characters, except letters, digits and !#$%&'*+-/=?^_`{|}~@.[]
FILTER_SANITIZE_URL Remove all characters, except letters, digits and $-_.+!*'(),{}|\\^~[]`<>#%";/?:@&=
FILTER_SANITIZE_NUMBER_INT Remove all characters, except digits and +-
FILTER_SANITIZE_NUMBER_FLOAT Remove all characters, except digits, +- and optionally .,eE
FILTER_SANITIZE_MAGIC_QUOTES Apply addslashes()
FILTER_UNSAFE_RAW Do nothing, optionally strip or encode special characters
FILTER_VALIDATE_INT Validate value as integer, optionally from the specified range
FILTER_VALIDATE_BOOLEAN Return TRUE for "1", "true", "on" and "yes", FALSE for "0", "false", "off", "no", and "", NULL otherwise
FILTER_VALIDATE_FLOAT Validate value as float
FILTER_VALIDATE_REGEXP Validate value against regexp, a Perl-compatible regular expression
FILTER_VALIDATE_URL Validate value as URL, optionally with required components
FILTER_VALIDATE_EMAIL Validate value as e-mail
FILTER_VALIDATE_IP Validate value as IP address, optionally only IPv4 or IPv6 or not from private or reserved ranges



检测判断的例子


1 <html>
2 <head></head>
3 <body
4 <form action="example04.php" method="post" >
5 Enter your age: <input name="age" size="2">
6 <input type="submit" name="submit" value="Go">
7 </form>
8 </body>
9 </html>
view plain | print | copy to clipboard | ?

<html>
<head></head>
<body
<form action="example04.php" method="post" >
Enter your age: <input name="age" size="2">
<input type="submit" name="submit" value="Go">
</form>
</body>
</html>

处理脚本:


1 <?php
2 if (!filter_has_var(INPUT_POST, 'submit')) {
3 echo "form";
4 // include the form.
5 }
6
7 $age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT);
8 if (is_null($age)) {
9 echo "The 'age' field is required.<br />";
10 } elseif ($age === FALSE) {
11 echo "Please enter a valid age.<br />";
12 } else {
13 echo "Welcome.<br/>";
14 }
15 ?>
view plain | print | copy to clipboard | ?

<?php
if (!filter_has_var(INPUT_POST, 'submit')) {
echo "form";
// include the form.
}
$age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT);
if (is_null($age)) {
echo "The 'age' field is required.<br />";
} elseif ($age === FALSE) {
echo "Please enter a valid age.<br />";
} else {
echo "Welcome.<br/>";
}
?>

filter_has_var检测给定的变量是否存在。它不会做任何处理只会告诉程序变量是否已经设置。相当于isset($_POST[‘submit’])。filter_input会取得一个变量返回处理好的数据。在上面的例子中会返回一个整数。

如果是要返回一个处于一定范围之内的值,假设是7-77岁之间的人。可以指定一个最大值和一个最小值。


1 <?php
2 if (!filter_has_var(INPUT_POST, 'submit')) {
3 echo "form";
4 // include the form.
5 }
6 $options = array('options'=> array('min_range'=>7, 'min_range'=>77));
7 $age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT, $options);
8
9 if (is_null($age)) {
10 echo "The 'age' field is required.<br />";
11 } elseif ($age === FALSE) {
12 echo "You must be enter a valid age and be between 7 and 77 years old.<br />";
13 } else {
14 echo "Welcome.<br/>";
15 }
16 ?>
view plain | print | copy to clipboard | ?

<?php
if (!filter_has_var(INPUT_POST, 'submit')) {
echo "form";
// include the form.
}
$options = array('options'=> array('min_range'=>7, 'min_range'=>77));
$age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT, $options);
if (is_null($age)) {
echo "The 'age' field is required.<br />";
} elseif ($age === FALSE) {
echo "You must be enter a valid age and be between 7 and 77 years old.<br />";
} else {
echo "Welcome.<br/>";
}
?>

如果是要判断一个有效的邮件地址的话,可以这样:


1 $email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
view plain | print | copy to clipboard | ?

$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);

如果邮件地址不正确或者是空的话$email的值将为FALSE。

过滤判断的例子


1 <html>
2 <head></head>
3 <body>
4 <form action="example05.php" method="post" >
5 Enter your name: <input name="name" size="50">
6 <input type="submit" name="submit" value="Go">
7 </form>
8 </body>
9 </html>
view plain | print | copy to clipboard | ?

<html>
<head></head>
<body>
<form action="example05.php" method="post" >
Enter your name: <input name="name" size="50">
<input type="submit" name="submit" value="Go">
</form>
</body>
</html>

下面的filter_input函数将自动过滤并返回适当的值:


1 <?php
2 if (!filter_has_var(INPUT_POST, 'submit')) {
3 echo "form";
4 // include the form.
5 }
6 $name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_SPECIAL_CHARS);
7 if (is_null($name)) {
8 echo "The 'name' field is required.<br />";
9 } else {
10 echo "Hello $name.<br/>";
11 }
12 ?>
view plain | print | copy to clipboard | ?

<?php
if (!filter_has_var(INPUT_POST, 'submit')) {
echo "form";
// include the form.
}
$name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_SPECIAL_CHARS);
if (is_null($name)) {
echo "The 'name' field is required.<br />";
} else {
echo "Hello $name.<br/>";
}
?>

如果接收到的name值是:
Johnny Wei&szlig;müller <b>Jr</b>

FILTER_SANITIZE_SPECIAL_CHARS 将会返回:
Hello Johnny Wei&#223;müller <b>Jr</b>.

一个更好的过滤写法:


1 $name = filter_input(INPUT_POST,
2 'name',
3 FILTER_SANITIZE_STRING,
4 FILTER_FLAG_ENCODE_HIGH|FILTER_FLAG_ENCODE_LOW);
view plain | print | copy to clipboard | ?

$name = filter_input(INPUT_POST,
'name',
FILTER_SANITIZE_STRING,
FILTER_FLAG_ENCODE_HIGH|FILTER_FLAG_ENCODE_LOW);

输出:
Hello Johnny Weißmüller Jr.

这里的函数还有很多选项,如果你想了解更多的细节可以查看Filter的文档。

如何一次处理所有输入?


1 <html>
2 <head></head>
3 <body
4 <form action="example07.php" method="post" >
5 Name: <input name="name" size="50"><br />
6 Email: <input name="email" size="50"><br />
7 Homepage: <input name="homepage" size="50"><br />
8 Age: <input name="age" size="4"><br />
9 Income: <input name="income" size="50"><br />
10 Your two favourites languages:
11 <select name="favourites[]" size="6" multiple>
12 <option value="haskell">haskell</option>
13 <option value="r">R</option>
14 <option value="lua">Lua</option>
15 <option value="pike">Pike</option>
16 <option value="rebol">Rebol</option>
17 <option value="php">PHP</option>
18 </select><br />
19 <input type="submit" name="submit" value="Go">
20 </form>
21 </body>
22 </html>
view plain | print | copy to clipboard | ?

<html>
<head></head>
<body
<form action="example07.php" method="post" >
Name: <input name="name" size="50"><br />
Email: <input name="email" size="50"><br />
Homepage: <input name="homepage" size="50"><br />
Age: <input name="age" size="4"><br />
Income: <input name="income" size="50"><br />
Your two favourites languages:
<select name="favourites[]" size="6" multiple>
<option value="haskell">haskell</option>
<option value="r">R</option>
<option value="lua">Lua</option>
<option value="pike">Pike</option>
<option value="rebol">Rebol</option>
<option value="php">PHP</option>
</select><br />
<input type="submit" name="submit" value="Go">
</form>
</body>
</html>

处理程序:


1 <?php
2 if (!filter_has_var(INPUT_POST, 'submit')) {
3 echo "form";
4 // include the form.
5 }
6
7 $defs = array(
8 'name' => array('filter'=>FILTER_SANITIZE_STRING,
9 'flags' => FILTER_FLAG_ENCODE_HIGH|FILTER_FLAG_ENCODE_LOW),
10 'email' => FILTER_VALIDATE_EMAIL,
11 'homepage' => FILTER_VALIDATE_URL,
12 'age' => array( 'filter' => FILTER_VALIDATE_INT,
13 'options'=> array('min_range'=>7, 'min_range'=>77)),
14 'income' => FILTER_VALIDATE_FLOAT,
15 'favourites' => array(
16 'filter' => FILTER_SANITIZE_STRING,
17 'flags' => FILTER_REQUIRE_ARRAY
18 ),
19 );
20
21 $input = filter_input_array(INPUT_POST, $defs);
22
23 if ($input['age'] === FALSE) {
24 exit("You must be between 7 and 77 years old.");
25 }
26
27 if (is_null($input['favourites'])) {
28 exit("You have to choose two or more languages.");
29 }
30
31 if (!in_array('PHP', $inputs['favourites'])) {
32 exit("You don't like PHP!");
33 }
34
35 /*Other checks for required values */
36 ?>
view plain | print | copy to clipboard | ?

<?php
if (!filter_has_var(INPUT_POST, 'submit')) {
echo "form";
// include the form.
}
$defs = array(
'name' => array('filter'=>FILTER_SANITIZE_STRING,
'flags' => FILTER_FLAG_ENCODE_HIGH|FILTER_FLAG_ENCODE_LOW),
'email' => FILTER_VALIDATE_EMAIL,
'homepage' => FILTER_VALIDATE_URL,
'age' => array( 'filter' => FILTER_VALIDATE_INT,
'options'=> array('min_range'=>7, 'min_range'=>77)),
'income' => FILTER_VALIDATE_FLOAT,
'favourites' => array(
'filter' => FILTER_SANITIZE_STRING,
'flags' => FILTER_REQUIRE_ARRAY
),
);
$input = filter_input_array(INPUT_POST, $defs);
if ($input['age'] === FALSE) {
exit("You must be between 7 and 77 years old.");
}
if (is_null($input['favourites'])) {
exit("You have to choose two or more languages.");
}
if (!in_array('PHP', $inputs['favourites'])) {
exit("You don't like PHP!");
}
/*Other checks for required values */
?>

正如上面例子中的,通过一个函数就能处理所有的变量。唯一不同的就是事先定义一个对应的数组。需要注意的是数组中选项的正确性。

这样的做法不但增加了程序的易读性,并且如果要添加移除或者修改处理规则也会非常方便。

更复杂的处理

在下面的处理“favourites”变量时用到了用户自定义函数。"options"指定一个用户自定义函数通过定义callback来实现,语法和PHP的call_user_func一样。


1 <?php
2 class language {
3 function __construct($name) {
4 $this->name = $name;
5 }
6 }
7
8 function check_languages($var) {
9 static $called = 0;
10 $called++;
11 echo "called: $called: $var<br />";
12 $var = filter_var($var, FILTER_SANITIZE_STRIPPED);
13 $l = new language($var);
14 return $l;
15 }
16
17 if (!filter_has_var(INPUT_POST, 'submit')) {
18 echo "form";
19 // include the form.
20 }
21
22 $defs = array(
23 'name' => array('filter'=>FILTER_SANITIZE_STRING,
24 'flags' => FILTER_FLAG_ENCODE_HIGH|FILTER_FLAG_ENCODE_LOW),
25 'email' => FILTER_VALIDATE_EMAIL,
26 'homepage' => FILTER_VALIDATE_URL,
27 'age' => FILTER_VALIDATE_INT,
28 'income' => FILTER_VALIDATE_FLOAT,
29 'favourites' => array(
30 'filter' => FILTER_CALLBACK,
31 'options' => 'check_languages'
32 ),
33 );
34
35 $input = filter_input_array(INPUT_POST, $defs);
36
37 if ($input['age'] === FALSE) {
38 exit("You must be between 7 and 77 years old.");
39 }
40
41 if (is_null($input['favourites'])) {
42 exit("You have to choose two or more languages.");
43 }
44
45 echo "Your favourite languages:<br /><ul>";
46 foreach ($input['favourites'] as $l) echo '<li>' . $l->name . "</li>";
47 echo '</ul>';
48 ?>
view plain | print | copy to clipboard | ?

<?php
class language {
function __construct($name) {
$this->name = $name;
}
}
function check_languages($var) {
static $called = 0;
$called++;
echo "called: $called: $var<br />";
$var = filter_var($var, FILTER_SANITIZE_STRIPPED);
$l = new language($var);
return $l;
}
if (!filter_has_var(INPUT_POST, 'submit')) {
echo "form";
// include the form.
}
$defs = array(
'name' => array('filter'=>FILTER_SANITIZE_STRING,
'flags' => FILTER_FLAG_ENCODE_HIGH|FILTER_FLAG_ENCODE_LOW),
'email' => FILTER_VALIDATE_EMAIL,
'homepage' => FILTER_VALIDATE_URL,
'age' => FILTER_VALIDATE_INT,
'income' => FILTER_VALIDATE_FLOAT,
'favourites' => array(
'filter' => FILTER_CALLBACK,
'options' => 'check_languages'
),
);
$input = filter_input_array(INPUT_POST, $defs);
if ($input['age'] === FALSE) {
exit("You must be between 7 and 77 years old.");
}
if (is_null($input['favourites'])) {
exit("You have to choose two or more languages.");
}
echo "Your favourite languages:<br /><ul>";
foreach ($input['favourites'] as $l) echo '<li>' . $l->name . "</li>";
echo '</ul>';
?>

如果参数是标准参数,函数将只会别调用一次,如果变量是一个数组,将会自动被数组的每个成员调用一次。

当使用callback的时候Filter不会转换或者验证输入数据。但是上面例子中的filter_var可以在callback函数或者方法中使用。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics