Как исправить ошибку "Заголовки уже отправлены" в PHP. Оператор управления ошибками

  • 03.11.2019

Неотъемлемой частью программирования является выявление ошибок в коде. Будь программист хоть семь пядей во лбу, все равно, он будет совершать ошибки, иногда даже банальные. Этому способствует сама природа человека. Поэтому за отладкой и выявлением ошибок в коде программист проводит достаточно большую часть времени. Соответственно, чем гибче и удобнее существуют инструменты для выявления ошибок в коде, и чем лучше программист ими владеет, - тем выше его продуктивность.

Поскольку PHP является скриптовым языком программирования, то все ошибки, допущенные в коде, выявляются по ходу исполнения кода. Программисту PHP предстоит сталкиваться как со стандартными ошибками, присущими программированию в целом, так и с довольно скрытыми ошибками – такими как опечатки в именовании переменных.

Язык PHP предусматривает два механизма выявления ошибок в скрипте в процессе его выполнения: стандартный механизм ошибок PHP и механизм исключений. В PHP множество функционала использует стандартный механизм ошибок, поэтому не знать о нем нельзя. Поэтому в данной статье речь пойдет именно об этом механизме.

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

Видим ошибки

Так, для того, чтобы PHP отображал ошибки прямо на странице, необходимо установить специальный параметр в коде:

ini_set("display_errors", 1); //display_errors отвечает за отображение ошибок прямиком на странице. Если 0 – ошибки не отображаются

Теперь, при возникновении какой-либо ошибки в скрипте, интерпретатор выведет информацию о ней на странице. Например, если запустить скрипт с несуществующей функцией:

ini_set("display_errors", 1);
echo "

Строка, которая будет отображена

";
echo abrakadabra();
echo "

Строка, которая не будет отображена из-за ошибки

";

то на странице отобразится такая ошибка:

Фатальная ошибка. Такого рода ошибка означает, что скрипт прерывает свою работу, и далее идущий код не будет выполнен.

Отображение ошибок скрипта на странице используется только для отладки самого скрипта, поэтому при запуске кода в боевой среде параметру display_errors устанавливают значение 0.

Вообще, в PHP имеется ошибки разных категорий значимости: некоторые из них прерывают дальнейшее выполнение кода – другие нет, одни можно перехватывать – другие нельзя. Полный перечень категорий ошибок приведен ниже:

Значение
Константа
Описание
Возможность
1
E_ERROR
Неустранимая ошибка
Нет
2
E_WARNING
Исправимая ошибка
Да
4
E_PARSE
Ошибка парсера
Нет
8
E_NOTICE
Потенциальная ошибка
Да
16
E_CORE_ERROR
Аналогично E_ERROR, но генерируется ядром PHP
Нет
32
E_CORE_WARNING
Аналогично E_WARNING, но генерируется ядром PHP Нет
64
E_COMPILE_ERROR
Аналогично E_ERROR, но генерируется Zend Engine
Нет
128
E_COMPILE_WARNING
Аналогично E_WARNING, но генерируется Zend Engine Нет
256
E_USER_ERROR
Аналогично E_ERROR, но инициируется вызовом trigger_error()
Да
512
E_USER_WARNING
Аналогично E_WARNING, но инициируется вызовом trigger_error() Да
1024
E_USER_NOTICE
Аналогично E_NOTICE, но инициируется вызовом trigger_error() Да
2048
E_STRICT
Сообщение от исполнительной среды с рекомендациями по улучшению качества кода (начиная с PHP5)
-
4096
E_RECOVERABLE_ERROR
Опасная, но не фатальная ошибка(например, несоответствие типа)
Да
8192
E_DEPRECATED
Предупреждение об использовании устаревшей функции или возможности
Да
16384
E_USER_DEPRECATED
Предупреждение об использовании устаревшей функции или возможности, инициированное в коде
Да
32767
E_ALL
Все ошибки
Нет

Для удобства предусмотрены константы, которые используются для определения уровня обработки ошибок, построения бит-маски. Константы имеют "говорящие" имена. Глядя на константу - мы можем сказать, что ошибка уровня E_PARSE возникает в случае синтаксической ошибки, E_NOTICE - это напоминание программисту о нарушении "хорошего стиля" программирования на PHP.

По умолчанию включено значение режима генерации сообщений об ошибках E_ALL & ~E_NOTICE , что соответствует выводу всех сообщений, не относящихся к категории E_NOTICE . Программист может гибко настроить, какие категории ошибок ему необходимо видеть на странице. Для того, чтобы изменить режим генерации ошибок, необходимо изменить конфигурационный параметр error_reporting . Чтобы включить отображение любых ошибок, необходимо задать данному параметру значение E_ALL :

Например, если запустить следующий код:

ini_set("display_errors", 1);
ini_set("error_reporting", E_ALL);

Мы получим ошибки сразу двух категорий (notice и warning):

Когда используется необъявленная переменная – появляется ошибка E_NOTICE . Когда соединение с базой данных MySQL (или другой) завершается неудачей - интерпретатор PHP сообщает об ошибке уровня E_WARNING .

Логируем ошибки

Если даже конфигурационный параметр display_errors установлен в 0, все равно должна быть возможность просматривать наличие случившихся ошибок в процессе выполнения скрипта. Таким образом, в случае если случится ошибка – мы должны знать, где и почему она случилась. Для этих целей в PHP существуют настройки логирования ошибок.

По умолчанию средствами языка PHP ошибки нигде не логируются. Чтобы это изменить, необходимо изменить конфигурационный параметр log_errors в 1 с 0:

ini_set("log_errors", 1);

В таком случае, ошибки автоматически будут записываться в файл, указанный в конфигурационном параметре error_log . Параметр error_log также можно изменить, указав путь к желаемому файлу, куда будут записываться ошибки:

ini_set("error_log", "/var/log/php_errors.log");

Так, для кода:

ini_set("display_errors", 1);
ini_set("error_reporting", E_ALL);
ini_set("log_errors", 1);
ini_set("error_log", __DIR__ . "/log.txt");
$db = mysql_connect($db_host, "user", "password");

В лог-файл записывается аналогичная информация, которая выводится на страницу:

PHP Notice: Undefined variable: db_host in Z:\home\test\www\index.php on line 7
PHP Warning: mysql_connect(): Access denied for user "user"@"localhost" (using password: YES) in Z:\home\test\www\index.php on line 7

Обрабатываем ошибки

Ошибки делятся на перехватываемые и не перехватываемые. Некритические ошибки можно перехватывать пользовательским кодом. Сводная таблица описания категорий ошибок раскрывает информацию, какие категории ошибок можно перехватывать.

Для того, чтобы перехватывать некритические ошибки в коде, достаточно реализовать и объявить собственную функцию и передать ее название в функцию set_error_handler . При этом, в реализованную функцию передаются 5 параметров:

  • уровень ошибки в виде целого числа;
  • сообщение об ошибки в виде строки;
  • имя файла, в котором произошла ошибка, в виде строки;
  • номер строки, в которой произошла ошибка, в виде целого числа;
  • массив всех переменных, существующих в области видимости, где произошла ошибка. Причем, будут включены также и глобальные переменные.
,

Вывод

PHP имеет мощные средства обработки и управления стандартным распространением ошибок. Поэтому отловить ту или иную ошибку не составит труда при условии, что скрипт грамотно сконфигурирован. Знания этой области является неотъемлемыми любого PHP-программиста, поскольку множество кода использует описанный выше механизм

PHP поддерживает один оператор управления ошибками: знак @. В случае, если он предшествует какому-либо выражению в PHP-коде, любые сообщения об ошибках, генерируемые этим выражением, будут проигнорированы.

Если вы установили собственную функцию обработки ошибок с помощью set_error_handler() , то она все равно будет вызвана, однако, если внутри этой функции будет вызвана функция error_reporting() , то она вернет 0, если функция, вызвавшая данную ошибку, была подавлена с помощью @.

В случае, если установлена опция track_errors , все генерируемые сообщения об ошибках будут сохраняться в переменной $php_errormsg . Эта переменная будет перезаписываться при каждой новой ошибке, поэтому в случае необходимости проверяйте ее сразу же.

Замечание : Оператор @ работает только с выражениями . Есть простое правило: если что-то возвращает значение, значит вы можете использовать перед ним оператор @. Например, вы можете использовать @ перед именем переменной, произвольной функцией или вызовом include , константой и так далее. В то же время вы не можете использовать этот оператор перед определением функции или класса, условными конструкциями, такими как if , foreach и т.д.

Также ознакомьтесь с описанием функции error_reporting() и разделом руководства Обработка ошибок и функции логирования .

Внимание

На сегодняшний день оператор "@" подавляет вывод сообщений даже о критических ошибках, прерывающих работу скрипта. Помимо всего прочего, это означает, что если вы использовали "@" для подавления ошибок, возникающих при работе какой-либо функции, в случае если она недоступна или написана неправильно, дальнейшая работа скрипта будет остановлена без каких-либо уведомлений.

12 years ago

To suppress errors for a new class/object:



I found this most useful when connecting to a
database, where i wanted to control the errors
and warnings displayed to the client, while still
using the class style of access.

14 years ago

Better use the function trigger_error() ()
to display defined notices, warnings and errors than check the error level your self. this lets you write messages to logfiles if defined in the php.ini, output
messages in dependency to the error_reporting() level and suppress output using the @-sign.

8 years ago

If you use the ErrorException exception to have a unified error management, I"ll advise you to test against error_reporting in the error handler, not in the exception handler as you might encounter some headaches like blank pages as error_reporting might not be transmitted to exception handler.


{
}

function catchException ($e )
{
{
return;
}

// Do some stuff
}

?>

It would be better to do:

Function exception_error_handler ($errno , $errstr , $errfile , $errline )
{
if (error_reporting () === 0 )
{
return;
}

Throw new ErrorException ($errstr , 0 , $errno , $errfile , $errline );
}

Set_error_handler ("exception_error_handler" );

function catchException ($e )
{
// Do some stuff
}

Set_exception_handler ("catchException" );

?>

4 years ago

While you should definitely not be too liberal with the @ operator, I also disagree with people who claim it"s the ultimate sin.

For example, a very reasonable use is to suppress the notice-level error generated by parse_ini_file() if you know the .ini file may be missing.
In my case getting the FALSE return value was enough to handle that situation, but I didn"t want notice errors being output by my API.

TL;DR: Use it, but only if you know what you"re suppressing and why.

2 years ago

What is PHP"s behavior for a variable that is assigned the return value of an expression protected by the Error Control Operator when the expression encounteres an error?

Based on the following code, the result is NULL (but it would be nice if this were confirmed to be true in all cases).

$var = 3 ;
$arr = array();

$var = @ $arr [ "x" ]; // what is the value of $var after this assignment?

// is it its previous value (3) as if the assignment never took place?
// is it FALSE or NULL?
// is it some kind of exception or error message or error number?

Var_dump ($var ); // prints "NULL"

?>

5 years ago

I was wondering if anyone (else) might find a directive to disable/enable to error operator would be a useful addition. That is, instead of something like (which I have seen for a few places in some code):

If (defined (PRODUCTION )) {
@function();
}
else {
function();
}

?>

There could be something like this:

If (defined (PRODUCTION )) {
ini_set ("error.silent" , TRUE );
}
else {
ini_set ("error.silent" , FALSE );
}

?>

12 years ago

If you want to log all the error messages for a php script from a session you can use something like this:

Hope this helps someone...

PHP предоставляет прекрасную возможность контролировать возникающие ошибки. Здесь мы поговорим о том, как обработать ошибку — сообщить (или не сообщить) о происшествии пользователю, в случае необходимости — сообщить администратору с помощью электронной почты, записать информацию о происшествии в log-файл.

Итак, для начала давайте определимся, что такое ошибки в PHP.

PHP поддерживает следующие уровни ошибок:

E_ERROR
E_WARNING
E_PARSE
E_NOTICE
E_CORE_ERROR
E_CORE_WARNING
E_COMPILE_ERROR
E_COMPILE_WARNING
E_USER_ERROR
E_USER_WARNING
E_USER_NOTICE
E_ALL
E_STRICT

На самом деле — это просто константы, которые используются для определения уровня обработки ошибок, построения бит-маски. Константы имеют "говорящие" имена. Глядя на константу — мы можем сказать, что ошибка уровня E_PARSE возникает в случае синтаксической ошибки, E_NOTICE — это напоминание программисту о нарушении "хорошего стиля" программирования на PHP.

Несколько примеров:

Когда соединение с базой данных MySQL (или другой) завершается неудачей — интерпретатор PHP сообщает об ошибке уровня E_WARNING

Warning: mysql_connect(): Access denied for user: "VVingless@localhost" (Using password: YES) In /home/mysite/index.php (line 83)

Замечание: Для того чтобы интерпретатор PHP сообщал об ошибках — PHP должен быть настроен соответствующим образом: флаг display_errors должен быть включен — 1, директива error_reporting должна указывать на то, что необходимо отображать ошибки уровня E_WARNING (желательно конечно и другие). Если значения этих директив не удовлетворяют вашим требованиям — вы можете попробовать установить их самостоятельно, положив в папку со скриптом файл.htaccess (точка в начале имени обязательна) примерно такого содержания:

Php_flag display_errors on
php_value error_reporting "E_ALL & ~E_NOTICE"

Это означает, что сообщения об ошибках будут показываться, причем всех уровней, кроме E_NOTICE
Когда программист допускает синтаксическую ошибку — интерпретатор PHP сообщает об ошибке уровня E_PARSE

Parse error: parse error, unexpected ‘(‘, expecting T_STRING in /home/mysite/index.php on line 150

Но самые интересные для нас уровни ошибок — E_USER_ERROR и E_USER_WARNING. Как становится понятно из названия — это уровни ошибок, которые может устанавливать пользователь. Для этого существует функция trigger_error() — с её помощью, Вы можете сообщать пользователю о происшествии так, как это делает PHP.

Как известно из руководства по PHP — функция trigger_error() принимает два параметра.

void trigger_error (string error_msg [, int error_type])

Первый параметр — текстовое сообщение об ошибке, например "файл не найден". Второй параметр — определяет уровень ошибки. Функция trigger_error() работает только с семейством ошибок E_USER — это значит, что вы можете установить ошибку уровня E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE и не можете установить ошибку уровня E_WARNING. Второй параметр является не обязательным, и по умолчанию принимает значение E_USER_NOTICE.

Давайте попробуем:

Допустим, наши данные для ленты новостей хранятся в файле news.txt, и если файл не найден — необходимо сообщить об ошибке. Текст программы будет выглядеть примерно так:

if (!file_exists(‘/home/mysite/news.txt’)) {
trigger_error(‘News file not found’);
}

В результате интерпретатор PHP сообщит об ошибке уровня E_USER_NOTICE

Notice: News file not found in /home/mysite/index.php on line 47
Но что нам это даёт? Для начала то, что если в php.ini или файле.htaccess были установлены директивы

php_value log_errors "1"
php_value log_errors_max_len "1024"
php_value error_log "/home/mysite/my.log"
То в файл /home/mysite/my.log автоматически будет добавлена запись о происшествии.

PHP Notice: News file not found in /home/mysite/index.php on line 47
Далее, с помощью функции set_error_handler() мы можем установить свой собственный обработчик ошибок возникающих во время выполнения PHP скрипта.

Как известно из мануала — в PHP 4 функция принимает один единственный строковый параметр — имя функции, которая будет выполняться каждый раз, когда происходит ошибка. PHP 5 даёт возможность установить ещё один параметр — тип ошибок которые будут обрабатываться с помощью нашего обработчика. Функция возвращает строку — имя функции обработчика, который был установлен до этого момента.

string set_error_handler (callback error_handler [, int error_types])

устанавливаем так

set_error_handler ("my_error_handler");
Пользовательская функция, которая будет обрабатывать ошибки, может принимать следующие входные параметры:

— код уровня ошибки
— строковая интерпретация ошибки
— имя файла, в котором произошла ошибка
— строка, в которой произошла ошибка

Следует так же заметить, что эта функция не может обрабатывать ошибки уровней E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING

Это связанно с тем, что ошибки перечисленных уровней происходят до того, как интерпретатор получает информацию о пользовательском обработчике ошибок.

Итак, объявляем нашу функцию

function my_error_handler($code, $msg, $file, $line) {
}

Замечание: каждый более-менее объемный скрипт обычно разделяется на несколько файлов для удобства работы с ним. Как организовывать модульность программы — тема отдельно разговора. Сейчас же, я хочу лишь посоветовать выделять общие настройки в отдельный файл, который будет подключаться в начале программы с помощью инструкции include, либо с помощью директивы auto_prepend_file. В этот файл можно поместит и наш обработчик. Установка обработчика ошибок должна осуществится как можно ближе к началу программы, желательно в самом начале.
Для того чтобы убедится что это действительно работает — создадим новый PHP файл, и попробуем запустить его

Содержимое файла myerrortest.php

Результат обработки данного файла будет таким:

Произошла ошибка News file not found (1024)
/home/mysite/myerrortest.php (12)
Теперь у нас есть функция, которая получает данные обо всех происходящих ошибках. Подумаем, как мы можем это использовать.

Будем обрабатывать ошибки уровней
E_ERROR
E_WARNING
E_NOTICE
E_USER_ERROR
E_USER_NOTICE

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

Что касается остальных двух — как Вы уже догадались — они могу там пригодиться. Мы сами будем вызывать ошибки этих уровней в случае необходимости. Допустим — ошибки уровня E_USER_ERROR — будем вызывать в случае, когда сообщение об ошибке должно попасть в log-файл и быть отправлено на e-mail администратору (например — ошибка при выполнении SQL запроса, или отсутствии парв доступа к необходимому файлу). Ошибки уровня E_USER_NOTICE будут вызываться при возникновении "лёгких" ошибок (например — пользователь некорректно заполнил форму, или запросил из базы несуществующую запись).

Теперь наша функция обработки ошибок будет выглядеть примерно так:

// Немного предварительных настроек // устанавливаем режим отображения ошибок // отображать все ошибки, кроме E_NOTICE error_reporting (E_ALL & ~E_NOTICE); // эта константа отвечает за // включение/выключение режима отладки // во время отладки - сообщения не отсылаются // по почте, а просто печатаются на экран define("DEBUG", 0); // это глобальная переменная, в которой // будет храниться сообщение, которое // должен видеть пользователь $MSG = ""; // e-mail разработчика, куда отправлять ошибки define("ADM_EMAIL","[email protected]"); // log-файл define("LOGFILE","/home/mysite/mylog.log"); // разница во времени с сервером (в секундах) define("TIMEOFFSET", 0); // сама функция function my_error_handler($code, $msg, $file, $line) { // глобальная переменная, в которую будет // записываться сообщение об ошибке. global $MSG; // пропускаем ошибки уровня E_NOTICE // и игнорируем ошибки, если режим сообщения об ошибках отключен if (($code == E_NOTICE) or (error_reporting() == 0)) { return; } // если мы вызвали ошибку уровня E_USER_NOTICE - просто // записать текст ошибки в глобальную переменную $MSG // и прекратить выполнение функции if ($code == E_USER_NOTICE) { $MSG = $msg; Return; } // если ошибка уровня E_ERROR - печатаем текст ошибки // и завершаем выполнение скрипта if ($code == E_ERROR) { die ("
ERROR: ".$msg."
In ".$file." (line ".$line.")
"); } // если ошибка уровня E_WARNING - печатаем текст ошибки // и прекращаем выполнение функции if ($code == E_WARNING) { echo "
WARNING: ".$msg."
In ".$file." (line ".$line.")
"; Return; } // если ошибка уровня E_USER_ERROR if ($code == E_USER_ERROR) { // записываем в переменную $MSG текст, о том что произошла ошибка, // причины сообщать не будем, только сообщим что подробности // отправлены на e-mail кому следует. $MSG = "Критическая Ошибка: действие выполнено небыло.
Сообщение об ошибке было отправлено разработчику."; // подробности записываем в переменную $text $text = $msg."
"."Файл: ".$file." (".$line.")"; // Если константа DEBUG установлена в 1 - печатаем информацию об // ошибке на экран, если нет - отправляем текст ошибки почтой // функция error_mail() и пишем в log - функция error_writelog() if (DEBUG == 1) { error_print($text); } else { error_mail($text); error_writelog($text); } Return; } } // устанавливаем обработчик set_error_handler("my_error_handler"); Теперь описываем служебные функции // ф-я печатает ошибку на экран function error_print($text) { echo $text."

"; } // ф-я отправляет ошибку почтой function error_mail($text) { $text = str_replace("
", "n", $text); $info = "Время: ".get_datetime()."nRemote IP:".get_ip()."n"; mail(ADM_EMAIL, "Error reporting", $info.$text); } // ф-я пишет ошибку в лог function error_writelog($text) { $text = str_replace("
", "t", $text); if (@$fh = fopen(LOGFILE, "a+")) { fputs($fh, get_datetime()."t".get_ip()."t".$text."n"); fclose($fh); } } // получаем время, с учётом разницы во времени function get_time() { return(date("H:i", time () + TIMEOFFSET)); } // получаем дату, с учётом разницы во времени function get_date() { return(date("Y-m-d", time () + TIMEOFFSET)); } // получаем дату и время, с учётом разницы во времени function get_datetime() { return get_date()." ".get_time(); } // получаем IP function get_ip() { return($_SERVER["REMOTE_ADDR"]); } И наконец пример использования // ф-я записывает новость в файл function write_news($title, $text) { $news_file = "/home/mysite/news.txt"; // проверяем наличие заголовка - ошибка не критическая if (!trim($title)) { // для того чтобы определить что функция завершилась // неудачей - необходимо вернуть false. Функция // trigger_error() - возвращает true, мы будем // возвращать её инвертированный результат return !trigger_error("Необходимо указать заголовок новости"); } // проверяем наличие текста новости - ошибка не критическая if (!trim($text)) { return !trigger_error("Необходимо указать текст новости"); } // проверяем наличие файла в который будем писать // если файл не найден - возникает критическая ошибка if (!file_exists($news_file)) { return !trigger_error("Файл базы новостей не найден!", E_USER_ERROR); } // ...тут предварительная обработка данных... // записываем новость $fh = fopen($news_file, "a+"); fputs($fh, $title."t".$text."n"); fclose($fh); // если всё нормально - функция возвращает true return true; } // пытаемся записать новость // эти данные могут приходить из web-формы $res = write_news("Моя новость", "Текст моей новости"); if ($res === false) { // если вернулся false - печатаем ошибку echo $MSG; } else { // если всё в порядке - можно сообщить об этом // а лучше отфорвардить пользователя куда-нибудь. echo "Новость была добавлена"; }

Для того чтобы пример заработал — просто скопируйте в PHP-файл три предыдущих блока кода. Не забудьте установить права доступа на log-файл 777 для того чтобы скрипт мог с ним работать, прописать правильные пути и указать свой e-mail. Вы можете включить режим отладки установкой переменной DEBUG в 1.

    Преднамеренное:

    • print , echo и другие функции, производящие вывод
    • Необработанные разделы, предшествующие

      Если источник ошибки упоминается как за закрытие?> то здесь выписывается какой-то пропущенный или необработанный текст. Маркер конца PHP не завершает выполнение script при этом точка. Любые символы текста/пробела после того, как они будут выписаны как содержимое страницы до сих пор.

      Общепринято, в частности, новичкам, что trailing ?> PHP теги close должны быть опущены. Это предотвращает небольшую часть этих случаев. (Чаще всего сценарии include()d являются виновниками.)

    • Источник ошибки, указанный как "Неизвестно в строке 0"

      Обычно это расширение PHP или php.ini, если источник ошибок конкретизируется.

      • Иногда параметр настройки потока gzip или ob_gzhandler .
      • Но это может быть и любой загруженный в два раза модуль extension= генерирование неявного сообщения о запуске/предупреждении PHP.
    • Предыдущие сообщения об ошибках

      Если другой оператор или выражение PHP вызывает предупреждение или уведомление распечатывается, что также считается преждевременным выходом.

      В этом случае вам нужно избежать ошибки, задержать выполнение оператора или подавить сообщение, например. isset() или @() - когда либо не препятствует отладке позже.

    Нет сообщения об ошибке

    Если у вас error_reporting или display_errors отключено на php.ini , то предупреждение не появится. Но игнорирование ошибок не вызовет проблемы далеко. Заголовки по-прежнему не могут быть отправлены после преждевременного выхода.

    Поэтому, когда header("Location: ...") перенаправляет молча, рекомендуется проконтролировать предупреждения. Обозначить их двумя простыми командами на вызов script:

    Error_reporting(E_ALL); ini_set("display_errors", 1);

    Или set_error_handler("var_dump"); , если все остальное не работает.

    Говоря о переадресации заголовков, вы должны часто использовать идиому вроде это для конечных путей кода:

    Exit(header("Location: /finished.html"));

    Предпочтительно даже функция полезности, которая печатает сообщение пользователя в случае сбоев header() .

    Буферизация вывода в качестве обходного пути

    Он может скрывать пробелы для вывода HTML. Но как только приложение логические попытки отправить двоичный контент (например, сгенерированное изображение), буферизованный посторонний выход становится проблемой. (Необходимость ob_clean() как предыдущий вариант.)

    Буфер ограничен по размеру и может быть легко переполнен, если оставить его по умолчанию. И это не редкость, трудно отследить когда это произойдет.

    Оба подхода могут стать ненадежными - в частности, при переключении между разработки и/или производственные серверы. Именно поэтому буферизация вывода широко считается просто костылем/строго обходным путем.

    Это сообщение об ошибке запускается, когда что-либо отправляется перед отправкой заголовков HTTP (с setcookie или header). Общие причины вывода чего-либо перед заголовками HTTP:

      Случайные пробелы, часто в начале или в конце файлов, например:

    Чтобы избежать этого, просто оставьте закрытие?>

    • Значения байтов байтов в начале php файла. Изучите ваши php файлы с помощью шестнадцатеричного редактора, чтобы узнать, является ли этот случай. Они должны начинаться с байтов 3F 3C . Вы можете безопасно удалить спецификацию EF BB BF с начала файлов.
    • Явный вывод, например вызовы echo , printf , readfile , passthru , код до DO CHECK FOR BLANK SPACES HERE AS WELL; THIS LINE (blank line) SHOULD NOT EXIST.

      Большая часть времени это должно решить ваш problem.Do проверить все файлы, связанные с файлом вам require .

      Примечание. Иногда EDITOR (IDE), например gedit (стандартный Linux-редактор), добавляет одну пустую строку в файл save save. Этого не должно быть. Если вы используете linux. вы можете использовать редактор VI для удаления пробела/строк после?> в конце страницы.

      Если это не ваше дело, тогда вы можете использовать ob_start для буферизации вывода, как показано ниже:

      Возможное решение 2:

      Это приведет к буферизации вывода, и ваши заголовки будут созданы после буферизации страницы.

      Вместо строки ниже

      //header("Location:".ADMIN_URL."/index.php");

      написать

      Echo("location.href = "".ADMIN_URL."/index.php?msg=$msg";");

      ?>loadHTML("..."); libxml_clear_errors();

      Вы также можете сделать

      @$dom->loadHTML($htmlString);

      Вы можете отфильтровать ошибки, которые вы получаете от анализатора. В соответствии с другими ответами здесь отключите отчет об ошибках на экране, а затем повторите ошибки и покажите только те, которые вы хотите:

      Libxml_use_internal_errors(TRUE); // Do your load here $errors = libxml_get_errors(); foreach ($errors as $error) { /* @var $error LibXMLError */ }

      Вот print_r() одной ошибки:

      LibXMLError Object ( => 2 => 801 => 17 => Tag section invalid => => 39)

      Совпадая с message и / или code , их можно легко отфильтровать.

      Это сработало для меня:

      ", "", "", "", "", ""); $replace = array("", "","", "", "", ""); $html = str_replace($search, $replace, $html); $dom = new DOMDocument(); $dom->loadHTML($html);

      Если вам нужен тег заголовка, измените заголовок тегом div и используйте идентификатор. Например:

      $search = array("", ""); $replace = array("", "");

      Это не лучшее решение, но в зависимости от ситуации это может быть полезно.

      Кажется, что нет способа убить предупреждения, но не ошибки. PHP имеет константы, которые должны это делать, но они, похоже, не работают. Вот что ДОЛЖНО работать, но не потому что (ошибка?) ….

      $doc=new DOMDocument(); $doc->loadHTML("Hi", LIBXML_NOWARNING); echo $doc->saveHTML();

      Теги HTML5 почти всегда используют такие атрибуты, как id, class и т. Д. Таким образом, код для замены будет:

      $html = file_get_contents($url); $search = array("