Illegal string offset foreach - php

i have this code, and i get the error when i use foreach on the bottom of the page.
<table>
<tr>
<?php
$data =('https://www.example.com/api/report_advertiser?key=abcd&campaigns=6757955,6781745,6739793,6349821&quick=last_month');
$data_json = json_encode($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,$data_json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
foreach ($response as $value)
echo $value['campaigns']
?>
</tr>
</table>

$response = curl_exec($ch);
Looking at this code, you should know that curl_exec() returns a string, when the execution was successful, otherwise false.
But in the next step you iterate over a string
foreach ($response as $value) {
echo $value['campaigns'];
}
You can iterate only over iterable types like arrays.
As it looks like you expect a JSON string you can convert it into an array. Use json_decode() for that and pass true as second parameter to receive an associative array instead of an object.
Assuming you will receive a multidimensional array having the inner loops key campaigns, following code will do the job.
$response = json_decode($response, true);
foreach ($response as $value) {
echo $value['campaigns'];
}
Update 1
Using the URL you provided before (I anonymized because you submitted credentials) you will receive an error.
if (!empty($response['errors'])) {
throw new Exception(print_r($response['errors'], true));
}
Gives out following, so it can not work as you expect, because the data is simply not available.
[status] => 405
[code] => 13
[title] => Method not allowed for this action

Related

PHP parse array data using file_get_contents($url)

I have the following data I pulled from an API using PHP's file_get_contents($url), I would like to parse this data and put each comma separated value into a variable whilst looping to the next set (there are thousands of row, I simply extracted the first two), I have tried parsing methods however most have an element consisting of the datalabel:data, any assistance would be gladly appreciated.
[[1610223840000,"3.63410000","3.65100000","3.62900000","3.64150000","14194.01000000",1610223899999,"51684.84892800",195,"7619.89000000","27756.15839400","0"],[1610223900000,"3.64610000","3.65090000","3.63410000","3.65000000","2219.73000000",1610223959999,"8090.68646600",46,"1176.75000000","4290.44934900","0"]]
Ok figured this out today, for anyone who needs it
$ch = curl_init();
$url = "https://api.blahblahblah";
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
$result = curl_exec($ch);
curl_close($ch);
$obj = json_decode($result, true);
foreach ($obj as $key => $value) {
echo $value[0] . "<br>";
echo $value[1] . "<br>";
}

How to return an object and not a string with PHP curl request

I am attempting to request data from a url and am having success for most endpoints except for one. Throughout my troubleshooting, I can retrieve the text and display it in the browser, however, when I try to store it as an object, I get nothing. It actually still stores as a string. I would like to iterate through the object so that I can run calculations on the contents.
Is it because the JSON string is malformed? If so, how do I correct? I have tried a variety of solutions with no success.
Important to note that gzip is required, for that reason I have included 'ob_gzhandler'. the contents only echos when I use gzhandler.
THE ECHOS IN THE FUNCTION ARE FOR TROUBLESHOOTING PURPOSES. THEY ILLUSTRATE WHERE STRINGS ARE BEING PRODUCED AND NOT OBJECTS.
function CallAPI_oanda_v20($instruments)
{
$curl = curl_init();
$url = 'https://api-fxtrade.oanda.com/v3/instruments/'.$instruments.'/positionBook';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HTTPGET,TRUE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Authorization: <USE MY API KEY>'));
$response = curl_exec($ch);
echo gettype($response); //returns "string"
$json = json_decode($response, true);
echo gettype($json); //returns "NULL"
curl_close($ch);
return $json;
}
$call = CallAPI_oanda_v20("GBP_USD");
ob_start('ob_gzhandler');
//$output = ob_get_contents();
echo $call->positionBook; //returns an error:Trying to get property 'positionBook' of non-object
echo gettype($output); //THIS WILL RETURN "string".
$jsonIterator = new RecursiveIteratorIterator(
new RecursiveArrayIterator(json_decode($output, TRUE)),
RecursiveIteratorIterator::SELF_FIRST);
foreach ($jsonIterator as $key => $val) {
if(is_array($val)) {
echo "$key:\n";
} else {
echo "$key => $val\n";
}
}
In order to troubleshoot that the call is correct, I echo the contents by graying out the following line:
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
Here is the json string that prints:
{"positionBook":{"instrument":"GBP_USD","time":"2019-09-02T00:00:00Z","unixTime":"1567382400","price":"1.21584","bucketWidth":"0.00050","buckets":[{"price":"1.19950","longCountPercent":"0.0189","shortCountPercent":"0.0189"},{"price":"1.20000","longCountPercent":"0.0000","shortCountPercent":"0.0189"},{"price":"1.20100","longCountPercent":"0.0000","shortCountPercent":"0.0189"},{"price":"1.20150","longCountPercent":"0.0000","shortCountPercent":"0.0757"}]}}
ob_start('ob_gzhandler');
$output = ob_get_contents();
echo gettype($output); //THIS WILL RETURN "string".
This is exactly what you expect. The output buffer is just a big string that is appended to whenever you write to it. When you gettype($output) you're just getting the output of that buffer, which is nothing to do with any of your other code.
As you're not actually writing anything to said buffer, it will be an empty string.
You're not actually using the result of your function ($call) anywhere. You should be passing it to your recursive array iterator. In your top function you probably want to add TRUE as the second argument to json_decode so it's fully array based.
SOLVED. I was improperly decoding the gzip string.
$response = gzdecode($response);
This was the key, along with removing:
ob_start('ob_gzhandler');
$output = ob_get_contents();
Here is the solved piece of code:
{
$curl = curl_init();
$url = 'https://api-fxtrade.oanda.com/v3/instruments/'.$instruments.'/positionBook';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HTTPGET,TRUE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Authorization: <USE MY API KEY>'));
$response = curl_exec($ch);
$response = gzdecode($response);
$json = json_decode($response, true);
curl_close($ch);
return $json;
}
$call = CallAPI_oanda_v20("GBP_USD");
echo '<pre>';
print_r($call);
echo '<pre>';```

Getting data from JSON

Just wondering if anyone knew what I was doing wrong here?
I am trying to get data from an API for bitcoin via php. However, I am getting no results from my php page.
$url = "https://api.coinmarketcap.com/v1/ticker/bitcoin/?convert=EUR";
$json = file_get_contents($url);
$json_data = json_decode($json, true);
echo "ID: ". $json_data["id"];
However I am getting nothing show at all on the php page. If I use the code below, It works and dumps out the entire information. But, I would prefer to obtain the information separately, instead of one big dump.
$url = "https://api.coinmarketcap.com/v1/ticker/bitcoin/?convert=EUR";
$ch = curl_init();
// Disable SSL verification
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// Will return the response, if false it print the response
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Set the url
curl_setopt($ch, CURLOPT_URL,$url);
// Execute
$result=curl_exec($ch);
// Closing
curl_close($ch);
var_dump(json_decode($result, true));
Anyone have any ideas why the first code block isn't working? Thanks! Very new to API and Json
Using cURL is much better
Updated code (needs error checking)
$url = "https://api.coinmarketcap.com/v1/ticker/bitcoin/?convert=EUR";
$ch = curl_init();
// Disable SSL verification
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// Will return the response, if false it print the response
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Set the url
curl_setopt($ch, CURLOPT_URL,$url);
// Execute
$result=curl_exec($ch);
// Closing
curl_close($ch);
$json_data = json_decode($result, true);
foreach ($json_data as $item)
echo "ID: ". $item["id"];
I have printed the result it will produce following output
echo "<pre>";
print_r(json_decode($result, true));
Array
(
[0] => Array
(
[id] => bitcoin
[name] => Bitcoin
[symbol] => BTC
[rank] => 1
[price_usd] => 3821.37
[price_btc] => 1.0
[24h_volume_usd] => 2089880000.0
[market_cap_usd] => 63298556016.0
[available_supply] => 16564362.0
[total_supply] => 16564362.0
[percent_change_1h] => -1.72
[percent_change_24h] => -4.57
[percent_change_7d] => -15.76
[last_updated] => 1505359771
[price_eur] => 3214.536444
[24h_volume_eur] => 1758007056.0
[market_cap_eur] => 53246745321.0
)
)
so you can use foreach loop if your api contain multiple
$data=json_decode($result, true);
foreach($data as $key=>$val){
echo $val->id;
}
full code
<?php
$url = "https://api.coinmarketcap.com/v1/ticker/bitcoin/?convert=EUR";
$ch = curl_init();
// Disable SSL verification
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// Will return the response, if false it print the response
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Set the url
curl_setopt($ch, CURLOPT_URL,$url);
// Execute
$result=curl_exec($ch);
// Closing
curl_close($ch);
$data=json_decode($result, true));
foreach($data as $key=>$val){
echo $val->id;
}
The setting you are looking for is allow_url_fopen.
You have two ways of getting around it without changing php.ini, one of them is to use fsockopen(), and the other is to use cURL.
I recommend using cURL over file_get_contents() anyways, since it was built for this.

GET a JSON Array with an API in PHP?

Basically I'm trying to GET an API that gives me a JSON array. It should only be one integer. Whenever I try to though I receive the error:
Notice: Trying to get property of non-object in /public_html/call.php on line 16
Here's call.php:
<?php
require 'connection.php';
$players2weeks = '(removed api)';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $players2weeks);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$response = curl_exec($ch);
curl_close($ch);
$response = json_decode($response);
print_r($response);
echo $response->players_2weeks;
?>
I have the print_r for troubleshooting but I'm getting nothing. My apologies for a noob question by the way, I have no experience with JSON.
Appreciate the help!
I think you can use this Code :
<?php
require 'connection.php';
$players2weeks = '(removed api)';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $players2weeks);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$response = curl_exec($ch);
curl_close($ch);
$responses = json_decode($response);
print_r($responses);
echo $responses['players_2weeks'];
?>
You should change the format of echo when the decoded JSON objects. and the Variable same means some clashes in the print so I changed the $response variable also...
You have to make array to json string by using the json_encode() function on the api.
For example: xxx.php (api)
$result = array(); //return array
echo json_encode($result);
Then you can get result by json array on the api caller.
var_dump(json_decode($result)); // Object
var_dump(json_decode($result, true)); // Associative array

Curl request with array values as input for query (GET) params

I have output from an array I would like to use as input in a PHP Curl request. Do I store them as another array and loop through the array with the Curl request?
Here is the output from the array:
foreach ($threadsarray['threads'] as $thread) {
print $thread['id']."<br />";
}
These are values I would like to use as input for Curl (obviously these values are different every time depending on the output for each loop above):
178369845
291476958
224408290
270960091
270715888
270513013
229639500
229630641
215503057
214314923
I want to execute a curl request for each of those thread id's...
Here is how I am building the Curl request:
$url2 = 'https://api.website.com/endpoint';
$data2 = array (
'specialkey' => '123abcd789xyz',
'anotherparam' => 'Brown',
'locale' => 'en-US',
'thread_id' => array (
$thread['id']
)
);
//build the query string because this is a get request
$params2 = '';
foreach($data2 as $key2=>$value2)
$params2 .= $key2.'='.$value2.'&';
$params2 = trim($params2, '&');
// Excecute the curl request
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url2.'?'.$params2 );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 'false');
$mycurlresult = curl_exec($ch);
echo '<pre>';
$resultarray = json_decode($mycurlrequest, TRUE);
print_r($resultarray);
echo '</pre>';
if (FALSE === $mycurlrequest)
throw new Exception(curl_error($ch), curl_errno($ch));
I can't seem to build the request string correctly...what am I missing?
I can't really test this, but I'd suggest something like this. First, set up your curl, and create an array with an empty placeholder for thread_id.
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 'false');
$url2 = 'https://api.website.com/endpoint';
$data2 = array(
'specialkey' => '123abcd789xyz',
'anotherparam' => 'Brown',
'locale' => 'en-US',
'thread_id' => ''
);
Then loop over your array. For each item, replace the thread_id key in the $data2 parameters array with that item's id, build the query using http_build_query and execute the request.
foreach ($threadsarray['threads'] as $thread) {
$data2['thread_id'] = $thread['id']; // add the current id
$params2 = http_build_query($data2); // build the new query
curl_setopt($ch, CURLOPT_URL, $url2.'?'.$params2 );
$mycurlresult = curl_exec($ch);
echo '<pre>';
$resultarray = json_decode($mycurlrequest, TRUE);
print_r($resultarray);
echo '</pre>';
if (FALSE === $mycurlrequest)
throw new Exception(curl_error($ch), curl_errno($ch));
}

Categories