I am working to connect with an API using curl and PHP
I have this CURL statement
curl -i --user api:YXBpOmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1 --data-binary #test.png https://api.blahblah.com/blah
where YXBpOmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1 is the api key and #test.png is the image file I need to transfer to the API for upload. What I don't get is how to write the curl for the link above
and I also have this Example Statement as given by the site for developers(looks a JSON)
POST /blah HTTP/1.1
Host: api.blahblah.com
Authorization: Basic YXBpOmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1
Till now, I have written this up,
$url = 'https://api.tinypng.com/shrink';
$image = 'bf4lwp2.png';
$key = 'YXBpOmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1';
$jsonscript = array(
'Host' => 'api.tinypng.com',
'Authorization' => $key );
$json_string = json_encode($jsonscript);
$ch = curl_init($url);
// Disable SSL verification
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'api:'.$key);
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FILE, $image);
// Execute
$result=curl_exec($ch);
Also, if my request is a success, I get this...
HTTP/1.1 201 Created
Location: https://api.blahblah.com/blahblah.png
Content-Type: application/json; charset=utf-8
{
"input": {
"size": 87654
},
"output": {
"size": 102020,
"ratio": 0.236
}
}
I know I have to use file_get_contents() to get all that, but I don't know what URL to put in that function.
To get data from json first you can use json decode and than use foreach loop to
parse those data into variables
Related
I'm using the below code to upload an MP4 file to a web service, using PHP cURL.
I've specified the 'Content-Type' as 'video/mp4', in CURLOPT_HTTPHEADER.
Unfortunately, having uploaded the file, the 'Content-Type' stored for it in the service displays as: "content_type":"video/mp4; boundary=----WebKitFormBoundaryfjNZ5VkJS8z3CB9X"
As you can see, the 'boundary' has been inserted into the 'content_type'.
When I then download the file, it fails to play, with a 'file unsupported/file extension incorrect/file corrupt' message.
$authorization = "Authorization: Bearer [token]";
$args['file'] = curl_file_create('C:\example\example.mp4','video/mp4','example');
$url='[example web service URL]';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: multipart/form-data', 'Accept: application/vnd.mendeley-content-ticket.1+json', $authorization));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS , $args);
$response = curl_exec($ch); // URL encoded output - needs to be URL encoded to get the HREF link header
curl_close($ch);
Would be extremely grateful for any help, advice or pointers!
Maybe the API doesn't expects a POST multipart, but the actual contents in the body itself:
Ref: How to POST a large amount of data within PHP curl without memory overhead?
You need to use PUT method for the actual contents of the file to go inside the body - if you use POST, it will try to send as a form.
$authorization = "Authorization: Bearer [token]";
$file = 'C:\example\example.mp4';
$infile = fopen($file, 'r');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.mendeley.com/file_contents");
curl_setopt($ch, CURLOPT_PUT, 1 ); // needed for file upload
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($file));
curl_setopt($ch, CURLOPT_INFILE, $infile);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST' );
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: video/mp4', 'Accept: application/vnd.mendeley-content-ticket.1+json', $authorization));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec ($ch);
I have the same problem calling a Openai API from PHP curl.
I send options: Content-Type and Authorization (with my api key) but, when I send request, I receive this error:
Invalid Content-Type header (application/json; boundary=------------------------66a0b850cd1421c8), expected application/json
I tried to use some of your options with no success.
I cannot remove the boundary parameter added automatically.
I have a sample json object contain these data. I'm trying to store those data in a variable, and passing through curl POST
$json = '{
"mac": "1234567890",
"dns": "8.8.8.8,4.2.2.1",
"acl_mode": 1
}';
$url = 'http://my-site.com/api';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(array('json' => $json)));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
dd($result);
My result is 500
{
"status": 500,
"error_code": 1005
}
Is the way I set up my curl post wrong ?
After testing with curl in the terminal we found out that the endpoint consumes the entire POST payload without a key.
This was used for testing
curl -X POST -d '{"mac": "1234567890","dns": "8.8.8.8,4.2.2.1","acl_mode": 1}' http://mysite/api
So sending the $json payload as it is, without the json_encode and the array encapsulation.
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
worked just fine.
I have an api link which is working fine on terminal. I wand to use same api link to retrieve data using CURL in php. I tried below code:
<?php
// set up the curl resource
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
//curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, 'urlxxxxx');
// execute the request
$output = curl_exec($ch);
// output the profile information - includes the header
echo "curl response is : <br> ".($output). PHP_EOL;
// close curl resource to free up system resources
curl_close($ch);
?>
but I am getting response as :
curl response is :
{ "error" : "JSON syntax error: malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before \"(end of string)\") at /usr/share/perl5/JSON.pm line 171.\n" }
I am new to CURL guide me regarding the issue for resolving it.
Add:
curl_setopt($ch, CURLOPT_POSTFIELDS, "{}");
so you send an empty JSON object as the parameter. This is the PHP equivalent of
-d "{}"
from the command line.
To put some other array into the post data, use json_encode.
$data = array('userId' => array(),
'user_list' => array("1", "2", "3", "4", "5", "6", "7", "8")
);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data);
You either need to set the method to 'GET' by removing curl_setopt($ch, CURLOPT_POST, true);
Or supplying valid JSON curl_setopt($curl, CURLOPT_POSTFIELDS, "{}");
I am using KeyRock from FiWare.org. Previously everything seems to work find but now the rest server after user authorization send me the following response. I have looked at the server response and it seems to be a NULL/Empty response. But on the NodeJS the request is processed seamlessly. I am using wp-oauth plugin and have modified it to work with FiWare. I am sending this request via PHP CURL.
{
"error": {
"message": "Expecting to find application/json in Content-Type header - the server could not comply with the request since it is either malformed or otherwise incorrect. The client is assumed to be in error.",
"code": 400,
"title": "Bad Request"
}
}
Following is the CURL request I am using:
$url = URL_TOKEN . $url_params;
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $params);
curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($curl, CURLOPT_USERPWD, CLIENT_ID . ":" . CLIENT_SECRET);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, (get_option('wpoa_http_util_verify_ssl') == 1 ? 1 : 0));
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, (get_option('wpoa_http_util_verify_ssl') == 1 ? 2 : 0));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($curl);
have you tried to add application/json in Content-Type header?
BR
I'm trying to debug a curl request to a webservice 'getToken' endpoint.
I'm not 100% confident that the URL and the auth info is getting written in to the curl handle correctly.
I'm trying to use curl_getinfo($ch, CURLINFO_HEADER_OUT); to capture the sent request, but it doesn't give me much info. Is there a way to get more in depth diagnostics about what the actual curl request looks like?
Here's the code:
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_HEADER, 1); // just getting header to see if we got an auth token
curl_setopt($ch, CURLOPT_FILE, $fh);
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLINFO_HEADER_OUT, 1); // capture the header info
curl_setopt($ch, CURLOPT_VERBOSE, 1); // turn verbose on
// execute the curl request
$rh = fopen("request.txt", "w"); // open request file handle
$verbose = fopen('php://temp', 'rw+');
curl_setopt($ch, CURLOPT_STDERR, $verbose);
curl_exec($ch); // execute request
$sent_request = curl_getinfo($ch, CURLINFO_HEADER_OUT);
fwrite($rh, $sent_request); // save the request info
fclose($rh);
!rewind($verbose);
$verboseLog = stream_get_contents($verbose);
echo "Verbose information:\n<pre>", htmlspecialchars($verboseLog), "</pre>\n";
This all works as far as it goes, but returns a 401 every time-- the API admin assures me that the username / pass I have is correct.
I was wondering if I'm somehow getting the URL value wrong, or not sending the right username / pass, but this info isn't printed in the request data saved:
HEAD /export/auth HTTP/1.1
Authorization: Basic Y2FpcmRzdW5mYTpENWlAaVM4cw==
Host: webservices.mycompany.com
Accept: */*
You can see that the username/pass is not recorded (I assume for security). The endpoint URL I think is the host value plus the start of the HEAD value, so webservices.mycompany.com/export/auth?
The "Verbose Information" statement prints nothing. Not sure why on this either!
Thanks for help.
EDIT: added verbose mode from Php - Debugging Curl thanks to commenter immulatin
If you set CURLINFO_HEADER_OUT to true, outgoing headers are available in the array returned by curl_getinfo(), under request_header key:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://foo.com/bar");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "someusername:secretpassword");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_exec($ch);
$info = curl_getinfo($ch);
print_r($info['request_header']);
This will print:
GET /bar HTTP/1.1
Authorization: Basic c29tZXVzZXJuYW1lOnNlY3JldHBhc3N3b3Jk
Host: foo.com
Accept: */*
Note the auth details are base64-encoded:
echo base64_decode('c29tZXVzZXJuYW1lOnNlY3JldHBhc3N3b3Jk');
// prints: someusername:secretpassword
Also note that username and password need to be percent-encoded to escape any URL reserved characters (/, ?, &, : and so on) they might contain:
curl_setopt($ch, CURLOPT_USERPWD, urlencode($username).':'.urlencode($password));
You can also use a proxy tool like Charles to capture the outgoing request headers, data, etc. by passing the proxy details through CURLOPT_PROXY to your curl_setopt_array method.
For example:
$proxy = '127.0.0.1:8888';
$opt = array (
CURLOPT_URL => "http://www.example.com",
CURLOPT_PROXY => $proxy,
CURLOPT_POST => true,
CURLOPT_VERBOSE => true,
);
$ch = curl_init();
curl_setopt_array($ch, $opt);
curl_exec($ch);
curl_close($ch);
curl_getinfo() must be added before closing the curl handler
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://example.com/bar");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "someusername:secretpassword");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_exec($ch);
$info = curl_getinfo($ch);
print_r($info['request_header']);
curl_close($ch);
The request is printed in a request.txt with details
$ch = curl_init();
$f = fopen('request.txt', 'w');
curl_setopt_array($ch, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_VERBOSE => 1,
CURLOPT_STDERR => $f,
));
$response = curl_exec($ch);
fclose($f);
curl_close($ch);
You can also use curl_getinfo() function.