Отправка данных из скрипта методом POST
Пусть у нас есть простая форма, состоящая из двух полей и кнопки для отправки данных:
Имя: <input name="name" type="text" /><br/>
Пароль: <input name="password" type="password" /><br/>
<input name="submit" type="submit" value="Отправить" />
</form>
Обработчик формы action.php выводит в браузер текст, введенный в поля формы:
echo 'Имя: '.$_POST['name'].'<br/>';
echo 'Пароль: '.$_POST['password'].'<br/>';
?>
HTML форма позволяет пользователю сформировать POST-запрос, который затем отсылается браузером. Мы сформируем такой запрос скриптом.
Метод POST, в отличие от метода GET, посылает данные не в строке запроса, а в области данных, после заголовков. Передача данных аналогична методу GET: группы name=value объединяются при помощи амперсанда (&):
Кроме того, необходимо учитывать, что данные передаются в текстовом виде, поэтому все национальные символы следует подвергать кодированию при помощи функции urlencode.
Отправка данных методом POST через сокеты
$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;
?>
Результат работы скрипта выглядит примерно так
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).
// Задаем адрес удаленного сервера
$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.
Ссылки по теме:
Владислав:
у меня вот возник вопрос пожалуйста не обессудьте. Вот делаю так как у вас написано
тестирую все на локальной машине стоит денвер, но в сети есть почтовый сервер его адрес я и указываю, так вот если не вписывать имя и пароль в броузере выходит окошко авторизации на почтовый сервер, а если написать имя и пароль то идет по неправильному адресу, денвер вот что выдает - Вы ошиблись при наборе URL в браузере. Вероятнее всего, сервер пытается найти файл Z:/home/mysait.ru/www/WorldClient.dll, которого не существует. Не подскажите что я неправильно делаю?
25 Декабрь 2008, 4:30admin:
Владислав, я ничего не понял из Ваших объяснений. В заметке рассматривается способ отправки данных формы с помощью скрипта. Т.е. данные формы формирует не браузер на основе заполненных пользователем полей, как это бывает обычно, а скрипт. Скрипт, принимающий данные формы, должен как-то обработать полученный массив $_POST. По вопросам настройки Денвера лучше спросить на форуме Дмитрия Котерова. А по поводу почтового сервера - вообще загадка…
25 Декабрь 2008, 11:38Вацлав:
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.
1 Февраль 2009, 15:05Apache/2.2.4 (Win32) mod_ssl/2.2.4 OpenSSL/0.9.8d PHP/5.2.4 Server at localhost Port 80
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 надо бы указать кодировку
header("Content-Type: text/html;charset=windows-1251");
echo 'Имя: '.$_POST['name'].'<br/>';
echo 'Пароль: '.$_POST['password'].'<br/>';
?>
Еще один момент: необходимо указать кодировку данных формы, которая будет использоваться скриптом-обработчиком:
Если атрибут accept-charset отсутствует, браузер отправит данные формы в кодировке, указанной в meta-теге страницы формы
Когда мы формируем POST-данные скриптом, мы должны отправить этот заголовок сами:
$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";