How to send Accept Encoding header with with curl in PHP
$data=json_encode($data);
$url = 'url to send';
$headers = array(
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_SSLVERSION, 4);
$datas = curl_exec($ch);
curl_close($ch);
How to Decompress the response
You can use CURLOPT_ENCODING:
curl_setopt($ch, CURLOPT_ENCODING, "");
The contents of the "Accept-Encoding: " header. This enables decoding
of the response. Supported encodings are "identity", "deflate", and
"gzip". If an empty string, "", is set, a header containing all
supported encoding types is sent.
http://php.net/manual/en/function.curl-setopt.php
Alternatively, you can send an header:
$headers = array(
'Accept: text/plain'
);
To force the response in text/plain
If you mean how to ungzip the response I did it like this:
<?php
....
$headers = array(
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Encoding: gzip, deflate",
"Accept-Charset: utf-8;q=0.7,*;q=0.3",
"Accept-Language:en-US;q=0.6,en;q=0.4",
"Connection: keep-alive",
);
....
$response = curl_exec($curl);
// check for curl errors
if ( strlen($response) && (curl_errno($curl)==CURLE_OK) && (curl_getinfo($curl, CURLINFO_HTTP_CODE)==200) ) {
// check for gzipped content
if ( (ord($response[0])==0x1f) && (ord($response[1])==0x8b) ) {
// skip header and ungzip the data
$response = gzinflate(substr($response,10));
}
}
// now $response has plain text (html / json / or something else)
Related
I'm attempting to make a cUrl request with PHP to the Dropbox API, in order to begin to upload a very large zip file. Here is the documentation I'm trying to implement, found at https://www.dropbox.com/developers/documentation/http/documentation#files-upload -
URL structure: https://content.dropboxapi.com/2/files/upload_session/start
Example cUrl Request:
curl -X POST https://content.dropboxapi.com/2/files/upload_session/start \
--header "Authorization: Bearer <get access token>" \
--header "Dropbox-API-Arg: {\"close\": false}" \
--header "Content-Type: application/octet-stream" \
--data-binary #local_file.txt
And here is my code:
$uploads = wp_upload_dir();
$file = $uploads['basedir']."/maintainme/backups/files/backup_".$filename.'/'.$filename.'.zip';
$ch = curl_init();
$url = 'https://content.dropboxapi.com/2/files/upload_session/start';
$headers = array(
'Authorization: Bearer ' .$dropbox_token,
'Dropbox-API-Arg: {\"close\": false}',
'Content-Type: application/octet-stream',
);
$fields = array('file' => '#' . $file);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields );
curl_setopt($ch, CURLOPT_VERBOSE, 1);
$result = curl_exec($ch);
curl_close($ch);
The error message I get is:
Error in call to API function "files/upload_session/start": Bad HTTP "Content-Type" header: "application/octet-stream; boundary=------------------------1ee7d00b0e9b0c47". Expecting one of "application/octet-stream", "text/plain; charset=dropbox-cors-hack".
It seems that this 'Boundary=------------blahblahblah' gets appended to my content-type header each time I try to make this request. Anyone have any ideas??? Thanks!
Solved it! On a whim, I checked into the 'CURLOPT_POSTFIELDS' option found at http://php.net/manual/en/function.curl-setopt.php, and here's what it said:
The full data to post in a HTTP "POST" operation. To post a file, prepend a filename with # and use the full path. The filetype can be explicitly specified by following the filename with the type in the format ';type=mimetype'. This parameter can either be passed as a urlencoded string like 'para1=val1¶2=val2&...' or as an array with the field name as key and field data as value. If value is an array, the Content-Type header will be set to multipart/form-data. As of PHP 5.2.0, value must be an array if files are passed to this option with the # prefix. As of PHP 5.5.0, the # prefix is deprecated and files can be sent using CURLFile. The # prefix can be disabled for safe passing of values beginning with # by setting the CURLOPT_SAFE_UPLOAD option to TRUE.
The relevant part is bolded in the paragraph above. Apparently passing an array to the CURLOPT_POSTFIELDS option is what was appending that 'Boundary=----blahblahblah' the Content-Type and causing the API call to fail. I changed
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields );
to
curl_setopt($ch, CURLOPT_POSTFIELDS, '#'.$file );
and tried again. The initial issue was fixed, but I then encountered a new issue with the 'Dropbox-API-Arg' line in this section of code:
$headers = array(
'Authorization: Bearer ' .$dropbox_token,
'Dropbox-API-Arg: {\"close\": false}',
'Content-Type: application/octet-stream',
);
Turns out, these arguments need to be properly JSON-Encoded. I did this with the code below:
$args = array('close'=>false);
$args = json_encode($args);
and then changed
'Dropbox-API-Arg: {\"close\": false}'
to:
'Dropbox-API-Arg:'.$args
Here is the complete, final code:
$uploads = wp_upload_dir();
$file = $uploads['basedir']."/maintainme/backups/files/backup_".$filename.'/'.$filename.'.zip';
error_log($file);
$args = array('close'=>false);
$args = json_encode($args);
$ch = curl_init();
$url = 'https://content.dropboxapi.com/2/files/upload_session/start';
$headers = array(
'Authorization: Bearer ' .$dropbox_token,
'Dropbox-API-Arg:'.$args,
'Content-Type: application/octet-stream',
);
$fields = array('file' => '#' . $file);
error_log($fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, '#'.$file );
curl_setopt($ch, CURLOPT_VERBOSE, 1);
$result = curl_exec($ch);
error_log($result);
curl_close($ch);
I'm trying to run a CURL command in my PHP file, but I'm not able to see the output. The following is modified slightly without the real usernames/passwords/URLs.
The reason I'm trying to see the output is to make sure the CURL command is working as expected (I've run it in bash so I know the expected result).
$ch = curl_init();
// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, 'http://www.example.com');
curl_setopt($ch, CURLOPT_POST, 1 );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT , 'Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0');
$headers = array();
$headers[] = 'Accept: application/json';
$headers[] = 'Content-Type: text/plain;charset=utf-8';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_USERPWD, '$username:$password');
curl_setopt($ch, CURLOPT_POSTFIELDS, '$data');
// grab URL and pass it to the browser
curl_exec($ch);
I've run the following to make sure CURL is installed with my PHP server, and that is the case:
function _is_curl_installed() {
if (in_array ('curl', get_loaded_extensions())) {
return true;
}
else {
return false;
}
}
// Ouput text to user based on test
if (_is_curl_installed()) {
echo "cURL is <span style=\"color:blue\">installed</span> on this server";
} else {
echo "cURL is NOT <span style=\"color:red\">installed</span> on this server";
}
Is there something I'm doing wrong? I've run the curl command on my bash, and I'm able to see a response fine:
curl -X POST --user $username:$password --header "Content-Type: text/plain;charset=utf-8" --header "Accept: application/json" --data-binary #Test.txt "http://www.example.com"
Try this example:
<?php
// SEND CURL POST DATA
$jsonData = array(
'user' => 'Username',
'pass' => 'Password'
);
//Encode the array into JSON.
$jsonDataEncoded = json_encode($jsonData);
//API Url
$url = 'http://fxstar.eu/JSON/api.php';
//Initiate cURL.
$ch = curl_init($url);
//Tell cURL that we want to send a POST request.
curl_setopt($ch, CURLOPT_POST, 1);
//Attach our encoded JSON string to the POST fields.
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonDataEncoded);
//Set the content type to application/json
//curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_HTTPHEADER, array(Content-Type: text/plain;charset=utf-8);
//Execute the request
echo $result = curl_exec($ch);
?>
Get json from js:
<?php
// GET JSON CONTENT FROM JS api.php
$jsonStr = file_get_contents("php://input"); //read the HTTP body.
$json = json_decode($jsonStr);
?>
Example:
curl H "Contenttype: application/xml" \
H "AcceptCharset: utf8" \
H "openapikey:50667854bb253d281ce0fe36ebaeebaa" \
api.11street.com.my
How to I authenticate in PHP using curl by using the information above?
After that I want to add product by using curl. Below is my code and it is not working. Website URL: http://lazino.com.my/super/marketplace/11street.php
Reference:
<?php
$ch = curl_init();
//COOKIES
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
// Headers
$headers = array();
$headers[] = 'Content-Type: application/xml; charset=utf-8';
$headers[] = 'openapikey:50667854bb253d281ce0fe36ebaeebaa';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// URL
curl_setopt($ch, CURLOPT_URL, 'http://api.11street.my/rest/prodservices/product');
$fields_string = array(
'selMthdCd' => "01",
'dispCtgrNo' => "1",
'prdTypCd' => "01",
'prdNm' => "TEST product",
'prdStatCd' => "01",
'prdWght' => "0.1",
'minorSelCnYn' => "Y",
'prdImage01' => "http://staticfs.nexgan.com/images/logo/sallyfashion.com.my_new.jpg",
'selTermUseYn' => "N",
'selPrc' => "25.00",
'prdSelQty' => "0",
'asDetail' => "test",
'dlvMthCd' => "01",
'dlvCstInstBasiCd' => "11",
'rtngExchDetail' => "Test",
'suplDtyfrPrdClfCd' => "01"
);
curl_setopt($ch,CURLOPT_POST, sizeof($fields_string));
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
$html = curl_exec($ch);
curl_close($ch);
echo $html;
?>
The -H directives are just headers, so you can set them as is described by this SO: PHP cURL custom headers, and then make your GET request using curl_exec. If you're not familiar with HTTP verbs I'd suggest reading this: http://www.restapitutorial.com/lessons/httpmethods.html
To authenticate with cURL from PHP:
<?php
$ch = curl_init();
//COOKIES
curl_setopt($ch, CURLOPT_COOKIEFILE, 'path/to/cookies.txt');
// Headers
$headers = array();
$headers[] = 'Content-Type: application/xml; charset=utf-8';
$headers[] = 'openapikey:50667854bb253d281ce0fe36ebaeebaa';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// URL
curl_setopt($ch, CURLOPT_URL, 'api.11street.com.my');
$html = curl_exec($ch);
curl_close($ch);
I think you can find more answers if you just search a little on this website..
UPDATE:
Maybe something like this ?
<?php
$ch = curl_init();
//COOKIES
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
// Headers
$headers = array();
$headers[] = 'Content-Type: application/xml';
$headers[] = 'openapikey:50667854bb253d281ce0fe36ebaeebaa';
// URL
curl_setopt($ch, CURLOPT_URL, 'http://api.11street.my/rest/prodservices/product');
$xml = "<xml>
<selMthdCd>01</selMthdCd>
<dispCtgrNo>1</dispCtgrNo>
<prdTypCd>01</prdTypCd>
<prdNm>TEST PRODUCT</prdNm>
<prdStatCd>01</prdStatCd>
<prdWght>0.1</prdWght>
<minorSelCnYn>Y</minorSelCnYn>
<prdImage01>http://staticfs.nexgan.com/images/logo/sallyfashion.com.my_new.jpg</prdImage01>
<selTermUseYn>N</selTermUseYn>
<selPrc>25.00</selPrc>
<prdSelQty>0</prdSelQty>
<asDetail>test</asDetail>
<dlvMthCd>01</dlvMthCd>
<dlvCstInstBasiCd>11</dlvCstInstBasiCd>
<rtngExchDetail>Test</rtngExchDetail>
<suplDtyfrPrdClfCd>01</suplDtyfrPrdClfCd>
</xml>";
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_POSTFIELDS, $xml );
$html = curl_exec($ch);
curl_close($ch);
echo $html;
What is the server supposed to recieve ?
Here is my curl commaad line .
curl -u 'username:password' -X GET -H 'Accept: application/json' -H 'Content-Type: application/xml' -d '<request><layout>1</layout><filtermode>category</filtermode><filtervalue>115399046</filtervalue><limit>1</limit><start></start><sortfield></sortfield><sortdir></sortdir></request>' https://example.com/contacts
I use curl command line. It works for me. Now, I need do it in PHP.
The hard part is: The server accept GET request, but need a xml string in request body. I have tried to change GET to POST, the server did NOT return the correct message.
<?php
$ch = curl_init();
$credentials = "user:pass";
$data = 'xml string';
$page = "/contacts";
$headers = array( "GET ".$page." HTTP/1.0", "Content-type: application/xml", "Accept: application/json", "Authorization: Basic " . base64_encode($credentials) );
curl_setopt($ch, CURLOPT_URL, 'example.com/contacts');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$ret = curl_exec($ch);
?>
You can't put the GET line in $header, that causes an invalid header to be sent. The PHP equivalent of -X GET is:
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
I've reviewed the old questions posted here on Stackoverflow about this issue.
But I didn't find any example for php integration.
Here is a sample of my code to do that but it's failing
$url = 'https://connect.squareup.com/v1/me/items/9999999/image';
$auth_bearer = 'Authorization: Bearer ' . $this->accessToken;
$image_data = base64_encode(file_get_contents('image.jpeg'));
$header = array(
$auth_bearer,
'Accept: application/json',
'Content-Type: multipart/form-data; boundary=BOUNDARY',
);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'files=' . $image_data);
$head = curl_exec($ch);
curl_close($ch);
$response = json_decode($head);
echo "<pre>";
print_r($response);
echo "</pre>";
And nothing happens... any help here?
Thanks
You need to post the raw image data (not base64 encoded) with the proper multipart header for a file object. Here's a working example (replace ACCESS_TOKEN, ITEM_ID, and IMAGE_FILE).
<?php
function uploadItemImage($url, $access_token, $image_file) {
$headers = ["Authorization: Bearer $access_token"];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, ['image_data' => "#$image_file"]);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($ch);
$return_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
print "POST to $url with status $return_status\n";
curl_close($ch);
return $data ? json_decode($data) : false;
}
print_r(
uploadItemImage(
'https://connect.squareup.com/v1/me/items/ITEM_ID/image',
'ACCESS_TOKEN',
'IMAGE_FILE.jpg'
)
);
?>
Here is my PHP implementation for uploading a PNG image. Sometimes a different code view helps.
As #Troy stated, the important field to include for images is 'Content-Type: multipart/form-data'. Everything else I upload to Square uses 'Content-Type: application/json'.
$square_url = 'https://connect.squareup.com/v1/me/items/' . $square_item_id . '/image';
$cfile = new CURLFile($image_path_on_server, 'image/png', 'image_data');
$image_data = array('image_data' => $cfile);
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Authorization: Bearer ' . $access_token,
'Content-Type: multipart/form-data',
'Accept: application/json'
));
curl_setopt($curl, CURLOPT_POSTFIELDS, $image_data);
curl_setopt($curl, CURLOPT_URL, $square_url);
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_SAFE_UPLOAD, TRUE);
curl_setopt($curl, CURLOPT_BINARYTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLINFO_HEADER_OUT, TRUE);
curl_setopt($curl, CURLOPT_VERBOSE, TRUE);
$json = curl_exec($curl);
curl_close($curl);
Strictly speaking Square API documentation, their method can be implemented keeping a few things in mind.
-- Your request must be enclosed in a boundary and contain the Content disposition, name, filename, content type like the sample below.
--BOUNDARY
Content-Disposition: form-data; name="image_data"; filename="MyImage.png"
Content-Type: image/png
{BLANK LINE IS REQUIRED}
IMAGE BINARY DATA GOES HERE
--BOUNDARY--
In essence, the format of the request must be exactly as specified in the sample. This includes the 'boundary', the newline characters, the necessary headers, a blank line between the headers (for some reason nothing works if the line isn't present), and the actual image binary data. NOTE: the boundary can be any string that you choose, but it must be used consistently. In code, this would look something like this:
$boundary = "---------------------" . md5(mt_rand() . microtime());
$imageToUpload = "--{$boundary}" . "\r\n" .
"Content-Disposition: form-data; name=\"image_data\"; filename=\"" . $full_path_to_image_file . "\"" . "\r\n" .
"Content-Type: image/jpeg" . "\r\n" .
"\r\n" . // <- empty line is required
(file_get_contents($full_path_to_image_file)) . "\r\n" .
"--{$boundary}--";
The above will produce a request that looks like this:
-----------------------51b62743876b1201aee47ff4b1910e49
Content-Disposition: form-data; name="image_data"; filename="/some/directory/image.jpg"
Content-Type: image/jpeg
����
-----------------------51b62743876b1201aee47ff4b1910e49--
-- Technically speaking, the Content-Type in the request must change with the type of image you're uploading (image/jpeg or image/png). You can set the content type to application/octet-stream to cover all basis.
-----------------------51b62743876b1201aee47ff4b1910e49
Content-Disposition: form-data; name="image_data"; filename="/some/directory/image.jpg"
Content-Type: application/octet-stream
����
-----------------------51b62743876b1201aee47ff4b1910e49--
The two examples above will upload an image.
-- 'Image binary data' can be misleading as my every search showed that an image binary is obtained by using the base64_encode function. In my experiments, the base64_encoding doesn't do anything. You only need to open the file with the file_get_contents.
-- In your cURL request, must have the header's Content-Type set to multipart/form-data and have the same boundary as the request. Example below:
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Authorization: Bearer ' . $personalAccessToken, 'Content-Type: multipart/form-data; boundary=' . $boundary ));
So this adds another solution to the mix.
Troy's solution using # is deprecated and I was unable to get it to work. Byron's solution works with the CURLOPT_POST before the CURLOPT_POSTFIELDS (see Mavooks comment at https://www.php.net/manual/en/function.curl-setopt.php) and removing the Content-Type from the header. That is because it is automatically multipart if CURLOPTS_POSTFIELDS is an array and manually including it seems to override it, but then it is missing the boundary.
$square_url = 'https://connect.squareup.com/v1/me/items/' . $square_item_id . '/image';
$cfile = new CURLFile($image_path_on_server, 'image/png', 'image_data');
$image_data = array('image_data' => $cfile);
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Authorization: Bearer ' . $access_token,
'Accept: application/json'
));
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_POSTFIELDS, $image_data);
curl_setopt($curl, CURLOPT_URL, $square_url);
curl_setopt($curl, CURLOPT_SAFE_UPLOAD, TRUE);
curl_setopt($curl, CURLOPT_BINARYTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLINFO_HEADER_OUT, TRUE);
curl_setopt($curl, CURLOPT_VERBOSE, TRUE);
$json = curl_exec($curl);
curl_close($curl);