php get запрос с заголовками
Базовая работа с PHP CURL: GET, POST, JSON, Headers
В прошлой статье по написанию своего первого парсера я описал основы работы с cURL. Текущая статья будет одной из цикла статей по экскурсу в написание ботов и парсеров. Однако, эта статья, в основном, будет похожа на шпаргалку, в большей мере, чем на туториал.
PHP cURL основы
Отправка GET запроса из PHP cURL
Иногда стоит необходимость отправки GET-запроса, формируя URL-адрес из Query-параметров. Для таких случаев, можете воспользоваться встроенной PHP-функцией, формирующей URL-строку с параметрами из массива:
Теперь вы знаете, как склеить массив данных в URL из PHP.
Отправка POST запроса из PHP cURL
PHP cURL POST запрос обычно не выполняется с пустым телом. Запрос этого типа считается запросом на добавление данных (создание новой сущности в БД, к примеру) и обычно нам необходимо передавать серверу набор каких-то данных. Код отправки POST-запроса с передачей данных будет выглядеть так:
Отправка cURL запроса из PHP с собственными заголовками (PHP cURL Headers)
Отправка POST JSON запроса в PHP cURL
Очень часто, при написании ботов, имитирующих взаимодействие с API, приходится отправлять данные на целевой сервер в формате JSON. И так сложилось, что отправка Form-Data POST параметров отличается от алгоритма отправки JSON данных, потому, и передавать эти данные для cURL нужно по-другому.
Для того, чтобы корректно передать данные в формате JSON через PHP cURL, необходимо исходный массив с параметрами, перекодировать в JSON вручную, и заполнить этими данными тело (body) запроса. А так же, чтобы сервер понял, что это данные в формате JSON, нужно передать соответствующие HTTP-заголовки (о которых мы говорили выше).
Основной принцип передачи данных в JSON с помощью CURL заключается в том, что нужно выполнить POST запрос, тело которого заполнить закодированными в JSON данными, после чего, указать соответствующий заголовок позволяющий серверу понять, что ему на обработку пришли JSON данные.
Резюме
Работа всех этих опций, их работа и настройка подробно рассказано в этой статье. А так же, на закрепление этого материала, в следующей статье был изложен алгоритм написания ботов на PHP, советую почитать, и попробовать написать собственного бота, чтобы полноценно разобраться в этой теме. Эта статья охватывает большинство важных тем: отправка POST-запросов, обработка ответов, имитация браузера из PHP.
Subscribe to Блог php программиста: статьи по PHP, JavaScript, MySql
Get the latest posts delivered right to your inbox
Протокол HTTP и работа с заголовками
Протокол HTTP
Как работает WWW (всемирная паутина, веб) в двух словах:
Иными словами, весь современный веб построен на модели клиент-серверного взаимодействия. И чтобы весь этот процесс оказался возможным, необходим универсальный язык-протокол, который будет понимать и сервер, и браузер. Такой протокол есть, а называется он HTTP.
Как работает HTTP, и зачем нам это знать
Программировать на PHP можно и без знания протокола HTTP, но есть ряд ситуаций, когда для решения задач нужно знать, как именно работает веб-сервер. Ведь PHP — это, в первую очередь, серверный язык программирования.
Протокол HTTP очень прост и состоит, по сути, из двух частей:
Сначала идёт список заголовков, затем пустая строка, а затем (если есть) тело запроса/ответа.
И клиент, и сервер могут посылать друг другу заголовки и тело ответа, но в случае с клиентом доступные заголовки будут одни, а с сервером — другие. Рассмотрим пошагово, как будет выглядеть работа по протоколу HTTP в случае, когда пользователь хочет загрузить главную страницу социальной сети «Вконтакте».
1. Браузер пользователя устанавливает соединение с сервером vk.com и отправляет следующий запрос:
2. Сервер принимает запрос и отправляет ответ:
3. Браузер принимает ответ и показывает готовую страницу
Больше всего нам интересен самый первый шаг, где браузер инициирует запрос к серверу vk.com
Рассмотрим подробнее, что там происходит. Первая строка запроса определяет несколько важных параметров, а именно:
GET — это метод (глагол), который мы применяем для доступа к указанной странице.
GET является самым часто используемым методом, потому что он говорит серверу о том, что клиент всего лишь хочет прочитать указанный документ. Но помимо GET есть и другие методы, один из них мы рассмотрим уже в следующем разделе.
Больше всего здесь интересен именно код состояния, он же код ответа сервера.
В этом примере код ответа — 200, что означает: сервер работает, документ найден и будет передан клиенту. Но не всегда всё идет гладко.
Например, запрошенный документ может отсутствовать или сервер будет перегружен, в таком случае клиент не получит контент, а код ответа будет отличным от 200.
Спецификация HTTP 1.1 определяет 40 различных кодов HTTP.
После стартовой строки следуют заголовки, а затем тело ответа.
Работа с заголовками в PHP
В PHP есть все возможности для взаимодействия с протоколом HTTP:
Разберём всё по порядку.
Получение тела запроса
Получение заголовков запроса
Пример, как получить предыдущую страницу, с которой перешёл пользователь:
Добавление/изменение заголовков ответа
В PHP-сценарии можно управлять всеми заголовками ответа, которые попадут к пользователю вместе с контентом страницы. Это возможно, потому что PHP работает на стороне веб-сервера и имеет с ним очень тесную интеграцию.
Вот примеры сценариев, когда пригодится управление заголовками ответа:
Управление телом ответа
Параметры запроса
На сайте дневника наблюдений за погодой мы сделали отдельную страницу, чтобы показывать на ней информацию о погоде из истории за один конкретный день. То есть страница одна, но показывает разные данные, в зависимости от выбранного дня.
Также пользователи хотят добавить в закладки адреса страниц с нужными им днями. Получается, что имея только один сценарий сделать страницу, способную показывать дневник погоды за любой день невозможно? Вовсе нет!
Из чего состоит URI
URI — это уникальный идентификатор ресурса. Ресурс в нашем случае — это полный путь до страницы сайта. И вот как может выглядеть ресурс для показа погоды за конкретный день:
http://weather-diary.ru/day.php?date=2017-10-15
В примере выше указывается два аргумента: дата и единица измерения температуры.
Параметры запроса как внешние переменные
Теперь в адресе страницы используются параметры запроса, но какая нам от этого польза? Она состоит в том, что если имя страницы вызывает к исполнению соответствующий PHP-сценарий, то параметры запроса превращаются в специальные внешние переменные в этом сценарии. То есть, если в адресе присутствуют такие параметры, то их легко получить внутри кода сценария и выполнить с ними какие-нибудь действия. Например, показать погоду за конкретный день в выбранных единицах измерения.
Получение параметров запроса
Формирование URI с параметрами запроса
Иногда нужно совершить обратную операцию: сформировать адрес страницы, включив туда нужные параметры запроса из массива.
Скажем, на странице погодного дневника надо поставить ссылку на следующий и предыдущий день. Нужно также сохранить выбранную единицу измерений. То есть необходимо сохранить текущие параметры запроса, поменять значение одного из них (день), и сформировать новую ссылку.
Вот как это можно сделать:
Здесь мы использовали две функции:
cURL в PHP: примеры POST, GET запросов с headers, cookie, JSON и многопоточностью
В этой статье мы рассмотрим эффективные приемы работы с cURL, отправление POST, GET и т.д. запросов, работу с cookie, заголовки, JSON а также в конце статьи будут некоторые полезные инструменты, которые могут значительно облегчить вам работу с HTTP запросами.
GET запрос при помощи cURL
Для того, чтобы отправить запрос, нужно создать объект при помощи функции curl_init(), а затем следует настроить его.
Все настройки, которые вы можете найти по этой ссылке. Там вы найдете опции, которые мы будем устанавливать функцией curl_setopt, в дальнейших примерах.
Пример простого GET запроса при помощи cURL:
Если в результате сервер вернет нам редирект, то мы по нему автоматически не перейдем. А иногда это бывает полезно. Чтобы cURL автоматически шел по редиректу нужно установить опцию CURLOPT_FOLLOWLOCATION.
С установленной опцией скрипт автоматически перейдет по вернувшемуся редиректу и вернет ответ уже с итоговой страницы.
POST запрос при помощи cURL
Теперь давайте отправим post запрос на адрес https://httpbin.org/anything
Отлично, с GET и POST запросами в cURL мы немного освоились. Теперь разберемся с заголовками, которые мы можем отсылать в запросе.
Заголовки устанавливаются при помощи опции CURLOPT_HTTPHEADER Чтобы получше узнать, для чего нужна эта опция давайте попробуем отправить POST запрос в формате JSON
cURL: POST запрос в формате JSON
Отличия конфигурации JSON запроса от обычного POST запроса заключается в том, что мы кодируем поля при помощи json_encode() И добавляем заголовок Content-Type: application/json
cURL: GET запрос в формате JSON
GET запрос в формате JSON отправляется так же как и POST запрос, просто нужно CURLOPT_CUSTOMREQUEST установить в ‘GET’
cURL и другие виды HTTP запросов: PUT, DELETE, HEAD, PATCH, OPTIONS, CONNECT и т.д.
Стоп, Дмитрий, прекрати выдумывать виды запросов!
Ничего я не выдумываю: HTTP протокол предполагает множество типов HTTP запросов просто POST и GET являются более распространенными.
Чтобы отправить PUT запрос, нужно установить опцию CURLOPT_PUT таким образом:
Это делается по тому же принципу, как и CURLOPT_POST. Но что делать с остальным зоопарком запросов? Разве у cURL есть CURLOPT_DELETE или CURLOPT_HEAD? Нет.
Для того, чтобы отправлять другие виды запросов есть другая опция: CURLOPT_CUSTOMREQUEST
Вместо строки curl_setopt($curl, CURLOPT_POST, true); мы явно задаем имя запроса опцией CURLOPT_CUSTOMREQUEST:
Замечание: Не используйте эту возможность пока не убедитесь, что сервер поддерживает данный тип запроса.
Как получить заголовки ответа
В предыдущем примере мы научились посылать заголовки. Самый правильный способ принять заголовки:
Иногда можно встретить другой вариант получения заголовков ответа. К сожалению, они не совсем правильные и могут работать некорректно в некоторых случаях.
Рассмотрим такой пример:
Мы сначала определяем размер заголовка, с помощью CURLINFO_HEADER_SIZE затем вырезаем его из ответа. К сожалению, это может не срабатывать, когда используется прокси или в некоторых случаях редиректа.
Скачивание больших файлов с помощью cURL
Для того, чтобы скачать большой файл пригодится этот способ:
Обратите внимание, если вы будете использовать file_get_contents для скачивания файлов, то файл сначала загружается в оперативную память, а потом сохраняется на диск. Поэтому если файл действительно большой, то скорее всего вашему серверу не хватит памяти. Также к памяти будет требователен следующий код:
Здесь мы скачиваем файл при помощи cURL в оперативную память, а затем сохраняем его на диск. Не смотря на то, что этот способ не годится для скачивания больших файлов, с помощью него можно вполне сохранить простую веб страницу.
Параллельные cURL запросы в PHP
Для чего могут потребоваться многопоточные запросы? Например у нас есть много URL адресов:
И если мы будем по очереди отправлять запросы, то второй запрос начнется только после того, как закончился первый и так далее, а это существенно увеличивает время работы скрипта.
Как выполнить 3 запроса одновременно? В этом нам поможет curl_multi_
Давайте решим конкретную задачу при помощи параллельных curl запросов. Нам нужно отправить одновременно 3 запроса.
Такие параллельные запросы выполняются значительно быстрее чем поочередные.
cURL запросы с сохранением и загрузкой cookie из файла
cURL позволяет нам установить cookie при передачи запросов, а также автоматически принимать и устанавливать cookie, которые нам возвращает сервер, сохраняя их между запросами.
Давайте рассмотрим такой пример:
Теперь cookie у нас хранятся в файле cookie.txt в директории со скриптом (если вы ничего не меняли). Если мы совершаем повторные запросы, то cURL автоматически берет и отправляет cookie на сервер, как и обычный браузер. Таким образом мы можем авторизироваться на сайте и сохранить сеанс между запросами.
Передача cookie без файлов
Иммитация браузера с помощью cURL
Иногда сайт, к которому мы обращаемся может фильтровать запросы, защищаясь от парсинга. Если для этого используются упрощенные способы защиты, например проверка User-Agent, то мы можем легко притвориться, что являемся реальным польователем, который взаимодействует с сайтом через браузер, мы можем послать заголовки и cookie, которые обычно посылает браузер.
В данном примере установлены заголовки, которые посылает Chrome.
В простых ситуациях этого хватает. Но если используется защита при помощи javascript или что-то более продвинутое, то здесь cURL бессилен, и следует использовать либо BAS либо Zennoposter. Либо если вы хотите попытать счастье с PHP, то Selenium.
Не используйте эти знания в противоправных целях.
cURL запросы через прокси
Простой пример для отправки запросов через proxy. Если ваш прокси предполагает авторизацию, то раскомментируйте соответствующие строчки.
Отправка файлов
Авторизация с помощью cURL
HTTP Авторизация
Чтобы с помощью cURL авторизироваться на сайте, который использует Basic HTTP-аутентификацию нужно установить опцию CURLOPT_USERPWD, в которой будет наш логин и пароль.
OAuth авторизация
Авторизация через форму
Давайте применим полученные нами знания и авторизируемся на каком-нибудь сайте. Для этого нужно посмотреть куда форма отправляет данные и отправить туда то же самое.
Допустим на сайте есть такая форма:
Тогда наш cURL запрос должен быть сформирован так:
Автоматическое построение запросов
Перевод консольной команды curl в PHP
И вот еще один сервис, который переводит консольную команду curl в PHP: https://incarnate.github.io/curl-to-php/
Так вы можете создать простые запросы на cURL в PHP не создавая их вручную.
Лайфхак
В консоли браузера, во вкладке сеть, вы можете кликнуть правой кнопкой мыши и скопировать любой запрос в виде команды cURL, а потом с помощью сервиса curl-to-php перевести запрос в PHP. Теперь вы вообще можете сконвертировать в cURL абсолютно любой запрос, который посылает ваш браузер.
Как работать с cURL гораздо проще
Вы можете спросить: почему у cURL такие кривые и страшные методы? У вас может возникнуть желание взять и создать обертку для работы с cURL, чтобы вы могли не писать каждый раз большие куски некрасивого кода, а писать все проще, например так:
К счастью, такая обертка уже написана и найти ее можно здесь: https://github.com/php-curl-class/php-curl-class
Просто установите ее при помощи: composer require php-curl-class/php-curl-class и не работайте с кривыми кусками кода, которые таковы вероятно потому, что cURL изначально консольное приложение.
POST и GET запросы без cURL
С помощью PHP мы можем отправить простой GET запрос используя функцию file_get_contents.
При помощи file_get_contents мы также можем отправить POST запрос.
Подробнее о том, какие опции можно передавать в stream_context_create, вы можете изучить здесь: http://docs.php.net/manual/ru/context.http.php
Другие инструменты для работы с запросами в PHP
Для работы с запросами есть еще более мощный инструмент: Guzzle
Несколько примеров на Guzzle
GET запросы на Guzzle
Разные типы запросов на Guzzle
Асинхронные запросы на Guzzle
Если интересно, то читайте: Guzzle Quick Start
Пишите комментарии, если что-то осталось не понятно.
get_headers
get_headers — Возвращает все заголовки из ответа сервера на HTTP-запрос
Описание
get_headers() возвращает массив с заголовками из ответа сервера на HTTP-запрос.
Список параметров
Если необязательный параметр associative установлен в ненулевое значение, get_headers() разберёт ответ сервера и установит ключи для возвращаемого массива.
Возвращаемые значения
Возвращает индексированный или ассоциативный массив с заголовками ответа или false при возникновении ошибки.
Список изменений
Примеры
Пример #1 Пример использования get_headers()
Результатом выполнения данного примера будет что-то подобное:
Пример #2 Пример использования запроса HEAD в функции get_headers()
Смотрите также
User Contributed Notes 27 notes
If the URL redirected and the new target is also redirected, we got the Locations in array. Also we got the HTTP codes in a number indexed values.
array
(
[0] => HTTP/1.1 302 Moved Temporarily
[Location] => Array
(
[0] => /test.php?id=2
[1] => /test.php?id=3
[2] => /test.php?id=4
)
[1] => HTTP/1.1 302 Moved Temporarily
[2] => HTTP/1.1 302 Moved Temporarily
[3] => HTTP/1.1 200 OK
)
In a typical situation we need only the landing page information, so here is a small code to get it:
How to check if a url points to a valid video
I know you’re not supposed to reference other notes, but sincere props to Nick at Innovaweb’s comment, for which I base this addition to his idea:
If you use that function, it will return a string, which is great if you are checking for only files that return 404, or 200, or whatnot. If you cast the string value to an integer, you can perform mathematical comparison on it.
if( intval ( get_http_response_code ( ‘filename.jpg’ )) 400 ) <
// File exists, huzzah!
>
?>
Rule of thumb is if the response is less than 400, then the file’s there, even if it doesn’t return 200.
if the URL does not exist, it returns incomplete headers, making the substring default to rubbish.
The integer value of rubbish is always 0. So your lower than 400 does not always means it exists!
To check URL validity, this has been working nicely for me:
If you don’t want to display Warning when get_headers() function fails, you can simply add at-sign (@) before it.
// in failure, Warning will be hidden and false returned
$withoutWarning = @ get_headers ( «http://www.some-domain.com» );
// in failure, Warning displays and false will be returned, too
$withWarning = get_headers ( «http://www.some-domain.com» );
Note that get_headers should not be used against a URL that was gathered via user input. The timeout option in the stream context only affects the idle time between data in the stream. It does not affect connection time or the overall time of the request.
(Unfortunately, this is not mentioned in the docs for the timeout option, but has been discussed in a number of code discussions elsewhere, and I have done my own tests to confirm the conclusions of those discussions.)
If you are publishing your code, even default_socket_timeout cannot be relied on to remedy this, because it is broken for the HTTPS protocol on many but the more recent versions of PHP: https://bugs.php.net/bug.php?id=41631
With get_headers accepting user input, it can be very easy for an attacker to make all of your PHP child processes become busy.
Instead, use cURL functions to get headers for a URL provided by the user and parse those headers manually, as CURLOPT_TIMEOUT applies to the entire request.
hey, i came across this afew weeks ago and used the function in an app for recording info about domains that my company owns, and found that the status this returns was wrong most of the time (400 bad request or void for sites that were clearly online). then looking into it i noticed the problem was that it wasn’t able to get the correct info about sites with redirections. but thats not the full problem because everything on my server was returning the wrong status too. i searched around on php.net for other info and found that fsockopen’s example worked better and only needed some tweeking.
heres the function i put together from it and a small change.
hope this’ll help someone else.
It should be noted that rather than returning «false» on failure, this function (and others) return a big phat WARNING that will halt your script in its tracks if you do not have error reporting /warning turned off.
Thats just insane! Any function that does something like fetch a URL should simply return false, without a warning, if the URL fails for whatever reason other than it is badly formatted.
The following code dose NOT work with PHP version 7.0.26 with my server.
Some other setting may be required?
Tried with website pages and path to local files.
The word ‘Finished’ is printed only.
Should be the same than the original get_headers():
I’ve noticed it.
Some Server will simply return the false reply header if you sent ‘HEAD’ request instead of ‘GET’. The ‘GET’ request header always receiving the most actual HTTP header instead of ‘HEAD’ request header. But If you don’t mind for a fast but risky method then ‘HEAD’ request is better for you.
aeontech, this the below change adds support for SSL connections. Thanks for the code!
I found that this function is the slowest in obtaining the headers of a page probably because it uses a GET request rather then a HEAD request. Over 10,000,000 trials of obtaining the headers of a page from a server i found the following (results in seconds).
cURL: Mean: 0.584127946. Sigma: 0.050581736.
fsocketopen: Mean: 0.622114251. Sigma: 0.263170424.
get_headers: Mean: 0.90375551. Sigma: 0.273823419.
cURL was the fastest with fsocketopens being the second fastest. I noticed as well that fsocketopen had some outliers where as cURL did not.
In some cases, you don’t want get_headers to follow redirects. For example, some of my servers can access a particular website, which sends a redirect header. The site it is redirected to, however, has me firewalled. I need to take the 302 redirected url, and do something to it to give me a new url that I *can* connect to.
The following will give you output similar to get_headers, except it has a timeout, and it doesn’t follow redirects:
Testing the validity of a URL that is preceded by one or more server redirects is tricky. There will be more than one status code returned and all but the first will be redirect codes.
This function will return an integer containing the three digit status code of the last code returned, which is what you want.
return (int) substr($value, strpos($value, ‘ ‘, 8) + 1, 3);
>
If getHeaders() fails, PHP will throw an error. Test the return value for === false.
/**
* Fetches all the real headers sent by the server in response to a HTTP request without redirects
*
* @link http://php.net/function.get_headers
* @link http://bugs.php.net/bug.php?id=50719
*/
For anyone reading the previous comments, here is code that takes into account all the previous suggestions and includes a bugfix, too.
In response to dotpointer’s modification of Jamaz’ solution.
if(! function_exists ( ‘get_headers’ )) <
Unfortunately there is still no useful output format to handle redirects.
This function will bring all non-broken headers into a usable format. Too bad it has to call the get_headers() funtion 2 times, but i dont see any other possibility right now.
Content-Type returns a value depending only on the extension and not the real MIME TYPE.
Типы HTTP-запросов и философия REST
Этот пост — ответ на вопрос, заданный в комментарии к одной из моих статей.
В статье я хочу рассказать, что же из себя представляют HTTP-методы GET/POST/PUT/DELETE и другие, для чего они были придуманы и как их использовать в соответствии с REST.
Итак, что же представляет из себя один из основных протоколов интернета? Педантов отправлю к RFC2616, а остальным расскажу по-человечески 🙂
Этот протокол описывает взаимодействие между двумя компьютерами (клиентом и сервером), построенное на базе сообщений, называемых запрос (Request) и ответ (Response). Каждое сообщение состоит из трех частей: стартовая строка, заголовки и тело. При этом обязательной является только стартовая строка.
Стартовые строки для запроса и ответа имеют различный формат — нам интересна только стартовая строка запроса, которая выглядит так:
где METHOD — это как раз метод HTTP-запроса, URI — идентификатор ресурса, VERSION — версия протокола (на данный момент актуальна версия 1.1).
Заголовки — это набор пар имя-значение, разделенных двоеточием. В заголовках передается различная служебная информация: кодировка сообщения, название и версия браузера, адрес, с которого пришел клиент (Referrer) и так далее.
Тело сообщения — это, собственно, передаваемые данные. В ответе передаваемыми данными, как правило, является html-страница, которую запросил браузер, а в запросе, например, в теле сообщения передается содержимое файлов, загружаемых на сервер. Но как правило, тело сообщения в запросе вообще отсутствует.
Пример HTTP-взаимодействия
Первая строка — это строка запроса, остальные — заголовки; тело сообщения отсутствует
Ресурсы и методы
Вернемся к стартовой строке запроса и вспомним, что в ней присутствует такой параметр, как URI. Это расшифровывается, как Uniform Resource Identifier — единообразный идентификатор ресурса. Ресурс — это, как правило, файл на сервере (пример URI в данном случае ‘/styles.css’), но вообще ресурсом может являться и какой-либо абстрактный объект (‘/blogs/webdev/’ — указывает на блок «Веб-разработка», а не на конкретный файл).
Тип HTTP-запроса (также называемый HTTP-метод) указывает серверу на то, какое действие мы хотим произвести с ресурсом. Изначально (в начале 90-х) предполагалось, что клиент может хотеть от ресурса только одно — получить его, однако сейчас по протоколу HTTP можно создавать посты, редактировать профиль, удалять сообщения и многое другое. И эти действия сложно объединить термином «получение».
В игру вступает REST
REST (REpresentational State Transfer) — это термин был введен в 2000-м году Роем Филдингом (Roy Fielding) — одним из разработчиков протокола HTTP — в качестве названия группы принципов построения веб-приложений. Вообще REST охватывает более широкую область, нежели HTTP — его можно применять и в других сетях с другими протоколами. REST описывает принципы взаимодействия клиента и сервера, основанные на понятиях «ресурса» и «глагола» (можно понимать их как подлежащее и сказуемое). В случае HTTP ресурс определяется своим URI, а глагол — это HTTP-метод.
REST предлагает отказаться от использования одинаковых URI для разных ресурсов (то есть адреса двух разных статей вроде /index.php?article_id=10 и /index.php?article_id=20 — это не REST-way) и использовать разные HTTP-методы для разных действий. То есть веб-приложение, написанное с использованием REST подхода будет удалять ресурс при обращении к нему с HTTP-методом DELETE (разумеется, это не значит, что надо давать возможность удалить всё и вся, но любой запрос на удаление в приложении должен использовать HTTP-метод DELETE).
REST дает программистам возможность писать стандартизованные и чуть более красивые веб-приложения, чем раньше. Используя REST, URI для добавления нового юзера будет не /user.php?action=create (метод GET/POST), а просто /user.php (метод строго POST).
В итоге, совместив имеющуюся спецификацию HTTP и REST-подход наконец-то обретают смысл различные HTTP-методы. GET — возвращает ресурс, POST — создает новый, PUT — обновляет существующий, DELETE — удаляет.
Проблемы?
Да, есть небольшая проблема с применением REST на практике. Проблема эта называется HTML.
PUT/DELETE запросы можно отправлять посредством XMLHttpRequest, посредством обращения к серверу «вручную» (скажем, через curl или даже через telnet), но нельзя сделать HTML-форму, отправляющую полноценный PUT/DELETE-запрос.
Дело в том, спецификация HTML не позволяет создавать формы, отправляющие данные иначе, чем через GET или POST. Поэтому для нормальной работы с другими методами приходится имитировать их искусственно. Например, в Rack (механизм, на базе которого Ruby взаимодействует с веб-сервером; с применением Rack сделаны Rails, Merb и другие Ruby-фреймворки) в форму можно добавить hidden-поле с именем «_method», а в качестве значения указать название метода (например, «PUT») — в этом случае будет отправлен POST-запрос, но Rack сможет сделать вид, что получил PUT, а не POST.