Iterating part of array causes error - php

I have some Json being returned from facebook which I'm then parsing in to an array using json _decode. The data ends up looking like this (this is just the snippet I'm interested in):
( [data] =>
Array ( [0] =>
Array (
[id] => 1336269985867_10150465918473072
[from] =>
Array ( [name] => a name here
[category] => Community
[id] => 1336268295867 )
[message] => A message here
Now I've been able to iterate over this data and get what I need:
$jsonDecoded = json_decode($json, true);
$xmlOutput = '<?xml version="1.0"?><data><items>';
foreach ($jsonDecoded as $e) {
foreach ($e as $i) {
$xmlOutput .= '<item><timestamp>' . $i['created_time'] . '</timestamp><title><![CDATA[ ' . $i['message'] .' ]]></title><link>' . $link . '</link><type>facebook</type></item>';
}
}
$xmlOutput .= '</items></data>';
..up until now where I need to check on the from->id value.
I added this line in the second for each:
foreach ($e as $i) {
if($i['from']['id'] == '1336268295867') {
But this just gives me an error:
Fatal error: Cannot use string offset as an array in /Users/Desktop/Webs/php/getFeeds
Any ideas why? I'm sure this is the correct way to get at that value and in actual fact if I echo this out in my loop instead of doing the if statement above I get the value back:
$jsonDecoded = json_decode($json, true);
$xmlOutput = '<?xml version="1.0"?><data><items>';
foreach ($jsonDecoded as $e) {
foreach ($e as $i) {
echo $i['from']['id']
This returns me all of the from->id values in the code returned from facebook and then following this I get the error:
133626829985867133626829985867133626829985867133626829985867195501239202133626829985867133626829985867133626829985867133626829985867133626829985867
Fatal error: Cannot use string offset as an array in /Users/Desktop/Webs/php/getFeeds.php on line 97
(line 97 is the echo line)

Your code makes a lot of assumptions about $i['from']['id'] and at least one of them is incorrect for at least one entry.
Let's add some tests:
$jsonDecoded = json_decode($json, true);
$xmlOutput = '<?xml version="1.0"?><data><items>';
foreach ($jsonDecoded as $e) {
if ( !is_array($e) ) {
die('type($e)=='.gettype($e).'!=array');
}
foreach ($e as $i) {
if ( !is_array($i) ) {
die('type($i)=='.gettype($i).'!=array');
}
else if ( !array_key_exists('from', $i) ) {
die('$i has no key "from"');
}
else if ( !is_array($i['from']) ) {
die('type($i["from"])=='.gettype($i['from']).'!=array');
}
else if ( !array_key_exists('id', $i['from']) ) {
var_dump($i);
die('$i["from"] has no key "id"');
}
echo $i['from']['id'];
}
}
And then you can add a var_dump(...) before the die(...) to take a look at the actual data.

It seems to me that (according to the last code snippet) at some point your $i is not an array anymore. Try to do:
$jsonDecoded = json_decode($json, true);
$xmlOutput = '<?xml version="1.0"?><data><items>';
foreach ($jsonDecoded as $e) {
foreach ($e as $i) {
if(is_array($i))
echo $i['from']['id']

Related

Looping through a JSON in PHP

I'm trying to loop through a JSON that I post to my PHP backend. The JSON looks like this:
[
{
"number":"5613106"
},
{
"number":"56131064"
},
{
"number":"56131063"
}
]
I post it from Postman like so:
I want to be able to print each number that I've posted individually using
echo $number;
Right now when I use the following it just prints the last number:
$number = $json['number'];
echo $number;
My function:
public function check_users_post()
{
$json = $this->request->body;
print_r($json);
$this->response($json, REST_Controller::HTTP_OK);
}
The output:
Array
(
[0] => Array
(
[number] => 5613106
)
[1] => Array
(
[number] => 56131064
)
[2] => Array
(
[number] => 56131063
)
)
Hope this generic iterator will help you.
$jsonIterator = new RecursiveIteratorIterator(
new RecursiveArrayIterator(json_decode($json, TRUE)),
RecursiveIteratorIterator::SELF_FIRST);
foreach ($jsonIterator as $key => $val) {
if(is_array($val)) {
echo "$key:\n";
} else {
echo "$key => $val\n";
}
}
Use
json_decode()
PHP built in function for decoding json back to PHP variable or array and then loop through each index and print number.
Got it done like this:
public function check_users_post()
{
$json = $this->request->body;
$jsonIterator = new RecursiveIteratorIterator(
new RecursiveArrayIterator($json),
RecursiveIteratorIterator::SELF_FIRST);
$phone_numbers = "";
foreach ($jsonIterator as $key => $val) {
if(is_array($val)) {
} else {
$phone_numbers = "$phone_numbers" . ", " . "$val";
}
}
$phone_numbers = substr($phone_numbers, 2);
$phone_numbers = "(" . $phone_numbers . ")";
$query = $this->db->query("SELECT * FROM users WHERE user_number in $phone_numbers;");
$result = $query->result();
$this->response($result, REST_Controller::HTTP_OK);
if (mysql_num_rows($result)==0) {
$data = [ 'message' => 'No users returned'];
$this->response($data, REST_Controller::HTTP_BAD_REQUEST);
} else {
$this->response($result, REST_Controller::HTTP_OK);
}
}
Description
First stringify your JSON, than use JSON_DECODE() function which gives you the array afterwards iterate on this array using foreach loop which will give you the each key which you want to echo.
Code
$str = '[
{
"number":"5613106"
},
{
"number":"56131064"
},
{
"number":"56131063"
}
]';
$array = json_decode($str, true);
echo "<pre>";
foreach ($array as $key => $key_value) { // then loop through it
echo "<br>";
echo $array[$key]['number'];
echo "<br>";
}
Output
5613106
56131064
56131063

check if value from a foreach loop is in an array

Ok I'm seriously stuck, I've been working on a nav menu that I just cannot get to function how I want it to so i've changed tack but am now stuck again so any help would be much appreciated and desperately needed!
I have the code below and am trying to do the following - I have an array that holds info for all the pages of a site and then another array that holds the ids of the pages that are child pages. What I want to do is use a foreach loop to loop through all the pages of the first array and check whether their ids are in the array of child ids or not. If they are not then they are top level nav pages and I want to output some code and then set up another foreach loop which will check whether any subpages have a parent id of the current page and so on.
I can't seem to work out how to compare $b with the ids in the $childpages array no matter what I try! Is this even possible and if so how please?
This is the first section of what im trying at present
<?php function buildMenu4 ($allpages, $childpages) {
foreach ($allpages as $pages){
$a = $pages['parentid'];
$b = $pages['id'];
$c = $childpages;
echo "<ul>\n";
if (!in_array($b, $c)) {
DO SOMETHING..........
Array contents of $c:
Array
(
[0] => Array ( [id] => 6 )
[1] => Array ( [id] => 15 )
[2] => Array ( [id] => 100 )
[3] => Array ( [id] => 101 )
[4] => Array ( [id] => 103 )
[5] => Array ( [id] => 104 )
[6] => Array ( [id] => 105 )
)
edit ---------------------------------
I have reworked my code and am back to a variation of where I was a couple of days ago!! Anyway the code below works as intended until I try to loop it and then it just echoes the results of the first foreach loop e.g. foreach ($allpages as $pages){..... but fails to do anything else.
I am trying to make a function called loopMenu and then run this recursively until there are no more pages to be displayed. I have tried to write the function as shown with the pusedo code in the code block below but I just can't get it to work. I may have muddled up some of the arguments or parameters or perhaps I have just made a big mistake somewhere but I can't see it - any help would be hugely appreciated and desperately needed!
<?php function buildMenu6 ($allpages, $childpageids, $childpages, $subchildpages) {
foreach ($childpageids as $childid){
$c[] = $childid['id'];
};
echo "<ul>\n";
foreach ($allpages as $pages){
$a = $pages['parentid'];
$b = $pages['id'];
if (!in_array($b, $c)){
echo "<li>" . $pages['linklabel'] . "";
WHERE I WANT THE FUNCTION TO START E.G. function loopMenu($childpages, $subchildpages){...the code that follows....
echo"<ul>\n";
foreach ($childpages as $childparent) {
$d = $childparent['parentid'];
$e = $childparent['id'];
if (($d == $b) or ($d == $g)) {
echo "<li>" . $childparent['linklabel'] . "";
echo "<ul>\n";
foreach ($subchildpages as $subchild){
$g = $subchild['id'];
$f = $subchild['parentid'];
if ($f == $e){
echo "<li>" . $subchild['linklabel'] . "";
WHERE I TRY TO RERUN THE FUNCTION USING loopMenu($childparent, $subchild);
echo "<li/>";
};
};
echo"</ul>\n";
echo "</li>";
};
};
echo "</ul>\n";
WHERE I WANT MY FUNCTION TO END E.G. };
echo "</li>";
};
};
echo "</ul>\n";
}; ?>
Then I call the main buildMenu6 function like so:
<?php buildMenu6($pageids, $childPageIds, $childPageArray, $childPageArray); ?>
You need a nested foreach (I've changed your var names or used the original ones for readability):
foreach($allpages as $page) {
foreach($childpages as $child) {
if($page['id'] == $child['id']) {
//do something
break;
}
}
}
Or PHP >= 5.5.0 use array_column:
$childids = array_column($childpages, 'id');
foreach($allpages as $page) {
if(in_array($page['id'], $childids)) {
//do something
}
}
As a kind of hybrid:
foreach($childpages as $child) {
$childids[] = $child['id'];
}
foreach($allpages as $page) {
if(in_array($page['id'], $childids)) {
//do something
}
}
foreach ($allpages as $pages){
$a = $pages['parentid'];
$b = $pages['id'];
$c = $childpages;
echo "<ul>\n";
// In array isn't aware of the 'id' keys
$found = false;
foreach ($c as $id => $value) {
if ($value == $b) {
$found = true;
}
}
if ($found) {
// DO SOMETHING
}
according to THIS SO ANSWER, array_key_exists is (marginally) the fastest array lookup for php.
since, from your description, it seems reasonable to suppose that [id] is a PRIMARY key and, therefore, unique, i would change the [id] dimension and put values directly in its lieu:
$c[105] = NULL; // or include some value, link page URL
... // some code
$needle = 105;
... // some more code
if (array_key_exists($needle,$c)) {
instead of
$c[5] = 105; // $c is the haystack
... // some code
$needle = 105;
... // some more code
foreach ($c as $tempValue) {
if ($tempValue == $needle) {
in case you want to put values in $c, then you could also use isset (it will return FALSE if array value is NULL for said key).

PHP parse assoc. array or XML

How to acces this assoc array?
Array
(
[order-id] => Array
(
[0] => 1
[1] => 2
)
)
as a result of XML parsing
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE request SYSTEM "http://shits.com/wtf.dtd">
<request version="0.5">
<order-states-request>
<order-ids>
<order-id>1</order-id>
<order-id>2</order-id>
...
</order-ids>
</order-states-request>
</request>
$body = file_get_contents('php://input');
$xml = simplexml_load_string($body);
$src = $xml->{'order-states-request'}->{'order-ids'};
foreach ($src as $order) {
echo ' ID:'.$order->{'order-id'};
// dont work - echoes only ID:1, why?
}
// ok, lets try just another way...
$items = toArray($src); //googled function - see at the bottom
print_r($items);
// print result - see at the top assoc array
// and how to acces order ids in this (fck) assoc array???
//------------------------------------------
function toArray(SimpleXMLElement $xml) {
$array = (array)$xml;
foreach ( array_slice($array, 0) as $key => $value ) {
if ( $value instanceof SimpleXMLElement ) {
$array[$key] = empty($value) ? NULL : toArray($value);
}
}
return $array;
}
MANY THANKS FOR ANY HELP!
What you want is:
$body = file_get_contents('php://input');
$xml = simplexml_load_string($body);
$src = $xml->{'order-states-request'}->{'order-ids'}->{'order-id'};
foreach ($src as $id)
{
echo ' ID:', $id, "\n";
}
Live DEMO.
What happens with your code is that you're trying to loop:
$xml->{'order-states-request'}->{'order-ids'}
Which is not the array you want, order-id is, as you can see on your dump:
Array
(
[order-id] => Array

Getting Twitter followers with JSON in PHP?

I can get Tweets of users quite easily using PHP and JSON, but as soon as I use it to get a list of followers, I get errors. Both use JSON to return the values.
The code is:
$jsonurl = "https://api.twitter.com/1/followers/ids.json?cursor=-1&screen_name=mooinooicat";
$contents = file_get_contents($jsonurl);
$results = json_decode($contents, true);
echo "<pre>";
print_r($results);
echo "</pre>";
This gives me the following array:
Array
(
[next_cursor] => 0
[ids] => Array
(
[0] => 31085924
[1] => 53633023
[2] => 18263583
)
[previous_cursor] => 0
[next_cursor_str] => 0
[previous_cursor_str] => 0
)
How do I get the values of next_cursor and previous_cursor and how do I loop just through the ids array?
I want to parse the results for reading into a database.
you are not using the correct api try something like this
function fetch_twitter_count($user) {
if ($json = file_get_contents("http://api.twitter.com/1/users/show.json?screen_name=$user")) {
if(empty($json)) return 0;
$json = json_decode($json['body'], true);
return number_format(intval($json['followers_count']));
}
return 'API Error';
}
have not tested but should do what you want however keep inmind that you will want to use some sort of caching
Thanks for all the answers without examples...
I finally managed to figure it out using the example from Getting values from a single array
Here is the code:
foreach ( $results as $result ) {
if ( is_array( $result ) ) {
foreach ( $result as $sub_result ) {
// You can store this value in a variable, or output it in your desired format.
echo $sub_result . "<br />";
}
} else {
echo $result . "<br />";
}
}

PHP foreach loop breaking with sub object

I'm trying to access third party api which gives me object and sub object, for example:
stdClass Object
(
[truncated] =>
[text] => "some text"
[user] => stdClass Object
(
[count] => 9370
[comments_enabled] => yes
When I try and loop through the object with the following code I get an error at the start of sub-object 'user'. Can anyone help me either 1) iterate through the sub-object, or 2) block the sub-object from the loop.
The code:
$test = $s[0];
$obj = new ArrayObject($test);
foreach ($obj as $data => $name) {
print $data . ' - ' . $name . '<br />';
}
thanks
It's because the 'user' field is an object, so you need to separately run through each field within that object
function iterateObject($obj, $name='') {
//for each element
foreach ($obj as $key=>$val) {
$myName = ($name !='') ? "$name.$key" : $key;
//if type of the element is an object or array
if ( is_object($val) || is_array($val) ) {
//if so, iterate through its properties
iterateObject($val, $myName);
}
//otherwise output name/ value combination
else {
print "$myName - $val <br/>";
}
}
}
$test = $s[0];
$obj = new ArrayObject( $test );
iterateObject( $obj );
Will output
truncated -
text - some text
user.count - 9370
user.comments_enabled - yes
This will iterate through a tree of objects and print key - value pairs...
printObject($test);
function printObject($obj) {
foreach (get_object_vars($obj) as $field => $value) {
if (is_object($value)) {
printObject($value);
} else {
print $field . ' - ' . $value . '<br />';
}
}
}
<?php
function traceObject($object) {
foreach ($object as $data => $name) {
if (is_object($name)) {
traceObject($name);
} else {
echo $data . ' - ' . $name .'<br />';
}
}
}

Categories