Функция header в PHP

Функция header



Установление кодировки

Организация редиректа

Проблемы вывода

Изменение статуса страницы. Отправление другого кода ответа сервера браузеру

Как отдать нужное содержимое. Как поменять тип документа




Эта функция предназначена для отправки HTTP заголовка. (php.net)

HTTP заголовки это специальная информация, которая присоединяется к документу, то есть, к тому файлу, который запрашивается браузером с сервера. Когда мы вбиваем в адресную строку какой-нибудь адрес то, соответственно, запрашиваем на сервере по этому адресу какой-нибудь документ. Эта информация(документ) видна у нас на экране. Но кроме видимой части есть еще и невидимая - те самые HTTP заголовки, которые отправляются сервером браузеру и они нужны для того, чтобы браузер корректно отобразил страницу. То есть, заголовки подсказывают браузеру как показать страницу или как отдать страницу.


Для браузера firefox: кнопка F12 -> сеть -> кликнуть "статус" и обновить страницу :


header1



Среди прочего в заголовках отправляется информация о кодировке страницы, как давно модифицировалась страница, информация о том, что это за страница (html-страница, обычный текстовый документ; или, вместо того чтобы показать страницу, отдать ее на скачивание)



Установление кодировки




Один, из наиболее часто используемых вариантов функции header , это использование функции для установления кодировки.

В файле index.php в папке с нашим уроком запишем: привет, мир! и посмотрим в браузере, что получили. Мы можем получить крабозябры. Это происходит по тому, что браузер будет открывать документ в той кодировке, которую сервер отправил в заголовках по умолчанию. Если кодировка нашего документа не совпадает с кодировкой сервера - получим крабозябры.


Кодировка для всех частей нашего приложения должна быть единой!!!

Рекомендуется всегда использовать кодировку utf-8 - как универсальную кодировку.

Использование метатэга <meta charset="UTF-8"> - не всегда помогает, потому что сервер может отправлять по умолчанию свою кодировку в заголовках и в этом случае она будет иметь больший приоритет, чем метатэг charset.

В этом случае мы должны переопределить кодировку сервера с помощью функции header . (php.net)

Функция header позволяет указать нужную нам кодировку.


Файл index.php


-- файл index.php --

<?php
header('Content-Type: text/html; charset=utf-8');
?>


<!doctype html>
<html Lang="en">
<html>
<head>
<meta charset ="UTF-8">
<title>Document</title>
</head>
<body>
<p>привет мир!</p>
</body>
</html>
выведет:
привет мир!




где:
text/html - тип документа;
charset=utf-8 - нужная нам кодировка.


Если посмотрим заголовки в "разработка/инструменты разработчика/сеть" firefox), то увидим, что они дополнились кодировкой charset="UTF-8", то есть, мы указали браузеру (отправили заголовки), что нужно использовать именно данную кодировку. При этом она имеет приоритет над метатэгом charset.


header2



Еще один способ установления кодировки по умолчанию - это использовать специальный файл .htaccess . Данный файл является файлом настройки сервера Apache .

Создадим даннный файл в нашей папке.

Установим кодировку для сервера по умолчанию с помощью специальной директивы AddDefaultCharset .

Данная директива заставляет сервер отправлять в заголовках кодировку, указанную в качестве значения данной дериктивы.


Файл .htaccess:


-- файл .htaccess --

AddDefaultCharset utf -8




Организация редиректа




Функцию header часто используют для редиректа.

Создадим новый файл - inc.php и выведем в нем строку: "привет из подключаемого файла".

Файл inc.php


-- inc.php --

<?php
echo 'Привет из подключаемого файла';
?>




В индексном файле используем функцию header для редиректа. Его можно сделать двумя командами:
- командой 'Location'
- командой 'refresh'


Файл index.php


-- файл index.php --

<?php
header('Content-Type: text/html; charset=utf-8');
header( 'Location: inc.php' ); // где inc.php - относительный путь к файлу
?>


<!doctype html>
<html Lang="en">
<html>
<head>
<meta charset ="UTF-8">
<title>Document</title>
</head>
<body>
<p>привет мир!</p>
</body>
</html>
после обновления страницы выведет:
- привет из подключаемого файла




При работе с редиректом нужно помнить что редирект происходит не сразу. Когда отрабатывает
данная команда (header('Location: inc.php');), выполнение файла продолжается дальше.
Чтобы сделать безусловный редирект и не выполнять дальнейший код нужно воспользоватся
одной из двух команд - функция die (пер.- умри) и функция exit (пер.- выйти).
Эти команды почти всегда рекомендуется использовать после редиректа.


Чтобы убедиться, что у нас код после команды редиректа выполняется, используем редирект
с задержкой: header('refresh: 5, url'), где
5 - время задержки в секундах,
url=inc.php - адрес, на который должен быть перенаправлен пользователь (если внешний адрес,
то используем - http, если внутренний, то используем - относительный путь к файлу).
Запускаем файл index.php:


-- файл index.php --

<?php
header('Content-Type: text/html; charset=utf-8');

header( 'Location: inc.php' );
// - где inc.php - относительный путь к файлу

header ('refresh: 5, url=inc.php');
// - адрес, на который должен быть перенаправлен пользователь

?>


<!doctype html>
<html Lang="en">
<html>
<head>
<meta charset ="UTF-8">
<title>Document</title>
</head>
<body>
<p>привет мир!</p>
</body>
</html>
выведет:
- привет мир!
через 5 секунд выведет:
- привет из подключаемого файла




--- после загрузки документа весь код у нас выполнился - выводится: привет мир!
После пятисекундной задержки нас перенаправляет на другой файл ( inc.php) - выводится: привет из подключаемого файла.
Чтобы код не выполнялся используем любую из функций: либо exit, либо die.


-- файл index.php --

<?php
header('Content-Type: text/html; charset=utf-8');
header( 'Location: inc.php' );
// - где inc.php - относительный путь к файлу

header ('refresh: 5, url=inc.php');
exit ;
// die;
?>


<!doctype html>
<html Lang="en">
<html>
<head>
<meta charset ="UTF-8">
<title>Document</title>
</head>
<body>
<p>привет мир!</p>
</body>
</html>
выведет:
- пустую страницу
через 5 секунд выведет:
- привет из подключаемого файла




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



Проблемы вывода




Функция header отправляет заголовки в браузер. Они помогают коректно отобразить страницу. Эти заголовки должны бать отправленны раньше перед самим контентом страницы, поскольку браузер должен проанализировать заголовки и, в соответствии с ними, показать нашу страницу. Поэтому заголовки должны быть всегда отправленны до вывода, при этом заголовки могут отправлятся только один раз.
Если мы инициализируем вывод в браузер, то заголовки автоматически будут отправленны. Это значит, что если перед функцией header есть какой-то вывод в браузер, то она просто не отработает.


1. В этом легко убедиться, если в индексном файле поставим какой нибудь вывод, например, перенос строки перед функцией header:


-- файл index.php --

- здесь будет перенос строки -
<?php
...
...
...
?>
...
...
...




- будет выведена ошибка:

- не удается изменить информацию заголовка - заголовки уже отправленны.

Выводом считается любой символ, который показывается в браузере, например, даже пробел.


2. С проблемой вывода можно столкнуться при подключении какого нибудь файла.

Например, мы подключаем файл inc.php, и в нем есть какая-то переменная - $test = 'TEST'.

В индексном файле мы хотим использовать данную переменную: <?= $test ?>.


Файл index.php


-- файл index.php --

<?php
require_once 'inc.php' ;
header ( 'Content-Type: text/html; charset=utf-8' );
?>
<!doctype html>
<html Lang="en">
<html>
<head>
<!-- <meta charset="UTF-8"> -->
<title>Урок 1</title>
</head>
<body>
<?= $test ?> <!-- используем переменную из подключаемого файла -->
<p>привет мир!</p>
</body>
</html>




Файл inc.php


-- файл inc.php --

<?php
$test = 'TEST';




- в результате выполнения выведется: TEST привет мир! - заголовки успешно отправляются.

Однако, если в файле inc.php мы организуем вывод, например выведем на экран переменную $test:


-- файл inc.php --

<?php
echo $test = 'TEST';




- то получим известную нам ошибку. Фактически, содержимое подключаемого файла inc.php, вставляется вместо строки require_once 'inc.php'.


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


4. Еще один вариант данной проблемы - это использование кодировки просто utf-8, вместо кодировки utf-8 без BOM. BOM - это маркер, в котором зашифрована информация о том, что за кодировка используется. В данном случае этот маркер и есть вывод в браузер.



Изменение статуса страницы. Отправление другого кода ответа сервера браузеру




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

Все коды ответов (список кодов состояния HTTP): wikipedia.org


Отправление кода ответа 404 Not Found :


Представим, что наш файл index.php - это несуществующая страница - страница 404 и мы должны отправить соответствующий код: header('HTTP/1.0 404 Not Found');


-- файл index.php --

<?php
require_once 'inc.php' ;
header ( 'Content-Type: text/html; charset=utf-8' );
header ('HTTP/1.0 404 Not Found'); // отправление кода ответа 404 Not Found

// header('Location: inc.php');
// header('refresh: 5, url=inc.php');
// exit;
// die;
?>
<!doctype html>
<html Lang="en">
<html>
<head>
<!-- <meta charset="UTF-8"> -->
<title>Урок 1</title>
</head>
<body>
<?= $test ?> <!-- используем переменную из подключаемого файла -->
<p>привет мир!</p>
</body>
</html>




Обновляем страницу и получаем нужный нам ответ:


header3



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



Как отдать нужное содержимое. Как поменять тип документа




Создадим файл text.txt и запишем в него: ПРИВЕТ, МИР!!!


файл text.txt:


-- файл text.txt --

ПРИВЕТ, МИР!!!




- мы хотим отдать на скачивание этот текстовый файл. Делаем это следующим образом:


1)- переопределяем тип нашего документа - text/html меняем на text/plain (текстовые данные): header('Content-Type: text/plain; charset=utf-8');

Список всех типов документов (список MIME-типов) здесь: wikipedia.org

Когда мы используем text/plain то мы говорим браузеру, что это обычный текстовый документ, где мы не предусматриваем каких-то html-тэгов, и соответственно браузер не будет обрабатавать эти самые html-тэги.


файл index.php


-- файл index.php --

<?php
require_once 'inc.php' ;

// меняем тип документа
header ( 'Content-Type: text/plain; charset=utf-8' );
?>
<!doctype html>
<html Lang="en">
<html>
<head>
<!-- <meta charset="UTF-8"> -->
<title>Урок 1</title>
</head>
<body>
<?= $test ?> <!-- используем переменную из подключаемого файла -->
<p>привет мир!</p>
</body>
</html>




Обновляем страницу и увидим:


-- страница в браузере --

<!doctype html>
<html lang="en">
<head>
<!-- < meta charset="UTF-8"> -->
<title> Document </title>
</head>
<body>
TEST
<p>привет мир!</p>
</body>
</html>




2) - отдаем документ на скачивание - header('Content-Disposition: attachment; filename="downloaded.txt"');

- Content-Disposition: attachment - указывает на то, что файл необходимо отдать на скачивание

- filename="downloaded.txt" - указывает, как файл будет назван после сохранения


Файл index.php:


-- файл index.php --

<?php
require_once 'inc.php' ;

// меняем тип документа
header ( 'Content-Type: text/plain; charset=utf-8' );

// отдаем документ на скачивание
header('Content-Disposition: attachment; filename="downloaded.txt"');
?>
...
...
...




После обновления страницы появится окно, предлагающее открыть или сохранить файл по именем downloaded.txt:


header4




3) - читаем файл - readfile('text.txt');


Файл index.php:


-- файл index.php --

<?php
require_once 'inc.php' ;

// меняем тип документа
header ( 'Content-Type: text/plain; charset=utf-8' );

// отдаем документ на скачивание
header('Content-Disposition: attachment; filename="downloaded.txt"');

readfile ('text.txt' );// читаем файл
?>
...
...
...




После обновления страницы и нажатии "ОК" в появившемся окне, получаем:


Файл downloaded.txt:


-- файл downloaded.txt --

ПРИВЕТ, МИР!!!
<!doctype html>
<html lang="en">
<head>
<!-- < meta charset="UTF-8" > -->
<title> Document </title>
</head>
<body>
TEST
<p>привет мир!</p>
</body>
</html>




Чтобы отсечь html-код, необходимо завершить выполнение нашего скрипта, для этого воспользуемся функцией dia или exit.


Файл index.php:


-- файл index.php --

<?php
// header ('Content-Type: text/html; charset=utf-8' );

// переопределяем тип нашего документа
header('Content-Type: text/plain; charset=utf-8');

// отдаем документ на скачивание
header('Content-Disposition: attachment; filename="downloaded.txt"');

// читаем файл
readfile ('text.txt' );

die; // завершаем выполнение нашего скрипта
?>
...
...
...




И тогда получим в файле downloaded.txt:


-- файл downloaded.txt --

ПРИВЕТ, МИР!!!




--- этот способ используется часто для организации платного скачивания на сайте.


Структура файлов урока


php14.png






Наверх Наверх