Друзья, на просторах интернетика можно найти много инфомрации, но, когда тебе необходимо не 1,5 млн страниц, как может предложить Ваша любимая поисковая система, а всего один точный ответ, на помощь приходит код ниже...
Чтобы логировать ошибки PHP, а также перехватывать ошибки самого PHP, понадобиться посмотреть видосик, а также следующий код...
Код, который необходимо разметить вверху приложения (в index.php). ОН НЕ ООП-шный, поэтому НЕ суйте его в классы, так как он не будет работать.
function handler($errno, $errMess, $errfile, $errline)//номер ошибки, ссобщение, файл, строка
{
throw new Exception($errMess." FILE: {$errfile} LINE: {$errline}", $errno);
}
set_error_handler('handler');
Далее, чтобы заработало всё, как в видео, необходимы эти функции:
function repl($ar)/*просто что-то на что-то меняем (для безопасности)*/
{
$arTo=[];
if(is_array($ar)){
foreach ($ar as $item_=>$value_) {
array_push($arTo," *00* {$value_} *00* ");
}
}
return $arTo;
}
function clear($data,$newLine=false,$link=false){ /*очищаем данные...*/
$array1 = array('?','%', '/*', '*/', '//', 'wss:', 'ws:', 'blob:', '\x', 'localhost', 'http:', 'https:', 'script', 'base64', 'mysql', 'union', 'select','update','where','\0x','delete','drop','information','schema');
if($newLine){
$data=str_ireplace("\n",'\r\n',$data);
}
if($link){
$array1 = array('/*', '*/', 'wss:', 'ws:', 'blob:', 'localhost', 'script', 'base64', 'mysql', 'union', 'select','update','where','\0x','delete','drop','information','schema');
}
$data = trim(htmlspecialchars(strip_tags($data), ENT_QUOTES));
$data = filter_var($data,FILTER_SANITIZE_STRING);
return str_ireplace($array1, '', $data);
}
function ip(){/*получаем IP клиента*/
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
return $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
return $_SERVER['HTTP_X_FORWARDED_FOR'];
} else { return $_SERVER['REMOTE_ADDR']; }
}
function url(){/*получаем базовую ссылку приложения (например, inversre.pro — т.е. сам адрес сайта)*/
if(isset($_SERVER['HTTPS'])){
$protocol = ($_SERVER['HTTPS'] && $_SERVER['HTTPS'] != "off") ? "https" : "http";
}else{
$protocol = 'http';
} return $protocol . "://" . $_SERVER['HTTP_HOST'];
}
Это пример того, как далее использовать саму функцию логирования внутри класса, ну, и сам класс.
Функцию логирования (logErrors) необходимо с помощью функции set_exception_handler запустить внутри __construct
, чтобы перехватчик ошибок «завёлся»
public function __construct(){
set_exception_handler([$this, 'exceptionHandler']);
}
и внутри ЭТОГО ЖЕ класса должет быть сам метод...
public function exceptionHandler($e){
$this->logErrors($e->getMessage(), $e->getFile(), $e->getLine());
}
Пример классса:
class Start{
public function __construct(){
set_exception_handler([$this, 'exceptionHandler']);
}
public function exceptionHandler($e){
$this->logErrors($e->getMessage(), $e->getFile(), $e->getLine());
}
public function logErrors($message=NULL,$file=NULL,$line=NULL){
define('ROOT',getenv('DOCUMENT_ROOT').'/');
define('LOGS',ROOT.'/logs/');
/**
may..
* string(494)"LOGIN DATA (RAW): {"location_":"https: \/\/0.inverser.pro\/public-login","get":"public-login","data":{"login":"0@gmail.com","password":"y^gSh=K+i2^"},"publicToken":"9lJKbHlMUHg4WHYxcHUreG1JeEE2RVhxV1NFMVExdllzT3pLQkZYdEN2VXJYZFZXTEhIWXZReFc3SUlaTlo0czdzc0M0ZVdJT0N6bTd4QUwwWU1xbUs5NXlNeXlSS2VWemlFR2lpbXczZUdIRWFMTnJQWkVUdz0="}"
*/
if(!empty($message)){
$message=str_ireplace('https:\/\/p.com','',$message);
$arFrom1=['https://','http://','ws://','wss://','\/','.','\\'];
$arTo1=[' https ',' http ',' ws ',' wss ',' / ',' . ',''];
$message=str_ireplace(
$arFrom1,
$arTo1,
$message
);
$arFrom2=['<','>','?','&','eval','exec'];
$arTo2=repl($arFrom2);
$message=str_ireplace(
$arFrom2,
$arTo2,
$message
);
}
$mtime=round(explode(' ',microtime())[0],3);
if(!empty($mtime) and strpos($mtime,'.')!==false){
$mtime=explode('.',$mtime)[1];
}
$er_time=date("Y-m-d H:i:s").'.'.$mtime;
$yyyymm=date("Y-m");
$U=clear(getenv("HTTP_USER_AGENT"));
$folder=LOGS;
if(!is_dir($folder)){
mkdir($folder, 0700);
}
$fNm=$folder.'log_'.$yyyymm.'.php';
$toLogReferrer=clear(str_ireplace(url(),'',urldecode(getenv('HTTP_REFERER'))));
$toLogRequest=clear(str_ireplace(url(),'',urldecode(getenv('REQUEST_URI'))));
try{
$firstData='';
if(!file_exists($fNm)){
$firstData='
Если Вы видите в сообщение такие символы «*00*» — это значит, что скрипт заменил некоторые символы. К примеру, пароль в файле лога выглядит так:
z9456567gqFafghgSh=K+i2^ *00* ? *00*
^ ^
а на самом деле он:
z9456567gqFafghgSh=K+i2^?
^
'."\n";
}
file_put_contents(
$fNm,
"{$firstData}$er_time | IP: " . ip() . " | MSG: {$message} | F: {$file} | L: {$line} | RQ: ". $toLogRequest .' | RF: ' . $toLogReferrer . ' | Br: ' . clear($U) . ' | SID: ' . session_id() . " \r\n\n",
FILE_APPEND /*| LOCK_EX*/
);
/*if(filesize($fNm)>1024000){//1 MB
try {
$nameArch=date("Y-m-d__H_i_s").'_'. uniqid().'.tar';
$a = new PharData($folder.$nameArch );
$a->addFile($fNm);
$a->compress(Phar::GZ);
unlink($folder.$nameArch);//del archive
unlink($fNm);//del .txt
} catch (Exception $e) {
throw new Exception('EB001. '. $e ,500);
}
}*/
}catch(Exception $e){
if(!file_exists($fNm)){
$firstData=''."\n";
}
file_put_contents(
$fNm,
"{$firstData}$er_time | IP: " . ip() . " | MSG: {$e} | F: {$file} | L: {$line} | RQ: ". $toLogRequest .' | RF: ' . $toLogReferrer . ' | Br: ' . clear($U) . ' | SID: ' . session_id() . " \r\n\n",
FILE_APPEND /*| LOCK_EX*/
);
throw new Exception('EB002. ' ,500);
}
}
}
new Start;//пример инициализации класса (чтобы логирование заработало)
Помните, чтобы метод логирования (logErrors) мог гзиповать файлы логов, перед классом (с рабочим autoload), вам необходимо использовать
use PharData;
use Phar;
Like this: