陈浩民为老婆剃下体毛:十天学会PHP/第九天:错误处理、异常处理、过滤器

来源:百度文库 编辑:中财网 时间:2024/04/27 17:32:50

PHP 错误处理

  • 在创建脚本和web应用程序时,错误处理是一个重要的部分。如果您的代码缺少错误检测编码,那么程序看上去很不专业,也为安全风险敞开了大门。
  • 本教程介绍了 PHP 中一些最为重要的错误检测方法。
  • 我们将为您讲解不同的错误处理方法:
  1. 简单的 "die()" 语句
  2. 自定义错误和错误触发器
  3. 错误报告
  4. 基本的错误处理:使用 die() 函数
  • 第一个例子展示了一个打开文本文件的简单脚本:
  • 如果文件不存在,您会获得类似这样的错误:
Warning: fopen(welcome.txt) [function.fopen]: failed to open stream: No such file or directory in C:\webfolder\test.php on line 2
  • 为了避免用户获得类似上面的错误消息,我们在访问文件之前检测该文件是否存在:
  • 现在,假如文件不存在,您会得到类似这样的错误消息:
  • 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 "Error: [$errno] $errstr
"; echo "Ending Script"; die(); }
  • 上面的代码是一个简单的错误处理函数。当它被触发时,它会取得错误级别和错误消息。然后它会输出错误级别和消息,并终止脚本。
  • 现在,我们已经创建了一个错误处理函数,我们需要确定在何时触发该函数。
  • Set Error Handler
  • PHP 的默认错误处理程序是内建的错误处理程序。我们打算把上面的函数改造为脚本运行期间的默认错误处理程序。
  • 可以修改错误处理程序,使其仅应用到某些错误,这样脚本就可以不同的方式来处理不同的错误。不过,在本例中,我们打算针对所有错误来使用我们的自定义错误处理程序:
  • set_error_handler("customError");由于我们希望我们的自定义函数来处理所有错误,set_error_handler() 仅需要一个参数,可以添加第二个参数来规定错误级别。
  • 实例
  • 通过尝试输出不存在的变量,来测试这个错误处理程序:
Error: [$errno] $errstr"; }//set error handlerset_error_handler("customError");//trigger errorecho($test);?>
  • 以上代码的输出应该类似这样:
  • Error: [8] Undefined variable: test触发错误
  • 在脚本中用户输入数据的位置,当用户的输入无效时触发错误的很有用的。在 PHP 中,这个任务由 trigger_error() 完成。
  • 例子
  • 在本例中,如果 "test" 变量大于 "1",就会发生错误:
1){trigger_error("Value must be 1 or below");}?>
  • 以上代码的输出应该类似这样:
Notice: Value must be 1 or belowin 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,我们将使用我们的自定义错误处理程序并结束脚本:
Error: [$errno] $errstr
"; echo "Ending Script"; die(); }//set error handlerset_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 belowEnding Script
  • 现在,我们已经学习了如何创建自己的 error,以及如何处罚它们,现在我们研究一下错误记录。

错误记录

  • 默认地,根据在 php.ini 中的 error_log 配置,PHP 向服务器的错误记录系统或文件发送错误记录。通过使用 error_log() 函数,您可以向指定的文件或远程目的地发送错误记录。
  • 通过电子邮件向您自己发送错误消息,是一种获得指定错误的通知的好办法。
  • 通过 E-Mail 发送错误消息
  • 在下面的例子中,如果特定的错误发生,我们将发送带有错误消息的电子邮件,并结束脚本:
Error: [$errno] $errstr
"; echo "Webmaster has been notified"; error_log("Error: [$errno] $errstr",1, "someone@example.com","From: webmaster@example.com");}//set error handlerset_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 belowWebmaster has been notified
  • 接收自以上代码的邮件类似这样:
  • Error: [512] Value must be 1 or below这个方法不适合所有的错误。常规错误应当通过使用默认的 PHP 记录系统在服务器上进行记录。

什么是 PHP 过滤器?

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

为什么使用过滤器?

  • 几乎所有 web 应用程序都依赖外部的输入。这些数据通常来自用户或其他应用程序(比如 web 服务)。通过使用过滤器,您能够确保应有程序获得正确的输入类型。
  • 您应该始终对外部数据进行过滤!
  • 输入过滤是最重要的应用程序安全课题之一。

什么是外部数据?

  • 来自表单的输入数据
  • Cookies
  • 服务器变量
  • 数据库查询结果
  • 函数和过滤器
  • 如需过滤变量,请使用下面的过滤器函数之一
  1. filter_var() - 通过一个指定的过滤器来过滤单一的变量
  2. filter_var_array() - 通过相同的或不同的过滤器来过滤多个变量
  3. filter_input - 获取一个输入变量,并对它进行过滤
  4. filter_input_array - 获取多个输入变量,并通过相同的或不同的过滤器对它们进行过滤
  • 在下面的例子中,我们用 filter_var() 函数验证了一个整数:
  • 上面的代码使用了 "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" 选项验证了一个整数:
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 页面:

例子解释'

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

净化输入

  • 让我们试着清理一下从表单传来的 URL。
  • 首先,我们要确认是否存在我们正在查找的输入数据。
  • 然后,我们用 filter_input() 函数来净化输入数据。
  • 在下面的例子中,输入变量 "url" 被传到 PHP 页面:
例子解释:
  • 上面的例子有一个通过 "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 变量是一个名称、一个年龄以及一个邮件地址:
 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 and email)
  • 设置一个数组,其中包含了输入变量的名称,以及用于指定的输入变量的过滤器
  • 调用 filter_input_array 函数,参数包括 GET 输入变量及刚才设置的数组
  • 检测 $result 变量中的 "age" 和 "email" 变量是否有非法的输入。(如果存在非法输入,)
  • filter_input_array() 函数的第二个参数可以是数组或单一过滤器的 ID。
  • 如果该参数是单一过滤器的 ID,那么这个指定的过滤器会过滤输入数组中所有的值。
  • 如果该参数是一个数组,那么此数组必须遵循下面的规则:
  • 必须是一个关联数组,其中包含的输入变量是数组的键(比如 "age" 输入变量)
  • 此数组的值必须是过滤器的 ID ,或者是规定了过滤器、标志以及选项的数组

使用 Filter Callback

  • 通过使用 FILTER_CALLBACK 过滤器,可以调用自定义的函数,把它作为一个过滤器来使用。这样,我们就拥有了数据过滤的完全控制权。
  • 您可以创建自己的自定义函数,也可以使用已有的 PHP 函数。
  • 规定您准备用到过滤器的函数,与规定选项的方法相同。
  • 在下面的例子中,我们使用了一个自定义的函数把所有 "_" 转换为空格:
"convertSpace"));?>
  • 以上代码的结果是这样的:
  • Peter is a great guy!例子解释:
  • 上面的例子把所有 "_" 转换成空格:
  • 创建一个把 "_" 替换为空格的函数
  • 调用 filter_var() 函数,它的参数是 FILTER_CALLBACK 过滤器以及包含我们的函数的数组