Skip to the content...

Welcome to the David Walsh Blog. I'm a MooTools, Dojo, jQuery, CSS, and PHP Web Developer located in Madison, Wisconsin, United States. Please contact me if I can make your experience on my website better.

Execute a HTTP POST Using PHP CURL

55 Responses »

A customer recently brought to me a unique challenge. My customer wants information request form data to be collected in a database. Nothing new, right? Well, there's a hurdle -- the information isn't going to be saved on the localhost database -- it needs to be stored in a remote database that I cannot connect directly to.

I thought about all of the possible solutions for solving this challenge and settled on this flow:

  1. User will submit the form, as usual.
  2. In the form processing PHP, I use cURL to execute a POST transmission to a PHP script on the customer's server.
  3. The remote script would do a MySQL INSERT query into the customer's private database.

This solution worked quite well so I thought I'd share it with you. Here's how you execute a POST using the PHP CURL library.

//extract data from the post
extract($_POST);

//set POST variables
$url = 'http://domain.com/get-post.php';
$fields = array(
						'lname'=>urlencode($last_name),
						'fname'=>urlencode($first_name),
						'title'=>urlencode($title),
						'company'=>urlencode($institution),
						'age'=>urlencode($age),
						'email'=>urlencode($email),
						'phone'=>urlencode($phone)
				);

//url-ify the data for the POST
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
rtrim($fields_string,'&');

//open connection
$ch = curl_init();

//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);

//execute post
$result = curl_exec($ch);

//close connection
curl_close($ch);

How would you have solved this problem?

Discussion

  1. jay
    March 11, 2008 @ 3:13 pm

    Well you’re basically calling a de facto web service. I hope they are escaping values that you’re passing. Your idea is simple enough tho if you’re going to be continually working with this remote database with limited access (are you working with a 3rd party?) you might want to use something a little more standard like SOAP or REST so that you can have error checking, etc.

    PHP Curl is pretty nice.

  2. March 11, 2008 @ 3:20 pm

    Thank you for the suggestion Jay!

  3. March 11, 2008 @ 7:40 pm

    I like this solution. Thank-you very much for sharing.

    However, it sounds a little shady that you need to post using curl. Traditionally the remote administrator would grant you access to perform mySQL inserts into the database.

  4. shock17
    March 29, 2008 @ 3:08 pm

    really nice explanation :) i like it

  5. sam anderson
    May 14, 2008 @ 2:20 am

    you can use $fields_string = implode(‘&’, $fields); instead of deleting the last ‘&’.
    just a little quicker.

  6. May 14, 2008 @ 7:38 am

    @Sam: Absolutely. I’ve come to know impode() quite well in the past few months. Unfortunately, I can’t go back and change all my old code. Thanks for pointing this out though!

  7. May 31, 2008 @ 6:17 am

    I have learned a lot from this article, thanks

  8. sardu
    July 3, 2008 @ 11:21 am

    A+ – Thanks for the sample.

  9. July 14, 2008 @ 8:26 am

    hi david , i like your solution very much , but i need to ask you if i can use the same way with facebook , i mean to login to facebook using curl and how?
    thanks rasha

  10. July 14, 2008 @ 8:43 am

    @rasha: That would be worth a try. Let me know how it goes!

  11. July 14, 2008 @ 12:13 pm

    Hi david, thanks for sharing. I learned about this some time ago and used it to extract address book for gmail & yahoo! mail

    Anyway, I learn some good ways from you in having cleaner coding. ^_^

  12. July 25, 2008 @ 2:21 pm

    Actually, the best way to turn that array into a properly escaped URL is http_build_query which takes care to escape everything properly.

  13. October 25, 2008 @ 4:15 am

    Hi PHP experts,

    I need to run a URL from a .php file. I dont need to grab its output or do anything.

    All I want to do is just call a URL [e.g. http://www.topinews.com/story/15624/modify/dopublished/ ] so that the server receives a request for the URL and executes the request.

    Any help would be great.
    Thanks
    Neeraj

  14. November 1, 2008 @ 6:15 pm

    I can see one major security flaw here.
    If this were to be implemeted as an inlude or the likes, or even as part of another larger PHP file, this could be grounds for a big security issue.
    Say the user had the variable $admin, which represent via boolean whether the current user has administrative permissions or not. I could POST admin=true, and since extract (without any second argument) overwrites existing variables, $admin would be true at that point. I’d just say assign specific variables to each individual option to be sent via cURL. Also, reading up, someone suggested implode(). This would not work. Implode() only joins the values of the array. I’d suggest either an array_walk() cycle, or the current method.

  15. jsmith
    November 3, 2008 @ 1:37 am

    Thank you so much for the excellent post. It has helped a lot. I’m a little confused on how to work in the ‘implode’ function, and was hoping you could elaborate. When I trying using “$fields_string = implode(’&’, $fields);” I simply get the values stored in $value with ‘&’ signs between them. The $key variable is no where to be found when I echo $field_strings. Also, how would I insert the ‘=’ between $key and $value using the ‘implode’ function? Any and all help is most appreciated. Thank you and have a great night.

  16. laurens
    November 5, 2008 @ 4:36 am

    Hi david, i am having the same kind of challenge, exept.. i need to login first onto a site before i can make a post…

    Example: You want to post on a forum.. So the url would be: http://www.your-forum.com..
    the string would be: login_name=yourname&password=yourpassword..

    after u did that, the url and the string has to change, and the ‘site’ must know you have already logged in…

    its getting me crazy! what sollution would you use for this?
    just an array with the urls and the strings hes going through?

    Regards,
    Laurens

  17. zzz
    December 16, 2008 @ 9:16 pm

    em, wouldn’t it be just easier to urlencode in foreach cycle? less code, more readable.

    btw thx)

  18. great tutorial
    April 1, 2009 @ 8:30 am

    hm.. my comments gone

  19. trink
    April 2, 2009 @ 12:00 pm

    Once again… Notice the large security flaw on line 2. There’s no reason to extract the variables, just use them in the current array, its much safer. If you don’t like using them from their current superglobal (I don’t know why not) then assign the entire array to a variable. Extracting them and possibly overwriting current scalar security variables is not a good idea whatsoever. Not only that, but especially for newbies at PHP, they might use this religiously.

  20. trink
    April 2, 2009 @ 12:07 pm

    Credits to the warning on the PHP extract page for this one…
    Do not use extract() on untrusted data, like user-input ($_GET, …). If you do, for example, if you want to run old code that relies on register_globals temporarily, make sure you use one of the non-overwriting extract_type values such as EXTR_SKIP and be aware that you should extract in the same order that’s defined in variables_order within the php.ini. (I’d suggest either changing or ridding this code snippet.)

  21. April 29, 2009 @ 3:36 pm

    Hi, when I use your code it works for the most part expect for the line:

    print(“foreach($fields as $key=>$value) { $fields_string .= $key.’=’.$value.’&’; }”);

    I’m not sure why this line doesn’t work. Any help?

  22. April 29, 2009 @ 5:19 pm

    @Boudga: Why are you trying to print() that?

  23. paolo gabrielli
    May 28, 2009 @ 8:59 am

    David,
    the rtrim() function returns the modified string. So you should use it like that:
    $fields_string = rtrim($fields_string,’&’);
    BTW I don’t think any webserver/scripting_language will bitch about an ending &

    Thanks for your usefull howto,
    P.

  24. May 30, 2009 @ 4:30 pm

    Hello,

    I’m french, so I’m sorry for my schoolar english.

    I think you can replace this

    foreach($fields as $key=>$value) {
    $fields_string .= $key.’=’.$value.’&’;
    }
    18.rtrim($fields_string,’&’);

    With php5, it exists the http_build_query(); function

    $fields_string = http_build_query($fields);

    The documentation is here => http://fr3.php.net/manual/fr/function.http-build-query.php

    I hope that I am not irrelevant

    Ciao ;)

  25. les
    June 28, 2009 @ 11:37 am

    You couldn’t use implode( ‘..’, $array ); as you would loose the array key indexes, so stick to what you are using :)

  26. July 8, 2009 @ 10:58 am

    Instead of

    foreach($fields as $key=>$value) { $fields_string .= $key.’=’.$value.’&’; }
    rtrim($fields_string,’&’);

    May I suggest

    foreach($fields as $key=>$value) { $fields_string .= $sep.$key.’=’.$value; $sep=’&’; }

    It’s a little easier to read and saves a call to rtrim(). If you are strict or do not want to raise a php notice, place $sep=”; above the foreach() loop.

  27. October 16, 2009 @ 9:22 pm

    @Raphael Deschler: Yeah it works n I have used it last few days. And I say it _is_ relevant. Thanks m8.

    Im gonna check it now, funny though my XAMPP mysql service isnt starting, I’ve clickd n waited a few times. nvm It happens sometimes. I’m pretty much used to Uniserver but .. anyway I’ll check this on my Uniserver n post a better comment next time. l8r.

    Im working on a SugarCRM (I hate it) leadcapture from Drupal user registration module using the hook_user() and the drupal thing is done. But I have to send the data as POST coz thts how Sugar receives these stuff. Hope curl will get me outta Sugar so I could be off with better useful stuff in Drupal.

  28. depinder bharti
    October 23, 2009 @ 2:16 pm

    Its Gr8 solution ,i myself use the similar solution from past much time ,Just Now after googling i found out im not the only one lol :D

    But my other problem is How to run a php at the background?
    Tried with Cron Jobs but it restricts me to atleast of 1 minute when i want it to be 15 sec.
    My script loads security numbers every 15 secs and based on that i want to send an Sms every 15 sec which is on external server . I done Everything Except how to execute my script after every 15 sec automatically at the server without interacting with it .
    If anyone have a good solution mail me at depinder@gmail.com

    Btw GR8 work David :)

  29. depinder bharti
    October 24, 2009 @ 11:14 am

    Btw there is another small solution also if ignoring security issues :)

    ‘valueofvariable1′,
    ‘variable2′ => ‘valueofvariable2′
    )
    );
    $opts = array(‘http’ =>
    array(
    ‘method’ => ‘POST’,
    ‘header’ => ‘Content-type: application/x-www-form-urlencoded’,
    ‘content’ => $postdata
    )
    );
    $context = stream_context_create($opts);
    $result = file_get_contents(‘http://abc.com/anyscript.php’, false, $context);

    ?>

  30. depinder bharti
    October 24, 2009 @ 11:17 am

    damn Let me post again

    $postdata = http_build_query(
    array(
    ‘variable1′ => ‘valueofvariable1′
    ‘variable2′ => ‘valueofvariable2′
    )
    );
    $opts = array(‘http’ =>
    array(
    ‘method’ => ‘POST’,
    ‘header’ => ‘Content-type: application/x-www-form-urlencoded’,
    ‘content’ => $postdata
    )
    );

  31. depinder bharti
    October 24, 2009 @ 11:18 am

    $context = stream_context_create($opts);
    $result = file_get_contents(‘http://yoursite.com/abc.php’, false, $context);

  32. depinder bharti
    October 24, 2009 @ 11:31 am

    Another Way can be

    $url = “http://Yoursite.com/abc.php”;
    $useragent=”Fake Mozilla 5.0 “;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
    curl_setopt($ch, CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS,”variable1=valueofvariable”);
    $result= curl_exec ($ch);
    curl_close ($ch);
    print $result;

  33. vijayakumar
    October 27, 2009 @ 4:36 am

    hi,
    i have doubts in php.i am going to use cURL for posting url.
    but i tried so many ways,but it is not getting run it’s showing
    error showing like this

    Fatal error: Call to undefined function curl_init() in C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\newsms.php on line 4

    please any body knows about this please let me know

    please make it from beginning to end(upto run the php)

    thanks and regards
    vijay

  34. bp
    November 20, 2009 @ 11:47 am

    How to use it in a form. When do I do all the curl. I have a simple form which posts to itself. where do i use the urlencode? Any help will be appreciated.

    Thanks

  35. peter
    December 9, 2009 @ 7:13 pm

    @Paolo Gabrielli: Good Call Paolo, I noticed the same thing, but hadn’t taken the time to figure out why it was happening. And David, since I am completely unable to remember the proper syntax for a curl call with post vars, I come back to reference this page about once a week. Thanks for posting it!

  36. vic
    December 21, 2009 @ 5:29 am

    ..so what about a http post WITHOUT using curl?

  37. January 21, 2010 @ 3:51 pm

    Exactly what I needed!

    Thanks!

  38. amit
    February 2, 2010 @ 9:50 am

    Hello

    I am new user of curl functionality. can somebody help me with above define curl example

    //extract data from the post
    extract($_POST);

    //set POST variables
    $url = ‘http://domain.com/get-post.php’;
    $fields = array(
    ‘lname’=>urlencode($last_name),
    ‘fname’=>urlencode($first_name),
    ‘title’=>urlencode($title),
    ‘company’=>urlencode($institution),
    ‘age’=>urlencode($age),
    ‘email’=>urlencode($email),
    ‘phone’=>urlencode($phone)
    );

    //url-ify the data for the POST
    foreach($fields as $key=>$value) { $fields_string .= $key.’=’.$value.’&’; }
    rtrim($fields_string,’&’);

    //open connection
    $ch = curl_init();

    //set the url, number of POST vars, POST data
    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch,CURLOPT_POST,count($fields));
    curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);

    //execute post
    $result = curl_exec($ch);

    //close connection
    curl_close($ch);

    i will be very great full

    Thanks and regards
    Amit khurana

  39. iverson
    February 4, 2010 @ 3:35 pm

    $fields_string is being appended before you initialize it.

  40. nick
    February 13, 2010 @ 2:14 pm

    Hi David
    I used your script above to send post data to a payment system but I want the user to be re-directed there with the post data as if they were submitting an html form. My aim is to create an order id in the local database and pick it up to send it on to the SagePay system. Is there a way to send the user with it rather than pulling the info from the target site?

  41. dave
    February 18, 2010 @ 5:21 pm

    what syntax highlighter are you using here, i like it.

  42. February 26, 2010 @ 12:27 am

    This solutions is really helpful .. thanks to the creator .

  43. xavier
    March 1, 2010 @ 3:11 am

    Hello, nice script, It’s exactly what i was looking at!
    Just one thing : to pass arrays using POST, i always do that in the first page :

    $example = base64_encode(serialize($array));

    where $array is…my array.

    In the second one, who receive the POST data :

    $reception = unserialize(base64_decode($ret_array));

    This solution work with multidimensionnals too, no care of the array size, it works.
    Hope this help!

    Xavier

  44. manu
    March 3, 2010 @ 7:58 am

    can use http_build_query () to url-ify the data for the POST

  45. ben
    March 29, 2010 @ 5:02 am

    Thank you, helped me a lot!

  46. April 7, 2010 @ 12:52 am

    This code was EXACTLY what I needed. Man, it’s good to have people like you around!

    Cheers, mate!

    James

  47. April 22, 2010 @ 10:20 am

    I wonder why you count fields for CURLOPT_POST
    as PHP manual
    http://www.php.net/manual/en/function.curl-setopt.php
    CURLOPT_POST should be set to ‘true’

    additionally, CURLOPT_POSTFIELDS accepts array with the field name as key and field data as value

  48. albertux
    April 29, 2010 @ 12:11 pm

    Hey david, great post, question, are you using php –with-curlwrappers option?

  49. charbel
    May 4, 2010 @ 6:06 am

    hi Guys, I was searching for something and I landed here. In fact, I need to catch the send data from an http post (like the example above and not from a form). I am trying the $_POST and is not working. I tried to loop on $_REQUEST and also nothing. Can anyone help on how to catch this data?

  50. kane
    May 10, 2010 @ 12:38 pm

    Hi,
    Great post! I have a couple questions. In my scenario Im submitting sign up for service, including cc info to a third party API. I just need to get the data there as their script will prep data for API. #1 is curl the best way to do this securely? (is https enough?) #2what steps do I need to do (if any) to my PHP library on my server. #3 Is this the best way to do this? BTW, Im a creative directory who because of lack of resources has been tasked with this!
    Thanks!

  51. kane
    May 18, 2010 @ 10:39 am

    How would you do this over an SSL? Would fsockopen be better for use over SSL?
    thanks

  52. June 17, 2010 @ 5:57 am

    Thanks you very much sir!..

  53. June 18, 2010 @ 1:08 am

    I usualy use fsocks. But lately it seems much easier to just use curl. This post was well laid out and has had some great feedback also.
    Thanks,
    Joe

  54. marlon
    July 12, 2010 @ 2:10 pm

    hi all,
    good post, I’d like to know how can I do the same on login page
    have any idea?
    thanks

  55. July 23, 2010 @ 8:25 am

    Hello sir
    i am new in Cakephp framework, currently i am facing a problem.
    Problem is that i am working on scrapping in cakephp and i am scrapping a site which is developed in .Net platform.
    My problem is that how can i be logged in that .net site through php code means how to POST username and password on that site and response get back to on my site which is php site. After that i will scrape data from there and store it to DB.

    Reference site link http://www.plentyoffish.com (.net site)
    for example i am scrapping gmail account and logged in there from my php code but how it possible.

    please help me

    Thanks in advance

Be Heard!

Share your thoughts with fellow developers of all skill levels! I want to hear from you!

Name*:
Email*:
Website:  
Wrap your code with <code> tags, f00!