在正式的生产环境中,通常我们会关闭PHP页面上的错误输出,也就是设置php.ini中的 display_errors 选项为 off,这时如果遇到程序出错我们还可以查看Nginx的错误日志error.log来得知报错原因(前提是php.ini中的 log_errors 选项设置为 on),例如这样的:
2017/07/17 10:25:19 [error] 1556#868: *1 FastCGI sent in stderr: "PHP Parse error: syntax error, unexpected end of file in E:\project\demo\test.php on line 19" while reading response header from upstream, client: 127.0.0.1, server: 127.0.0.1, request: "GET /test.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "127.0.0.1:800"
2017/07/17 10:26:03 [error] 1556#868: *1 FastCGI sent in stderr: "PHP Fatal error: Uncaught Error: Call to undefined function add() in E:\project\demo\test.php:18
Stack trace:
#0 {main}
thrown in E:\project\demo\test.php on line 18" while reading response header from upstream, client: 127.0.0.1, server: 127.0.0.1, request: "GET /test.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "127.0.0.1:800"
2017/07/17 10:26:15 [error] 1556#868: *1 FastCGI sent in stderr: "PHP Fatal error: Uncaught Error: Call to undefined function add() in E:\project\demo\test.php:18
Stack trace:
#0 {main}
thrown in E:\project\demo\test.php on line 18" while reading response header from upstream, client: 127.0.0.1, server: 127.0.0.1, request: "GET /test.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "127.0.0.1:800"
2017/07/17 10:26:16 [error] 1556#868: *1 FastCGI sent in stderr: "PHP Fatal error: Uncaught Error: Call to undefined function add() in E:\project\demo\test.php:18
Stack trace:
#0 {main}
thrown in E:\project\demo\test.php on line 18" while reading response header from upstream, client: 127.0.0.1, server: 127.0.0.1, request: "GET /test.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "127.0.0.1:800"
错误日志中同样记录了错误原因,错误文件以及错误行号。但是一般的框架都会实现自己的日志系统,比如CI框架,对于CI框架,默认配置是不记录日志的,所以首先需要进行一定的配置。
/*
|--------------------------------------------------------------------------
| Error Logging Threshold
|--------------------------------------------------------------------------
|
| You can enable error logging by setting a threshold over zero. The
| threshold determines what gets logged. Threshold options are:
|
| 0 = Disables logging, Error logging TURNED OFF
| 1 = Error Messages (including PHP errors)
| 2 = Debug Messages
| 3 = Informational Messages
| 4 = All Messages
|
| You can also pass an array with threshold levels to show individual error types
|
| array(2) = Debug Messages, without Error Messages
|
| For a live site you'll usually only enable Errors (1) to be logged otherwise
| your log files will fill up very fast.
|
*/
$config['log_threshold'] = 0;
/*
|--------------------------------------------------------------------------
| Error Logging Directory Path
|--------------------------------------------------------------------------
|
| Leave this BLANK unless you would like to set something other than the default
| application/logs/ directory. Use a full server path with trailing slash.
|
*/
$config['log_path'] = '';
/*
|--------------------------------------------------------------------------
| Log File Extension
|--------------------------------------------------------------------------
|
| The default filename extension for log files. The default 'php' allows for
| protecting the log files via basic scripting, when they are to be stored
| under a publicly accessible directory.
|
| Note: Leaving it blank will default to 'php'.
|
*/
$config['log_file_extension'] = '';
/*
|--------------------------------------------------------------------------
| Log File Permissions
|--------------------------------------------------------------------------
|
| The file system permissions to be applied on newly created log files.
|
| IMPORTANT: This MUST be an integer (no quotes) and you MUST use octal
| integer notation (i.e. 0700, 0644, etc.)
*/
$config['log_file_permissions'] = 0644;
/*
|--------------------------------------------------------------------------
| Date Format for Logs
|--------------------------------------------------------------------------
|
| Each item that is logged has an associated date. You can use PHP date
| codes to set your own date formatting
|
*/
$config['log_date_format'] = 'Y-m-d H:i:s';
以上是CI框架中关于日志的配置项,主要是前两项:日志级别配置和日志路径配置
$config['log_threshold']
日志级别配置,该项默认是0,也就是不记录日志,如果我们想要记录日志,则必须更改该值为1~4中的任意值,值越大日志记录的越详细,
$config['log_path']
对于日志存放路径,留空表示使用默认路径 也就是 application/logs/ 下,以日期命名分天存放,或者我们配置自己的存放路径,要注意的是,路径存放目录必须要有可写权限。
这样配置之后,就可以记录和查看错误日志了,下面是一个日志的示例:
<?php defined('BASEPATH') OR exit('No direct script access allowed'); ?>
ERROR - 2017-07-17 08:41:52 --> Severity: error --> Exception: Call to undefined function add() E:\project\CodeIgniter-3.1.2\application\controllers\Welcome.php 28
ERROR - 2017-07-17 08:42:43 --> Severity: error --> Exception: Call to undefined function add() E:\project\CodeIgniter-3.1.2\application\controllers\Welcome.php 28
ERROR - 2017-07-17 08:42:45 --> Severity: error --> Exception: Call to undefined function add() E:\project\CodeIgniter-3.1.2\application\controllers\Welcome.php 28
ERROR - 2017-07-17 08:42:45 --> Severity: error --> Exception: Call to undefined function add() E:\project\CodeIgniter-3.1.2\application\controllers\Welcome.php 28
ERROR - 2017-07-17 08:42:45 --> Severity: error --> Exception: Call to undefined function add() E:\project\CodeIgniter-3.1.2\application\controllers\Welcome.php 28
但是对于习惯了一出问题就查看Nginx错误日志的程序员来说,CI框架并不写Nginx错误日志,可能是一个不习惯的地方,但是首先我们要搞清楚,是什么机制导致了CI框架不写Nginx错误日志。当我们自己写的PHP程序出错时,是写Nginx错误日志的,说明写Nginx的错误日志是PHP的默认行为。
实际上,写Nginx错误日志是PHP的标准错误处理程序做的事情,但是当我们调用了set_error_handler 或 set_exception_handler 注册了自己的异常处理方法时,异常交由我们注册的方法处理,不再被标准错误处理程序处理,也就不会写入Nginx的错误日志了。
CI框架的注册错误处理器的代码位置在 CodeIgniter.php 130行处:
/*
* ------------------------------------------------------
* Define a custom error handler so we can log PHP errors
* ------------------------------------------------------
*/
set_error_handler('_error_handler');
set_exception_handler('_exception_handler');
register_shutdown_function('_shutdown_handler');
所以,要想记录Nginx错误日志,只需要简单注释掉上面的代码即可,这时错误日志就会默认记到Nginx的error.log中了,但是这要修改框架代码,所以不推荐这么做,还是建议大家使用框架自带的日志功能,这篇文章的主要目的是对PHP的异常处理机制做一个简单介绍。