前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PHP-错误处理

PHP-错误处理

原创
作者头像
汤清丽
修改2019-11-04 11:48:34
1.7K0
修改2019-11-04 11:48:34
举报
文章被收录于专栏:PHP知识PHP知识

## 第1章 错误报告级别

PHP 程序的错误一般归属于下列三个领域:

**语法错误:**

​ 语法错误最常见,并且也容易修复。如:代码中遗漏一个分号。这类错误会阻止脚本的执行。

**运行时错误:**

​ 这种错误一般不会阻止PHP脚本的执行,但会阻止当前要做的事情。输出一条错误,但php脚本继续执行。

**逻辑错误:**

​ 这种错误最麻烦,既不阻止脚本执行,也不输出错误消息。

**图解 Apache Web 服务器与 PHP 引擎的关系。**

![](./img/apache.png)

案例:

```php

//语法错误,忘记加分号

echo "123"

//运行时错误

echo '123';

function laowang(){

echo '456';

}

laoliu();

//逻辑错误,想要输出隔壁老王,结果出现的是帽子,在系统角度看,这并不是错误。

if(1==1){

echo "帽子";

}else{

echo "隔壁老王";

}

```

**在 PHP 系统中,到底有哪些错误报告级别?**

在 php.ini 中可以找到错误级别的说明和设置。

```php

//表示打开所有错误提示但屏蔽NOTICE错误

error_reporting = E_ALL & ~E_NOTICE

//直接关闭所有错误提示,开发阶段一般是on,但上线以后一般会选择off

display_errors = off/on

```

| 级别常量 | 错误值 | 错误报告描述 |

| ----------------- | ------ | ---------------------------------------- |

| E_ERROR | 1 | 致命的运行时错误(阻止脚本执行) |

| E_WARNING | 2 | 运行时警告(非致命性错误) |

| E_PARSE | 4 | 从语法中解析错误 |

| E_NOTICE | 8 | 运行时注意消息(可能是或可能不是一个问题) |

| E_CORE_ERROR | 16 | PHP启动时初始化过程中的致命错误 |

| E_CORE_WARNING | 32 | PHP启动时初始化过程中的警告(非致命性错) |

| E_COMPILE_ERROR | 64 | 编译时致命性错 |

| E_COMPILE_WARNING | 128 | 编译时警告(非致命性错) |

| E_USER_ERROR | 256 | 用户自定义的致命错误 |

| E_USER_WARNING | 512 | 用户自定义的警告(非致命性错误) |

| E_USER_NOTICE | 1024 | 用户自定义的提醒(经常是bug) |

| E_STRICT | 2048 | 编码标准化警告(建议如何修改以向前兼容) |

| E_ALL | 6143 | 所有的错误、警告和注意信息 |

```php

//错误值一般都是系统定义好的常量

echo E_ERROR; //1

//1 2 4 8 ... 6143原理

//利用的二进制,采用亮灯的原理,错了就亮。

//000000000001 ---> 就是第一个错误

```

在实际的开发中,没有人关注什么错误级别错误值什么的,报错了,看一眼大概啥类型的,直接找BUG就行了。

**在实际的开发中,我们其实需要做大量的错误处理,写功能比较容易,无非就是增删改查,就像汽车,让一辆汽车开起来并不难,但如果要做各种安全防护,就要麻烦的多,考虑的因素也非常多,说明书厚的跟字典一样。**

## 第2章 调整错误报告级别

动态设置 PHP 错误信息是否输出,**只在当前脚本生效,并不会影响php.ini全局的设置。**

- **display_errors: 是否开启PHP输出错误报告的功能。**

​ 值为:On(默认输出错误报告)、 Off(屏蔽所有错误信息)

​ 在PHP脚本中可调用ini_set( )函数,动态设置php.ini配置文件.

​ 如:ini_set("display_errors","On"); //显示所有错误信息

```php

//设置是否输出错误信息

ini_set('display_errors',"off");//关闭

ini_set('display_errors',"on");//开启

ini_set('display_errors',0);//关闭

ini_set('display_errors',1);//开启

//调用函数进行试验

aa();

```

- **error_reporting: 设置不同的错误报告级别。**

​ error_reporting = E_ALL & ~E_NOTICE

​ -- 可以抛出任何非注意的错误,默认值。

​ error_reporting = E_ERROR | E_PARSE | E_CORE_ERROR

​ -- 只考虑致命的运行时错误、新解析错误和核心错误。

​ error_reporting = E_ALL & ~(E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE)

​ -- 报告除用户导致的错误之外的所有错误。

​ 在PHP脚本可以通过error_reporting( )函数动态设置错误报告级别。如:error_reporting(E_ALL);

```php

//动态设置错误等级

error_reporting(E_ALL);

//试验,报所有错误

echo $a;

//开启除了notice以外的所有错误

error_reporting(E_ALL & ~E_NOTICE);

echo $a;

```

案例:

```php

ini_set('display_errors',1);//开启

error_reporting(E_ALL);//开启所有错误

$sum=0;//此处如果屏蔽掉,初次使用sum时,变量未定义会notice报错

for($i=0;$i<=10;$i++){

$sum+=$i;

}

echo $sum;

strlen();//字符串长度函数,不给参数,报warning警告错误,不会影响程序执行

echo "aaaaaaaa";

aa();//致命错误,调用一个不存在的函数时程序会终止运行。

```

**php.ini 中错误设置选项(了解即可,无需深究)。**

| 配置指令 | 默认值 | 描述 |

| ---------------------- | ------ | ----------------------------------------------------------- |

| display_startup_errors | Off | 是否显示PHP引擎在初始化时遇到的错误 |

| log_errors | Off | 确定日志语句记录位置 |

| error_log | Null | 设置错误可以发送到syslog中 |

| log_errors_max_len | 1024 | 每个日志项的最大长度,以字节为单位,设置0表示指定最大长度。 |

| ignore_repeated_errors | Off | 是否忽略同一个文件、同一行发生的重复错误消息 |

| ignore_repeated_source | Off | 忽略不同文件中和同一文件中不同行发生的重复错误。 |

| track_errors | Off | 启动该指令会使PHP在$php_errormsg中存储最近发生的错误信息。 |

## 第3章 PHP 日志的记录方式

**1)采用文件记录 (推荐使用)。**

**2) 错误日志记录到操作系统日志中。**

思考:为什么要做日志记录?

​ 1.方便自己开发的时候查询,框架一般都自带日志功能,只需要开启就OK。

​ 2.可以借助运行日志开发相应的后台日志功能,给管理员查询,方便管理。

### 3.1 采用文件记录

**先配置 php.ini 文件**

```php

error_reporting = E_ALL //将向PHP发送每个错误

display_errors=Off //不显示错误报告

* log_errors=On //决定日志语句记录的位置

log_errors_max_len=1024 //每个日志项的最大长度

* error_log=G:/myerror.log //指定错误写进的文件

```

试验:

```php

a();//注意观察日志文件

conunt();//注意观察日志文件

```

以上记录的是系统报错的日志。

**思考:我能不能做一个用户操作的人为的日志?**

**使用函数:在 PHP 文件中使用 error_log() 来记录日志,就可以将信息写入到 myerror.log 文件中。**

```php

error_log("用户xxx想删除ID为69的用户名,已经记录到日志,请注意这个小子");

```

参数参考手册。

**rigger_error() 函数记录日志**

上一节中,我们使用error_log()报一个自定义的错误信息,让系统记录,**只记录信息。**

而使用 trigger_error() 比 error_log 更加灵活一些,**可指定等级和文件位置。**

```php

//可利用系统提供的错误等级给日志记录自己定义好的错误信息,默认为notic级别

trigger_error("用户xxx想删除ID为69的用户名,已经记录到日志,请注意这个小子",E_USER_ERROR);

```

### 3.2 错误日志记录到操作系统日志中

**先配置 php.ini 文件**

```php

error_reporting = E_ALL //将向PHP发送每个错误

* display_errors=Off //不显示错误报告

* log_errors=On //决定日志语句记录的位置

log_errors_max_len=1024 //每个日志项的最大长度

* error_log=syslog //指定错误写进的文件

```

**使用四个函数来记录日志:**

```php

//define_syslog_variables(); 为系统日志初始化配置

//openlog(); 打开一个日志链接

//syslog(); 发送一条日志记录

//closelog(); 关闭日志链接

```

试验:

```php

aa();//不再显示日志,而是记录到系统日志中去了。

```

目前的开发已经淘汰这种方式,4个函数必须同时使用,课后可自行试验,代码如下:

```php

define_syslog_variables();

openlog("PHP5", LOG_PID , LOG_USER);

syslog(LOG_WARNING, "警告报告向syslog中发送的演示,警告时间: ".date("Y/m/d H:i:s"));

closelog();

```

如何查看 Window 系统日志。

**计算机右键 ---> 管理(G) ---> 系统工具 ---> 事件查看器 ---> Windows 日志 ---> 应用程序**

![](./img/系统日志.png)

## 第4章 自定义错误处理

​ 自定义错误报告的处理方式,可以完全绕过标准的PHP错误处理函数,这样就可以按自己定义的格式打印错误报告,或改变错误报告打印的位置。

​ 说白了就是不使用系统的错误提示,改为自己的。

**set_error_handler() -- 设置用户自定义错误处理。**

​ 参数:[mixed](http://php.net/manual/zh/language.pseudo-types.php#language.types.mixed) **set_error_handler** ( [callable](http://php.net/manual/zh/language.types.callable.php) `$error_handler` [, int `$error_types` = E_ALL | E_STRICT ] )

回调函数:回来调取函数。

**所谓的回调函数:**

```php

function demo(){

return "我才不要呢";

}

function demo2(){

return "我也不要";

}

function result($suan){

return $suan();

}

//将函数名demo1 函数名demo2 作为字符串参数传递给result函数,那么可以自动调用上面的函数,我们就说demo1,demo2是result的回调函数

echo result('demo2');

```

案例:

```php

//回调函数也需要参数接收,参考手册

/*

errno

第一个参数 errno,包含了错误的级别,是一个 integer。

errst

第二个参数 errstr,包含了错误的信息,是一个 string。

errfile

第三个参数是可选的,errfile, 包含了发生错误的文件名,是一个 string。

errline

第四个参数是一个可选项, errline, 包含了错误发生的行号,是一个 integer。

*/

function callbackset($errno,$errstr,$errfile,$errline){

echo "自定义错误处理:错误级别:{$errno},错误信息是:{$errstr}.所在文件:{$errfile}的第{$errline}行";

}

set_error_handler("callbackset");//此处设置为报错的返回信息交给callbackset自行处理

echo $aa;

```

**特别注意:E_ERROR、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING是不会有效果的,通常会用原始的方式显示。**

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档