HTTP POST from PHP, without cURL
I don't think we do a very good job of evangelizing some of the nice things that the PHP streams layer does in the PHP manual, or even in general. At least, every time I search for the code snippet that allows you to do an HTTP POST request, I don't find it in the manual and resort to reading the source. (You can find it if you search for "HTTP wrapper" in the online documentation, but that's not really what you think you're searching for when you're looking).
So, here's an example of how to send a POST request with straight up PHP, no cURL:
<?php function do_post_request($url, $data, $optional_headers = null) { $params = array('http' => array( 'method' => 'POST', 'content' => $data )); if ($optional_headers !== null) { $params['http']['header'] = $optional_headers; } $ctx = stream_context_create($params); $fp = @fopen($url, 'rb', false, $ctx); if (!$fp) { throw new Exception("Problem with $url, $php_errormsg"); } $response = @stream_get_contents($fp); if ($response === false) { throw new Exception("Problem reading data from $url, $php_errormsg"); } return $response; }
$optional_headers is a string containing additional HTTP headers that you would like to send in your request.
PHP's HTTP wrapper will automatically fill out the Content-Length header based on the length of the $data that you pass in. It will also automatically set the Content-Type to application/x-www-form-urlencoded if you don't specify one in the $optional_headers.
I find this very handy; I don't need to code in redirection logic, HTTP auth handling, user agent setting and so on; they are handled for me by PHP.
You may also want to look into http_build_query() which is a convenience function that allows you to assemble query/post parameters from a PHP variable, applying appropriate escaping.
Kudos to Sara Golemon for both of these things. You can find more documentation on the HTTP wrapper options in the HTTP and HTTPS page in the PHP manual.
Would you like to work
with me?
I have positions open for server/infrastructure software development (C) and QA.

Sending binary data
Great code! But was wondering, how do I send binary data, such as an image?
Re: POST example on php.net
Thank Roland!
This script works quite well, and is avoids the memory leak issue.
Bruno
Thanks!
Thanks for this script!
I used it along with a few hundred lines of test data in a script to test a form that I built. The script worked great!!!
Simplifying
You could further simplify the code by file file_get_contents() rather then fopen, (get data) fclose.
I get errors?
Parse error: parse error, unexpected T_NEW in /home/web_dev/www/passgomedia.com/HOHO.php on line 17
??
cool!
thanks dude, that code really got me on to the right track, creating a XML-RPC compilant blog autopinger!
Alternative to stream_get_contents?
I'm stuck on PHP 4.3 so unfortunately I'm not able to get this working because stream_get_contents is PHP 5.
Is there an alternative I can use? I tried fpassthru() and it did not seem to work right.
PHP4 Alternative
A PHP4 alternative (if it exists) would be really nice!
A PHP 4 alternative
I wrote a PHP 4 alternative which you can see here:
http://www.enyem.com/wiki/index.php...T_request_(PHP)
Cool app
<a href="http://madhuri-dixit.110mb.com">Madhuri Dixit</a> likes this cool tutorial. Madhuri was previously using cURL. Now Dixit will do it with vanilla PHP
$data
I don't understand what we have to put into $data, I tried some requests like:
$data = "name1=info1&name2=info2$name3=info3";
But it doesn't work... what do we have to do?
$data and redirect
Hi,
Same as Jack, I'm not sure what to put in $data, is it just an array or http_build_query()?
Another question, will the function redirect the page to new url?
Hi
Hey Wez, are you the dr. Evil from http://www.hatebook.org?
$data
Try this for the data:
$data = array ('username' => $username, 'first_name' => $first_name, 'last_name' = $last_name);
$data = http_build_query($data);
HTTPS
Hey...
Could someone please help me with HTTPS POST request?
What changes do I need to make to change a request from HTTP to HTTPS?
Content-Type
Hi,
I am using the script to try and interact with the Google Calendar API which requires the content type to be set as "application/atom+xml".
I have used the option headers parameter to try and do this, but the response coming back from Google is claiming the Content-Type is "application/x-www-form-urlencoded".
How should I be adding the information to the headers parameter correctly? I have tried using an array ($Headers = Array('Content-Type'=> 'application/atom+xml');) and also just entering the string "Content-Type: application/atom+xml" with no luck.
Any ideas where I could be going wrong?
restrieving the returned data?
Hi,
Awesome function... just one thing... may be a dumb question but how do I retrieve the response as a variable to work with.
ie. (This is just the end of my code)
The data that I'm requesting is returning fine and always contains a 'Status' value, which you can see I'm trying to get hold of in the above code. Above I'm trying '$response' but it's not working.
If you can see what I'm trying to explain, anyone have any help?
Thanks
HTTPS
The same as Sumedh Inamdar, will HTTPS work too?
HTTP retriever library
Here is a library that is working using php4 HTTP POST and GET.
sample code included.
Tested, OK.
<a href="http://www.phpclasses.org/browse/package/3105.html" title="HTTP retriever class">http://www.phpclasses.org/browse/package/3105.html</a>
https post help
Hi Wez,
I've seen your 'http post' code in many sites, but I'm having a hard time implementing it myself.
Could you please provide a usage example ?
Specifically the code keeps throwing the first exception and I don't understand why or how to fix it..
Thanks in advance.
$php_errormsg
What is $php_errormsg? It doesn't seem to be set anywhere and it's not some magic PHP variable either. So how do I know exactly what the errors that are being thrown are?
$php_errormsg
Daevid, you need to work on those search skills.
Go to php.net, search the online documentation for php_errormsg and you find this:
http://www.php.net/manual/en/reserv...phperrormsg.php
HTTPS
Yes, if you have the openssl extension loaded, you should be able to use the same trick for HTTPS.
don't suppress warnings
Better leave out the @ before fopen and stream_get_contents, as this suppresses HTTP 500 'warnings'.
Works beautifully
I'm using this when simple_xml_loadfile fails because the $_GET data is too long. Works a treat.
Example usage:
$data = array ('code' => 'tpsadd', 'id' => $id, 'text' => $tpsnumbers);
$data = http_build_query($data);
$url = 'http://' . XML_SERV0 . '/xml/ukpb_corp';
do_post_request($url, $data);
remote post
If I use this script on my web server, I am able to post to other pages on my web server just fine!
BUT when I put the same exact script on my localhost server and try to post to my web server, the post request reaches the post target page but does not pass on variables.
Why is this?
Thanks for the script! I'm sure a few tweaks later, we'll have it working!
Go to url, instead of getting
Hi
I am trying to go to another url using your script, but I cant figure out how to make the changes.
The goal is to redirect my visitor to another url with the post values hidden. Can you give me a hint?
Thanks!
Fredric
HTTP POST
PH P's HTTP wrapper will automatically fill out the Content-Length header based on the length of the $data that you pass in. It will also automatically set the Content-Type to application/x-WWW-form-URL encoded if you don't specify one in the $optional_headers. I have used the option headers parameter to try and do this, but the response coming back from Google is claiming the Content-Type is "application/x-WWW-form-URL encoded"......
http://www.roulette-gambling-site.com
POST example on php.net
I saw another example posted on php.net, which seemed to be quite a pretty solution, at the page introducing the "HTTP context options"
http://www.php.net/manual/en/context.http.php
#
Hello. I think this article is very interesting. I think that your post about HTTP POST from PHP, without cURL is really good. I will try it and tell you how it show up.
<a href="http://www.leodata.de/webdesign">
Webdesign Stuttgart
</a>
fopen memory leaks
Really interesting technique. However, there is a pretty serious memory leak in fopen in php5. Making many of these requests during the lifetime of a script will definitely cause you to run out of memory.
Check out the bug here :
http://bugs.php.net/bug.php?id=32255
It's a fairly old bug, but it still seems to be open. A quick test on a server running 5.2.8 confirms that the leak is still there. Using this beats cURL in readability and succinctness, but it needs to be used with caution!
help me, I am so close.
I am using a switch statement to error check an included form. When it passes I am trying to use your beuty to pass it on to a url. The trick is the url requires
<form action='http://crm.zoho.com/crm/WebToContactForm' method='POST' onSubmit='javascript:document.charset="UTF-8";' accept-charset='UTF-8'>
Here is what I got, can you help?
I didn't clean up the spacing yet cause I am just trying to get it to work.
oh geeze
nm. such a noob.