PHP学习基础第五节

一、php过滤器

PHP 过滤器用于验证和过滤来自非安全来源的数据,比如用户的输入。测试、验证和过滤用户输入或自定义数据是任何 Web 应用程序的重要组成部分。PHP 的过滤器扩展的设计目的是使数据过滤更轻松快捷。

几乎所有的 Web 应用程序都依赖外部的输入。这些数据通常来自用户或其他应用程序(比如 web 服务)。通过使用过滤器,您能够确保应用程序获得正确的输入类型。

什么是外部数据?来自表单的输入数据    Cookies    Web services data    服务器变量
  数据库查询结果

您应该始终对外部数据进行过滤!输入过滤是最重要的应用程序安全课题之一。

如需过滤变量,请使用下面的过滤器函数之一:

filter_var() - 通过一个指定的过滤器来过滤单一的变量

filter_var_array() - 通过相同的或不同的过滤器来过滤多个变量

filter_input - 获取一个输入变量,并对它进行过滤

filter_input_array - 获取多个输入变量,并通过相同的或不同的过滤器对它们进行过滤

<?php

$int = 123;

if(!filter_var($int, FILTER_VALIDATE_INT))

{

echo  ("Integer is not valid");

}

else

{

echo   ("Integer is valid");

}

?>

上面的代码使用了 "FILTER_VALIDATE_INT" 过滤器来过滤变量。由于这个整数是合法的,因此上面的代码将输出:"Integer is valid"。

如果我们尝试使用一个非整数的变量(比如 "123abc"),则将输出:"Integer is not valid"。

有两种过滤器:

Validating 过滤器:

用于验证用户输入

严格的格式规则(比如 URL 或 E-Mail 验证)

如果成功则返回预期的类型,如果失败则返回 FALSE

Sanitizing 过滤器:

用于允许或禁止字符串中指定的字符Are used to allow or disallow specified characters in a string

无数据格式规则

始终返回字符串

选项和标志

选项和标志用于向指定的过滤器添加额外的过滤选项。

不同的过滤器有不同的选项和标志。

在下面的实例中,我们用 filter_var() 和 "min_range" 以及 "max_range" 选项验证了一个整数:

<?php

$var=300;

$int_options = array(

"options"=>array

(

"min_range"=>0,

"max_range"=>256

)

);

if(!filter_var($var, FILTER_VALIDATE_INT, $int_options))

{

echo("Integer is not valid");

}

else

{

echo("Integer is valid");

}

?>

就像上面的代码一样,选项必须放入一个名为 "options" 的相关数组中。如果使用标志,则不需在数组内。

由于整数是 "300",它不在指定的范围内,以上代码的输出将是 "Integer is not valid"。

验证输入

让我们试着验证来自表单的输入。

我们需要做的第一件事情是确认是否存在我们正在查找的输入数据。

然后我们用 filter_input() 函数过滤输入的数据。

在下面的实例中,输入变量 "email" 被传到 PHP 页面:

<?php

if(!filter_has_var(INPUT_GET, "email"))

{

echo("Input type does not exist");

}

else

{

if (!filter_input(INPUT_GET, "email", FILTER_VALIDATE_EMAIL))

{

echo "E-Mail is not valid";

}

else

{

echo "E-Mail is valid";

}

}

?>

上面的实例有一个通过 "GET" 方法传送的输入变量 (email):检测是否存在 "GET" 类型的 "email" 输入变量,如果存在输入变量,检测它是否是有效的 e-mail 地址

净化输入

让我们试着清理一下从表单传来的 URL。

首先,我们要确认是否存在我们正在查找的输入数据。

然后,我们用 filter_input() 函数来净化输入数据。

在下面的实例中,输入变量 "url" 被传到 PHP 页面:

<?php

f(!filter_has_var(INPUT_POST, "url"))

{

echo("Input type does not exist");

}

else

{

$url = filter_input(INPUT_POST,

"url", FILTER_SANITIZE_URL);

}

?>

上面的实例有一个通过 "POST" 方法传送的输入变量 (url):

检测是否存在 "POST" 类型的 "url" 输入变量

如果存在此输入变量,对其进行净化(删除非法字符),并将其存储在 $url 变量中

假如输入变量是一个类似这样的字符串:"http://www.W3CååSchøøool.cc/",则净化后的 $url 变量如下所示:

http://www.W3CSchool.cc/

过滤多个输入

表单通常由多个输入字段组成。为了避免对 filter_var 或 filter_input 函数重复调用,我们可以使用 filter_var_array 或 the filter_input_array 函数。

在本例中,我们使用 filter_input_array() 函数来过滤三个 GET 变量。接收到的 GET 变量是一个名字、一个年龄以及一个 e-mail 地址:

<?php

$filters = array

(

"name" => array

(

"filter"=>FILTER_SANITIZE_STRING

),

"age" => array

(

"filter"=>FILTER_VALIDATE_INT,

"options"=>array

(

"min_range"=>1,

"max_range"=>120

)

),

"email"=> FILTER_VALIDATE_EMAIL

);

$result = filter_input_array(INPUT_GET, $filters);

if (!$result["age"])

{

echo("Age must be a number between 1 and 120.
");

}

elseif(!$result["email"])

{

echo("E-Mail is not valid.
");

}

else

{

echo("User input is valid");

}

?>

上面的实例有三个通过 "GET" 方法传送的输入变量 (name、age 和 email):

设置一个数组,其中包含了输入变量的名称和用于指定的输入变量的过滤器

调用 filter_input_array() 函数,参数包括 GET 输入变量及刚才设置的数组

检测 $result 变量中的 "age" 和 "email" 变量是否有非法的输入。(如果存在非法输入,在使用 filter_input_array() 函数之后,输入变量为 FALSE。)

filter_input_array() 函数的第二个参数可以是数组或单一过滤器的 ID。

如果该参数是单一过滤器的 ID,那么这个指定的过滤器会过滤输入数组中所有的值。

如果该参数是一个数组,那么此数组必须遵循下面的规则:

必须是一个关联数组,其中包含的输入变量是数组的键(比如 "age" 输入变量)

此数组的值必须是过滤器的 ID ,或者是规定了过滤器、标志和选项的数组

使用 Filter Callback

通过使用 FILTER_CALLBACK 过滤器,可以调用自定义的函数,把它作为一个过滤器来使用。这样,我们就拥有了数据过滤的完全控制权。

您可以创建自己的自定义函数,也可以使用已存在的 PHP 函数。

将您准备用到的过滤器的函数,按指定选项的规定方法进行规定。在关联数组中,带有名称 "options"。

在下面的实例中,我们使用了一个自定义的函数把所有 "_" 转换为空格:

<?php

function convertSpace($string)

{

return str_replace("_", " ", $string);

}

$string = "Peter_is_a_great_guy!";

echo filter_var($string, FILTER_CALLBACK,

array("options"=>"convertSpace"));

?>

上面代码的结果如下所示:

Peter is a great guy!

上面的实例把所有 "_" 转换成空格:创建一个把 "_" 替换为空格的函数,调用 filter_var() 函数,它的参数是 FILTER_CALLBACK 过滤器以及包含我们的函数的数组





二、PHP中header的用法总结

header()函数的作用是:发送一个原始 HTTP 标头[Http Header]到客户端。

标头 (header) 是服务器以 HTTP 协义传 HTML 资料到浏览器前所送出的字串,在标头

与 HTML 文件之间尚需空一行分隔。有关 HTTP 的详细说明,可以参 RFC 2068 官方文件

(http://www.w3.org/Protocols/rfc2068/rfc2068)。

在 PHP 中送回 HTML 资料前,需先 传完所有的标头。

使用范例:

范例一: 本例使浏览器重定向到 PHP 的官方网站。

<?php

Header("Location:http://www.php.net";);

exit;//在每个重定向之后都必须加上“exit",避免发生错误后,继续执行。

?>

<?php

header("refresh:3;url=http://axgle.za.net");

print('正在加载,请稍等...
三秒后自动跳转~~~');

header重定向 就等价于替用户在地址栏输入url

?>

范例二:禁止页面在IE中缓存

要使用者每次都能得到最新的资料,而不是 Proxy 或 cache中的资料,可以使用下列的标头

<?php

header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');

header('Last-Modified: '.gmdate('D, d M Y H:i:s') .' GMT');

header('Cache-Control: no-store, no-cache,

must-revalidate');

header('Cache-Control: post-check=0,

pre-check=0',false);

header('Pragma: no-cache');//兼容http1.0和https

?>

CacheControl = no-cache

Pragma=no-cache

Expires = -1

Expires是个好东东,如果服务器上的网页经常变化,就把它设置为-1,表示立即过期。如果一个网页每天凌晨1点更新,可以把Expires设置为第二天的凌晨1点。

当HTTP1.1服务器指定CacheControl = no-cache时,浏览器就不会缓存该网页。

旧式 HTTP 1.0 服务器不能使用 Cache-Control 标题。所以为了向后兼容 HTTP 1.0服务器,IE使用Pragma:no-cache 标题对 HTTP 提供特殊支持。

如果客户端通过安全连接 (https://) 与服务器通讯,且服务器在响应中返回 Pragma:no-cache 标题,则Internet Explorer 不会缓存此响应。

注意:Pragma:no-cache仅当在安全连接中使用时才防止缓存,如果在非安全页中使用,处理方式与 Expires:-1相同,该页将被缓存,但被标记为立即过期。

http-equiv meta标记:

html页面中可以用http-equiv meta来标记指定的http消息头部。老版本的IE可能不支持htmlmeta标记,所以最好使用http消息头部来禁用缓存。

范例三: 让使用者的浏览器出现找不到档案的信息。

网上很多资料这样写:php的函数header()可以向浏览器发送Status标头,

如 header(”Status: 404 Not Found”)。

但是我发现实际上浏览器返回的响应却是:

HTTP/1.x 200 OK

Date: Thu, 03 Aug 2006 07:49:11 GMT

Server: Apache/2.0.55 (Win32) PHP/5.0.5

X-Powered-By: PHP/5.0.5

Status: 404 Not Found

Content-Length: 0

Keep-Alive: timeout=15, max=98

Connection: Keep-Alive

Content-Type: text/html

查了一些资料,正确的写法是:

header(”http/1.1 404 Not

Found”);

第一部分为HTTP协议的版本(HTTP-Version);第二部分为状态代码(Status);第三部分为原因短语(Reason-Phrase)。

范例四:让使用者下载档案( 隐藏文件的位置 )

html标签 就可以实现普通文件下载。如果为了保密文件,就不能把文件链接告诉别人,可以用header函数实现文件下载。


header("Content-type: application/x-gzip");

header("Content-Disposition: attachment; filename=文件名\");

header("Content-Description: PHP3 Generated Data");

?>

范例四:header函数前输入内容

一般来说在header函数前不能输出html内容,类似的还有setcookie() 和 session函数,这些函数需要在输出流中增加消息头部信息。如果在header()执行之前有echo等语句,当后面遇到header()时,就会报出“Warning: Cannot modify header information - headers already sentby….”错误。就是说在这些函数的前面不能有任何文字、空行、回车等,而且最好在header()函数后加上exit()函数。例如下面的错误写法,在两个php代码段之间有一个空行:

//some code here

?>

//这里应该是一个空行

header(”http/1.1 403 Forbidden”);

exit();

?>

原因是:PHP脚本开始执行 时,它可以同时发送http消息头部(标题)信息和主体信息. http消息头部(来自 header() 或SetCookie() 函数)并不会立即发送,相反,它被保存到一个列表中. 这样就可以允许你修改标题信息,包括缺省的标题(例如Content-Type 标题).但是,一旦脚本发送了任何非标题的输出(例如,使用 HTML 或 print()调用),那么PHP就必须先发送完所有的Header,然后终止 HTTPheader.而后继续发送主体数据.从这时开始,任何添加或修改Header信息的试图都是不允许的,并会发送上述的错误消息之一。

解决办法:

修改php.ini打开缓存(output_buffering),或者在程序中使用缓存函数ob_start(),ob_end_flush()等。原理是:output_buffering被启用时,在脚本发送输出时,PHP并不发送HTTPheader。相反,它将此输出通过管道(pipe)输入到动态增加的缓存中(只能在PHP4.0中使用,它具有中央化的输出机制)。你仍然可以修改/添加header,或者设置cookie,因为header实际上并没有发送。当全部脚本终止时,PHP将自动发送HTTP header到浏览器,然后再发送输出缓冲中的内容。


PHP 手册实例应用

1:您可以使用heder命令,强制使浏览器使用新鲜的内容(无缓存) 。

也可以给网址增加了一个唯一的编号,使其每次都读取新的内容,避免缓存。

example:

<?php

print"<img src='yourfile.jpg'>";//通常读取的是缓存文件

?>

<?php

print"<img src='yourfile.jpg?".time()."'>";//增加了唯一的编号,使浏览器重新请求

w//print"<img src='yourfile.jpg?".rand(100,999)."'>";

?>

2: 下面是个很好的函数,将图片传送给浏览器显示。

<?php

function PE_img_by_path($PE_imgpath = "")

{

if(file_exists($PE_imgpath)) {

$PE_imgarray = pathinfo($PE_imgpath);

$iconcontent = file_get_contents($PE_imgpath);

header("Content-type: image/" . $PE_imgarray["extension"]);

header('Content-length: ' . strlen($iconcontent));

echo $iconcontent;

die(0);

}

returnfalse;

}

?>

更多的实例:

<?php

// ok

header('HTTP/1.1 200 OK');

//设置一个404头:

header('HTTP/1.1 404 Not Found');

//设置地址被永久的重定向

header('HTTP/1.1 301 Moved Permanently');

//转到一个新地址

header('Location:http://www.example.org/');

//文件延迟转向:

header('Refresh: 10; url=http://www.example.org/');

print 'You will be redirected in 10 seconds';

//当然,也可以使用html语法实现

//<meta http-equiv="refresh"   content="10;http://www.example.org/ />

// override X-Powered-By: PHP:

header('X-Powered-By: PHP/4.4.0');

header('X-Powered-By: Brain/0.6b');

//文档语言

header('Content-language: en');

//告诉浏览器最后一次修改时间

$time = time() - 60; // or filemtime($fn), etc

header('Last-Modified: '.gmdate('D, d M Y H:i:s', $time).'GMT');

//告诉浏览器文档内容没有发生改变

header('HTTP/1.1 304 Not Modified');

//设置内容长度

header('Content-Length: 1234');

//设置为一个下载类型

header('Content-Type: application/octet-stream');

header('Content-Disposition: attachment;filename="example.zip"');

header('Content-Transfer-Encoding: binary');

// load the file to send:

readfile('example.zip');

// 对当前文档禁用缓存

header('Cache-Control: no-cache, no-store, max-age=0,must-revalidate');

header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in thepast

header('Pragma: no-cache');

//设置内容类型:

header('Content-Type: text/html; charset=iso-8859-1');

header('Content-Type: text/html; charset=utf-8');

header('Content-Type: text/plain'); //纯文本格式

header('Content-Type: image/jpeg'); //JPG图片

header('Content-Type: application/zip'); // ZIP文件

header('Content-Type: application/pdf'); // PDF文件

header('Content-Type: audio/mpeg'); // 音频文件

header('Content-Type: application/x-shockwave-flash');//Flash动画

//显示登陆对话框

header('HTTP/1.1 401 Unauthorized');

header('WWW-Authenticate: Basic realm="Top Secret"');

print 'Text that will be displayed if the user hits cancel or';

print 'enters wrong login data';

?>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,591评论 18 139
  • 一、概念(载录于:http://www.cnblogs.com/EricaMIN1987_IT/p/3837436...
    yuantao123434阅读 8,328评论 6 152
  • 什么是HTTP Headers HTTP是“Hypertext Transfer Protocol”的所写,整个万...
    苏文星阅读 2,645评论 0 4
  • 转载自cr180大神DiscuzX2.5完整目录结构【source程序文件库】 /source/admincp后台...
    cndaqiang阅读 832评论 1 2
  • 今天在家里窝了一天,什么也没做,什么也不想做,再过三天我就要开始实习了,继续这个可能让我转正的工作。我还没有想好,...
    荭荭阅读 170评论 0 0