Xdebug — подскажите с решением вопроса об отображении ошибок (xdebug_start_error_collection)

Здравствуйте PHP-хабраобщественность.

Опять вас начинаю тревожить из-за решения тонких вопросов правильного программирования.
Из-за этого поднялся еще один интересный вопрос для пытливых PHP-умов.

Введение:


Есть Xdebug — это вещь святая, она имеет хорошую функциональность одной из которой является отображения ошибок в красивом виде, о чем мы и будем разговаривать. К вопросу о перехвате ошибок, нашел я 3 замечательных функции:
  • xdebug_start_error_collection — начинает сохранять все проблемы кода где-то у себя в буфере в красивом виде, тем самым сохраняется и красивый вид, и вывод ошибок как будто отключается.
  • xdebug_get_collected_errors — выводит накопленные на данный момент данные. Соответственно можно вывести ошибки в нужное место
  • xdebug_stop_error_collection — приказ остановить копить данные, впринципи можно даже не вызвать, но просто для полноты описания сюда вставил.


Перехожу к вопросу


Друзья, они не работают чета, я всю документацию уже изрыл, все конфиги прочитал, а на других ресурсах они вообще не упоминаются, так как видась редко кто пользуется, но я вижу что этим реально прикольно пользоваться, так как все рабоатет «из коробки» и не надо самому все это перехватывать (set_error_handler к примеру) и тратить программист часы на красиво отображение.
У меня xampp сборка 1.7.4, на функции не ругаются, значит версия xdebug >= 2.1, они тупо не работают. Ну не буферизируют они и все, как будто их и не вызывали вовсе.

UPD: Привожу примеры
echo "before xdebug_start_error_collection\n";
xdebug_start_error_collection();
echo "after xdebug_start_error_collection\n";
echo $generate_notice; // переменная ранее не была объявлена, значит будет E_NOTICE
echo "after notice generate\n";
xdebug_get_collected_errors();
echo "after xdebug_get_collected_errors";


before xdebug_start_error_collection
after xdebug_start_error_collection
// Тут много данных xdebug
after notice generate
// тут ничего нет, а на самом деле вывод должен был «задержаться» до этого момента
after xdebug_get_collected_errors

Причина использования:


Условия и Задача

Есть некий код в котором что-либо выводится в поток. На рабочем сервере понятное дело, они выводиться вообще не будут (отключен вывод ошибок), а вот на локальном сервере захотелось этот вывод «стандартными красивыми способами xdebug» вывести в нужное место браузера (для меня это на самом верху перед тегом html, а не где-нибудь внутри тега title).

Замечу еще одно условие:
Все выводится посредством echo, то есть не используется буферизированный вывод через накопление в строковую переменную (я недавно исключил это из своей системы за её медлительность — до 30% ухудшает скорость при массовом вызове оператора ".="). Функции буферизации ob_*** не работают, так как в какой стек не пиши, все равно ошибки в стандартный вывод попадают, либо я не придумал способа, как это сделать.

Решение

Вот вам и решение — это как раз эти 3 функции. И echo сохраню, и ошибки в нужное место выведу и они еще и красиво оформленные будут с профилированием и колстеком.

А если мы мозговым штурмом не сможем на это ответить?


Я буду тревожить разработчиков, не хочется их тревожить и задавать глупые вопросы, если они действительно глупые. Если же написать придется, то я потом по этому поводу напишу статью, дабы всем знать что существуют такие вкусности в нашей жизни.

Пожалуйста, помогите кто может или кто сталкивался случайно.
Спасибо.
  • Вопрос задан
  • 3705 просмотров
Решения вопроса 1
wartur
@wartur Автор вопроса
Господа, походу баг. Как видно из кода, функция не выполняет предназначения, даже базовое — «сокрытие данных об ошибках», про накопление ничего сказать не могу.

/* Display errors */
if (PG(display_errors) && !PG(during_request_startup)) {
	char *printable_stack;

	/* We need to see if we have an uncaught exception fatal error now */
	if (type == E_ERROR && strncmp(buffer, "Uncaught exception", 18) == 0) {
		xdebug_str str = {0, 0, NULL};
		char *tmp_buf, *p;
				
		/* find first new line */
		p = strchr(buffer, '\n');
		/* find last quote */
		p = ((char *) zend_memrchr(buffer, '\'', p - buffer)) + 1;
		/* Create new buffer */
		tmp_buf = calloc(p - buffer + 1, 1);
		strncpy(tmp_buf, buffer, p - buffer );

		/* Append error */
		xdebug_append_error_head(&str, PG(html_errors) TSRMLS_CC);
		xdebug_append_error_description(&str, PG(html_errors), error_type_str, tmp_buf, error_filename, error_lineno TSRMLS_CC);
		xdebug_append_printable_stack(&str, PG(html_errors) TSRMLS_CC);
		xdebug_str_add(&str, XG(last_exception_trace), 0);
		xdebug_append_error_footer(&str, PG(html_errors));
		php_output_error(str.d TSRMLS_CC);

		xdfree(str.d);
		free(tmp_buf);
	} else {
		printable_stack = get_printable_stack(PG(html_errors), error_type_str, buffer, error_filename, error_lineno TSRMLS_CC);
		php_output_error(printable_stack TSRMLS_CC);
		xdfree(printable_stack);
	}
}
if (XG(do_collect_errors)) {
	char *printable_stack;
	printable_stack = get_printable_stack(PG(html_errors), error_type_str, buffer, error_filename, error_lineno TSRMLS_CC);
	xdebug_llist_insert_next(XG(collected_errors), XDEBUG_LLIST_TAIL(XG(collected_errors)), printable_stack);
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы