天天看點

php tp6 錯誤日志接管分析,ThinkPHP6 記錄日志 Permission denied 的解決方法

最近用ThinkPHP6.0寫了一個項目,送出到線上測試時發現背景登入後又被中間件重定向到了登入頁面,導緻背景無法正常使用,綁定了異常處理接管,打開資料庫檢視異常日志,發現兩處異常:

'file' => 'vendor/topthink/think-log/src/log/driver/File.php',

'line' => 123,

'message' => 'error_log(/201907/09.log): failed to open stream: Permission denied'

'file' => 'vendor/topthink/framework/src/think/Cookie.php',

'line' => 203,

'message' => 'Uncaught think\\exception\\ErrorException: Cannot modify header information - headers already sent by (output started at .......'

檢視源碼

// vendor/topthink/think-log/src/log/driver/File.php

protected function write(array $message, string $destination): bool

{

// 檢測日志檔案大小,超過配置大小則備份日志檔案重新生成

$this->checkLogSize($destination);

$info = [];

foreach ($message as $type => $msg) {

$info[$type] = is_array($msg) ? implode(PHP_EOL, $msg) : $msg;

}

$message = implode(PHP_EOL, $info) . PHP_EOL;

return error_log($message, 3, $destination); // 123

}

// vendor/topthink/framework/src/think/Cookie.php

protected function saveCookie(string $name, string $value, int $expire, string $path, string $domain, bool $secure, bool $httponly): void

{

setcookie($name, $value, $expire, $path, $domain, $secure, $httponly); // 203

}

應該是error_log沒有權限,抛出了異常,導緻setcookie失敗,果斷chomd -R 777 runtime/,重新整理重試,依然出現一樣的錯誤。runtime已經777了還報Permission denied,難道日志目錄不在runtime,檢視日志配置檔案

// +----------------------------------------------------------------------

// | 日志設定

// +----------------------------------------------------------------------

return [

// 預設日志記錄通道

'default' => 'file',

// 日志記錄級别

'level' => [],

// 日志類型記錄的通道 ['error'=>'email',...]

'type_channel' => [],

// 是否關閉日志寫入

'close' => false,

// 日志通道清單

'channels' => [

'file' => [

// 日志記錄方式

'type' => 'File',

// 日志儲存目錄

'path' => '',

// 單檔案日志寫入

'single' => false,

// 獨立日志級别

'apart_level' => [],

// 最大日志檔案數量

'max_files' => 0,

],

// 其它日志通道配置

],

];

path為空,架構應該有預設值啊,然後就一路找到vendor\topthink\think-log\src\log\driver\File.php getMasterLogFile方法

protected function getMasterLogFile(): string

{

if (substr($this->config['path'], -1) != DIRECTORY_SEPARATOR) {

$this->config['path'] .= DIRECTORY_SEPARATOR;

}

.

.

.

卧槽!!! 預設日志儲存路徑/,然後修改配置檔案'path' => app()->getRuntimePath() . '/log',再次重新整理重試,運作正常,檢視runtime目錄,日志已記錄進去,然後想到本地windows環境不存在權限問題,打開D盤,果然

php tp6 錯誤日志接管分析,ThinkPHP6 記錄日志 Permission denied 的解決方法

文檔裡日志處理也沒有對path參數特别說明,感覺是個坑!