PHP常见错误

news/2024/11/26 8:51:35/

初学者在编程时,经常会遇到各种错误,那么如何 正确的处理错误则是可以提高开发效率。

一:错误(Error)

1.1 什么是错误及错误的级别

错误是指在开发阶段中由一些失误引起的程序问题,根据其出现在编程过程中的不同环节。这些错误一般是由PHP内部引擎和扩展程序引发,或通过 trigger_error() 函数抛出

PHP中每个错误都有一个错误级别与之对应,如表所示

级别说明
E_ALL所有错误和警告信息
E_ERROR致命的运行时错误(它会阻止脚本运行)
E_WARNING运行时警告(非致命的错误)
E_PARSE编译时语法解析错误
E_NOTICE运行时通知,表示脚本遇到可能会表现为错误的情况
E_STRICT启用 PHP 对代码的修改建议
E_CORE_ERRORPHP初始启动期间发生的致命错误
E_CORE_WARNINGPHP初始启动期间出现的警告(非致命的错误)
E_COMPILE_ERROR编译时致命错误
E_COMPILE_WARNING编译时警告(非致命错误)
E_USER_ERROR用户产生的错误信息
E_USER_WARNING用户产生的警告信息
E_USER_NOTICE用户产生的通知信息

每个错误级别常量都是一个整数,此处并没有列出其值,使用时可以通过按位运算符来组合这些常量,用来表示某些类型的错误

1.2 显示错误级别

在开发程序时,有时希望可以控制是否显示错误以及显示错误的级别。为此,PHP提供了两种方法来显示错误报告,如下所示:

1.2.1 修改配置文件

在配置文件 php.ini 中修改配置指令error_reporting的值,修改完成后重新启动Web服务器,具体示例如下:

error_reporting(E_All & ~E_NOTICE);
display_errors=on;

注意:如果不知道 php.ini 文件的具体位置,可以使用 php --ini 查看配置文件的具体位置

error_reporting:显示错误的级别,多个错误级别用 & 分割,如果不想显示某个错误级别只需要在错误级别前加上 ~ 符号即可,这个符号等同于逻辑符号 取反 的意思

display_errors:是否开启显示错误,默认为开启(on),关闭设置为 off 即可

重启web服务时,如果是nginx服务器类型的服务器,需要重启php-fpm

1.2.2 ini_set()和error_reporting()函数

除了通过配置文件修改显示错误级别,还可以通过 ini_set() 和 error_reporting() 函数来实现。

error_reporting()函数等同于配置文件中的 error_reporting 配置选项。

ini_set()函数可以设置配置文件中所有可配置的选项,自然也包括error_reporting选项。其格式如下:

ini_set(string $varname, string $newvalue)

$varname:配置文件中的配置选项

$newvalue:新的值

1.3 错误日志记录

不管是何种类型的错误,默认情况下,PHP都会给出提示信息。在实际Web开发中,显示错误会造成极差的用户体验,还会给服务器带来安全隐患。例如错误信息一般包含文件路径信息,黑客据此可以发起攻击。故此,实际工作中,我们不会显示系统错误,一般都是把错误信息记录到日志文件。

错误日记的记录可以通过 php.ini 文件配置,主要就是开启日志记录和记录日志的文件路径:

# 开启错误日志
log_errors = On# 错误日志记录的文件路径
error_log = '/tmp/runtime/php/error.php'

正式环境,建议大家关闭显示错误信息,把所有错误记录到日志文件中。这样可以有效避免黑客攻击我们的服务器。

1.4 自定义错误处理函数

通过 set_error_handler() 函数设置全局错误处理函数。如果我们设置了处理函数,PHP出现错误时,就会把所有错误回调到我们设定的函数中,具体用法如下:

set_error_handler(callable $error_handler, int $error_types = E_ALL | E_STRICT)

error_handler:错误处理句柄,即错误处理的回调函数

error_types:错误类型,可以是多个

用户自定义的函数(error_handler)的参数:

  1. $error_type:错误类型

  2. $errstr:错误信息

  3. $errfile:产生错误的文件地址

  4. $errline:产生错误的行号

  5. $errcontext:包含参数和变量信息

整体用法如下:

function error_function($error_level, $error_message, $error_file, $error_line, $error_context){// 错误处理逻辑
}
// 设置错误处理句柄
set_error_handler('error_function', E_WARNING); // 这里error_function对应上面创建的自定义处理器名,第二个参数为使用自定义错误处理器的错误级别;

现在我们就可以在错误处理句柄中处理具体的错误逻辑,报错日志记录等。

二:异常(Exception)

上面我们介绍了错误及错误级别,但是错误往往只是粗浅的记录的错误信息及产生错误的文件。但是错误是不可预见的,无法提前处理。但是有些错误我们是可以提前预料到的,比如某个参数漏了,或者参数的值不对时,我们就应该这类错误做出警告并记录错误信息。如何优雅的实现这样的需求呢?此时异常处理就能很好的实现该功能了。

异常处理是对可预见且可处理的错误情况进行处理,一般都是由开发者自己手动创建并抛出。

Error和Exception都实现了Throwable接口,大部分Error和所有Exception都可以使用catch (Throwable $e)捕获它们

2.1 异常处理机制

throw语句抛出异常后,如果异常没有被try/catch捕获并处理,程序会终止并报出致命错误,如果是被 set_exception_handler() 捕获后,程序会终止。相反,如果被try/catch捕获后,程序可以继续执行。

2.2 捕获异常

set_exception_handler(callable $exception_handler)函数设置默认的异常处理函数。可以捕获大部分错误和异常,但不能捕获警告和通知类型的错误。使用方法和上面的 set_error_handler() 相同,大家可以参考上面的写法

2.3 try/catch 捕获异常

大部分的Error 和所有 Exception异常都能被捕获,而warning和notice类的错误(Error)不能被捕获并且通过 trigger_errors() 抛出的用户级别的错误不能被捕获。格式如下:

<?php
try {// PHP 脚本执行发生错误或手动抛出错误throw new Exception('错误信息');
} catch (Exception $e) {// 根据类型捕获错误var_dump('异常');
} finally {// 异常处理完之后依然会执行finally,如果不想异常处理完后执行finally,可以在catch中使用exit()终止程序// return 语句之后仍会执行 finally,但 die 和 exit 后不会执行 finallyvar_dump('不管有没有异常都会执行的代码块');
}

注意:exit()及die()是终止程序,无法捕获。因此,exit()和die()之后不会执行finally 。但是如果我们在try/catch内return,最后依然会执行finally

在现代PHP的web框架中,框架都已经帮我们实现的异常捕获相关封装,如果我们想要自己接管异常处理,可以通过配置异常句柄显示。例如,ThinkPHP中就可以通过配置 think\exception\Handle 来接管异常处理句柄


http://www.ppmy.cn/news/1255307.html

相关文章

Python面向对象②:属性与方法【侯小啾python领航班系列(二十)】

Python面向对象:属性与方法【侯小啾python领航班系列(二十)】 大家好,我是博主侯小啾, 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ�…

P27 C++this 关键字

目录 前言 01 this关键字的引入 02 this关键字 前言 本章的主题是 C 中的 this 关键字。 以前第一次学qt的时候就遇到了this关键字&#xff0c;那时候还不是很会C&#xff0c;所以有点懵&#xff0c;现在我们就来讲解以下C中的this关键字 C 中有一个关键字 this&#xff0…

网上商城、宠物商城源码(Java)

javaWebjsp网上书城以及宠物商城源码&#xff0c;功能有购物车、收藏以及下单等等功能 带后台管理功能 运行示意图&#xff1a;

【Node.js】笔记梳理 8 - API和JWT

写在最前&#xff1a;跟着视频学习只是为了在新手期快速入门。想要学习全面、进阶的知识&#xff0c;需要格外注重实战和官方技术文档&#xff0c;文档建议作为手册使用 系列文章 【Node.js】笔记整理 1 - 基础知识【Node.js】笔记整理 2 - 常用模块【Node.js】笔记整理 3 - n…

关于前端学习的思考-word-wrap和word-break的区别

如上图word-wrap里面的break-word就是按照单词来换行的&#xff0c;空格在前&#xff0c;连字符在后的时候&#xff0c;按照连字符进行换行&#xff0c;那么空格和连字符哪一个拥有优先级呢&#xff1f; 连字符在前&#xff0c;空格在后的时候&#xff0c;还是按照连字符进行换…

关于css的一些知识

position&#xff1a; 在 CSS 中&#xff0c;position 属性用于定义元素的定位方式。它有几个取值&#xff1a; static: 默认值。元素按照正常文档流进行定位&#xff0c;不会被特殊地定位。relative: 相对定位。元素相对于它正常位置进行定位&#xff0c;但是在文档流中仍保…

苍穹外卖面试题-下

17. 项目参与人员角色 项目经理&#xff08;1人&#xff09;&#xff1a;对整个项目负责&#xff0c;任务分配、把控进度 产品经理&#xff08;1人&#xff09;&#xff1a;进行需求调研&#xff0c;输出需求调研文档、产品原型等 UI设计师&#xff08;1人&#xff09;&#…

ThinkPHP的方法接收json数据问题

第一次接触到前后端分离开发&#xff0c;需要在后端接收前端ajax提交的json数据&#xff0c;开发基于ThinkPHP3.2.3框架。于是一开始习惯性的直接用I()方法接收到前端发送的json数据&#xff0c;然后用json_decode()解析发现结果为空&#xff01;但是打印出还未解析的值却打印得…