I have an issue with SounCloud PHP wrapper. When I make an oembed request to the SounCloud API. This last one gives me back a string data. It's composed by something like a header and the JSON data. It looks like this:
Age: 0
Via: 1.1 varnish
X-Cache: MISS
Vary: Accept-Encoding
{"version":1.0,"type":"rich",......."author_url":"https://soundcloud.com/forss"}
So when I use json_decode function on this data it can't decode the JSON part.
Does anyone have any idea in how do delete header from this content?
NB: I am working behind an proxy so I have add this code below to make the curl request work
$client->setCurlOptions(array(
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_PROXY => "http://xxxxxxxxxx",
CURLOPT_PROXYPORT => 8080,
CURLOPT_PROXYUSERPWD => "xxxx:xxxx",
CURLOPT_SSL_VERIFYPEER => 0));
That's strange! what you can do is:
if(strstr($response, "{") !== false){
$response = substr($response, strstr("{"));
}
Related
I have searched a lot, and found many related questions and forums related to this, but this one is a challenging one.
I'm trying to POST a complex array via curl. It has to be form-data while the first value in the array is of type JSON.
The two other values of array are two images which are uploaded and ready to send.
I tried to run it in Postman, and works perfectly fine. I used the generated PHP code from Postman, but it is not working. Seems like postman is handling some of its tricks without revealing them to us.
Any way, I'm posting a Postman image to illustrate what I mean:
As you can see, I'm sending the data in form-data tab, my first value (param1) is a JSON with content-type application/json, the second and third values are images uploaded in Postman.
This works just fine in Postman.
The problem is, if I set Content-Type:multipart/form-data in header, the destination server throws an error saying the content-type must be JSON.
If I set the Content-Type:application/json in header, the destination server says content must be of type Multipart.
Somehow, I need to set both content-types. The main one as form-data and the one for param1 as JSON.
I paste the Postman code as well, may that be a good start for you fellas to help out with the code.
Postman Code:
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'http://xxxxx.com/xxxx/xxx/xxxx',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => array('param1' => '{
"AgentId":"1414",
"ContractId":36529,
"Files":[
{
"FileName":"car_card_front_image.png",
"FileTypeId":2
},
{
"FileName":"car_card_back_image.png",
"FileTypeId":2
}
]
}','param2'=> new CURLFILE('/C:/images/icons/car_card_back_image.png'),'param3'=> new CURLFILE('/C:/images/icons/car_card_front_image.png')),
CURLOPT_HTTPHEADER => array(
'authenticationToken: xxxx-xxx-xx-xxxxxxxx'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
The PHP generated code by postman, is not working. One of the reasons can be that there's no content-type mentioned in it.
I tried modifying the code, adding content-types in header and in parameter, nothing seems to work.
If Postman can do it, we should be able it too, right?
Go ahead, make as much changes as you would or suggest anything that comes to your mind, I will test them all.
Cheeeeers...
May i suggest the ixudrra/curl library ?
It would make your life easier ....
$response = Curl::to('http://example.org')
->withData( array( 'Foo' => 'Bar' ) )
->withFile( 'image_1', '/path/to/dir/image1.png', 'image/png', 'imageName1.png' )
->withFile( 'image_2', '/path/to/dir/image2.png', 'image/png', 'imageName2.png' )
->post();
Request:
$headers = array( 'Content-Type:application/xml' );
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'https://example.com',
CURLOPT_POST => 1,
CURLOPT_HEADER => $headers,
CURLOPT_USERPWD=>'test:test',
CURLOPT_POSTFIELDS => $XMLData
));
$APIResponse = curl_exec($curl);
curl_close($curl);
And I get this response from an API
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html; charset=utf-8
Server: ----
X-AspNet-Version: -----
X-Powered-By: ASP.NET
Date: ---- GMT
Content-Length: 100
<?xml version="1.0" encoding="utf-8"?><response xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.example.com"><ID>12345</ID></response>
I want to fetch ID from xml ID tag. How can I get that in my php code?
You're getting the HTTP header data included within your response from cURL, which is making it hard to extract the XML part.
However this is happening due to a simple misunderstanding - the CURLOPT_HEADER option doesn't do what you think it does.
That doesn't include your request headers in the request (as your code seems to be trying to do), instead it sets an option telling cURL whether or not the response headers should be included in the main output or not. If you set
CURLOPT_HEADER => 0
in your code, your problem should go away - then only the response body (in your case, just the XML) will included in the output from curl_exec.
In the meantime, if you need to set custom HTTP headers in your request, you can do it via the CURLOPT_HTTPHEADER option - a detailed example can be found here and in many other places online.
P.S. Admittedly these option names are not, in themselves, very clear about the difference between them, but the PHP manual does describe what they do in more detail.
I am developing REST API and while it is easy to set raw JSON data for request in cURL for POST
$payload = json_encode(array("user" => $data));
//attach encoded JSON string to the POST fields
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
I cannot figure out how to send such data with GET requests.
Is there something like CURLOPT_GETFIELDS or CURLOPT_RAWDATA? The purpose of sending JSON with GET request is to pass in some params.
I do not wish to add formdata to the request, I wish to post JSON so that it can be parsed on the receiver.
Thanks!
EDIT:
based on comments I want to avoid confusion, so the resulting request should look like:
GET / HTTP/1.1
Host: 127.0.0.1:3000
Content-Type: application/json
Accept: application/json
Host: 127.0.0.1:3000
content-length: 13
Connection: keep-alive
cache-control: no-cache
{
"a": "b"
}
as you can see, GET request here has data and it is parsed and works perfectly by web server. How do I achieve this with cURL?
GET requests do not have a body, that's the whole idea: you're just getting something from the server, as opposed to posting something to it. From RFC 7231:
A payload within a GET request message has no defined semantics;
sending a payload body on a GET request might cause some existing
implementations to reject the request.
In other words, a GET request can have data, but it should not. From earlier in the spec, where GET is defined as a safe method:
Request methods are considered "safe" if their defined semantics are
essentially read-only; i.e., the client does not request, and does
not expect, any state change on the origin server as a result of
applying a safe method to a target resource.
...
Of the request methods defined by this specification, the GET, HEAD,
OPTIONS, and TRACE methods are defined to be safe.
If you really want to have JSON in your GET request (and send it to a reasonably implemented server resource) the only place it can go is in the URI as part of the query string. For GET requests I find using file_get_contents to be much easier than dealing with cURL.
<?php
$payload = json_encode(["user" => $data]);
$url_data = http_build_query([
"json" => $payload
]);
$url = "https://some.example/endpoint.php?" . $url_data;
$result = file_get_contents($url);
If you want to send it to an unreasonably implemented server resource, and violate the spirit of the HTTP RFCs, you could do this:
<?php
$url = "https://some.example/endpoint.php";
$payload = json_encode(["user" => $data]);
$ctx = stream_context_create(["http" => [
"header"=>"Content-Type: application/json",
"content"=>$payload
]]);
$result = file_get_contents($url, false, $ctx);
If you're determined to do this specifically with cURL, you might have luck with the CURLOPT_CUSTOMREQUEST option set to "GET" and CURLOPT_POSTDATA with your data.
I was wondering what is the default Content-Type header option when requesting a json string from an API.
I've noticed even if the requested Content-Type is application/json the response header Content-Type will be text/html
Does file_get_contents set the headers automatically based on what it is requesting or does it have a default one that is used always?
Does file_get_contents set the headers automatically based on what it is requesting or does it have a default one that is used always?
I think no defaults. For the context parameter you read below and see the 4-th example in docs:
A valid context resource created with stream_context_create(). If you don't need to use a custom context, you can skip this parameter by NULL.
Tested with Wireshark.
PHP 5.5.8 sends:
POST /path HTTP/1.0
Host: example.com
Content-Length: [appropriate number]
Content-Type: application/x-www-form-urlencoded
For the following context:
$options = array(
'http' => array(
'method' => 'POST',
'content' => $content
)
);
$context = stream_context_create($options);
I'm working on a XML reader and am running into a odd issue with a few feeds. Using CURL or even file_get_contents the feeds load as binary data more often than real data. Whenever I load the feed in a browser it looks fine.
The specific feed is http://www.winnipegsun.com/home/rss.xml
The code I am using is
$string = file_get_contents("http://www.winnipegsun.com/home/rss.xml");
var_dump( $string );
The response is gzipped:
If you look at the HTTP headers:
Content-Encoding: gzip
Unzip it with PHP:
gzinflate(substr($string, 10));
http://php.net/manual/en/function.gzinflate.php
Hope that helps... cheers
You should be able to send an empty Accept-Encoding header to the server and then it should not send the content gzipped or return a Not Acceptable response:
$string = file_get_contents(
"http://www.winnipegsun.com/home/rss.xml",
FALSE,
stream_context_create(
array(
'http' => array(
'method' => "GET",
'headers' => 'Accept-Encoding:\r\n'
)
)
)
);
var_dump($string);
I am not sure the webserver is configured correctly though, because it wouldnt respond to that with the uncompressed feed, even when adding Cache Control headers telling to it not send a cached response. Oddly enough, just doing
$string = file_get_contents("http://www.winnipegsun.com/home/rss.xml?".time());
worked out of the box. And you can also send a POST request.