Let's say we have a form like the one below. We want to send the data to our webserver via AJAX and from there to a script running on an external server.
So we have normal inputs, a multi-select field and a file dropzone where we can upload multiple files.
Assuming the AJAX POST request was successful we get the following data on PHP site:
// print_r($_POST)
Array
(
[first_name] => John
[last_name] => Doe
[activities] => Array
(
[0] => soccer
[1] => hiking
)
)
and the files should look like this
// print_r($_FILES)
Array
(
[upload] => Array
(
[name] => Array
(
[0] => my_photo.jpg
[1] => my_life.pdf
)
[type] => Array
(
[0] => image/jpg
[1] => application/pdf
)
[tmp_name] => Array
(
[0] => /tmp/phpW5spji
[1] => /tmp/phpWgnUeY
)
[error] => Array
(
[0] => 0
[1] => 0
)
[size] => Array
(
[0] => 647548
[1] => 643223
)
)
)
So far, so good. Now we want to send this data and files to the external server using cURL with the CurlFile Class
Since cURL only accepts a simple but not a multi-dimensional array, we have to flatten the $_POST array first.
To do this, you could use this function for example which gives you the following:
// print_r($new_post_array)
Array
(
[first_name] => John
[last_name] => Doe
[activities[0]] => soccer
[activities[1]] => hiking
)
The next step is to create CurlFile Objects for the uploaded files. This is done by the following loop:
$files = array();
foreach ($_FILES["upload"]["error"] as $key => $error) {
if ($error == UPLOAD_ERR_OK) {
$files["upload[$key]"] = curl_file_create(
$_FILES['upload']['tmp_name'][$key],
$_FILES['upload']['type'][$key],
$_FILES['upload']['name'][$key]
);
}
}
curl_file_create is a helper function of the CurlFile Class and creates the CurlFile objects. We save each object in the $files array with keys named "upload[0]" and "upload[1]" for our two files.
We now have to combine the flattened post array and the files array and save it as $data like this:
$data = $new_post_array + $files;
The last step is to send the cURL request:
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_POST => 1,
CURLOPT_URL => "https://api.externalserver.com/upload.php",
CURLOPT_RETURNTRANSFER => 1,
CURLINFO_HEADER_OUT => 1,
CURLOPT_POSTFIELDS => $data
));
$result = curl_exec($ch);
curl_close ($ch);
Since $data is now a simple (flat) array, cURL automatically sends this POST request with Content Type: multipart/form-data
In upload.php on the external server you can now get the post data and files with $_POST and $_FILES as you would normally do.