Главная | Форум | Статьи | Фaйлы| Картинки WoW | Профиль | Регистрация | Вход

[ Новые сообщения · Правила форума · Поиск · RSS ]

WoW-Info — информационный World of Warcraft портал

Передача данных из скрипта методом POST - Форум

  • Сторінка 1 з 1
  • 1
Передача данных из скрипта методом POST
DiyvolДата: Середа, 08.12.2010, 02:40 | Сообщение # 1



Diyvol
ЗлОй-АйТИшник
Центурион
Группа: Best of the Best user Wow-info
Сообщений: 356

Замечания:

Оффлайн
В этой статье я расскажу как отправлять данные из php скрипта методом POST так, как это делает обычная html форма. Необходимость в этом может возникнуть для отправки данных как на свой сайт, так и на чужой. В примере используются стандартные функции php.

Я покажу два варианта отправки данных:
1. Content-Type: application/x-www-form-urlencoded - возможна отправка значений переменных
2. Content-type: multipart/form-data - можно отправлять и значения переменных и файлы
Первый вариант, отправка только переменных с помощью application/x-www-form-urlencoded.

Чтобы отправить переменные методом POST, нужно установить соединение с сервером и отправить в открытое соединение подобный текст:

Code
POST /file.php HTTP/1.1\r\n  
Host: test.ru\r\n
Referer: test.ru\r\n
User-Agent: Opera\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Content-Length: 20\r\n
\r\n
var=test&var2=privet\r\n
\r\n

Как видите, принцип очень простой. Заголовки и тело запроса. В данном случае в теле находятся как раз переменные, которые передаются методом POST (var=test&var2=privet), внешне эти переменные выглядят как при обычной передаче методом GET по ссылке.
А теперь рассмотрим этот пример более подробно и сразу переложим его на PHP.

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

Code
$data="var=test&var2=privet";

В данном примере используются две переменные(var и var2), первая имеет значение "test" вторая "privet". Можете продолжать список переменных, разделяя их символом `&`.

Теперь нужно сформировать данные для отправки на сервер. Создаем еще одну текстовую переменную $out.

$out = "POST /file.php HTTP/1.1\n"; // здесь указываем какой файл запрашиваем и какой метод передачи данных будет использован. В данном примере вызывается файл file.php. Здесь нужно указывать путь до файла от корневой директории сайта (/path/file.php)

$out .= "Host: test.ru\n"; // тут указывается хост с которым будем соединяться (адрес вашего сайта)
$out .= "Referer: test.ru/\n"; // откуда идет отправка данных
$out .= "User-Agent: Opera\n"; // каким браузером притвориться
$out .= "Content-Type: application/x-www-form-urlencoded\n"; // это тип отправляемых данных из формы. Такой тип данных стоит у форм по умолчанию.

$out .= "Content-Length: ".strlen($data)."\n\n"; // здесь указывается размер передаваемых данных....
$out .= $data."\n\n"; // создаем полный набор данных для отправки.

Строка $out готова для отправки данных на сайт.
Остается только открыть соединение с сервером и кинуть ему эти данные.

Делается это так:

Code
$fp = fsockopen("test.ru", 80, $errno, $errstr, 10);

В качестве параметров этой функции указываем хост для соединения(test.ru).
Затем порт (80), как правило другой номер порта используется редко.
$errno и $errstr получают установки, указывающие фактический уровень системной ошибки, в случае ошибки соединения, особой необходимости в них нет.
И последняя цифра (10) - это таймаут соединения, то есть сколько секунд будет ждать скрипт установки соединения.

Итак, соединение с хостом открыто.
Передаем открытому соединению созданные данные:

Code
fputs($fp, $out);

Вот и все... Осталось закрыть соединение:

Code
fclose($fp);

Переменные
var=test
и
var2=privet

улетели по адресу http://test.ru/file.php методом POST, так же, как это сделала бы html форма.

А вот и полный листинг:

Code
<?  
$data="var=test&var2=privet";  
$fp = fsockopen("test.ru", 80, $errno, $errstr, 10);  
$out = "POST /file.php HTTP/1.1\n";  
$out .= "Host: test.ru\n";  
$out .= "Referer: test.ru/\n";  
$out .= "User-Agent: Opera\n";  
$out .= "Content-Type: application/x-www-form-urlencoded\n";  
$out .= "Content-Length: ".strlen($data)."\n\n";  
$out .= $data."\n\n";  
fputs($fp, $out);  
fclose($fp);  
?>

Это был самый простой пример, в нем я показал только принцип отправки данных.
Сейчас расширю данный пример, для демонстрации отправки данных методом POST и GET одновременно и получения ответа от сервера.

Code
<?  
$url = "http://test.ru/patch/file.php?var=23&var2=54"; // это адрес, по которому скрипт передаст данные методом POST. Как видно, здесь указаны переменные, которые будут переданы через GET  
$parse_url = parse_url($url); // при помощи этой функции разбиваем адрес на массив, который будет содержать хост, путь и список переменных.  
$path = $parse_url["path"]; // путь до файла(/patch/file.php)  
if($parse_url["query"]) // если есть список параметров  
$path .= "?" . $parse_url["query"]; // добавляем к пути до файла список переменных(?var=23&var2=54)  
$host= $parse_url["host"]; // тут получаем хост (test.ru)  
$data = "var3=test&var4=".urlencode("еще тест"); // а вот тут создаем список переменных с параметрами. Эти данные будут переданы через POST. Все значения переменных обязательно нужно кодировать urlencode ("еще тест")  

$fp = fsockopen($host, 80, $errno, $errstr, 10);  
if ($fp)  
{  
   $out = "POST ".$path." HTTP/1.1\n";  
   $out .= "Host: ".$host."\n";  
   $out .= "Referer: ".$url."/\n";  
   $out .= "User-Agent: Opera\n";  
   $out .= "Content-Type: application/x-www-form-urlencoded\n";  
   $out .= "Content-Length: ".strlen($data)."\n\n";  
   $out .= $data."\n\n";  

   fputs($fp, $out); // отправляем данные  

   // после отправки данных можно получить ответ сервера и прочитать информацию выданную файлом, в который отправили данные...  
   // читаем данные построчно и выводим их. Конечно, эти данные можно использовать по своему усмотрению.  
   while($gets=fgets($fp,2048))  
   {  
     print $gets;  
   }  
   fclose($fp);  
}  
?>  

В этом примере файл file.php получил переменные:
Code
GET var="23" и var2="54"
POST var3="test" и var4="еще тест"

Хочу обратить ваше внимание, данные передаваемые через POST или GET всегда передаются строкой(string), независимо от того, через форму они передаются или через скрипт.
Поэтому передавая число, помните, что в скрипт оно попадет как string.
Второй вариант отправки данных, с помощью multipart/form-data для отправки файлов.
Этот варинт отправки данных позволяет отправлять не только значения переменных, но и файлы.
Принцип отправки такой, соединяемся с сервером и отправляем в открытый поток подобный текст

Code

POST /file.php HTTP/1.0\r\n
Host: test.ru\r\n
Referer: test.ru\r\n
Content-type: multipart/form-data, boundary=ccf8111910\r\n
Content-length: 333\r\n
\r\n
--ccf8111910\r\n
Content-Disposition: form-data; name="mass[qwe]"\r\n
\r\n
значение переменной mass[qwe]\r\n
--ccf8111910\r\n
Content-Disposition: form-data; name="var"\r\n
\r\n
значение переменной var\r\n
--ccf8111910\r\n
Content-Disposition: form-data; name="var_file"; filename="a.txt"\r\n
Content-Type: text/plain\r\n
\r\n
содержимое файла\r\n
--ccf8111910--\r\n

В данном примере передаются переменные mass[qwe] и var, а так же текстовый файл a.txt, имеющий имя в форме var_file

В первую очередь обратите внимание на заголовок Content-type: multipart/form-data, boundary=ccf8111910. Именно multipart/form-data дает право пересылать не только текстовые значения переменных, но и файлы.
Так же в этой строке указывается разделитель данных boundary=... Это любой набор цифр или символов и будет служить для отделения значений друг от друга. Значение boundary должно быть уникальным в пределах пересылаемой информации, то есть таких символов не должно встречаться в пересылаемых файлах или переменных.
Все остальные заголовки точно такие же, как при отправке первым методом описаным в начале статьи.

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

Code
--ccf8111910  
Content-Disposition: form-data; name="mass[qwe]"

значение переменной

Так пересылается одна переменная с именем mass[qwe], в даном случае даже массив.
Далее можно перечислять таким же способом переменные и файлы, отделяя их друг от друга разделителями.

Для отправки файла нужно добавить еще тип и имя файла

Code
--ccf8111910
Content-Disposition: form-data; name="var_file"; filename="a.txt"
Content-Type: text/plain

содержимое файла

В конце перечисления файлов и переменных нужно закрыть разделитель, добавив в конце разделителя "--"
--ccf8111910--

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

Сейчас покажу как этот пример реализовать на php

Code
<?php
$host="test.ru"; // с каким хостом соединяемся
$file_send="a.txt"; // файл который нужно отправить, можно указать абсолютный или относительный путь до файла
$boundary = md5(rand(0,32000)); // создаем разделитель, md5 на основе случайного числа
$filesize = filesize($file_send); // получаем размер пересылаемого файла. если будете пересылать не файл, а текст, то здесь нужно посчитать количество символов текста

// создаем код для отправки двух переменных
$data= "--".$boundary."\r\n"; // разделитель
$data.="Content-Disposition: form-data; name=\"mass[qwe]\"\r\n\r\n"; // имя перемнной
$data.="значение переменной mass[qwe]\r\n"; // значение переменной
$data.="--".$boundary."\r\n"; // разделитель, начало следующего блока данных
$data.="Content-Disposition: form-data; name=\"var\"\r\n\r\n"; // имя следующей переменной
$data.="значение переменной var\r\n"; // ее значение

// создаем заголовки файла
$head_file="--".$boundary."\r\n"; // разделитель
$head_file.="Content-Disposition: form-data; name=\"var_file\"; filename=\"".$file_send."\"\r\n"; // имя переменной с файлом и имя пересылаемого файла
$head_file.="Content-Type: ".mime_content_type($file_send)."\r\n\r\n"; // mime-type файла. данная функция определения типа файла может не работать на многих серверах, поэтому ищите другой способ указания типа файла, можете вручную прописывать тип, например application/octet-stream

// считаем размер данных. размер нужно считать всего, что идет после основных заголовков, вместе с разделителями и всем остальным
// складываем данные с переменными, заголовки файла, размер файла который будет вставлен позже и плюс завершающий разделитель
$contentlength = strlen($data) + strlen($head_file) + $filesize + strlen("--".$boundary."--\r\n");

// теперь создаем основные заголовки, сам запрос
$headers = "POST /test/file.php HTTP/1.0\r\n"; // путь до скрипта, который принимает данные
$headers.="Host: ".$host."\r\n";
$headers.="Referer: ".$host."\r\n";
$headers.="User-Agent: Opera\r\n";
$headers.="Content-type: multipart/form-data, boundary=".$boundary."\r\n"; // тип передаваемых данных и разделитель
$headers.="Content-length: ".$contentlength."\r\n\r\n";  // размер всех данных

if(!$fp = fsockopen($host, 80))  exit; // открываем соединение
fputs($fp, $headers); // посылаем основные заголовки в открытый поток
fputs($fp, $data); // посылаем переменные
fputs($fp, $head_file); // посылаем заголовки файла и ниже отправим сам файл

$fp2 = fopen($file_send, "rb"); // открываем файл, который будет отправлять
while(!feof($fp2)) // начинаем читать этот файл
{
     $as=fgets($fp2, 2048); // читаем кусок файла
     fputs($fp, $as); // посылаем этот кусок файла в открытый поток
}
fclose($fp2); // закрываем файл, который прочитали и отправили в поток

fputs($fp, "\r\n--".$boundary."--\r\n"); // завершаем, отправляем закрывающий разделитель, указывающий на конец даных

// вывод ответа от скрипта
while($gets=fgets($fp,2048))
{
     print $gets;
}

fclose($fp); // закрыли поток.
?>  

Вот так можно отправить файл методом POST с помощью php.

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




Веб-дизайнер.
Работа, учеба и тренажерный зал. Жизнь это когда ты рад тому, что ты устал. Я не вижу смысла в жизни наркоманов. Наркотик в роли пастуха для всех этих баранов. Я иду вперед и не думаю сворачивать.
 
  • Сторінка 1 з 1
  • 1
Пошук:

Новые сообщения в темах
Сдам в аренду сервер и хостинг · (Хост Предложения)
Автор: redlaine
Последнее сообщение в 23:53
хаха :D · (Приколы)
Автор: [N1ke]Medved
Последнее сообщение в 18:40
Autobattle - новый боевой бот ... · (Боты для WoW)
Автор: terrikon
Последнее сообщение в 18:39
PvE руководство для Чернокнижн... · (Чернокнижник)
Автор: Darkensand
Последнее сообщение в 18:38
Пустой свиток (Часть 11) · (Истории WoW)
Автор: R_a_Z_o_R
Последнее сообщение в 18:37
Друиды в Катаклизме: Официальн... · (Друид)
Автор: Darkensand
Последнее сообщение в 18:37
[Баг 3.3.5] Фарм ледяных бадже... · (Читы для WoW)
Автор: Darkensand
Последнее сообщение в 18:35
FarmBot (Бот для фарма руды и ... · (Боты для WoW)
Автор: homma
Последнее сообщение в 18:34
Почему мы сражаемся: ролевая и... · (Воин)
Автор: Darkensand
Последнее сообщение в 18:34
Книги по Wold of Warcraft · (Истории WoW)
Автор: R_a_Z_o_R
Последнее сообщение в 18:33
Маг огня в Cataclysm · (Маг)
Автор: Darkensand
Последнее сообщение в 18:33
Как начать играть в World of W... · (Полезно знать)
Автор: Belkmondesh
Последнее сообщение в 18:32
Характеризация профессий · (Профессии)
Автор: Darkensand
Последнее сообщение в 18:31
Что значит для арканов бета те... · (Маг)
Автор: Darkensand
Последнее сообщение в 18:31

Контакты Контакты Copyright WoW-Info — World of Warcraft портал © 2025 | Условия и правила использования ресурса | Реклама / Услуги
WoW-Info портал.World of Warcraft портал — готовые сервера, сайты, картинки, аддоны, патчи, читы, баги, mangos, ArcEmu, TrinityCore, Warcraft 3, новости, Cataclysm...
Яндекс.Метрика Хостинг від uCoz