Форум программистов, компьютерный форум, киберфорум
PHP для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.66/497: Рейтинг темы: голосов - 497, средняя оценка - 4.66
Почетный модератор
 Аватар для Humanoid
11561 / 4356 / 453
Регистрация: 12.06.2008
Сообщений: 12,457

Что означает предупреждение "headers already sent"

09.08.2011, 11:14. Показов 108254. Ответов 76

Студворк — интернет-сервис помощи студентам
На форуме часто бывают вопросы, что при использовании session_start(), header() и setcookie() и некоторых других функций, появляется сообщения типа
Code
1
2
Warning: session_start(): Cannot send session cookie - headers already sent in D:\HTTP\a.php on line 5
Warning: session_start(): Cannot send session cache limiter - headers already sent in D:\HTTP\a.php on line 5
или
Code
1
Warning: Cannot modify header information - headers already sent in D:\HTTP\a.php on line 5
Это связано с тем, что браузеру уже были отправлены данные перед тем, как была вызвана одна из этих функций.
Если кому интересны подробности, то вот
немного теории
Давайте разберёмся, что происходит, когда мы заходим на сайт. Например, когда мы в браузере открываем страницу http://www.example.ru/file.php, то браузер запрашивает у DNS сервера, какой IP адрес принадлежит серверу www.example.ru. После этого он подключается по протоколу TCP к этому IP адресу на порт 80 (этот порт используется по умолчанию для HTTP) и отправляет текстовый запрос наподобие такого:
Code
1
2
3
4
5
6
7
8
9
GET /file.php HTTP/1.1
Host: www.example.ru
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru,chrome://global/locale/intl.properties;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Cookie: user=2; var=blablabla
Этим запросом в первой строке браузер указывает, что хочет просто получить страницу (GET), указывает адрес страницы и версию протокола (сейчас используются только две версии - 1.0 и 1.1... версия 0.9 устарела и сейчас не используется).
Так же обязательным является параметр Host. Т.к. на каждом сервере может быть несколько разных сайтов, то мы должны указать, к какому именно сайту мы хотим обратиться.
Остальные параметры необязательны... ими браузер просто рассказывает о себе (User-Agent) и рассказывает серверу, как он хочет общаться. Но сейчас речь не об этом...

В ответ на этот запрос веб-сервер запускает выполнение нашего php-скрипта, к которому обращается браузер. И веб-сервер отправляет браузеру результат работы скрипта... но перед этим он отправит свои заголовки ответа.
Code
1
2
3
4
5
6
7
8
9
10
11
HTTP/1.1 200 OK
Date: Tue, 09 Aug 2011 06:59:22 GMT
Server: Apache
X-Powered-By: PHP/5.3.5
Content-Length: 1234
Content-Type: text/html; charset=windows-1251
Set-Cookie: PHPSESSID=3ms50sjl2pt2s19sns5udiryn6; path=/
 
<!DOCTYPE html>
<html>
......
Как вы видите, заголовки идут вначале, а после одной пустой строки начинается тело самого html, который мы генерируем с помощью php-скрипта.

И вот мы подошли к основной сути... когда PHP приказывает веб-серверу начать отправлять само содержимое брузеру, то веб-серверу не остаётся ничего, кроме как отправить вначале все заголовки, которые имеются у него на текущий момент. Поэтому после этого PHP уже не сможет изменить эти заголовки.
Функция header() изменяет любой заголовок. Функция setcookie() добавляет куки к заголовку Set-Cookie, поэтому тоже не может работать после отправки заголовков. session_start() добавляет куки с идентификатором сессии (как в примере выше).


А пока найдём пути решения этой проблемы. Чаще всего такие ситуации происходят из-за использования BOM. BOM - это 2 или 3 невидимых символа в начале файла. Эти символы указывают на то, какая используется кодировка. Многие текстовые редакторы по умолчанию добавляют BOM ко всем файлам юникодовской кодировкой (например UTF-8). Например, создадим в блокноте файл
PHP
1
2
3
<?php
 
?>
И сохраним его в кодировке UTF-8. Но если мы теперь просмотрим файл в кодировке cp1251, то увидим, что вначале файла добавлены символы:
Code
1
2
3
п»ї<?php
 
?>
Именно эти символы и создают проблему. Ведь PHP исполняет свой код только внутри тегов <?php ?>... всё что снаружи отправляется браузеру как есть. Получается, что эти 3 байта сразу же отправятся к браузеру ещё до начала интерпретации PHP-кода. Хотя, по умолчанию в php.ini включен output_buffering и установлен в значение 4096... поэтому проблемы с BOM не должно быть... однако, у многих пользователей она почему-то есть. Подозреваю, что это следствие использования разных кривых сборок.

Я вижу 2 пути решения это проблемы:
1. Включить в php.ini
Code
1
output_buffering = 4096
На вашем компьютере это должно помочь. Но если вы позже закачаете свой сайт на хостинг, то у вас не будет уверенности, что там включен этот буфер.
2. Запретить текстовому редактору сохранять BOM. Но тут уже всё зависит от возможностей текстового редактора, который вы используете. Например, я пользуюсь Notepad++... там можно открыть меню "Кодировки" и выбрать "Преобразовать в UTF-8 без BOM".


Если вы уверены, что BOM не используется, значит где-то перед функциями header(), setcookie() и т.п. вы сами отправляете данные пользователю. Возможно, перед открытием тега <?php есть пустая строка... её тоже нужно убрать.
Если вначале вам необходимо отправлять данные, то можно включить использование буфера, что бы данные не отправлялись сразу браузеру:
PHP
1
2
3
4
5
6
<?php
ob_start();
 
echo "Всякие тексты";
header('Content-Type: text/plain; charset=windows-1251');
?>
В этом случае никаких проблем не будет, т.к. ob_start() указывает, что данные вначале надо накапливать в буфере и отправлять браузеру только когда выполнение скрипта будет завершено.
57
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
09.08.2011, 11:14
Ответы с готовыми решениями:

Что означает предупреждение " comparison between signed and unsigned integer expressions"
Я написал вот такую строчку: for(int i=0; i &lt; stringas.size();i++){ cout &lt;&lt; &quot; &lt;&lt; &quot;] &quot;; } cout &lt;&lt; endl; И мне пишет:...

Выходит предупреждение headers already sent by
Выходит предупреждение headers already sent by Warning: Cannot modify header information - headers already sent by (output started at...

Событие A означает, что извлечены 3 зеленых, а событие В - извлечены 3 красных леденца. Что означает сумма А или B?
Помогите с задачей! В упаковке 6 леденцов, из них 3 зеленых и 3 красных. Наудачу извлекают 3 леденца. Пусть событие A означает, что...

76
5 / 5 / 0
Регистрация: 20.08.2017
Сообщений: 685
24.09.2019, 18:32
Студворк — интернет-сервис помощи студентам
Что означает предупреждение "headers already sent" слишком поздно отправляешь заголовки , так как запрос уже был отправлен частично подними выше по коду....
0
11 / 11 / 2
Регистрация: 13.07.2014
Сообщений: 420
20.11.2019, 09:35
Здравствуйте, что-то я замучился. Перечитал и про BOM из UTF-8 нюанс, убрал везде это, про всякие пробелы в начале файлов, всё это просмотрел. Не помогает. Я ещё делаю пример из книги, не моя структура. И тем паче не понимаю в чём дело.
Ошибка возникает тут на последней строке (ну само собой на команде header).
"Cannot modify header information - headers already sent by (output started at W:\domains\temp\include\header.html:1) in W:\domains\temp\process.php on line 38"

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php
include ('include/header.html');
$page_title = 'PHP - Ошибки';
function fail ($str){
    echo "<p>Пожалуйста, укажите $str.</p>";
    echo '<p><a href="post.php">Написать сообщение</a>';
    include ('include/footer.html');
    exit();
}
if(isset($_POST['message'])){
    if(!empty(trim($_POST['first_name']))){
        $first_name = addslashes($_POST['first_name']);
    }
    else{fail('имя');}
    if(!empty(trim($_POST['last_name']))){
        $last_name = addslashes($_POST['last_name']);
    }
    else{fail('фамилию');}
    if(!empty(trim($_POST['subject']))){
        $subject = addslashes($_POST['subject']);
    }
    else{fail('тему');}
    if(!empty(trim($_POST['message']))){
        $message = addslashes($_POST['message']);
    }
    else{fail('текст сообщения');}
 
    require('../connect_db.php');
    $sql = "INSERT INTO forum (first_name, last_name, subject, message, post_date) VALUES ('$first_name', '$last_name', '$subject', '$message', NOW()) ";
    $result = mysqli_query ($dbc, $sql);
}
if (mysqli_affected_rows($dbc) != 1){
    echo '<p>Ошибка</p>'.mysqli_error($dbc);
    mysqli_close($dbc);
}
else{
    mysqli_close($dbc);
    header('Location: forum.php');
}
________________________________________ ___
А вот этот W:\domains\temp\include\header.html

HTML5
1
2
3
4
5
6
7
8
9
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Привет</title>
<link rel="stylesheet" href="include/style.css">
</head>
<body>
<header><h1>Шапка страницы</h1></header>
0
Эксперт PHP
3901 / 3239 / 1353
Регистрация: 01.08.2012
Сообщений: 10,917
20.11.2019, 11:26
Цитата Сообщение от Masai Посмотреть сообщение
header.html:1
У вас в header.html начинается вывод, поэтому функция header не работает.
1
Почетный модератор
 Аватар для Humanoid
11561 / 4356 / 453
Регистрация: 12.06.2008
Сообщений: 12,457
20.11.2019, 11:36  [ТС]
Цитата Сообщение от Masai Посмотреть сообщение
А вот этот W:\domains\temp\include\header.html
Он и выводит несколько строк данных. После этого header() уже не может сработать. Варианты всё те же: либо включать буферизацию, либо менять код таким образом, что бы перед вызовом header() не было никаких передач данных.

Возможно, тут у вас происходит путаница о том, что такое header из-за имени фала header.html. Есть протокол HTTP, который состоит из заголовков и данных. Заголовки как раз передаются через функцию header(), а данные выводятся через echo, в обход тегов <?php и т.п. Т.е, когда вы вызываете
PHP
1
include ('include/header.html');
то файл include/header.html парсится и так как там нет <?php, то этот файл просто передаётся в качестве данных. Содержимое header.html - это заголовки HTML и для HTTP они являются обычными данными... HTTP ничего не знает о структуре HTML.
Например, когда вы выполняете код:
PHP
1
2
3
4
<?php
header('Blablabla: Lalala');
include ('include/header.html');
?>
то браузеру передаётся следующее (я тут не стал указывает некоторые HTTP-заголовки... на самом деле есть такие, которые самим веб-сервером добавляются)
Code
1
2
3
4
5
6
7
8
9
10
11
12
HTTP/1.1 200 OK
Blablabla: Lalala
 
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Привет</title>
<link rel="stylesheet" href="include/style.css">
</head>
<body>
<header><h1>Шапка страницы</h1></header>
Тут видно, что содержимое header() передаётся в заголовках, а содержимое файла header.html - это уже часть самих данных и передаётся после заголовков. Заголовки и данные в HTTP разделяются пустой строкой. Поэтому если вы уже начали передавать данные, то уже не представляется возможным дополнить заголовки.

Если включена буферезация, то PHP не начинает сразу передавать данные браузеру, а вначале накапливает их у себя в памяти. И только когда размера буфера не хватает или вы ему явно дали команду отправить буфер, только в этом случае он отправляет все накопленные заголовки и данные браузеру.
1
11 / 11 / 2
Регистрация: 13.07.2014
Сообщений: 420
20.11.2019, 12:01
Цитата Сообщение от Jodah Посмотреть сообщение
У вас в header.html начинается вывод, поэтому функция header не работает.
Спасибо! Так как я пример брал из книги и всё скрупулёзно проверял, советуете просто пропустить и двигаться дальше? А то чую лишь время зря теряю на это. Автор книги так вот решил сделать почему-то. Я пробовал инклюдить header.html сразу же после header команды, т.е на 39 строке, но тогда не выводятся сообщения, хотя может и не из-за этого
И кстати, а в header.html что именно считается за вывод?

Добавлено через 37 секунд
Humanoid, ой только сейчас увидел сообщение, сейчас буду читать, спасибо!

Добавлено через 14 минут
Humanoid, спасибо за такой подробный ответ! Я ещё его пару раз перечитаю и обдумаю, сразу всё вразумить непросто. Хотя вчера уже и гуглил, читал про это частично. А вы всё подробно описали. Не понимаю только почему автор учебной книги написал такой код и даже не уточнил про все эти нюансы.
0
Эксперт PHP
3901 / 3239 / 1353
Регистрация: 01.08.2012
Сообщений: 10,917
20.11.2019, 12:32
Цитата Сообщение от Masai Посмотреть сообщение
почему автор учебной книги написал такой код
Подскажите название книги, автора и на какой странице этот код приведён.
0
11 / 11 / 2
Регистрация: 13.07.2014
Сообщений: 420
20.11.2019, 12:45
Цитата Сообщение от Jodah Посмотреть сообщение
Подскажите название книги, автора и на какой странице этот код приведён.
Автор Майк МакГрат.
Книга - PHP 7 для начинающих.

с 218 по 230 страницу. Но там страницы небольшие, страница за 10-15 секунд просматривается если по-беглому. На 226-ой конкретно тот process.php
П.С Ой, правда header.html на 189 странице.
0
Эксперт PHP
3901 / 3239 / 1353
Регистрация: 01.08.2012
Сообщений: 10,917
20.11.2019, 13:07
Masai, да, это косяк учебника. Да и сам код "попахивает".

PHP
1
2
3
    if(!empty(trim($_POST['subject']))){
        $subject = addslashes($_POST['subject']);
    }
Проверяем пустоту с trim, а в базу пишем без trim. Ещё и addslashes, хотя даже в документации написано, что её не надо использовать для защиты от sql-инъекций. В общем, много вопросов к автору.
0
11 / 11 / 2
Регистрация: 13.07.2014
Сообщений: 420
20.11.2019, 14:06
Цитата Сообщение от Jodah Посмотреть сообщение
да, это косяк учебника. Да и сам код "попахивает".
Да уж! Благодарю за это логическое завершение всей этой истории. Теперь хоть душа спокойна, как говорится. А то не понимал в чём дело, с лупой все эти файлы сравнивал, искал косяки. Но вообще полезный урок с этими заголовками, то что Humanoid описал...
Благо эта книга уже заканчивается.

Добавлено через 52 минуты
Jodah, вы вот код коль там уж проанализировали, не подскажите как его изменить чтоб заработало? Я всё же потратил время чтоб всё это переписать из книги, хочется всё же видеть сообщения на этом "форуме". Повторюсь я пробовал инклюдить header.html на 39-ую строку, ошибка пропадала эта, сообщения отправлялись вроде как, но ничего не отображалось, лишь пустота (на forum.php).
Или как советовал Humanoid надо врубить в самом начале буферизацию и только такое спасение для этого несчастного кода?
Я вроде бы пробовал и тот ob_start(). Но и в таком случае не отображалось всё
Просто я понял как бы суть проблемы, но я слишком слаб чтоб понять как поступить в данном случае..
0
Почетный модератор
 Аватар для Humanoid
11561 / 4356 / 453
Регистрация: 12.06.2008
Сообщений: 12,457
21.11.2019, 01:40  [ТС]
Вообще, код очень странный. Внутри условия "if(isset($_POST['message']))" делается подключение к БД "require('../connect_db.php')" и делается запрос к БД. А потом после этого условия вычитывается количество полученных в ходе запроса строк. Получается, что если в условие не попали (например, если это не POST-запрос), то сразу выполняется "mysqli_affected_rows($dbc)", при том, что переменная $dbc не была объявлена (скорее всего, она объявляется в connect_db.php). Поэтому PHP и валится, т.к. для этой функции должен передаваться какой-то хендл базы данных, а передаётся несуществующая переменная. В общем, выглядит так, что строки 32-39 должны быть внутри условия (между строками 30 и 31). Тогда PHP не должен падать, но и отображать ему тоже нечего, т.к. тут ожидается POST-запрос, а для GET он ничего не отображает. Где-то должна быть страница с формой, которая при нажатии кнопки отправляет данные на этот скрипт.

Цитата Сообщение от Masai Посмотреть сообщение
Не понимаю только почему автор учебной книги написал такой код и даже не уточнил про все эти нюансы.
Некоторые авторы часто пишут о том, чего сами не понимают. Просто надёргивают какого-нибудь кода из интернета в свою книгу и отдают в издательство. Им надо денег заработать и им наплевать на содержимое. Я не знаю на счёт именно этого автора, но некоторые (особенно наши) часто бред пишут. Но бегло посмотрев именно эту главу, складывается впечатление, что автор не понимает, что пишет в книге.

Наверное, должно быть примерно так
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php
function fail ($str)
{
    include ('include/header.html');
    echo "<p>Пожалуйста, укажите $str.</p>";
    echo '<p><a href="post.php">Написать сообщение</a>';
    include ('include/footer.html');
    exit();
}
 
function get_post_var($var, $name)
{
    if (empty($_POST[$var]))
        fail($name);
 
    return $_POST[$var];
}
 
if(isset($_POST['message'])) {
    $first_name = get_post_var('first_name', 'имя');
    $last_name = get_post_var('last_name', 'фамилию');
    $subject = get_post_var('subject', 'тему');
    $message = get_post_var('message', 'текст сообщения');
 
    require('../connect_db.php');
    $sql = "INSERT INTO forum (first_name, last_name, subject, message, post_date) VALUES (?, ?, ?, ?, NOW())";
    if (!($stmt = mysqli_prepare($dbc, $sql))) {
        echo "Ошибка";
        exit();
    }
    mysqli_stmt_bind_param($stmt, 's', $first_name);
    mysqli_stmt_bind_param($stmt, 's', $last_name);
    mysqli_stmt_bind_param($stmt, 's', $subject);
    mysqli_stmt_bind_param($stmt, 's', $message);
    mysqli_stmt_execute($stmt);
    if (mysqli_stmt_affected_rows($stmt) != 1) {
        include ('include/header.html');
        echo '<p>Ошибка</p>'.mysqli_stmt_error($stmt);
    } else {
        header('Location: forum.php');
    }
    mysqli_stmt_close($stmt);
    mysqli_close($dbc);
}
Написал на коленке без проверки... могут быть опечатки. И с mysqli я не работал, поэтому тоже мог что-нибудь напутать.
1
11 / 11 / 2
Регистрация: 13.07.2014
Сообщений: 420
23.11.2019, 09:40
Цитата Сообщение от Humanoid Посмотреть сообщение
Вообще, код очень странный.
Да уж! У меня кстати заработало всё, я там оказывается всё таки ошибся кое где и не выводил сообщения форумные. Хотя они и создавались, и заносились в БД. Потом исправил ошибку и увидел все эти 150+ сообщений.
Решил научиться удалять сразу все сообщения БД. Наверно крайне криво (в книге вообще нету про это и я знаю, что легко всё удалить через админку, но захотелось в коде). Добавил на forum.php это:
PHP
1
2
3
echo '<form action="delete.php" method="POST" accept-charset="utf-8">
<input type="submit" value="Удалить все сообщения">
</form>';

И создал файлик delete.php (правда основу кода я гуглил, пока сам запутаюсь такое написать, я лишь подкорректировал):
PHP
1
2
3
4
5
6
7
8
<?php
echo '<p><a href="forum.php">Вернуться к форуму</a></p>';
$link = mysqli_connect("127.0.0.1", 'root', '', 'website_db') 
or die("Ошибка " . mysqli_error($link)); 
$id = mysqli_real_escape_string($link, $_POST['id']);
$query ="DELETE FROM forum WHERE first_name != ' '";
$result = mysqli_query($link, $query) or die("Ошибка " . mysqli_error($link)); 
mysqli_close($link);
Наверно это крайне криво, но мне простительно, я не автор книги, впервые вообще это делаю.

Цитата Сообщение от Humanoid Посмотреть сообщение
скорее всего, она объявляется в connect_db.php
Ага, именно так.

Сразу показалось, что книга конечно очень поверхностная. Автор начинает темы с MySQL но так вообще не описывает детали. Почитал ваши комментарии по поводу подхода автора и его кода и в ужас пришёл. Хорошо, что книга заканчивается уже.
0
Почетный модератор
 Аватар для Humanoid
11561 / 4356 / 453
Регистрация: 12.06.2008
Сообщений: 12,457
23.11.2019, 12:45  [ТС]
Кстати, рекомендую сразу писать запросы к БД правильно. В функциях mysqli (да и в PDO тоже) есть два способа отправить запрос к базе данных:
1. mysqli_query()
2. mysqli_prepare() / mysqli_stmt_bind_param() / mysqli_stmt_execute()

Первый способ подходит только в том случае, когда в запрос не нужно вставлять переменные. Например, как в вашем последнем сообщении... там запрос - это единая строка без использования каких-то вставленных переменных. Точнее, переменные можно вставлять, но только если они константные, а не получены от пользователя. Например:
PHP
1
2
$condition = 'id = 1';
mysqli_query($link, "SELECT * FROM tab WHERE $condition");  // так делать можно, потому что $condition - написана вами в этом же коде
Но нельзя вставлять переменные, полученные от пользователя, например, через $_GET или $_POST:
PHP
1
2
3
$id = $_POST['id'];
$condition = "id = $id";
mysqli_query($link, "SELECT * FROM tab WHERE $condition");  // !!! так делать НЕЛЬЗЯ, потому что содержимое $_POST['id'] непредсказуемо
Второй способ нужно использовать, когда нужно вставить в запрос переменную (например, полученную из $_GET или $_POST). Например:
PHP
1
2
3
$stmt = mysqli_prepare($dbc, 'SELECT * FROM tab WHERE id=?');  // создаём заготовку запроса, где нужно заменить вопросительные знаки на какие-то значения
mysqli_stmt_bind_param($stmt, 'i', $_POST['id']);  // вместо вопросительного знака подставляем $_POST['id']... функция сама приведёт тип или добавит экранирование где нужно
mysqli_stmt_execute($stmt); // исполняем полученный запрос
При этом вам не нужно использовать всякие addslashes(), mysqli_real_escape_string() и т.п. Функция mysqli_stmt_bind_param() сама расставит экранирование.
1
11 / 11 / 2
Регистрация: 13.07.2014
Сообщений: 420
26.11.2019, 09:47
Humanoid, спасибо за полезную информацию! Надо бы мне это в памятку занести, запомнить. Интересно.
Столько нюансов. Хотя если пообвыкнуться то несложно. Надо про все эти функции почитать просто.

Кстати по поводу той книги, после той истории последней там была ещё одна последняя тема, опять всё не работало, благо это было последнее в этой книге и наконец я с ней покончил. Эта книга годится только с синтаксисом ознакомиться.
Вторая книга интересней и третья.

П.С Кстати, не уточните, что тут происходит?
$condition = "id = $id";
Это будет строковой переменной у которой значение "id = (текст пришедший из POST запроса)" - т.е просто такой Текст?
0
Почетный модератор
 Аватар для Humanoid
11561 / 4356 / 453
Регистрация: 12.06.2008
Сообщений: 12,457
26.11.2019, 10:53  [ТС]
Цитата Сообщение от Masai Посмотреть сообщение
П.С Кстати, не уточните, что тут происходит?
$condition = "id = $id";
Это будет строковой переменной у которой значение "id = (текст пришедший из POST запроса)" - т.е просто такой Текст?
Да. Например, из POST пришло $id = '123', тогда после
$condition = "id = $id"
переменная $condition будет содержать строку "id = 123"
0
0 / 0 / 2
Регистрация: 30.11.2018
Сообщений: 32
12.05.2021, 10:01
Ошибка "Заголовки уже отправлены" у начинающих программировать на РНР может иметь следующие причины:
1 - Не нужно писать Echo везде и подряд. В коде Echo должно быть одно. Особенно когда в коде используются функции из внешних, подключённых через include или recuire, файлов.
2 - Посторонние служебные символы перед <?PHP. Скопируйте весть код, создайте пустой файл в блокноте, сохраните в нужной кодировке и вставьте туда код.
3 - session_start(); только в самом начале кода, второй строкой полсе <?PHP
0
Эксперт PHP
4925 / 3920 / 1620
Регистрация: 24.04.2014
Сообщений: 11,441
12.05.2021, 13:52
Цитата Сообщение от U_YNS Посмотреть сообщение
Ошибка "Заголовки уже отправлены" у начинающих программировать на РНР может иметь следующие причины:
Причина только одна - новички не знают что такое http протокол, и даже не представляют что с ним работают. Это причина. Всё остальное - следствия. И пока не будет ясна причина новичок будет заниматься всякой ерундой, типа переноса несчастного session_start, пересохранений во всевозможных кодировках и т.д.
1
0 / 0 / 0
Регистрация: 01.09.2021
Сообщений: 1
01.09.2021, 19:03
Цитата Сообщение от Humanoid Посмотреть сообщение
И сохраним его в кодировке UTF-8. Но если мы теперь просмотрим файл в кодировке cp1251, то увидим
Огромное спасибо, помог. Забыл, что блокнот сохраняет в UTF-8 BOM по умолчанию, в то время как VSC в UTF-8
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
01.09.2021, 19:03

Постоянные ошибки с сессиями (headers already sent и Cannot modify headers)
Добрый день, хоть тема я так понял и избитая но всё же не могу понять логику работы сессий. Вот у меня есть админ панель из десятка файлов....

Что означает появление письменности (языка), и что означает реформа письменности (языка)?
Не секрет, что духовность всегда сокрыта в письменности (языке), так высшая стадия развития духовности социума (общества) это всегда...

Что означает, что определение метода находится внутри определения класса?
Что означает, что определение метода находится внутри определения класса? Prostokat p0(&quot;Prostokat&quot;,2,3); cout &lt;&lt;...

Поясните пожалуйста что означает двоеточие и то что идет после него
В 4 строчке после параметра в скобочках нету &quot;;&quot; или же тела функции, что не сходится с моим шаблоном в голове. Поясните пожалуйста что...

Что такое dy1 и dy2 в программе, и зачем мы их перемножаем. Что означает строчка x=x1
Что такое dy1 и dy2 . и зачем мы их перемножаем? и что значит строчка x=x1 clear all; close all; clc; disp('Определение кол-ва...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
77
Ответ Создать тему
Новые блоги и статьи
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru