Пример #1
0
 /**
  * Перехватчик исключений.
  *
  * Ловит исключения, которые не были пойманы ранее. Последний шанс обработать ошибку. Например, записать в лог или
  * намылить админу. Можно так же вежливо откланяться юзеру.
  *
  * После выполнения этого обработчика программа остановится, обеспечено PHP.
  *
  * Если указано предыдущее исключение, отсюда не пишем в лог. Сей факт указывает на то, что реальное исключение
  * уже было поймано и обработано. Считаем, что необходимость логирования была решена в предыдущих обработчиках.
  *
  * Прим: для поддержки PHP 7.0 тип ожидаемого параметра расширен,
  * см. {@see http://php.net/manual/ru/function.set-exception-handler.php PHP::set_exception_handler()}
  *
  * @param \Throwable $ex
  */
 public static function exceptionHandler($ex)
 {
     $class = get_class($ex);
     $message = nl2br($ex->getMessage());
     $file = str_replace(ROOT_PATH, '/', $ex->getFile());
     $line = $ex->getLine();
     $trace = $ex->getTraceAsString();
     if (isConsoleInterface()) {
         echo 'Исключение: ' . $class . PHP_EOL . PHP_EOL . $message . PHP_EOL . PHP_EOL . 'Стек вызовов:' . PHP_EOL . $trace . PHP_EOL;
         return;
     }
     if (!headers_sent()) {
         header('500 Internal Server Error');
         header('Content-Type: text/html; charset=UTF-8');
     }
     if (DEBUG) {
         echo Render::fetch('exception.htm', compact('class', 'message', 'file', 'line', 'trace'));
     } else {
         echo Render::fetch('exception_prod.htm', ['domain' => Env::domainName()]);
         if ($ex->getPrevious() === null) {
             $logger = App::logger();
             $logger->addTyped("Class: {$class}" . PHP_EOL . "Message: {$message}" . PHP_EOL . "Source: {$file}:{$line}" . PHP_EOL . PHP_EOL . "Trace: {$trace}", $logger::EXCEPTION);
         }
     }
 }
Пример #2
0
 /**
  * Конструктор
  *
  * Логируем ошибку. В зависимости от кода пишем лог в БД или файлы: если исключение проброшено из попытки соединения,
  * сразу же пишем лог в файлы, не пытаясь еще раз ткнуться в базу.
  *
  * @param string    $message
  * @param int       $code
  * @param \Exception $previous
  */
 public function __construct($message, $code = self::QUERY, $previous = null)
 {
     $logger = App::logger();
     if ($code === self::CONNECT) {
         $logger->add(['message' => $message, 'type' => $logger::DB_CONNECT, 'file_force' => true]);
     } else {
         $logger->addTyped($message, $logger::DB_QUERY);
     }
     parent::__construct($message, $code, $previous);
 }
Пример #3
0
 /**
  * Редирект. Только для нужд роутера.
  * Если задана настройка "router.log_redirects", логируем такие редиректы.
  * @param string $url новый относительный адрес. Всегда без слеша слева, таков тут мой код.
  * @return void
  */
 private function redirect($url)
 {
     if ($_SERVER['QUERY_STRING']) {
         $url .= '?' . $_SERVER['QUERY_STRING'];
     }
     if (App::conf('router.log_redirects', false)) {
         App::logger()->addTyped('pедирект на /' . $url, 'router redirect');
     }
     Response::redirect('/' . $url, 301);
 }
Пример #4
0
 /**
  * Проверка права запускать скрипты через Консоль
  *
  * В режиме отладки - разрешено без вопросов, иначе - при указании правильного ключа. Количество ошибок считается.
  * Ключ и допустимое количество прописываем в конфиге приложения:
  * <pre>
  * 'console => [
  *      'ties' => int|0
  *      'key' => string|''
  * ]
  * </pre>
  *
  * <b>Внимание!</b> При отсутствии этого конфига, а так же со значениями по умолчанию, доступ будет разрешен.
  *
  * В дальнейшем можно добавить контроль на запрещенные/разрешенные IP и т.п.
  *
  * Неудавшиеся попытки логируются, после NN попыток консоль вообще блокируется через файл [TEMP_PATH/console.lock],
  * при блокировке админу пойдет письмо.
  *
  * @param string $key ключ доступа, спарсенный из запроса
  * @return null если нет права запуска, прямо тут все и закончится. Поэтому возвращаемое значение не важно.
  */
 private function checkAccess(string $key)
 {
     if (DEBUG) {
         return;
     }
     $lockFile = TEMP_PATH . 'convisor.lock';
     $count = file_exists($lockFile) ? file_get_contents($lockFile) : 0;
     $tries = (int) App::conf('convisor.tries', false);
     $critical = $tries && $count >= $tries;
     if ($critical) {
         exit('Консоль заблокирована' . PHP_EOL);
     }
     $allow = (string) App::conf('convisor.key', false) == $key;
     if (!$allow) {
         $count++;
         $msg = "{$count} неудачная попытка запуска скрипта в консоли: {$this->script} " . implode(' ', $this->params);
         if ($critical) {
             App::logger()->add(['message' => $msg, 'type' => 'deny console', 'notify' => true]);
         } else {
             App::logger()->addTyped($msg, 'deny console');
         }
         file_put_contents($lockFile, $count);
         exit('Запуск запрещен' . PHP_EOL);
     }
     FS::deleteFile($lockFile);
 }