Strange chars in JSON (obtained after cURL auth) - php

This is the function I use to grab a JSON file from Feedbin API.
<?php
error_reporting(E_ALL);
// JSON URL which should be requested
$json_url = 'https://api.feedbin.me/v2/entries.json';
$username = 'my_username'; // authentication
$password = ' my_password'; // authentication
// Initializing curl
$ch = curl_init( $json_url );
// Configuring curl options
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_USERPWD => $username . ":" . $password // authentication
);
// Setting curl options
curl_setopt_array( $ch, $options );
// Getting results
$result = curl_exec($ch); // Getting JSON result string
print_r ($result);
?>
Problem is the JSON I get is a bit.. strange.
It has a lot of chars like \u003E\u003C/a\u003E\u003C/p\u003E\n\u003Cp\u003E ...
You can see the JSON here.

When you call json_decode in PHP on strings that contain these encodings they will be correctly decoded. http://json.org/ lists \ufour-hex-digits as a valid character. There is no issue.
$ echo json_decode('"\u003E\u003C/a\u003E\u003C/p\u003E\n\u003Cp\u003E"');
></a></p>
<p>

They are valid unicode sequence. Here is a simple example
$data = array(
"abc" => 'åbcdéfg'
);
// Encode
$data = json_encode($data) . "\n";
// Output Value
echo $data;
// Output Decoded Value
print_r(json_decode($data));
Output
{"abc":"\u00e5bcd\u00e9fg"}
stdClass Object
(
[abc] => åbcdéfg
)

Related

PHP - json_decode - issues decoding string

I'm playing with the API from deepl.com that provides automatic translations. I call the API through cURL and I get a json string in return which appears to be fine but cannot be decoded by PHP for some reason.
Let me show first how I make the cURL call :-
$content = "bonjour <caption>monsieur</caption> madame";
$url = 'https://api.deepl.com/v2/translate';
$fields = array(
'text' => $content,
'target_lang' => $lg,
'tag_handling' => 'xml',
'ignore_tags' => 'caption',
'auth_key' => 'my_api_key');
$fields_string = "";
foreach($fields as $key=>$value)
{
$fields_string .= $key.'='.$value.'&';
}
rtrim($fields_string, '&');
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded','Content-Length: '. strlen($fields_string)));
$result = curl_exec($ch);
curl_close($ch);
If at this stage I do
echo $result;
I get:
{"translations":[{"detected_source_language":"FR","text":"Hola <caption>monsieur</caption> Señora"}]}
Which seems ok to me. Then if I use code below -
echo gettype($result);
I get "string" which is still ok but now, the following code fails:
$result = json_decode($result,true);
print_r($result);
The output is empty!
If I now do something like this:
$test = '{"translations":[{"detected_source_language":"FR","text":"Hola <caption>monsieur</caption> Señora"}]}';
echo gettype($test);
$test = json_decode($test,true);
print_r($test);
I get a perfectly fine array:
(
[translations] => Array
(
[0] => Array
(
[detected_source_language] => FR
[text] => Hola <caption>monsieur</caption> Señora
)
)
)
I did nothing else than copy/pasting the content from the API to a static variable and it works but coming from the API, it doesn't. It's like the data coming from the API is not understood by PHP.
Do you have any idea of what's wrong?
Thanks!
Laurent
I've had very similar issues before and for me the issue was with the encoding of the data returned from an API being unicode. I'm guessing when you do your copy/paste the string you hard-code ends up being a different encoding so it works fine when passed into json_decode.
The PHP docs specify json_decode only works with UTF-8 encoded strings:
http://php.net/manual/en/function.json-decode.php
You may be able to use mb_convert_encoding() to convert to UTF-8:
http://php.net/manual/en/function.mb-convert-encoding.php
Try this before calling json_decode:
$result = mb_convert_encoding($result, "UTF-8");
Make sure to set CURLOPT_RETURNTRANSFER to true. Only then will curl_exec actually return the response, otherwise it will output the response and return a boolean, indicating success or failure.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
if ($result !== false) {
$response = json_decode($result, true);
// do something with $response
} else {
// handle curl error
}
Like said #Eilert Hjelmeseth you have some special char in your JSON string => "Señora"
Another way to encode a string to UTF8: utf8_encode() :
$result = json_decode(utf8_encode($result),true);

can't get array key after i json_decode it

i json_decode ed an array, even thought i can print_r it, i cant call its keys. Im not a pro nor nothing, so any help is welcome. I tried a lot of things, but i cant get it to work.
My goal is to present the array results i a way that is easy to read, so I want to access it in the HTML part, and not only to be printed.
the array that i get after print_r is: Array ( [0] => stdClass Object ( [pda] => 41.52258509711 [upa] => 51.345212698165 [uu] => www.chevrolet.com.ar/ ) )
<?php
$accessID = "xxxxx";
$secretKey = "xxxxx";
// Set your expires times for several minutes into the future.
// An expires time excessively far in the future will not be honored by the Mozscape API.
$expires = time() + 300;
// Put each parameter on a new line.
$stringToSign = $accessID."\n".$expires;
// Get the "raw" or binary output of the hmac hash.
$binarySignature = hash_hmac('sha1', $stringToSign, $secretKey, true);
// Base64-encode it and then url-encode that.
$urlSafeSignature = urlencode(base64_encode($binarySignature));
$cols = "103079215108";
// Put it all together and you get your request URL.
$requestUrl = "http://lsapi.seomoz.com/linkscape/url-metrics/?Cols=".$cols."&AccessID=".$accessID."&Expires=".$expires."&Signature=".$urlSafeSignature;
// Put your URLS into an array and json_encode them.
$batchedDomains = array('xxxxxxxx.com');
$encodedDomains = json_encode($batchedDomains);
// Use Curl to send off your request.
// Send your encoded list of domains through Curl's POSTFIELDS.
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => $encodedDomains
);
$ch = curl_init($requestUrl);
curl_setopt_array($ch, $options);
$content = curl_exec($ch);
curl_close( $ch );
$contents = json_decode($content);
print_r($contents);
$pageAuthority=$contents->upa;
$domainAuthority = $contents->pda;
$theUrl = $contents->uu;
?>
<html>
<body>
<h1>MOZcape API</h1>
<ul>
<li>URL: <?php echo $theUrl; ?></li>
<li>PA: <?php echo $pageAuthority; ?></li>
<li>DA: <?php echo $domainAuthority; ?></li>
</ul>
</body>
</html>
Just had to change $contents = json_decode($content);
to $contents = json_decode($content, true); so it can be an array.
Then call it with:$pageAuthority=$contents[0]["upa"];
Instead of:$pageAuthority=$contents->upa;

how to get information from url into variable

So i'm trying to get location usng reverse geocoding
https://developers.google.com/maps/documentation/geocoding/#ReverseGeocoding
so my question is (since i'm very new to php) how to get the result from URL into parameter (the result will be json encoded data)
you can use function file_get_contents to get Data from URL
$API_KEY ="XXXXXXX";
$url = "http://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&key=".$API_KEY;
$data = #file_get_contents($url);
$jsondata = json_decode($data,true);
if(is_array($jsondata) && $jsondata['status'] == "OK")
{
echo '<pre>'; print_r($jsondata);echo '</pre>';
}
To get the data we use the PHP curl functions.
[php]
// jSON URL which should be requested
$json_url = ‘www.yourdomain.com';
$username = ‘your_username'; // authentication
$password = ‘your_password'; // authentication
// jSON String for request
$json_string = ‘[your json string here]';
// Initializing curl
$ch = curl_init( $json_url );
// Configuring curl options
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_USERPWD => $username . “:” . $password, // authentication
CURLOPT_HTTPHEADER => array(‘Content-type: application/json’) ,
CURLOPT_POSTFIELDS => $json_string
);
// Setting curl options
curl_setopt_array( $ch, $options );
// Getting results
$result = curl_exec($ch); // Getting jSON result string
[/php]
The result will be a jSON string.
Normally you have to send a jSON string to the jSON URL and you will get a jSON string back. To encode your data, just use the php jSON functions. Use json_encode to create a json string from your PHP array and use json_decode to transform the jSON string to PHP array.

Using cURL with wunderground api

Hey I'm having some issues using cURL (I can't use file_get_contents because my web host won't allow it) to access parts of the wunderground weather api.
When I use the following code to access info on weather conditions I have no issues whatsoever:
<? $json_url = 'http://api.wunderground.com/api/b2b4a1ad0a889006/geolookup/conditions
/q/IA/Cedar_Rapids.json';
// jSON String for request
$json_string = '[http://api.wunderground.com/api/b2b4a1ad0a889006/geolookup/conditions
/q/IA/Cedar_Rapids.json]';
// Initializing curl
$ch = curl_init( $json_url );
// Configuring curl options
$options = array(
CURLOPT_RETURNTRANSFER => true,
);
// Setting curl options
curl_setopt_array( $ch, $options );
// Getting results
$result = curl_exec($ch); // Getting jSON result string
$parsed_json = json_decode($result);
$location = $parsed_json->{'location'}->{'city'};
$temp_f = $parsed_json->{'current_observation'}->{'temp_f'};
echo "Current temperature in ${location} is: ${temp_f}\n";
?>
However, when I make slight modifications in order to get data on high and low tides using the following code I get nothing:
<? $json_url = 'http://api.wunderground.com/api/b2b4a1ad0a889006/tide/q/NJ/Wildwood.json';
// jSON String for request
$json_string = '[http://api.wunderground.com/api/b2b4a1ad0a889006/tide/q/NJ/Wildwood.json]';
// Initializing curl
$ch = curl_init( $json_url );
// Configuring curl options
$options = array(
CURLOPT_RETURNTRANSFER => true,
);
// Setting curl options
curl_setopt_array( $ch, $options );
// Getting results
$result = curl_exec($ch); // Getting jSON result string
$tide_time = $parsed_json->{'tide'}->{'tideSummary'}->{'date'}->{'pretty'};
echo "High tide is at ${tide_time} ";
?>
Now I know the issue may be that I'm dealing with an array in the second example but I'm not sure how to modify the code. I know that the record for the first low tide is [3] and I've tried making the following modification with no luck.
$tide_time = $parsed_json->{'tide'}->{'tideSummary'}->[3]->{'date'}->{'pretty'};
echo "High tide is at ${tide_time} ";
Any help would be greatly appreciated!
The second parameter of json_decode allows you to decode the JSON into an array instead of an object. Try turning that on so you always know what you're dealing with:
$response = json_decode($result, true);
If that fails maybe you're not using the API correctly?

Getting JSON response with PHP

I'm trying to connect an API that uses 0AUTH2 via PHP. The original plan was to use client-side JS, but that isn't possible with 0AUTH2.
I'm simply trying get a share count from the API's endpoint which is here:
https://api.bufferapp.com/1/links/shares.json?url=[your-url-here]&access_token=[your-access-key-here]
I do have a proper access_token that I am using to access the json file, that is working fine.
This is the code I have currently written, but I'm not even sure I'm on the right track.
// 0AUTH2 ACCESS TOKEN FOR AUTHENTICATION
$key = '[my-access-key-here]';
// JSON URL TO BE REQUESTED
$json_url = 'https://api.bufferapp.com/1/links/shares.json?url=http://bufferapp.com&access_token=' . $key;
// GET THE SHARE COUNT FROM THE REQUEST
$json_string = '[shares]';
// INITIALIZE CURL
$ch = curl_init( $json_url );
// CONFIG CURL OPTIONS
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array('Content-type: application/json') ,
CURLOPT_POSTFIELDS => $json_string
);
// SETTING CURL AOPTIONS
curl_setopt_array( $ch, $options );
// GET THE RESULTS
$result = curl_exec($ch); // Getting jSON result string
Like I said, I don't know if this is the best method - so I'm open to any suggestions.
I'm just trying to retrieve the share count with this PHP script, then with JS, spit out the share count where I need it on the page.
My apologies for wasting anyone's time. I have since been able to work this out. All the code is essentially the same - to test to see if you're getting the correct response, just print it to the page. Again, sorry to have wasted anyones time.
<?php
// 0AUTH2 ACCESS TOKEN FOR AUTHENTICATION
$key = '[your_access_key_here]';
// URL TO RETRIEVE SHARE COUNT FROM
$url = '[your_url_here]';
// JSON URL TO BE REQUESTED - API ENDPOINT
$json_url = 'https://api.bufferapp.com/1/links/shares.json?url=' . $url . ' &access_token=' . $key;
// GET THE SHARE COUNT FROM THE REQUEST
$json_string = '[shares]';
// INITIALIZE CURL
$ch = curl_init( $json_url );
// CONFIG CURL OPTIONS
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array('Content-type: application/json') ,
CURLOPT_POSTFIELDS => $json_string
);
// SETTING CURL AOPTIONS
curl_setopt_array( $ch, $options );
// GET THE RESULTS
$result = curl_exec($ch); // Getting jSON result string
print $result;
?>

Categories