十天学会PHP/第九天:错误处理、异常处理、过滤器
来自站长百科
十天学会PHP |
PHP 错误处理[ ]
- 在创建脚本和web应用程序时,错误处理是一个重要的部分。如果您的代码缺少错误检测编码,那么程序看上去很不专业,也为安全风险敞开了大门。
- 本教程介绍了 PHP 中一些最为重要的错误检测方法。
- 我们将为您讲解不同的错误处理方法:
- 简单的 "die()" 语句
- 自定义错误和错误触发器
- 错误报告
- 基本的错误处理:使用 die() 函数
- 第一个例子展示了一个打开文本文件的简单脚本:
<?php $file=fopen("welcome.txt","r"); ?>
- 如果文件不存在,您会获得类似这样的错误:
Warning: fopen(welcome.txt) [function.fopen]: failed to open stream: No such file or directory in C:\webfolder\test.php on line 2
- 为了避免用户获得类似上面的错误消息,我们在访问文件之前检测该文件是否存在:
<?php if(!file_exists("welcome.txt")) { die("File not found"); } else { $file=fopen("welcome.txt","r"); } ?>
- 现在,假如文件不存在,您会得到类似这样的错误消息:
- File not found比起之前的代码,上面的代码更有效,这是由于它采用了一个简单的错误处理机制在错误之后终止了脚本。
- 不过,简单地终止脚本并不总是恰当的方式。让我们研究一下用于处理错误的备选的 PHP 函数。
创建自定义错误处理器[ ]
- 创建一个自定义的错误处理器非常简单。我们很简单地创建了一个专用函数,可以在 PHP 中发生错误时调用该函数。
- 该函数必须有能力处理至少两个参数 (error level 和 error message),但是可以接受最多五个参数(可选的:file, line-number 以及 error context):
- 语法
error_function(error_level,error_message, error_file,error_line,error_context)
- 错误报告级别
- 这些错误报告级别是错误处理程序旨在处理的错误的不同的类型:
- 现在,让我们创建一个处理错误的函数:
function customError($errno, $errstr) { echo "<b>Error:</b> [$errno] $errstr<br />"; echo "Ending Script"; die(); }
- 上面的代码是一个简单的错误处理函数。当它被触发时,它会取得错误级别和错误消息。然后它会输出错误级别和消息,并终止脚本。
- 现在,我们已经创建了一个错误处理函数,我们需要确定在何时触发该函数。
- Set Error Handler
- PHP 的默认错误处理程序是内建的错误处理程序。我们打算把上面的函数改造为脚本运行期间的默认错误处理程序。
- 可以修改错误处理程序,使其仅应用到某些错误,这样脚本就可以不同的方式来处理不同的错误。不过,在本例中,我们打算针对所有错误来使用我们的自定义错误处理程序:
- set_error_handler("customError");由于我们希望我们的自定义函数来处理所有错误,set_error_handler() 仅需要一个参数,可以添加第二个参数来规定错误级别。
- 实例
- 通过尝试输出不存在的变量,来测试这个错误处理程序:
<?php //error handler function function customError($errno, $errstr) { echo "<b>Error:</b> [$errno] $errstr"; } //set error handler set_error_handler("customError"); //trigger error echo($test); ?>
- 以上代码的输出应该类似这样:
- Error: [8] Undefined variable: test触发错误
- 在脚本中用户输入数据的位置,当用户的输入无效时触发错误的很有用的。在 PHP 中,这个任务由 trigger_error() 完成。
- 例子
- 在本例中,如果 "test" 变量大于 "1",就会发生错误:
<?php $test=2; if ($test>1) { trigger_error("Value must be 1 or below"); } ?>
- 以上代码的输出应该类似这样:
Notice: Value must be 1 or below in C:\webfolder\test.php on line 6
- 您可以在脚本中任何位置触发错误,通过添加的第二个参数,您能够规定所触发的错误级别。
- 可能的错误类型:
- E_USER_ERROR - 致命的用户生成的 run-time 错误。错误无法恢复。脚本执行被中断。
- E_USER_WARNING - 非致命的用户生成的 run-time 警告。脚本执行不被中断。
- E_USER_NOTICE - 默认。用户生成的 run-time 通知。脚本发现了可能的错误,也有可能在脚本运行正常时发生。
- 例子
- 在本例中,如果 "test" 变量大于 "1",则发生 E_USER_WARNING 错误。如果发生了 E_USER_WARNING,我们将使用我们的自定义错误处理程序并结束脚本:
<?php //error handler function function customError($errno, $errstr) { echo "<b>Error:</b> [$errno] $errstr<br />"; echo "Ending Script"; die(); } //set error handler set_error_handler("customError",E_USER_WARNING); //trigger error $test=2; if ($test>1) { trigger_error("Value must be 1 or below",E_USER_WARNING); } ?>
以上代码的输出应该类似这样:
Error: [512] Value must be 1 or below Ending Script
- 现在,我们已经学习了如何创建自己的 error,以及如何处罚它们,现在我们研究一下错误记录。
错误记录[ ]
- 默认地,根据在 php.ini 中的 error_log 配置,PHP 向服务器的错误记录系统或文件发送错误记录。通过使用 error_log() 函数,您可以向指定的文件或远程目的地发送错误记录。
- 通过电子邮件向您自己发送错误消息,是一种获得指定错误的通知的好办法。
- 通过 E-Mail 发送错误消息
- 在下面的例子中,如果特定的错误发生,我们将发送带有错误消息的电子邮件,并结束脚本:
<?php //error handler function function customError($errno, $errstr) { echo "<b>Error:</b> [$errno] $errstr<br />"; echo "Webmaster has been notified"; error_log("Error: [$errno] $errstr",1, "someone@example.com","From: webmaster@example.com"); } //set error handler set_error_handler("customError",E_USER_WARNING); //trigger error $test=2; if ($test>1) { trigger_error("Value must be 1 or below",E_USER_WARNING); } ?>
- 以上代码的输出应该类似这样:
Error: [512] Value must be 1 or below Webmaster has been notified
- 接收自以上代码的邮件类似这样:
- Error: [512] Value must be 1 or below这个方法不适合所有的错误。常规错误应当通过使用默认的 PHP 记录系统在服务器上进行记录。
什么是 PHP 过滤器?[ ]
- PHP 过滤器用于验证和过滤来自非安全来源的数据。
- 验证和过滤用户输入或自定义数据是任何 Web 应用程序的重要组成部分。
- 设计 PHP 的过滤器扩展的目的是使数据过滤更轻松快捷。
为什么使用过滤器?[ ]
- 几乎所有 web 应用程序都依赖外部的输入。这些数据通常来自用户或其他应用程序(比如 web 服务)。通过使用过滤器,您能够确保应有程序获得正确的输入类型。
- 您应该始终对外部数据进行过滤!
- 输入过滤是最重要的应用程序安全课题之一。
什么是外部数据?[ ]
- 来自表单的输入数据
- Cookies
- 服务器变量
- 数据库查询结果
- 函数和过滤器
- 如需过滤变量,请使用下面的过滤器函数之一:
- filter_var() - 通过一个指定的过滤器来过滤单一的变量
- filter_var_array() - 通过相同的或不同的过滤器来过滤多个变量
- filter_input - 获取一个输入变量,并对它进行过滤
- filter_input_array - 获取多个输入变量,并通过相同的或不同的过滤器对它们进行过滤
- 在下面的例子中,我们用 filter_var() 函数验证了一个整数:
<?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"。
- 假如我们尝试使用一个非整数的变量,则输出是:"Integer is not valid"。
- 如需完整的函数和过滤器列表,请访问我们的 PHP Filter 参考手册。
Validating 和 Sanitizing[ ]
- 有两种过滤器:
- Validating 过滤器:
- 用于验证用户输入
- 严格的格式规则(比如 URL 或 E-Mail 验证)
- 返回若成功预期的类型,否则返回 FALSE
- Sanitizing 过滤器:
- 用于允许或禁止字符串中指定的字符
- 无数据格式规则
- 始终返回字符串
- 选项和标志
- 选项和标志用于向指定的过滤器添加额外的过滤选项。
- 不同的过滤器有不同的选项和标志。
- 在下面的例子中,我们用 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"。
- 如需完整的函数及过滤器列表,请访问 W3School 提供的 PHP Filter 参考手册。您可以看到每个过滤器的可用选项和标志。
验证输入[ ]
- 让我们试着验证来自表单的输入。
- 我们需要作的第一件事情是确认是否存在我们正在查找的输入数据。
- 然后我们用 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" 输入变量
- 如果存在输入变量,检测它是否是有效的邮件地址
净化输入[ ]
- 让我们试着清理一下从表单传来的 URL。
- 首先,我们要确认是否存在我们正在查找的输入数据。
- 然后,我们用 filter_input() 函数来净化输入数据。
- 在下面的例子中,输入变量 "url" 被传到 PHP 页面:
<?php if(!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.W3#$%S^%$#ool.com.cn/",则净化后的 $url 变量应该是这样的:
- http://www.W3School.com.cn/过滤多个输入
- 表单通常由多个输入字段组成。为了避免对 filter_var 或 filter_input 重复调用,我们可以使用 filter_var_array 或 the filter_input_array 函数。
- 在本例中,我们使用 filter_input_array() 函数来过滤三个 GET 变量。接收到的 GET 变量是一个名称、一个年龄以及一个邮件地址:
<?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.<br />"); } elseif(!$result["email"]) { echo("E-Mail is not valid.<br />"); } else { echo("User input is valid"); } ?>
例子解释:
- 上面的例子有三个通过 "GET" 方法传送的输入变量 (name, age and email)
- 设置一个数组,其中包含了输入变量的名称,以及用于指定的输入变量的过滤器
- 调用 filter_input_array 函数,参数包括 GET 输入变量及刚才设置的数组
- 检测 $result 变量中的 "age" 和 "email" 变量是否有非法的输入。(如果存在非法输入,)
- filter_input_array() 函数的第二个参数可以是数组或单一过滤器的 ID。
- 如果该参数是单一过滤器的 ID,那么这个指定的过滤器会过滤输入数组中所有的值。
- 如果该参数是一个数组,那么此数组必须遵循下面的规则:
- 必须是一个关联数组,其中包含的输入变量是数组的键(比如 "age" 输入变量)
- 此数组的值必须是过滤器的 ID ,或者是规定了过滤器、标志以及选项的数组
使用 Filter Callback[ ]
- 通过使用 FILTER_CALLBACK 过滤器,可以调用自定义的函数,把它作为一个过滤器来使用。这样,我们就拥有了数据过滤的完全控制权。
- 您可以创建自己的自定义函数,也可以使用已有的 PHP 函数。
- 规定您准备用到过滤器的函数,与规定选项的方法相同。
- 在下面的例子中,我们使用了一个自定义的函数把所有 "_" 转换为空格:
<?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 过滤器以及包含我们的函数的数组
参考来源[ ]
使用手册导航 | ||
---|---|---|
|