При использовании php redis в качестве обработчика сеанса с блокировкой сеанса, если возникает ошибка, из-за которой блокировка не может произойти php выдается уведомление, и сценарий продолжается. Есть ли способ настроить его на фатальную ошибку, и скрипт вообще НЕ обрабатывается?
Блокировка сеанса phpredis не может получить блокировку, выдает уведомление php о фатальной ошибке
Ответы (2)
Убедитесь, что вы следуете этому утверждению документации:
В настоящее время функция блокировки поддерживается только для установки Redis с одним главным экземпляром.
Если у вас все еще есть какие-то проблемы, быстрое решение для всего приложения может быть установлено вашим собственным обработчиком ошибок с помощью set_error_handler, который решает эту конкретную проблему. Пример обработчика ниже, который реагирует только на использование не объявленной переменной. Измените шаблон регулярного выражения, чтобы он соответствовал вашему сообщению об ошибке Redis.
<?php
error_reporting(E_ALL);
$redisNoticeFunction = function($errno, $errstr, $errfile, $errline, array $errcontext) {
// is the error E_NOTICE?
if ($errno === \E_NOTICE) {
// if error was suppressed with the @-operator
if (0 === \error_reporting()) {
// do nothing, continue execution of script
return;
}
// check if notice is about Redis
$pattern = '/.*Undefined variable.*/'; // <== change pattern so it matches notice about Redis
$subject = $errstr;
$status = \preg_match($pattern, $subject);
// if there was a problem with regex
if (false === $status) {
$msg = 'Could not perform preg_math with pattern: ' . $pattern . ' and subject: ' . $subject . \PHP_EOL;
// exit by throwing an exception
throw new \InvalidArgumentException($msg);
}
// if notice was about about Redis
if ($status) {
$error_msg = 'Redis locking problem with notice msg: ' . $errstr;
$error_msg .= ' at ' . $errfile . ':' . $errline . \PHP_EOL;
// signal fatal error
$error_type = \E_USER_ERROR;
\trigger_error ($error_msg, $error_type);
// or throw exception (comment above line with \trigger_error())
throw new \RuntimeException($error_msg);
}
// the notice was not related to the Redis
// echo its message and continue script
echo $errstr . \PHP_EOL;
return;
}
// the error was not the E_NOTICE
// do other error handling if needed
// or just end the script
die;
};
set_error_handler($redisNoticeFunction);
echo @ $notDeclared; // does not end script
echo $notDeclared; // end script or throws an exception
последняя строка
echo $notDeclared; // end script or throws an exception
заканчивает скрипт информацией:
Неустранимая ошибка: проблема блокировки Redis с уведомлением msg: Неопределенная переменная: notDeclared в /tmp/index.php:59
set_error_handler следует использовать в начале вашего php скрипт (идеально внутри общего файла, который требуется везде как bootstrap.php)
Недостатком использования собственного обработчика ошибок является то, что если вы работаете с фреймворком или другим кодом-оболочкой, он может уже установить свой собственный обработчик ошибок, который предоставляет некоторые полезные функции, такие как отладка, или, возможно, даже этот обработчик ошибок необходим для обработки ошибок этого фреймворка, ведения журнала. и т.п.
Если вы хотите вернуться к исходному обработчику ошибок (по умолчанию из PHP или к тому, который был установлен перед вашим собственным), используйте restore_error_handler
В случае, если кто-то хочет знать точный код для превращения уведомления session_lock в фатальную ошибку; вот. (Я не мог бы сделать это без другого ответа, но это именно то, что я использовал)
function redisNoticeFunction($errno, $errstr, $errfile, $errline, array $errcontext)
{
// is the error E_NOTICE?
if ($errno === E_NOTICE)
{
// if error was suppressed with the @-operator
if (0 === error_reporting())
{
// do nothing, continue execution of script
return;
}
// if notice was about about Redis locking
if ($errstr == 'session_start(): Acquire of session lock was not successful')
{
$error_msg = 'Redis locking problem with notice msg: ' . $errstr;
$error_msg .= ' at ' . $errfile . ':' . $errline . \PHP_EOL;
// signal fatal error
$error_type = E_USER_ERROR;
trigger_error ($error_msg, $error_type);
}
return;
}
}
$current_error_reporting = error_reporting();
error_reporting(E_ALL);
set_error_handler('redisNoticeFunction');
session_start();
//Use regular error handling if session_start() does not end in a lock
restore_error_handler();
error_reporting($current_error_reporting);
throw new Exception()
- person treyBake   schedule 03.02.2020