ThinkPHP6 寫入日誌許可權報錯

Zccc發表於2019-07-10

最近用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,檢視日誌配置檔案

<?php

// +----------------------------------------------------------------------
// | 日誌設定
// +----------------------------------------------------------------------
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/log/201907,日誌已記錄進去,然後想到本地windows環境不存在許可權問題,開啟D盤,果然
ThinkPHP6 寫入日誌許可權報錯

文件裡日誌處理也沒有對path引數特別說明,感覺是個坑!

相關文章