Таким образом, сценарий состоит в том, что у меня есть приложение, которое использует буферизацию вывода, и приложение возвращает некоторые дополнительные данные в дополнение к ожидаемым результатам. Я могу манипулировать точкой, в которой ожидаемые результаты добавляются в выходной буфер, чтобы подтвердить, что в этой точке приложения данные, отправляемые в выходной буфер, верны, поэтому неожиданные дополнительные данные должны поступать из другого источника.
Я подозреваю, что проблема заключается в случайном символе, которого нет в тегах скрипта PHP, но мне не повезло выяснить, какие (если есть) файлы являются виновником. Насколько я знаю, там может быть какой-то файл, который на самом деле делает явный echo
из дополнительных данных.
Поэтому я надеялся получить имя файла и номер строки любого файла, который записывает в выходной буфер, но это оказалось намного сложнее, чем я ожидал. Я знаю где начальный ob_start
есть, поэтому я пытался использовать обычай output_callback
, Вот несколько вещей, которые я уже пробовал:
ob_start(function($string) {
return __FILE__ . ":" . __LINE__ . " : " $string;
});
Это возвращает имя файла и номер строки, где определена функция, а не то, откуда она была вызвана (как я полагаю, как и ожидалось, но с ошибочным началом).
ob_start(function($string) {
return print_r(debug_print_backtrace(), true) . " : " $string;
});
Это выдает ошибку об уничтожении лямбда-функции.
ob_start(function($string) {
return var_dump(debug_backtrace()) . " : " $string;
});
Это имело смешанные результаты. Я признаю, я не совсем уверен, почему. Но в большинстве случаев var_dump
преобразован в пустую строку (ничего), но в одном случае он, казалось, генерировал некоторый массив трассировки, но не имел ничего, отражающего происхождение вызова ob_start (другими словами, независимо от того, что он выводит, исходный файл, который фактически вызывал echo
не был частью следа).
Имейте в виду, что с учетом вышесказанного я провел довольно простое тестирование, чтобы выяснить, что output_callback
функция будет выглядеть, когда я буду готов поместить ее в контекст устранения неполадок. Таким образом, проблема не зависит от приложения, я просто пытаюсь найти общий способ перехвата выходных функций (echo, print и т. Д.) И получения информации о том, откуда произошел этот выходной вызов.
Возможные решения
1
Если ваш код использует буферизацию вывода, чтобы выплевывать этот заблудший символ, приведенное ниже решение может помочь. Вы также правы, что это будет работать только тогда, когда буферизация вывода извлекается / извлекается, а не при каждом выражении print / echo. Кроме того, все встроенные функции не работают в функции обратного вызова и print_r
является одним из них, но мы можем бросить Exception
. Пожалуйста, попробуйте приведенный ниже код и посмотрите, поможет ли он вам в решении вашей проблемы.
ob_start(function($buffer) {
try {
$stackTrace = debug_print_backtrace();
throw new \Exception($stackTrace, 1);
} catch (\Exception $ex) {
//This line can be logged to a file instead of appending to the buffer
$buffer .= PHP_EOL.$ex->getTraceAsString().PHP_EOL.PHP_EOL;
}
return $buffer;
});
2
Если первое решение не помогает решить вашу проблему, вы можете использовать расширенные средства отладки и профилирования, такие как Xdebug
3
Если вы действительно не заботитесь о содержимом, которое уже выводится перед текущей строкой, или если вы хотите в будущем доказать, что подобная проблема не произойдет в будущем, вы можете просто очистить буфер с помощью ob_end_clean перед вашим ob_start.
ob_end_clean();
ob_start();
4
Поиск всего пробела в PHP после закрытия тега:
pcregrep -rMl '\?>[\s\n]+\z' *
ИЛИ ЖЕ
pcregrep -rM '\?>[\s]+[^\S]*$' *.php
Других решений пока нет …