Отправка данных из скрипта методом POST

Пусть у нас есть простая форма, состоящая из двух полей и кнопки для отправки данных:

<form action="action.php" method="post">
Имя: <input name="name" type="text" /><br/>
Пароль: <input name="password" type="password" /><br/>
<input name="submit" type="submit" value="Отправить" />
</form>

Обработчик формы action.php выводит в браузер текст, введенный в поля формы:

<?php
echo 'Имя: '.$_POST['name'].'<br/>';
echo 'Пароль: '.$_POST['password'].'<br/>';
?>

HTML форма позволяет пользователю сформировать POST-запрос, который затем отсылается браузером. Мы сформируем такой запрос скриптом.

Метод POST, в отличие от метода GET, посылает данные не в строке запроса, а в области данных, после заголовков. Передача данных аналогична методу GET: группы name=value объединяются при помощи амперсанда (&):

name=Евгений&password=qwerty

Кроме того, необходимо учитывать, что данные передаются в текстовом виде, поэтому все национальные символы следует подвергать кодированию при помощи функции urlencode.

Отправка данных методом POST через сокеты

<?php
$hostname = 'localhost';
$path = '/handler/action.php';
$content = '';
// Устанавливаем соединение с сервером $hostname
$fp = fsockopen($hostname, 80, $errno, $errstr, 30);
// Проверяем успешность установки соединения
if (!$fp) die('<p>'.$errstr.' ('.$errno.')</p>');

// Данные HTTP-запроса
$data = 'name='.urlencode('Евгений').'&password='.urlencode('qwerty');
// Заголовок HTTP-запроса
$headers = 'POST '.$path." HTTP/1.1\r\n";
$headers .= 'Host: '.$hostname."\r\n";
$headers .= "Content-type: application/x-www-form-urlencoded\r\n";
$headers .= 'Content-Length: '.strlen($data)."\r\n\r\n";
// Отправляем HTTP-запрос серверу
fwrite($fp, $headers.$data);
// Получаем ответ
while ( !feof($fp) ) $content .= fgets($fp, 1024);
// Закрываем соединение
fclose($fp);
// Выводим ответ в браузер 
echo $content;
?>

Результат работы скрипта выглядит примерно так

HTTP/1.1 200 OK
Date: Sat, 28 Jun 2008 07:53:19 GMT
Server: Apache/2.0.55 (Win32) PHP/5.2.1
X-Powered-By: PHP/5.2.1
Content-Length: 42
Content-Type: text/html

Имя - Евгений<br/>
Пароль - qwerty<br/>

Загрузка POST-данных с использованием CURL

Помимо сокетов, обеспечивающих низкоуровневое обращение к серверу, PHP располагает специальным расширением CURL (Client URL Library).

<?php
// Задаем адрес удаленного сервера
$curl = curl_init("http://localhost/handler/action.php");
// Передача данных осуществляется методом POST
curl_setopt($curl, CURLOPT_POST, 1);
// Задаем POST-данные
$data = 'name=Евгений&password=qwerty';
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
// Выполняем запрос и выводим ответ в браузер
curl_exec($curl);
// Закрываем CURL соединение
curl_close($curl);
?>

С помощью функции curl_init() задается адрес удаленного сервера и путь к файлу на нем. В отличие от функции fsockopen(), необходимо задавать адрес полностью, включая префикс http://, т.е. расширение CURL позволяет работать с несколькими видами протоколов (HTTP, HTTPS, FTP). Если соединение с указанным сервером происходит успешно, функция curl_init() возвращает дескриптор соединения, который используется во всех остальных функциях библиотеки.

Для того, чтобы сообщить CURL о том, что данные будут передаваться методом POST, необходимо задать параметр CURLOPT_POST. POST-данные устанавливаются при помощи параметра CURLOPT_POSTFIELDS.

По умолчанию библиотека удаляет HTTP-заголовки, возвращаемые сервером. Однако CURL можно настроить на выдачу заголовков, если установить при помощи функции curl_setopt() ненулевое значение параметра CURLOPT_HEADER.

P.S. Из-за ошибки библиотеки сокетов протокол HTTP 1.1 под Windows работает медленно. При работе скрипта использующего сокеты под управлением этой ОС, лучше использовать версию HTTP 1.0.

Ссылки по теме:

Комментариев: 4

  1. Владислав:

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

    тестирую все на локальной машине стоит денвер, но в сети есть почтовый сервер его адрес я и указываю, так вот если не вписывать имя и пароль в броузере выходит окошко авторизации на почтовый сервер, а если написать имя и пароль то идет по неправильному адресу, денвер вот что выдает - Вы ошиблись при наборе URL в браузере. Вероятнее всего, сервер пытается найти файл Z:/home/mysait.ru/www/WorldClient.dll, которого не существует. Не подскажите что я неправильно делаю?

  2. admin:

    Владислав, я ничего не понял из Ваших объяснений. В заметке рассматривается способ отправки данных формы с помощью скрипта. Т.е. данные формы формирует не браузер на основе заполненных пользователем полей, как это бывает обычно, а скрипт. Скрипт, принимающий данные формы, должен как-то обработать полученный массив $_POST. По вопросам настройки Денвера лучше спросить на форуме Дмитрия Котерова. А по поводу почтового сервера - вообще загадка…

  3. Вацлав:

    Content вывел это:
    POST w2.php HTTP/1.1 Host: localhost Content-type: application/x-www-form-urlencoded Content-Length: 42 ?name=%C5%E2%E3%E5%ED%E8%E9&password=qwertyHTTP/1.1 400 Bad Request Date: Sun, 01 Feb 2009 11:01:41 GMT Server: Apache/2.2.4 (Win32) mod_ssl/2.2.4 OpenSSL/0.9.8d PHP/5.2.4 Content-Length: 338 Connection: close Content-Type: text/html; charset=iso-8859-1
    Bad Request

    Your browser sent a request that this server could not understand.
    Apache/2.2.4 (Win32) mod_ssl/2.2.4 OpenSSL/0.9.8d PHP/5.2.4 Server at localhost Port 80

  4. admin:

    Вацлав, 400 Bad Request означает, что сервер обнаружил в запросе клиента синтаксическую ошибку. Об этом и сообщает сервер: Your browser sent a request that this server could not understand - ваш браузер отправил запрос, который (этот) сервер не понимает.
    Меня смущает вот эта строка
    Content-Type: text/html; charset=iso-8859-1
    В обработчике данных формы action.php надо бы указать кодировку

    <?php
    header("Content-Type: text/html;charset=windows-1251");
    echo 'Имя: '.$_POST['name'].'<br/>';
    echo 'Пароль: '.$_POST['password'].'<br/>';
    ?>

    Еще один момент: необходимо указать кодировку данных формы, которая будет использоваться скриптом-обработчиком:

    <form action="action" method="post" accept-charset="windows-1251">

    Если атрибут accept-charset отсутствует, браузер отправит данные формы в кодировке, указанной в meta-теге страницы формы

    <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">

    Когда мы формируем POST-данные скриптом, мы должны отправить этот заголовок сами:

    // Заголовки HTTP-запроса
    $headers = 'POST '.$path." HTTP/1.1\r\n";
    $headers .= 'Host: '.$hostname."\r\n";
    $headers .= "Content-type: application/x-www-form-urlencoded\r\n";
    $headers .= "Accept-Charset: windows-1251\r\n";
    $headers .= 'Content-Length: '.strlen($data)."\r\n\r\n";

Оставьте свой отзыв