Http ответ сервера php

PHP: How to send HTTP response code?

I have a PHP script that needs to make responses with HTTP response codes (status-codes), like HTTP 200 OK, or some 4XX or 5XX code. How can I do this in PHP?

None of the answers say what to do after calling header() for a 404 error detected in PHP code. Is exit() okay?

7 Answers 7

I just found this question and thought it needs a more comprehensive answer:

As of PHP 5.4 there are three methods to accomplish this:

Assembling the response code on your own (PHP >= 4.0)

The header() function has a special use-case that detects a HTTP response line and lets you replace that with a custom one

However, this requires special treatment for (Fast)CGI PHP:

$sapi_type = php_sapi_name(); if (substr($sapi_type, 0, 3) == 'cgi') header("Status: 404 Not Found"); else header("HTTP/1.1 404 Not Found"); 

Note: According to the HTTP RFC, the reason phrase can be any custom string (that conforms to the standard), but for the sake of client compatibility I do not recommend putting a random string there.

Note: php_sapi_name() requires PHP 4.0.1

Читайте также:  Base64 to byte array kotlin

3rd argument to header function (PHP >= 4.3)

There are obviously a few problems when using that first variant. The biggest of which I think is that it is partly parsed by PHP or the web server and poorly documented.

Since 4.3, the header function has a 3rd argument that lets you set the response code somewhat comfortably, but using it requires the first argument to be a non-empty string. Here are two options:

header(':', true, 404); header('X-PHP-Response-Code: 404', true, 404); 

I recommend the 2nd one. The first does work on all browsers I have tested, but some minor browsers or web crawlers may have a problem with a header line that only contains a colon. The header field name in the 2nd. variant is of course not standardized in any way and could be modified, I just chose a hopefully descriptive name.

http_response_code function (PHP >= 5.4)

The http_response_code() function was introduced in PHP 5.4, and it made things a lot easier.

Compatibility

Here is a function that I have cooked up when I needed compatibility below 5.4 but wanted the functionality of the «new» http_response_code function. I believe PHP 4.3 is more than enough backwards compatibility, but you never know.

Источник

Протокол HTTP и работа с заголовками

Весь современный веб построен на модели взаимодействия клиента и сервера. Как она работает:

  • браузер пользователя (клиент) отправляет на сервер запрос с адресом сайта (URL);
  • сервер получает запрос и отдаёт клиенту запрошенный контент.

Для реализации процесса используется универсальный протокол HTTP.

Как работает HTTP

Программировать на PHP можно и без знания протокола HTTP. Но для решения ряда задач нужно знать, как именно работает веб-сервер. Ведь PHP — это в первую очередь серверный язык программирования.

👉🏼 Протокол HTTP очень прост и состоит из двух частей:

Сначала идёт список заголовков, затем пустая строка, после неё (если есть) тело запроса/ответа.

И клиент, и сервер могут посылать друг другу заголовки и тело ответа. У клиента доступные заголовки будут одни, у сервера — другие. Рассмотрим, как выглядит работа по протоколу HTTP, когда пользователь хочет загрузить главную страницу социальной сети «ВКонтакте».

  1. Браузер пользователя устанавливает соединение с сервером vk.com и отправляет следующий запрос:
  2. Сервер принимает запрос и отправляет ответ:
  3. Браузер принимает ответ и показывает готовую страницу.

Нам интересен самый первый шаг, где браузер инициирует запрос к серверу vk.com.

Здесь определяется несколько важных параметров:

GET — это метод (глагол), который применяется для доступа к указанной странице. GET используется очень часто, потому что говорит серверу о том, что клиент хочет прочитать указанный документ. Есть и другие методы, один из них мы рассмотрим уже в следующем разделе.

После метода идёт указание на адрес страницы — URI (универсальный идентификатор ресурса). Мы запрашиваем главную страницу сайта, поэтому используется просто слэш — / . В конце строки указана версия протокола, почти всегда это будет HTTP/1.1 .

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

Среди заголовков, которые передаются при каждом запросе, есть один обязательный и самый важный — это заголовок Host . Он определяет адрес домена, который запрашивает браузер клиента.

Сервер, получив запрос, ищет у себя сайт с доменом из заголовка Host , а также указанную страницу. Если запрошенный сайт и страница найдены, клиенту отправляется ответ: HTTP/1.1 200 OK . Такой ответ означает, что документ найден и будет отправлен клиенту.

👉 Общая структура стартовой строки ответа:

HTTP/Версия Код состояния Пояснение

Больше всего здесь интересен именно код состояния, он же код ответа сервера. В этом примере код ответа — 200, что означает: сервер работает, документ найден и будет передан клиенту.

Не всегда всё идёт гладко.

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

  • 404 — если сервер доступен, но запрошенный документ не найден;
  • 503 — если сервер не может обрабатывать запросы по техническим причинам.

Спецификация HTTP 1.1 определяет 40 различных кодов HTTP.

После стартовой строки следуют заголовки, а затем тело ответа.

Работа с заголовками в PHP

В PHP есть все возможности для взаимодействия с HTTP:

  • Получение тела запроса;
  • Получение заголовков запроса;
  • Добавление/изменение заголовков ответа;
  • Управление телом ответа.

Получение тела запроса

Тело запроса — это информация, которую передал браузер при запросе страницы. Но тело запроса присутствует только, если браузер запросил страницу методом POST . Дело в том, что POST — это метод, специально предназначенный для отправки данных на сайт. Чаще всего метод POST браузер задействует в момент отправки формы. В этом случае телом запроса будет содержимое формы.

В PHP-сценарии все данные отправленной формы будут доступны в специальном массиве $_POST . Более подробно об этом написано в следующей главе, посвящённой формам.

Получение заголовков запроса

Напомним ещё раз, что заголовки запроса — это метаинформация, отправленная браузером при запросе сценария.

PHP автоматически извлекает такие заголовки и помещает их в специальный массив — $_SERVER . Стоит отметить, что в этом массиве, помимо заголовков, есть и другая информация. Значения заголовков запроса находятся под ключами, которые начинаются с HTTP_ . Подробно всё содержимое этого массива описано в официальной документации.

Пример, как получить предыдущую страницу, с которой перешёл пользователь:

Добавление/изменение заголовков ответа

В PHP-сценарии можно управлять всеми заголовками ответа, которые попадут к пользователю вместе с контентом страницы. Это возможно, потому что PHP работает на стороне веб-сервера и имеет с ним очень тесную интеграцию. Вот примеры сценариев, когда пригодится управление заголовками ответа:

  • Кэширование;
  • Переадресация пользователя;
  • Установка cookies;
  • Отправка файлов;
  • Передача дополнительной информации браузеру.

Заголовки ответа нужны для выполнения множества важных задач.

В PHP есть функция для отправки или смены заголовков: header() .

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

Например, так выполняется перенаправление пользователя на другую страницу:

За переадресацию отвечает заголовок с именем Location , а через двоеточие задаётся значение — адрес страницы для перехода.

Важное замечание по использованию заголовков

Есть одно ограничение: заголовки нельзя отправлять, если пользователю к этому моменту уже отправили любой контент. То есть если показать что-то на экране, например, через функцию print() , то после этого заголовки поменять уже не получится.

Управление телом ответа

Всё, что PHP выводит на экран, является содержимым ответа. Иными словами, вызовы функций print , echo или показ текста через шорт-теги являются телом ответа, которое попадает в браузер пользователю.

Параметры запроса

Мы привыкли, что на нашем сайте каждый PHP-сценарий отвечает за одну страницу. Посетитель сайта вводит в адресную строку путь, который состоит из имени домена и имени PHP-сценария. Например, так: http://weather-diary.ru/day.php .

Но как быть, если одна страница должна показывать разную информацию?

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

Также пользователи хотят добавить в закладки адреса страниц с нужными им днями. Получается, что, имея только один сценарий, сделать страницу, способную показывать дневник погоды за любой день невозможно? Вовсе нет!

Из чего состоит URI

URI — это уникальный идентификатор ресурса. Ресурс в нашем случае — это полный путь до страницы сайта. И вот как может выглядеть ресурс для показа погоды за конкретный день:

Разберём, из чего состоит этот URI.

Здесь есть имя домена: weather-diary.ru .

Затем идёт имя сценария: day.php .

А всё, что идёт после — это параметры запроса.

Параметры запроса — это как бы дополнительные атрибуты адреса страницы. Они отделяются от имени страницы знаком запроса. В примере выше параметр запроса только один: date=2017-10-30.

Имя этого параметра: date , значение: 2017-10-15 .

Параметров запроса может быть несколько, тогда они разделяются знаком амперсанда: ?date=2017-10-15&tscale=celsius .

В примере выше указывается два аргумента: дата и единица измерения температуры.

Параметры запроса — как внешние переменные

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

Получение параметров запроса

Если есть внешние переменные, то как их прочитать?

Все параметры запроса находятся в специальном, ассоциативном массиве $_GET , а значит, сценарий, вызванный с таким адресом: day.php?date=2017-10-15&tscale=celsius будет иметь в этом массиве два значения с ключами date и scale .

Запрос на получение данных за выбранный день выглядит так:

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

Никогда не полагайтесь на существование параметра в массиве $_GET и делайте проверку либо функцией isset() , либо как в этом примере.

В этом задании вы сможете потренироваться использовать $_GET .

Формирование URI с параметрами запроса

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

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

Вот как это можно сделать:

Здесь мы использовали две функции:

  • basename(__FILE__) — получает имя текущего сценария;
  • http_build_query() — преобразует ассоциативный массив в строку запроса.

«Доктайп» — журнал о фронтенде. Читайте, слушайте и учитесь с нами.

Источник

Оцените статью