How to do a POST request
This example shows how to do a simple POST request to another webserver by using a socket connection.
function post_request($url, $data, $referer='') { // Convert the data array into URL Parameters like a=b&foo=bar etc. $data = http_build_query($data); // parse the given URL $url = parse_url($url); if ($url['scheme'] != 'http') { die('Error: Only HTTP request are supported !'); } // extract host and path: $host = $url['host']; $path = $url['path']; // open a socket connection on port 80 - timeout: 30 sec $fp = fsockopen($host, 80, $errno, $errstr, 30); if ($fp){ // send the request headers: fputs($fp, "POST $path HTTP/1.1\r\n"); fputs($fp, "Host: $host\r\n"); if ($referer != '') fputs($fp, "Referer: $referer\r\n"); fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n"); fputs($fp, "Content-length: ". strlen($data) ."\r\n"); fputs($fp, "Connection: close\r\n\r\n"); fputs($fp, $data); $result = ''; while(!feof($fp)) { // receive the results of the request $result .= fgets($fp, 128); } } else { return array( 'status' => 'err', 'error' => "$errstr ($errno)" ); } // close the socket connection: fclose($fp); // split the result header from the content $result = explode("\r\n\r\n", $result, 2); $header = isset($result[0]) ? $result[0] : ''; $content = isset($result[1]) ? $result[1] : ''; // return as structured array: return array( 'status' => 'ok', 'header' => $header, 'content' => $content ); }
Author:
Jonas John
License:
Public Domain
Language:
PHP
Created:
08/05/2006
Updated:
03/23/2011
Tags:
http, network, connections
// Submit those variables to the server $post_data = array( 'test' => 'foobar', 'okay' => 'yes', 'number' => 2 ); // Send a request to example.com $result = post_request('http://www.example.com/', $post_data); if ($result['status'] == 'ok'){ // Print headers echo $result['header']; echo '<hr />'; // print the result of the whole request: echo $result['content']; } else { echo 'A error occured: ' . $result['error']; }
Sorry folks, comments have been deactivated for now due to the large amount of spam.
Please try to post your questions or problems on a related programming board, a suitable mailing list, a programming chat-room,
or use a QA website like stackoverflow because I'm usually too busy to answer any mails related
to my code snippets. Therefore please just mail me if you found a serious bug... Thank you!
Older comments:
What if i have 2 values and certain form name? is it possible?
fot example i have such form and want to change it for php request:
<form action="http://page.com/user/login" method="post" name="loginFormElement">
<div class="form-login">
<label>Username:</label>
<div class="input">
<input type="text" value="" id="name" name="username"/>
</div>
<label>
Pass:</label>
<div class="input">
<input type="password" value="" name="password"/>
</div>
<div>
<input type="submit" class="button btn-login" onclick="document.forms['loginFormElement'].submit();return false;" value="Login" />
</div>
</div>
</form>
so i have 2 values $_POST['username'], $_POST['password'] and have such submit-action:
document.forms['loginFormElement'].submit();return false;
is it possible to change it for php?
how does it looks like?
i will be grateful for example
function post_request($host, $path, $values, &$error = null)
{
$rs = '';
$data = http_build_query($values);
$size = strlen($data);
$fp = fsockopen($host,80, $errno, $errstr, 30);
if($fp) {
$request = "POST $path HTTP/1.1rn";
$request.= "Host: $hostrn";
$request.= "Content-type: application/x-www-form-urlencodedrn";
$request.= "Content-Length: ".$size."rn";
$request.= "Connection: Closernrn";
$request.= $data;
fwrite($fp, $request);
while(!feof($fp)) {
$rs .= fgets($fp, 128);
}
} else {
$error = "$errstr ($errno)";
}
fclose($fp);
list($header, $content) = explode("rnrn", $rs, 2);
return array('header' => $header, 'content' => $content);
}
I don't understand why some headers, uurl encoded are changed between the post and the phplist index page:
these are the value data send:
$data = array(
'makeconfirmed' => '1',
'htmlemail' => '1',
'list[2]' => 'signup',
'listname[2]' => 'Un Monde de Papier',
'subscribe' => 'yes',
'emailconfirm' => $_REQUEST['email'],
'email' => $_REQUEST['email'],
);
the post encoded:
makeconfirmed=1&htmlemail=1&list%5B2%5D=signup&listname%5B2%5D=Un+Monde+de+Papier&subscribe=yes&emailconfirm=zzz%40kk.de&email=zzz%40kk.de
finally the request content in index page from phplist
htmlemail => 1
list => Array
listname => Array
subscribe => yes
emailconfirm => zzz@kk.de
email => zzz@kk.de
the list[2] = signup
is transformed in list = Array
so it doesn't work,
thank you if you get something about that
This function works perfect, and is much easyer than all of yours...
Dont know ? but Isn't it?
function file_post_contents($url,$data) {
$url = parse_url($url);
if (!isset($url['port'])) {
if ($url['scheme'] == 'http') { $url['port']=80; }
elseif ($url['scheme'] == 'https') { $url['port']=443; }
}
$url['query']=isset($url['query'])?$url['query']:'';
$url['protocol']=$url['scheme'].'://';
$eol="rn";
$headers = "POST ".$url['protocol'].$url['host'].$url['path']." HTTP/1.0".$eol.
"Host: ".$url['host'].$eol.
"Referer: ".$url['protocol'].$url['host'].$url['path'].$eol.
"Content-Type: application/x-www-form-urlencoded".$eol.
"Content-Length: ".strlen($data).$eol.
$eol.$data;
$fp = fsockopen($url['host'], $url['port'], $errno, $errstr, 30);
if($fp) {
fputs($fp, $headers);
$result = '';
while(!feof($fp)) { $result .= fgets($fp, 128); }
fclose($fp);
// if (!$headers)
{
//removes headers
$pattern="/^.*rnrn/s";
$result=preg_replace($pattern,'',$result);
}
return $result;
}
}
Thanks !!
There is a small thing to add :
urlencode() for the key and the value. Because, if you want to send data with special characters, it will fail.
while(list($n,$v) = each($_data))
{
$n = urlencode($n);
$v = urlencode($v);
$data[] = "$n=$v";
}
Cheers !
I should also note that the 1000 iterations colin suggested for the loop catch was not allowing the application to completely pull down the data for really large files. I increased this number quite significantly to allow large files to download using this method.
Thanks again for the code snippet!
Transfer-Encoding: chunked
Further research indicates that the format I am seeing with linebreak, size, linebreak every once in a while throughout the file is based on the chunked transfer-encoding type. I'm going to continue to do research, but if anyone else has thoughts on the matter please post them here.
When I run the post request in a standard HTML form, I don't see this at the beginning and end of the content.
I can strip out those extraneous lines after the content is returned, but I was just curious why that was showing up and if I should tweak the code.
PD: Im tryng to request a .php page not a .html
Also, can this be done with Ajax? :D
Thanks
function PostRequest($url, $data)
{
// Se verifican los datos.
if (!is_array($data)) throw new Exception('Los datos deben pasarse como un array.');
// Se convierte la data en string (a=1&b=2).
$data_query = http_build_query($data);
// Se extrae la info de la url.
$url_parsed = parse_url($url);
// Se verifica que la petición hecha sea del tipo HTTP.
if ($url_parsed['scheme'] != 'http') throw new Exception('Solo se soportan peticiones HTTP.');
// Se abre una conexión vía socket.
$fp = @fsockopen($url_parsed['host'], 80);
if ($fp === FALSE) throw new Exception("No se pudo abrir la conexión con {$url_parsed['host']}.");
// Se hace la petición.
fputs($fp, "POST {$url_parsed['path']} HTTP/1.1rn");
fputs($fp, "Host: {$url_parsed['host']}rn");
fputs($fp, "Referer: $urlrn");
fputs($fp, "Content-type: application/x-www-form-urlencodedrn");
fputs($fp, "Content-length: ". strlen($data_query) ."rn");
fputs($fp, "Connection: closernrn");
fputs($fp, $data_query);
// Se almacena el resultado en una variable.
$result = '';
while(!feof($fp)) $result.= fgets($fp, 128);
// Se cierra la conexión.
fclose($fp);
// Se retorna el resultado.
return $result;
}
$data = array('nombre' => 'Pancho','apellido' => 'Villa');
$result = PostRequest('http://localhost/www/labs/test.php', $data);
function PostRequest($url, $referer, $_data) {
// convert variables array to string:
$data = array();
while(list($n,$v) = each($_data)){
$data[] = "$n=$v";
}
$data = implode('&', $data);
// format --> test1=a&test2=b etc.
// parse the given URL
$url = parse_url($url);
// extract host and path:
$host = $url['host'];
$path = $url['path'];
// open a socket connection on port 80
$fp = fsockopen("ssl://".$host, 443);
// send the request headers:
fputs($fp, "POST $path HTTP/1.1rn");
fputs($fp, "Host: $hostrn");
fputs($fp, "Referer: $refererrn");
fputs($fp, "Content-type: application/x-www-form-urlencodedrn");
fputs($fp, "Content-length: ". strlen($data) ."rn");
fputs($fp, "Connection: closernrn");
fputs($fp, $data);
$result = '';
$safe=0;
while(!feof($fp)&&$safe<1000) {
// receive the results of the request
$result .= fgets($fp, 128);
$safe++;
}
// close the socket connection:
fclose($fp);
// split the result header from the content
$result = explode("rnrn", $result, 2);
$header = isset($result[0]) ? $result[0] : '';
$content = isset($result[1]) ? $result[1] : '';
// return as array:
return array($header, $content);
}
/*
** The example:
*/
// submit these variables to the server:
$data = array(
'var'=>'value'
);
// send a request to example.com (referer = jonasjohn.de)
list($header, $content) = PostRequest(
"https://www.example.com/path/",
"http://www.myhost.com",
$data
);
// print the result of the whole request:
print $content;
while(!feof($fp)) {
// receive the results of the request
$result .= fgets($fp, 128);
}
I found during tests (I was trying to make it SSL compatible) that it failed to work (my fault, no doubt!), which normally wouldn't matter but this loop just didn't stop and completely filled my website's disk space with the amount of output it was shoving into the error_log and didn't stop even when the file was deleted! Result - downtime!
It might be worth putting in a counter to only allow it to loop a certain number of times before dying, at least until you're sure you've got it right!
// convert variables array to string:
$data = array();
while(list($n,$v) = each($_data)){
$data[] = "$n=$v";
}
$data = implode('&', $data);
// format --> test1=a&test2=b etc.
// parse the given URL
$url = parse_url($url);
if ($url['scheme'] != 'http') {
die('Only HTTP request are supported !');
}
// extract host and path:
$host = $url['host'];
$path = $url['path'];
$query = $url['query'];
// open a socket connection on port 80
$fp = fsockopen($host, 80);
echo "path: $path?$query\r\n";
// send the request headers:
fputs($fp, "POST $path?$query HTTP/1.1\r\n");
fputs($fp, "Host: $host\r\n");
fputs($fp, "Referer: $referer\r\n");
fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
fputs($fp, "Content-length: ". strlen($data) ."\r\n");
fputs($fp, "Connection: close\r\n\r\n");
fputs($fp, $data);
$result = '';
while(!feof($fp)) {
// receive the results of the request
$result .= fgets($fp, 128);
}
// close the socket connection:
fclose($fp);
// split the result header from the content
$result = explode("\r\n\r\n", $result, 2);
$header = isset($result[0]) ? $result[0] : '';
$content = isset($result[1]) ? $result[1] : '';
// return as array:
return array($header, $content);
}