ZH奶酪:PHP error_log()將錯誤信息寫入日志文件


error_log() 是發送錯誤信息到某個地方的一個函數,在程序編程中比較常見,尤其是在程序調試階段。

 bool error_log ( string $message [, int $message_type = 0 [, string $destination [, string $extra_headers ]]] ) 

把錯誤信息發送到 web 服務器的錯誤日志,或者到一個文件里。

message

應該被記錄的錯誤信息。信息長度限制:The default seem to be 1024 but can be changed by adjusting the value of the runtime configuration value of 'log_errors_max_len'

message_type

設置錯誤應該發送到何處。可能的信息類型有以下幾個:

error_log() 日志類型
0 message 發送到 PHP 的系統日志,使用 操作系統的日志機制或者一個文件,取決於 error_log 指令設置了什么。 這是個默認的選項。
1 message 發送到參數 destination 設置的郵件地址。 第四個參數 extra_headers 只有在這個類型里才會被用到。
2 不再是一個選項。
3 message 被發送到位置為 destination 的文件里。 字符 message 不會默認被當做新的一行。
4 message 直接發送到 SAPI 的日志處理程序中。
destination

目標。它的含義描述於以上,由 message_type 參數所決定。

extra_headers

額外的頭。當 message_type 設置為 1 的時候使用。 該信息類型使用了 mail() 的同一個內置函數。

代碼:

<?php
// 如果無法連接到數據庫,發送通知到服務器日志
if (!Ora_Logon($username, $password)) {
    error_log("Oracle database not available!", 0);
}

// 如果用盡了 FOO,通過郵件通知管理員
if (!($foo = allocate_new_foo())) {
    error_log("Big trouble, we're all out of FOOs!", 1,
               "operator@example.com");
}

// 調用 error_log() 的另一種方式:
error_log("You messed up!", 3, "/var/tmp/my-errors.log");
?>

代碼2:

<?php 
 $str='這是條錯誤信息。'; 
 error_log($str,3,'errors.log'); 
 ?>

 

上述是最常用的error_log()例子,它的作用是把一條信息寫入errors.log這個文件里,這個文件如果不存在則自動創建。

下面列舉一下使用error_log()這個函數的過程中可能出現的問題:

(1)程序報錯提示:Warning: error_log() [function.error-log]: failed to open stream: Permission denied in ...on line ...

上述錯誤的出現,是因為文件沒有寫權限,開啟該目錄的文件寫權限即可。

(3)寫入到log文件中的信息不能換行

使用error_log()寫入log文件,會發現文字是沒有換行的,可以在信息后邊加上\n

兩個自定義記錄出錯日志實例:

<?php
    //文件1:【error.class.php】
    function exceptionHandler(){
        error_reporting(E_ALL ^ E_NOTICE);
        date_default_timezone_set('Etc/GMT-8');    //設置時區
   
        ini_set('display_errors',0);    //將錯誤記錄到日志
        ini_set('error_log','D:\'.date('Y-m-d').'_weblog.txt');
        ini_set('log_errors',1);    //開啟錯誤日志記錄
        ini_set('ignore_repeated_errors',1);    //不重復記錄出現在同一個文件中的同一行代碼上的錯誤信息。

        $user_defined_err = error_get_last();
        if($user_defined_err['type'] > 0)
        {
            switch($user_defined_err['type']){
                case 1:
                    $user_defined_errType = '致命的運行時錯誤(E_ERROR)';
                    break;
                case 2:
                    $user_defined_errType = '非致命的運行時錯誤(E_WARNING)';
                    break;
                case 4:
                    $user_defined_errType = '編譯時語法解析錯誤(E_PARSE)';
                    break;
                case 8:
                    $user_defined_errType = '運行時提示(E_NOTICE)';
                    break;
                case 16:
                    $user_defined_errType = 'PHP內部錯誤(E_CORE_ERROR)';
                    break;
                case 32:
                    $user_defined_errType = 'PHP內部警告(E_CORE_WARNING)';
                    break;
                case 64:
                    $user_defined_errType = 'Zend腳本引擎內部錯誤(E_COMPILE_ERROR)';
                    break;
                case 128:
                    $user_defined_errType = 'Zend腳本引擎內部警告(E_COMPILE_WARNING)';
                    break;
                case 256:
                    $user_defined_errType = '用戶自定義錯誤(E_USER_ERROR)';
                    break;
                case 512:
                    $user_defined_errType = '用戶自定義警告(E_USER_WARNING)';
                    break;
                case 1024:
                    $user_defined_errType = '用戶自定義提示(E_USER_NOTICE)';
                    break;
                case 2048:
                    $user_defined_errType = '代碼提示(E_STRICT)';
                    break;
                case 4096:
                    $user_defined_errType = '可以捕獲的致命錯誤(E_RECOVERABLE_ERROR)';
                    break;
                case 8191:
                    $user_defined_errType = '所有錯誤警告(E_ALL)';
                    break;
                default:
                    $user_defined_errType = '未知類型';
                    break;
                }
            $msg = sprintf('%s %s %s %s %s',date("Y-m-d H:i:s"),$user_defined_errType,$user_defined_err['message'],$user_defined_err['file'],$user_defined_err['line']);
            error_log($msg,0);
        }
    }

    register_shutdown_function('exceptionHandler');
?>

調用方法

<meta charset="utf-8">
<?php
    //文件2:【test.php】
    include('error.class.php');
    echo $_COOKIE['aaaaadfa'];    //此cookie不存在就會產生一個錯誤,用來做測試用
    echo $_SESSION['aaaaadfa'];    //此session不存在就會產生一個錯誤,用來做測試用
?>
<?php
/**********************************************************
 * File name: LogsClass.class.php
 * Class name: 日志記錄類
 * Create date: 2008/05/14
 * Update date: 2008/09/28
 * Author: blue
 * Description: 日志記錄類
 * Example: //設定路徑和文件名
 * $dir="a/b/".date("Y/m",time());
 * $filename=date("d",time()).".log";
 * $logs=new Logs($dir,$filename);
 * $logs->setLog("test".time());
 * //使用默認
 * $logs=new Logs();
 * $logs->setLog("test".time());
 * //記錄信息數組
 * $logs=new Logs();
 * $arr=array(
 * 'type'=>'info',
 * 'info'=>'test',
 * 'time'=>date("Y-m-d H:i:s",time())
 * );
 * $logs->setLog($arr);
 **********************************************************/
class Logs {
    private $_filepath; //文件路徑
    private $_filename; //日志文件名
    private $_filehandle; //文件句柄
   

    /**
     *作用:初始化記錄類
     *輸入:文件的路徑,要寫入的文件名
     *輸出:無
     */
    public function Logs($dir = null, $filename = null) {
        //默認路徑為當前路徑
        $this->_filepath = empty ( $dir ) ? '' : $dir;
       
        //默認為以時間+.log的文件文件
        $this->_filename = empty ( $filename ) ? date ( 'Y-m-d', time () ) . '.log' : $filename;
       
        //生成路徑字串
        $path = $this->_createPath ( $this->_filepath, $this->_filename );
        //判斷是否存在該文件
        if (! $this->_isExist ( $path )) { //不存在
            //沒有路徑的話,默認為當前目錄
            if (! empty ( $this->_filepath )) {
                //創建目錄
                if (! $this->_createDir ( $this->_filepath )) { //創建目錄不成功的處理
                    die ( "創建目錄失敗!" );
                }
            }
            //創建文件
            if (! $this->_createLogFile ( $path )) { //創建文件不成功的處理
                die ( "創建文件失敗!" );
            }
        }
       
        //生成路徑字串
        $path = $this->_createPath ( $this->_filepath, $this->_filename );
        //打開文件
        $this->_filehandle = fopen ( $path, "a+" );
    }
   
    /**
     *作用:寫入記錄
     *輸入:要寫入的記錄
     *輸出:無
     */
    public function setLog($log) {
        //傳入的數組記錄
        $str = "";
        if (is_array ( $log )) {
            foreach ( $log as $k => $v ) {
                $str .= $k . " : " . $v . "n";
            }
        } else {
            $str = $log . "n";
        }
       
        //寫日志
        if (! fwrite ( $this->_filehandle, $str )) { //寫日志失敗
            die ( "寫入日志失敗" );
        }
    }
   
    /**
     *作用:判斷文件是否存在
     *輸入:文件的路徑,要寫入的文件名
     *輸出:true | false
     */
    private function _isExist($path) {
        return file_exists ( $path );
    }
   
    /**
     *作用:創建目錄(引用別人超強的代碼-_-;;)
     *輸入:要創建的目錄
     *輸出:true | false
     */
    private function _createDir($dir) {
        return is_dir ( $dir ) or ($this->_createDir ( dirname ( $dir ) ) and mkdir ( $dir, 0777 ));
    }
   
    /**
     *作用:創建日志文件
     *輸入:要創建的目錄
     *輸出:true | false
     */
    private function _createLogFile($path) {
        $handle = fopen ( $path, "w" ); //創建文件
        fclose ( $handle );
        return $this->_isExist ( $path );
    }
   
    /**
     *作用:構建路徑
     *輸入:文件的路徑,要寫入的文件名
     *輸出:構建好的路徑字串
     */
    private function _createPath($dir, $filename) {
        if (empty ( $dir )) {
            return $filename;
        } else {
            return $dir . "/" . $filename;
        }
    }
   
    /**
     *功能: 析構函數,釋放文件句柄
     *輸入: 無
     *輸出: 無
     */
    function __destruct() {
        //關閉文件
        fclose ( $this->_filehandle );
    }
}
?>

PS:
1,不用每寫一條日志就進行次文件的IO的操作,在對象聲明時打開文件句柄
2,支持數組類型的日志記錄
3,可使用默認路徑和默認文件,為當前目錄下的YYYY-MM-DD.log文件

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM