Infiniroot Blog: We sometimes write, too.

Of course we cannot always share details about our work with customers, but nevertheless it is nice to show our technical achievements and share some solutions.

How to convert form fields into JSON data and submit data with HTTP POST using curl in PHP

Published on October 28th 2020


When data needs to be submitted to an external URL, an API for example, curl can be used. Curl exists on both the command line and as a library in many programming languages, such as PHP.

Using curl in PHP and submit (POST) data to external URL

POSTing data with curl, the command

Starting with the curl command is usually very helpful. It also helps to understand how the remote URL works, what fields are required and what input types (such as multiform or json) are accepted.

ck@mintp ~ $ curl -X POST https://my.example.com/post.php -d "firstname=Claudio" -d "lastname=Kuenzler" -d "company=Infiniroot GmbH"

In this case multiple fields/parameters (firstname, lastname and company) are submitted to an external URL. Using this "default" way of submitting data, uses the content-type application/x-www-form-urlencoded in the background. This can be verified using the --trace option (followed by another dash):

ck@mintp ~ $ curl --trace - -X POST https://my.example.com/post.php -d "firstname=Claudio" -d "lastname=Kuenzler" -d "company=Infiniroot GmbH"
[...]
=> Send header, 175 bytes (0xaf)
0000: 50 4f 53 54 20 2f 61 63 74 69 6f 6e 2f 6e 69 6e POST /post.php H
0010: 6a 61 2e 70 68 70 20 48 54 54 50 2f 31 2e 31 0d TTP/1.1..Host: m
0020: 0a 48 6f 73 74 3a 20 77 77 77 2e 61 6c 76 61 6e y.example.com..U
0040: 0a 55 73 65 72 2d 41 67 65 6e 74 3a 20 63 75 72 ser-Agent: curl/
0050: 6c 2f 37 2e 35 32 2e 31 0d 0a 41 63 63 65 70 74 /7.52.1..Accept:
0060: 3a 20 2a 2f 2a 0d 0a 43 6f 6e 74 65 6e 74 2d 4c  */*..Content-Le
0070: 65 6e 67 74 68 3a 20 31 33 31 0d 0a 43 6f 6e 74 ngth: 131..Conte
0080: 65 6e 74 2d 54 79 70 65 3a 20 61 70 70 6c 69 63 nt-Type: applica
0090: 61 74 69 6f 6e 2f 78 2d 77 77 77 2d 66 6f 72 6d tion/x-www-form-
00a0: 2d 75 72 6c 65 6e 63 6f 64 65 64 0d 0a 0d 0a    urlencoded......
=> Send data, 131 bytes (0x83)
0000: 63 6f 6d 70 61 6e 79 3d 74 65 73 74 26 66 69 72 firstname=Claudi
0010: 73 74 6e 61 6d 65 3d 43 6c 61 75 64 69 6f 26 6c o&lastname=Kuenzl
0020: 61 73 74 6e 61 6d 65 3d 4b 75 65 6e 7a 6c 65 72 er&company=Infini
0030: 26 63 6f 6d 70 61 6e 79 3d 54 65 74 20 43 6f 6d root
== Info: upload completely sent off: 131 out of 131 bytes
[...]

Note 1: -trace is available since curl ~7.51.
Note 2: The original POST data was obfuscated, hence the Content-Length does not match.

If the remote API requires the submitted data in JSON format, the HTTP POST request needs to be slightly adjusted:

ck@mintp:~$ curl -X POST -H "Content-Type: application/json" https://my.example.com/post.php -d '"firstname":"Claudio","lastname":"Kuenzler","company":"Infiniroot GmbH"'

Here the Content-Type header was set to application/json and the data was formatted into JSON format.

POSTing data with libcurl in PHP

As mentioned, curl can also be used in PHP. If you're coming from the curl command line, this might look strange at first. All curl command line options and parameters are defined by curl_setopt for a single option or curl_setopt_array for multiple options at the same time.

So a typical POST with libcurl in PHP, using the same data as in the command line example, looks like this:

// Putting all the POST data into an array
$data = array(
        "firstname" => "Claudio",
        "lastname" => "Kuenzler",
        "company" => "Infiniroot GmbH",
);

// Initialize a new curl call
$curl = curl_init();

// Put all the different curl options into an array
$opts = [
        CURLOPT_URL => 'https://my.example.com/post.php',
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_POST => 1,
        CURLOPT_POSTFIELDS => $data,
];

// Use the options array and tell curl to use these options
curl_setopt_array($curl, $opts);

// Launch the curl request using curl_exec and save the output (from the remote URL) in $response
$response = curl_exec($curl);

// Close the curl call
curl_close($curl);

This again uses the default Content-Type application/x-www-form-urlencoded.

POSTing json data with libcurl in PHP

To submit the data in json format, the $data array first needs to be formatted into json. This can easily be done using the json_encode function. This function basically parses the array and creates a json string of it, saved as $payload. Besides this, the header Content-Type needs to be added in the $opts:

// Putting all the POST data into an array
$data = array(
        "firstname" => "Claudio",
        "lastname" => "Kuenzler",
        "company" => "Infiniroot GmbH",
);

// Re-format the data into JSON
$payload = json_encode($data);


// Initialize a new curl call
$curl = curl_init();

// Put all the different curl options into an array
$opts = [
        CURLOPT_URL => 'https://my.example.com/post.php',
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_POST => 1,
        CURLOPT_HTTPHEADER => [ 'Content-Type: application/json' ],
        CURLOPT_POSTFIELDS => $payload,
];

// Use the options array and tell curl to use these options
curl_setopt_array($curl, $opts);

// Launch the curl request using curl_exec and save the output (from the remote URL) in $response
$response = curl_exec($curl);

// Close the curl call
curl_close($curl);

Debugging with curl_getinfo

Whether or not the code runs fine, you may want to get additional information about the executed curl request. This is where curl_getinfo comes into play. This function analyzes the curl call ($curl) and saves information about the request and server response in an array. Before closing the curl call, the information can be stored into a variable ($info):

// Putting all the POST data into an array
$data = array(
        "firstname" => "Claudio",
        "lastname" => "Kuenzler",
        "company" => "Infiniroot GmbH",
);

// Re-format the data into JSON
$payload = json_encode($data);

// Initialize a new curl call
$curl = curl_init();

// Put all the different curl options into an array
$opts = [
        CURLOPT_URL => 'https://my.example.com/post.php',
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_POST => 1,
        CURLOPT_HTTPHEADER => [ 'Content-Type: application/json' ],
        CURLOPT_POSTFIELDS => $payload,
];

// Use the options array and tell curl to use these options
curl_setopt_array($curl, $opts);

// Launch the curl request using curl_exec and save the output (from the remote URL) in $response
$response = curl_exec($curl);

// Saving information about this executed curl call
$info = curl_getinfo($curl);


// Close the curl call
curl_close($curl);

As mentioned above, the information (return values) about this curl transmission is saved in an array. There are many return values, check out the curl_getinfo documentation for an up to date list. What definitely helps to use in every code, is to check the http_code (the http return code from the server response):

// Analyze http return code
if ( $info['http_code'] > 200 ) {
  echo "Remote API responded with a return code of $info['http_code']";
}