PHP Guide to Making HTTP Requests
This guide shows you how to make low-level HTTP requests with the core PHP library only, no dependencies such as extensions and libraries (like cURL), that also works with older versions of PHP that exist in the wild.
For this guide, the use case is building a PHP API client for my SASS. It shouldn’t require changes to the user’s PHP runtime or additional dependencies to work.
For a web-focused language, PHP doesn’t make it easy or obvious how to call out over to other servers to make API requests. I compiled all the information I found into this post, a resource I wish I had yesterday when writing an API client.
GET Requests (Read by URL)
PHP hid it’s feature to download a page from the web in the file_get_contents() function, which makes discovery hard.
This performs a “GET” request for the URL and returns the contents.
What about GET parameters? Another useful function can build the query string: http_build_query().
The “query string” is the part of the URL after the domain and path, separated by the “?” character. This does not have to be a structured format, but most web apps use it to hold a set of “name=value” pairs. These are mostly used to search and filter the data being returned.
POST and Advanced Requests
If you need other HTTP features, you are going to need another trick: setting up a PHP context, which holds meta-information for I/O operations. The stream_context_create() function builds the context that you pass to file_get_contents() . The full HTTP context options page documents what you can pass into stream_context_create() . Pass an associative array of ‘http’ => another array of options.
Here, let’s send the same request as a POST. POST data is sent as a content body, after the HTTP headers. http_build_query() returns data encoded in the same way web browsers send form data. We just set the “Content-Type” header on the request to tell the web server which format we are sending.
This creates a HTTP request that looks like this:
Additional Headers
So far, so good! Now to turn our attention to making an API request to some service on the internet. We are going to need to craft additional headers. Let’s create an array of additional headers:
Accept
First, we want the data returned in JSON format, so we need an Accept header to tell the remote web server what we want.
Authenticating
Note: Authentication provides credentials to verify your identity. You do this by providing an API Key, Access Token, or a standard user/password. Authorization controls your access to a see or modify a resource. This is usually controlled by the application using your user privilege and role. However, HTTP uses the “Authorization” header to authenticate your credentials, which can be confusing or misleading.
Assume we have an API Key given to us by a service for identification. There are different ways to pass your key to the service, though the most useful is using HTTP Basic Authentication.
PHP decodes incoming Basic Auth headers into $_SERVER[‘PHP_AUTH_USER’] and $_SERVER[‘PHP_AUTH_PW’] but does not provide a feature to send our own, but it’s easy enough to roll. The string “username:password” (no quotes) is Base64 encoded to prevent characters from disturbing the HTTP header protocol.
Usually for an API key, we format with an empty password, so really just appending the colon after the key: “apikey:”
Which creates the header that looks something like this:
I could not find documentation that PHP would create the Authorization header from a URL with the user/password prepended, so I doubt this would work, and if so, may very version to version:
If you have a token, usually from Oauth2 or a JSON Web Token or JWT passed after login, The “Bearer” format of the header is used:
and can be added to your headers as:
Cookies
Usually, we don’t need cookies for API requests, but some services use it to transfer your credentials, an API key or JWT token. We can add each cookie header as follows with whatever name and value you have.
Encoding of cookie strings is not well defined. Use the values returned previously from the remote server if available as they are in the format (url-encoded, Base64, etc) and character set expected to be received. Simple ASCII strings like the apikey example should work as expected.
User-Agent
We should identify what service is making the request – our program and version. We don’t need a special header for this! We can set this up the stream_context_create() arguments, right alongside the “method” parameter:
Of course, we can always create the header ourselves:
The user agent string is of the format
Building headers
Now we have an array of additional HTTP Request headers in $headers . The HTTP protocol requires the “\r\n” line end sequence between header lines. So we set up our context options like this:
Sending Files
PHP Doesn’t support sending files over HTTP either. But this isn’t all that hard; we need to understand MIME encoding. If you every looked at the raw source of an email message, you’ve likely seen MIME coding in action. We need to have a boundary string to separate each part–in our case, each file and POST parameter. When we switch to sending content in MIME “multipart” format, even the POST parameters are formatted this way as well.
Here is the structure of a MIME body, with headers:
Notice the final line boundary is followed by two hyphens to indicate the end of the parts.
NOTE: It seems HTTP is cool with transferring binary files like this without Base64 encoding like we would need in an email message.
In code, we generate a unique boundary string ( ——-XXXXXXX doesn’t cut it). Then we build each line of the content, and finally join them together.
In this case, we set the Content-Type differently than previously. Don’t send both!
Then we set the HTTP context like this:
Note that a very large file payload could cause your memory usage to spike. There is no way to chunk out the data using this method.
Responses and Errors
file_get_contents() returns the body of the response after processing.
On an error, it returns FALSE. When testing for FALSE in PHP, remember to use the === or “three-qual” operator. Unfortunately, is also swallows the response data, so if a detailed error message is on the body of the page–which is a proper response–there is no way to see it.
To quiet the errors, call it with the special “@” PHP prefix. FALSE seems to be returned when there was no connection or response from the web server. For connection errors, you need to call error_get_last() after the operation.
The response headers are in a special local variable, $http_response_header . It is an array of the headers received, not parsed. They can be useful in debugging.
Additional context
The stream_context_create() takes a couple more useful parameters: ‘timeout’ (float) and ‘ignore_errors’ which still returns the content when an error is detected. Sometimes a useful error message is in that content.
Receiving Cookies
When a web server returns a cookie to be resent on subsequent request it will send a Set-Cookie response header for each cookie.
Since API’s don’t use cookie-based sessions, I won’t cover it here, but the Set-Cookie documentation shows the various directives to process one.
Receiving Files
Receiving files from a remote API request was out of the scope of this post, but is discussed here for completeness.
The Content-Disposition header is normally set to “inline” for standard pages and responses.
When a file is returned, it is set to “attachment.” For web browsers, this usually triggers a “Save as” dialog unless configured to store it in your default download folder. The API client would need to identify the attachment and save to to a pre-determined location.
Additionally, complex results can send “multipart” responses with multiple attachments. For this case, it is best to use a MIME parsing library.
HEAD Request
The get_headers($url,$format,$context) function makes a HEAD method request with returns only headers without a body. The $format argument should be zero to return a list of headers, or non-zero to return an associative array of header names to values.
Callbacks
PHP offers a request callback, when fires at each event in processing your request. Generally, you won’t need it, but it is great for tracking progress of receiving large files.
Call stream_context_set_params() passing a “callable” function with the signature matching stream_notification_callback().
Better explanation and examples are found on the stream_notification_callback() page.
A Simple HTTP Client
We can put all we know together to write a simple HTTP client:
Source here: http_request()
You should be able to get the parts you need from this example. I have not fully tested this code, so you may find edge cases that need to be fixed. Good luck!
Attribution
I compiled this from a dozen or so stack overflow answers from people who I wish I could credit, but neglected to save their names. Apologies and thanks to those PHP masters wherever you are!
Hmm, I just found a PHP extension http_request of the same name I use for this function. Sorry about any confusion.
Php как сделать post запрос
Одним из основных способов передачи данных веб-сайту является обработка форм. Формы представляют специальные элементы разметки HTML, которые содержат в себе различные элементы ввода — текстовые поля, кнопки и т.д. И с помощью данных форм мы можем ввести некоторые данные и отправить их на сервер. А сервер уже обрабатывает эти данные.
Создание форм состоит из следующих аспектов:
Создание элемента <form><form> в разметке HTML
Установка метода передачи данных. Чаще всего используются методы GET или POST
POST-запросы
Итак, создадим новую форму. Для этого определим новый файл form.php , в которое поместим следующее содержимое:
Атрибут action=»user.php» элемента form указывает, что данные формы будет обрабатывать скрипт user.php , который будет находиться с файлом form.php в одной папке. А атрибут method=»POST» указывает, что в качестве метода передачи данных будет применяться метод POST.
Теперь определим файл user.php , который будет иметь следующее содержание:
Для обработки запросов типа POST в PHP используется встроенная глобальная переменная $_POST . Она представляет ассоциативный массив данных, переданных с помощью метода POST. Используя ключи, мы можем получить отправленные значения. Ключами в этом массиве являются значения атрибутов name у полей ввода формы.
Например, так как атрибут name поля ввода возраста имеет значение age ( <input type=»number» name=»age» /> ), то в массиве $_POST значение этого поля будет представлять ключ «age»: $_POST[«age»]
И поскольку возможны ситуации, когда поле ввода будет не установлено, то в этом случае желательно перед обработкой данных проверять их наличие с помощью функции isset() . И если переменная установлена, то функция isset() возвратит значение true .
Теперь мы можем обратиться к скрипту form.php и ввести в форму какие-нибудь данные:
И по нажатию кнопки введенные данные методом POST будут отправлены скрипту user.php :
Необязательно отправлять данные формы другому скрипту, можно данные формы обработать в том же файле формы. Для этого изменим файл form.php следующим образом:
Поскольку в данном случае мы отправляем данные этому же скрипту — то есть по тому же адресу, то у элемента форма можно не устанавливать атрибут action .
Стоит отметить, что в принципе мы можем отправлять формы и запросом GET, в этом случае для получения тех же значений формы применяется массив $_GET , который был рассмотрен в прошлой теме:
Массивы $_POST и $_GET в PHP. Обработка форм
Формы — это часть языка HTML. Формы нужны для передачи данных от клиента на сервер. Чаще всего формы используются для регистрации пользователей, заполнения анкет, оформления заказа в интернет магазине, и так далее.
Через формы можно отправлять как простую текстовую информацию, так и файлы.
Большую часть времени программирования на PHP вы будете так или иначе работать с формами и данными из них.
HTML описывает то, из каких элементов состоит форма, и как она выглядит. Но без принимающей стороны, то есть сервера, который принимает эти данные и обрабатывает их нужным образом, создавать формы нет никакого смысла.
PHP содержит множество средств для работы с формами. Это позволяет очень просто решать типичные задачи, которые часто возникают в веб-программировании:
- Регистрация и аутентификация пользователя;
- Отправка комментариев на форумах и социальных сетях;
- Оформление заказов.
Практически любой современный сайт содержит как минимум несколько разных HTML-форм.
Отправка формы
Рассмотрим один типичный пример — форма обратной связи. Для связи пользователей с авторами сайта, как правило, используются формы обратной связи, где человек указывает имя, почту для обратной связи и текст своего сообщения.
Такая форма в HTML может выглядеть следующим образом:
Это очень простая форма, состоящая из трёх полей и одной кнопки отправки.
Почти весь приведённый код описывает внешний вид и содержание формы, но следует обратить внимание на два атрибута тега <form> , которые нужны для указания на способ обработки данных:
method — этот атрибут используется для определения метода HTTP, который будет использован для передачи данных на сервер. Вы уже знакомы с HTTP-методом GET, предписывающим серверу просто вернуть определённый документ.
Метод POST сообщает о намерении передать на сервер некоторую информацию, что, впрочем, не отменяет последующее получение контента.
action — содержит адрес PHP-скрипта, который должен обработать эту форму.
После нажатия на кнопку «отправить», браузер выполняет POST запрос со введёнными данными на адрес, указанный в атрибуте action.
Обработка формы
После отправки формы управление передаётся PHP-скрипту, который должен получить переданные данные, выполнить с ними какие-либо действия (например, сохранить в базе данных) и показать результат.
Результатом может быть какое-нибудь сообщение об успешном завершении операции, например, «ваши данные успешно отправлены».
Поэтому требуется в первую очередь научиться получать данные из формы в сценарии.
В PHP это делается легко — все данные из формы находятся в глобальном ассоциативном массиве $_POST . Этот массив всегда будет неявно присутствовать в сценарии, если он был загружен по методу POST.
Каждое поле из формы будет находиться в массиве, где ключом будет значение атрибута name, а значением содержимое поля. Например, чтобы вывести из формы всю информацию на экран, можно написать такой сценарий:
Функция isset служит для определения, существует ли переданная ей переменная. Так мы проверяем, что сценарий загружен методом POST, то есть была отправлена форма.
Как правило, после обработки формы в PHP, сценарий должен переадресовать пользователя на другую страницу. Это связано с тем, что если форма была отправлена через метод POST, то после обновления страницы данные будут отправлены ещё раз, а это, в большинстве случаев, нежелательное поведение.
Отправка файлов
Кроме текстовой информации, существует возможность отправлять на сервер файлы любых типов. Пример формы для загрузки файла:
Тут есть два важных отличия от первого примера:
- Добавился новый атрибут enctype, который всегда должен иметь значение multipart/form-data . Если его не будет, то файл не отправится.
- Сам файл загружается при помощи поля с типом file.
В PHP загруженный файл будет доступен в другом специальном массиве — $_FILES .
PHP автоматически сохраняет все загруженные файлы во временную папку на сервере. Но хранить там файлы нельзя, потому что эта директория периодически очищается, и ссылку на такой файл нельзя дать на сайте. Решение здесь только одно — переместить загруженный файл в другую папку. Перемещение файла всегда выполняют сразу после загрузки.
Для начала нужно убедиться, что в рабочей директории проекта существует папка для хранения загруженных файлов. Пусть она называется uploads .
Перемещение загруженного файла
Для перемещения файла нужно знать, где он находится сейчас, и адрес папки, в которую он будет переноситься.
С текущим адресом всё крайне просто — он уже находится в массиве $_FILES . Новый адрес файла, в свою очередь, состоит из пути к папке и имени файла. Так как папка uploads находится там же, где и текущий сценарий, получить путь к ней можно так: dirname(__FILE__ )`.
Код для перемещения файла в новую папку:
Функция move_uploaded_file() выполняет два действия:
- Проверяет, что файл действительно загружен через форму.
- Перемещает загруженный файл по новому адресу.
Валидация формы
Валидация формы — это проверка содержимого её полей. Задача такой проверки — убедиться, что необходимые поля заполнены, а значения в них соответствуют ожидаемому формату.
Так, например, при регистрации пользователя на сайте, он должен заполнить поля с адресом электронной почты и придумать себе пароль. Оба поля обязательны к заполнению, но значение из поля email также должно быть корректным email-адресом.
Помимо текстовых значений формы, можно проверять формат и размер загружаемых файлов.
Общий подход к валидации
При выполнения валидации любой формы порядок действий будет всегда одним:
Как отправить HTTP запрос методом POST на URL через PHP?
Действительно, за время, которое потратили на создание вопроса, Вы могли без проблем найти интересующую Вас информацию в любом поисковике.
Но раз вопрос уже задан, то должен быть и ответ(ы).
Собственно, @OnYourLips дал ссылку на хороший фреймворк, но если нет смысла тащить в проект/скрипт целый фреймворк ради одного запроса, к примеру, то логичнее воспользоваться упомянутым CURL. В Вашем случае сценарий использования CURL будет выглядеть примерно следующим образом: