В похапэ нету finally, например. Поэтому если нам нужно чё-то подчистить, а потом перебросить исключение, то пустой обработчик --- таки необходимость.Это я намекаю на очередной антипаттерн "пустой обработчик исключения", который по факту ничем не лучше собаки
$track = @ini_set('track_errors', 1);
$this->socket = @stream_socket_client(
$remote, $errno, $errstr,
$this->request->getConfig('connect_timeout'),
STREAM_CLIENT_CONNECT, $context
);
if (!$this->socket) {
$e = new HTTP_Request2_ConnectionException(
"Unable to connect to {$remote}. Error: "
. (empty($errstr)? $php_errormsg: $errstr), 0, $errno
);
}
@ini_set('track_errors', $track);
if (isset($e)) {
throw $e;
}
$track = @ini_set('track_errors', 1);
$display = @ini_set('display_errors', 1);
ob_start();
$this->socket = stream_socket_client(
$remote, $errno, $errstr,
$this->request->getConfig('connect_timeout'),
STREAM_CLIENT_CONNECT, $context
);
$buffer = ob_get_clean();
if (!$this->socket) {
$e = new HTTP_Request2_ConnectionException(
"Unable to connect to {$remote}. Error: "
. (empty($errstr)? (empty($php_errormsg) ? $buffer : $php_errormsg): $errstr), 0, $errno
);
}
@ini_set('track_errors', $track);
@ini_set('display_errors', $display);
if (isset($e)) {
throw $e;
}
Спасибо, попробую. Этот (относительно) новый костыль как-то упустил.error_get_last() пробовал?
Объявлять её надо было, конечно, о чём и баг-репорт пришёл. Магическим образом она появляется как раз из track_errors. Или не появляется, если ini_set() запрещён...возможно скажу глупость, если ругается на неопределенную переменную я бы ее объявил где-нибудь сначала.
Хотя этой фичей track_errors никогда не пользовался, странно как-то откуда ни возьмись магическим образом появляется переменная $php_errormsg
Ну вот я и пытаюсь кинуть исключение по факту невозможности установки соединения. Проблема в том, что мне в это исключение сообщение нужно, собственно как и всем, кто хочет ошибки в исключения заворачивать.возможно если изначально кидать исключение на любой нотайс и выше это помогло бы избавиться от подобных костылей и собак заодно
не совсем. если запрет ini_set() через disabled_functions - поддерживаемая конфигурация и ожидаемая ситуация, лучше выставлять define (INI_SET_ENABLED) и потом по if (INI_SET_ENABLED)это иллюстрация, зачем в похапэ нужна собака.
что абсолютно равнозначно собаке, так как она именно это и делает.я бы скорее выставил error_reporting(0)
я имел в виду что-то вроде того как сделано в некоторых фреймворках, напр в коханеНу вот я и пытаюсь кинуть исключение по факту невозможности установки соединения.
function error_handler($code, $error, $file = NULL, $line = NULL)
{
if (error_reporting() & $code)
{
// This error is not suppressed by current error reporting settings
// Convert the error into an ErrorException
throw new ErrorException($error, $code, 0, $file, $line);
}
// Do not execute the PHP error handler
return TRUE;
}
set_error_handler('error_handler');
try {
$this->socket = stream_socket_client(...);
} catch (ErrorException $e) {
throw new HTTP_Request2_ConnectionException($e->getMessage());
}
Лучше бы от ini_set() вообще избавиться, всё равно придётся писать код, который будет заточен на работу когдане совсем. если запрет ini_set() через disabled_functions - поддерживаемая конфигурация и ожидаемая ситуация, лучше выставлять define (INI_SET_ENABLED) и потом по if (INI_SET_ENABLED)
track_errors = Off
disable_functions = ..., ini_set, ...
Пользовательский обработчик тут --- это из области казуистики. Предполагается, что PEAR'овский пакет не должен выводить при работе сообщений об ошибках (включая E_NOTICE, а для свежих пакетов и E_STRICT), а ошибки оборачивать в исключения. Пользователь, соответственно, должен исключения ловить, а не пытаться повторить эту работу. Если кто-то помешает исключение бросать --- ССЗБ.оборачивать stream_socket_client() в ob_handler тебе не поможет - оно будет кидать ворнинг/ноутис, который будет ловиться каким-нибудь обработчиком, и до HTTP_Request2_ConnectionException дело не дойдет
ставить HTTP_Request2_ConnectionException обработчиком ошибок - плохая идея, т.к. в приложении скорее всего будет свой,
я бы скорее выставил error_reporting(0), и взял ошибку из error_get_last()['message'] (проверил, она там есть)
а вот если пользовательский обработчик ошибок не учитывает уровень error_reporting() и ловит все по своему усмотрению - то я бы оставил это на автора такого обработчика
Warning: stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages:
error:14090086:SSL routines:func(144):reason(134) in ...\HTTP_Request2\HTTP\Request2\Adapter\Socket.php on line 322
Warning: stream_socket_client(): Failed to enable crypto in ...\HTTP_Request2\HTTP\Request2\Adapter\Socket.php on line 322
Warning: stream_socket_client(): unable to connect to ssl://google.com:443 (Unknown error) in ...\HTTP_Request2\HTTP\Request2\Adapter\Socket.php on line 322
Unable to connect to ssl://google.com:443. Error: stream_socket_client(): unable to connect to ssl://google.com:443 (Unknown error)
Unable to connect to ssl://google.com:443. Error: stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages:
error:14090086:SSL routines:func(144):reason(134)
protected $_socketException = NULL;
protected function _handleSocketError($code, $error, $file = NULL, $line = NULL) {
if (error_reporting() & $code) {
$this->_socketException = new ErrorException($error, $code, 0, $file, $line, $this->_socketException);
}
return TRUE;
}
set_error_handler(array($this, '_handleSocketError'));
$this->_socketException = NULL;
$this->socket = stream_socket_client(...);
restore_error_handler();
if ($this->_socketException instanceof ErrorException) {
throw $this->_socketException;
}
Сделал в результате без заморочек с getPrevious(), все Warning'и сразу идут в сообщение.grigori там предыдущий эксепшн передается последним параметром в конструктор - $previous
потом его можно получить из Exception::getPrevious
function start_server(){
$handle=socket_create(...);
$result=@socket_connect(...);
if($result !== false) {
socket_close(...)
self::log('server already exists!');
return true;
}
...
// start server
}
foreach ($lst as $item) {
$dom = new DOMDocument();
$dom->load($item);
if(@$dom->validate()) {
//***
}
}