Home / Submitting a form post with PHP and CURL

Submitting a form post with PHP and CURL

The PHP CURL functions use the libcurl library to allow you to connect to various servers and different protocols. This post shows how to make an HTTP POST with PHP and CURL passing several form fields. This can be useful for testing your own web forms, connecting to APIs that require POST data and so on.

The PHP Code

The following PHP code example posts to http://www.example.com/path/to/form sending three sets of values.


$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.example.com/path/to/form");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, true);

$data = array(
    'foo' => 'foo foo foo',
    'bar' => 'bar bar bar',
    'baz' => 'baz baz baz'

curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$output = curl_exec($ch);
$info = curl_getinfo($ch);


The "curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);" line is not actually necessary but it means the HTML from the web page returned goes into the $output variable rather than echoed out to standard output.


The "curl_setopt($ch, CURLOPT_POST, true);" line tells CURL that this is POST instead of the default GET.’


The $data array contains the POST field values. The first of these has the name ‘foo’ and value ‘foo foo foo’; the equivilent HTML form value for this might be something like <input type=’hidden’ name=’foo’ value=’foo foo foo’ />

The post field values are then set with the "curl_setopt($ch, CURLOPT_POSTFIELDS, $data);" line. $data can optionally be a string formatted in the same way a GET string is (e.g. foo=foo+foo+foo&bar=bar+bar+bar etc) but I find it easier to use an array.


The "$info = curl_getinfo($ch);" is also not required but returns an array of useful data about the request. Example output from the above would look something like so:

    [url] => http://www.example.com/path/to/form
    [content_type] => text/html; charset=UTF-8
    [http_code] => 200
    [header_size] => 516
    [request_size] => 197
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 2.256708
    [namelookup_time] => 0.672754
    [connect_time] => 0.899986
    [pretransfer_time] => 0.900012
    [size_upload] => 240
    [size_download] => 18717
    [speed_download] => 8293
    [speed_upload] => 106
    [download_content_length] => 0
    [upload_content_length] => 240
    [starttransfer_time] => 1.12957
    [redirect_time] => 0

Getting the http_code from the information can be useful so you know if it successfully connected to the page before parsing any of the return data.