PHP 日志工具类
好久没写php了,突然做个实验,发现竟然没有日志,哎
<?phpdefined('API') or exit('Access Denied');class Log{ private $FilePath; private $FileName; private $m_MaxLogFileNum; private $m_RotaType; private $m_RotaParam; private $m_InitOk; private $m_Priority; private $m_LogCount; const EMERG = 0; const FATAL = 0; const ALERT = 100; const CRIT = 200; const ERROR = 300; const WARN = 400; const NOTICE = 500; const INFO = 600; const DEBUG = 700; const LOG_SUFFIXED = ".log.txt"; const DEFAULT_ROTE = 5242880; /** * @abstract 初始化 * @param String $dir 文件路径 * @param String $filename 文件名 * @return */ public function __construct($dir, $filename, $priority = Log::INFO, $maxlogfilenum = 3, $rotatype = 1, $rotaparam = LOG::DEFAULT_ROTE) { $dot_offset = strpos($filename, "."); if ($dot_offset !== false) $this->FileName = substr($filename,0, $dot_offset); else $this->FileName = $filename; $this->FilePath = $dir; $this->m_MaxLogFileNum = intval($maxlogfilenum); $this->m_RotaParam = intval($rotaparam); $this->m_RotaType = intval($rotatype); $this->m_Priority = intval($priority); $this->m_LogCount = 0; $this->m_InitOk = $this->InitDir(); umask(0000); $path=$this->createPath($this->FilePath,$this->FileName); if(!$this->isExist($path)) { if(!$this->createDir($this->FilePath)) { #echo("创建目录失败!"); } if(!$this->createLogFile($path)){ #echo("创建文件失败!"); } } } private function createPath($dir,$file) { $file = fopen($dir.DIRECTORY_SEPARATOR.$file,'w'); if($file) { fclose($file); } return $dir.DIRECTORY_SEPARATOR.$file; } private function InitDir() { if (is_dir($this->FilePath) === false) { if(!$this->createDir($this->FilePath)) { //echo("创建目录失败!"); //throw exception return false; } } return true; } function console($priority, $log) { if ($this->m_InitOk == false) return; if ($priority > $this->m_Priority) return; $path = $this->getLogFilePath($this->FilePath, $this->FileName).Log::LOG_SUFFIXED; $handle= fopen($path,"a+"); if ($handle === false) { return; } $datestr = strftime("%Y-%m-%d %H:%M:%S "); $caller_info = $this->get_caller_info(); $status = fwrite($handle, $caller_info.$datestr.$log."\n"); if(!$status){//写日志失败 echo("写入日志失败"); } fclose($handle); $this->RotaLog(); } /** * @abstract 写入日志 * @param String $log 内容 */ function setLog($log) { $this->console(Log::NOTICE, $log); } function LogDebug($log) { $this->console(Log::DEBUG, $log); } function LogError($log) { $this->console(Log::ERROR, $log); } function LogNotice($log) { $this->console(Log::NOTICE, $log); } private function get_caller_info() { $ret = debug_backtrace(); foreach ($ret as $item) { if(isset($item['class']) && 'Logs' == $item['class']) { continue; } $file_name = basename($item['file']); return <<<S {$file_name}:{$item['line']} S; } } private function RotaLog() { $file_path = $this->getLogFilePath($this->FilePath, $this->FileName).LOG::LOG_SUFFIXED; if ($this->m_LogCount%10==0) clearstatcache(); ++$this->m_LogCount; $file_stat_info = stat($file_path); if ($file_stat_info === FALSE) return; if ($this->m_RotaType != 1) return; //echo "file: ".$file_path." vs ".$this->m_RotaParam."\n"; if ($file_stat_info['size'] < $this->m_RotaParam) return; $raw_file_path = $this->getLogFilePath($this->FilePath, $this->FileName); $file_path = $raw_file_path.($this->m_MaxLogFileNum - 1).LOG::LOG_SUFFIXED; //echo "lastest file:".$file_path."\n"; if ($this->isExist($file_path)) { unlink($file_path); } for ($i = $this->m_MaxLogFileNum - 2; $i >= 0; $i--) { if ($i == 0) $file_path = $raw_file_path.LOG::LOG_SUFFIXED; else $file_path = $raw_file_path.$i.LOG::LOG_SUFFIXED; if ($this->isExist($file_path)) { $new_file_path = $raw_file_path.($i+1).LOG::LOG_SUFFIXED; if (rename($file_path, $new_file_path) < 0) { continue; } } } } function isExist($path){ return file_exists($path); } /** * @abstract 创建目录 * @param <type> $dir 目录名 * @return bool */ function createDir($dir){ //判断目录是否存在 return is_dir($dir) or ($this->createDir(dirname($dir)) and mkdir($dir, 0777)); } /** * @abstract 创建日志文件 * @param String $path * @return bool */ function createLogFile($path){ $handle=fopen($path,"w"); //创建文件 if($handle) { fclose($handle); } return $this->isExist($path); } /** * @abstract 创建路径 * @param String $dir 目录名 * @param String $filename */ function getLogFilePath($dir,$filename){ return $dir."/".$filename; }}?>

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

在PHP中,應使用password_hash和password_verify函數實現安全的密碼哈希處理,不應使用MD5或SHA1。1)password_hash生成包含鹽值的哈希,增強安全性。 2)password_verify驗證密碼,通過比較哈希值確保安全。 3)MD5和SHA1易受攻擊且缺乏鹽值,不適合現代密碼安全。

PHP類型提示提升代碼質量和可讀性。 1)標量類型提示:自PHP7.0起,允許在函數參數中指定基本數據類型,如int、float等。 2)返回類型提示:確保函數返回值類型的一致性。 3)聯合類型提示:自PHP8.0起,允許在函數參數或返回值中指定多個類型。 4)可空類型提示:允許包含null值,處理可能返回空值的函數。

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

PHP和Python各有優劣,選擇取決於項目需求和個人偏好。 1.PHP適合快速開發和維護大型Web應用。 2.Python在數據科學和機器學習領域佔據主導地位。

在PHP中使用預處理語句和PDO可以有效防範SQL注入攻擊。 1)使用PDO連接數據庫並設置錯誤模式。 2)通過prepare方法創建預處理語句,使用佔位符和execute方法傳遞數據。 3)處理查詢結果並確保代碼的安全性和性能。

PHP在數據庫操作和服務器端邏輯處理中使用MySQLi和PDO擴展進行數據庫交互,並通過會話管理等功能處理服務器端邏輯。 1)使用MySQLi或PDO連接數據庫,執行SQL查詢。 2)通過會話管理等功能處理HTTP請求和用戶狀態。 3)使用事務確保數據庫操作的原子性。 4)防止SQL注入,使用異常處理和關閉連接來調試。 5)通過索引和緩存優化性能,編寫可讀性高的代碼並進行錯誤處理。

PHP用於構建動態網站,其核心功能包括:1.生成動態內容,通過與數據庫對接實時生成網頁;2.處理用戶交互和表單提交,驗證輸入並響應操作;3.管理會話和用戶認證,提供個性化體驗;4.優化性能和遵循最佳實踐,提升網站效率和安全性。

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。
