Wedge

Public area => The Pub => Off-topic => Topic started by: MultiformeIngegno on May 24th, 2013, 05:06 PM

Title: json_decode and arrays
Post by: MultiformeIngegno on May 24th, 2013, 05:06 PM
Code: [Select]
<?php
$json 
file_get_contents('http://pastebin.com/NLHGMapT');
$track_data json_decode($json);
?>

<?php
echo '<ul>';
    foreach (
$track_data as $data)
    {
        if (!empty(
$data)) {
            
$text $data->track[0]->artist->{'#text'};
        }
        echo 
'<li><span>'; echo $text; echo '</span></li>';
    }
echo 
'</ul>';
?>

How can I have $text for every array (track[0], track[1], track[2], track[n]) in respective <li>s?
Title: Re: json_decode and arrays
Post by: Arantor on May 24th, 2013, 05:11 PM
First glance says that you need to check !empty($data) then foreach ($data->track as $track) then you can iterate over $track to get artist and whatnot.

Possibly you might find it easier to wade through if you pulled it back from json_decode as an associative array rather than an object.
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on May 25th, 2013, 12:29 PM
Quote from Arantor on May 24th, 2013, 05:11 PM
First glance says that you need to check !empty($data) then foreach ($data->track as $track) then you can iterate over $track to get artist and whatnot.
Uhm, but before $track_data as $data, $data is not defined..
Quote from Arantor on May 24th, 2013, 05:11 PM
Possibly you might find it easier to wade through if you pulled it back from json_decode as an associative array rather than an object.
Something like this.. ?
Code: [Select]
$json = file_get_contents('http://pastebin.com/NLHGMapT');
$arrayObjects = json_decode($json, true);
Title: Re: json_decode and arrays
Post by: Arantor on May 25th, 2013, 03:03 PM
Um... you do foreach track_data as data, then foreach (data->track as track)...
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on May 30th, 2013, 06:04 PM
This appears to be working :)

Code: [Select]
<ul>
<?php
$json file_get_contents('http://pastebin.com/NLHGMapT');
$data json_decode($jsontrue);
$data $data['recenttracks'];

foreach ($data['track'] as $track) {

$artist $track['artist']['#text'];
$title $track['name'];
$url $track['url'];
echo '<li><a href="'; echo $url; echo '" title="'; echo $title; echo '">'; echo $artist; echo ' - '; echo $title; echo '</li></a>'; }
?>

</ul>

Can be improved or is it ok?
Title: Re: json_decode and arrays
Post by: Nao on May 30th, 2013, 06:26 PM
Well, apart from the indentation and multiple echos... :^^;:
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on May 30th, 2013, 06:58 PM
Quote from Nao on May 30th, 2013, 06:26 PM
Well, apart from the indentation and multiple echos... :^^;:
I still haven't properly learned the " . " trick to avoid the repetition.. :P
Title: Re: json_decode and arrays
Post by: ethankcvds on May 30th, 2013, 07:43 PM
Quote from MultiformeIngegno on May 30th, 2013, 06:58 PM
Quote from Nao on May 30th, 2013, 06:26 PM
Well, apart from the indentation and multiple echos... :^^;:
I still haven't properly learned the " . " trick to avoid the repetition.. :P
If this is of any help. You can also do it with a ,

Code: [Select]
echo '<a href="'.$url.'">'.$txt.'<a/>';
echo '<a href="',$url,'">',$txt,'<a/>';
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on May 30th, 2013, 07:46 PM
Uh, thanks. And are they the same in this case (dots and commas)?
Title: Re: json_decode and arrays
Post by: Arantor on May 30th, 2013, 07:48 PM
Doing it with a , has other consequences that with a . does not. Specifically, if you get into the realms of doing inline ternary expressions, you need to be careful of operator priority.

echo 'string' . $var > 1 ? 'high' : 'low'; does something different to echo 'string', $var > 1 ? 'high' : 'low';

The reason is that the concatenation will occur before the ternary is evaluated, so you'd have to wrap it in parentheses for it to work properly, i.e. $echo 'string' . ($var > 1 ? 'high' : 'low'); is what's required.


In this particular case it'd be OK:
Code: [Select]
echo '<li><a href="', $url, '" title="', $title, '">', $artist, ' - ', $title, '</li></a>';
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on May 30th, 2013, 08:06 PM
Thanks for the clarification. :)
I'm trying to add a caching mechanism.. local .json file is created, but "null" is its content :P

Code: [Select]
$json = "http://pastebin.com/NLHGMapT";
$cache_lastfm = 'BLAHBLAH/'.sha1($json).'.json';

    if(file_exists($cache_lastfm) && filemtime($cache_lastfm) > time() - 1000){
        // if a cache file newer than 1000 seconds exists, use it
        $data = json_decode(file_get_contents($cache_lastfm, true));
    } else {
        $data = json_decode($json, true);
        file_put_contents($cache_lastfm,json_encode($data));
    }

What's wrong with this?
Title: Re: json_decode and arrays
Post by: Dragooon on May 30th, 2013, 10:02 PM
You're decoding the URL under the else, you have to grab the contents of the URL.
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on May 30th, 2013, 11:10 PM
Yay, now works :)

Code: [Select]
else {
        $data = json_decode(file_get_contents($json), true);
        file_put_contents($cache_lastfm,json_encode($data));
    }
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on May 31st, 2013, 03:05 AM
How can I remove an "object" from JSON input if

Code: [Select]
        "@attr":{
           "nowplaying":"true"
        }

... is present in that object? To be clear, the right fragment is how it should be treated :) http://diffchecker.com/c9ha939m
Title: Re: json_decode and arrays
Post by: Arantor on May 31st, 2013, 03:08 AM
If it's an array, unset it like you would any other item. In theory the same should be true for using it as an object but I don't do the whole iterated objects thing if I can help it. The memory use is significantly higher.
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on May 31st, 2013, 03:11 AM
Quote from Arantor on May 31st, 2013, 03:08 AM
If it's an array, unset it like you would any other item. In theory the same should be true for using it as an object but I don't do the whole iterated objects thing if I can help it. The memory use is significantly higher.
Code: [Select]
    removeAttr($data);

    function removeAttr(&$array) {
        if (isset($array['@attr']['nowplaying']))
            unset($array['WHAT']);
        foreach ($array as &$value) {
            if (is_array($value)) {
                removeAttr($value);
            }
        }
    }

What should I type instead of 'WHAT'?
Title: Re: json_decode and arrays
Post by: Arantor on May 31st, 2013, 03:15 AM
Um... unset($array['@attr']); ?

I presume that's what you're trying to do...
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on May 31st, 2013, 03:34 AM
Code: [Select]
$data = $data['recenttracks'];
$tracks=$data['track'];

    foreach ($tracks as $index=>$track) {
        if (isset($track['@attr'])) {
            unset($tracks[$index]);
        }
    }

foreach ($tracks as $track) {
$artist = $track['artist']['#text'];
$title = $track['name'];
$url = $track['url'];
echo '<li><a href="', $url, '" title="', $title, '">', $artist, ' - ', $title, '</li></a>'; }

This did the trick :)
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on June 3rd, 2013, 08:25 PM
What's wrong with this foreach now? :(

Code: [Select]
<ul>
<?php
$json_dailymile "http://api.dailymile.com/people/multiforme/entries.json";
$cache_dailymile '/var/www/multiformeingegno.it/htdocs/wp-content/themes/multiformeingegno/dailymile_json/'.sha1($json_dailymile).'.json';

    if(
file_exists($cache_dailymile) && filemtime($cache_dailymile) > time() - 1000){
        
// if a cache file newer than 1000 seconds exist, use it
        
$data_dailymile json_decode(file_get_contents($cache_dailymile), true);
    } else {
        
$data_dailymile json_decode(file_get_contents($json_dailymile), true);
        
file_put_contents($cache_dailymile,json_encode($data_dailymile));
    }

$data_dailymile $data_dailymile['entries'];

foreach ($data_dailymile['entries'] as $run) {
$distance $run['workout']['distance']['value'];
$units $run['workout']['distance']['units'];
$duration $run['workout']['duration'];
$url $run['url'];
echo '<li><a href="'$url'">'$distance' '$units' in '$duration'</li></a>'; }
?>

</ul>
Title: Re: json_decode and arrays
Post by: Arantor on June 3rd, 2013, 08:27 PM
I don't know, what is wrong with it?
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on June 3rd, 2013, 08:32 PM
Quote from Arantor on June 3rd, 2013, 08:27 PM
I don't know, what is wrong with it?
Code: [Select]
2013/06/03 20:29:40 [error] 6002#0: *55092 FastCGI sent in stderr: "PHP message: PHP Warning:  file_put_contents(/BLAHBLAH/dailymile_json/7c51bf1c050135a03bde30dda21a977a2e0ed5c8.json): failed to open stream: Permission denied in /BLAHBLAH/test.php on line 11
PHP message: PHP Notice:  Undefined index: entries in /BLAHBLAH/test.php on line 16
PHP message: PHP Warning:  Invalid argument supplied for foreach() in /BLAHBLAH/test.php on line 16" while reading response header from upstream, client: XXXXX, server: XXXXX, request: "GET /BLAHBLAH/test.php HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "BLAHBLAH"

Posted: June 3rd, 2013, 08:29 PM

Oh, I probably need OAuth :(

It's strange though.. I can access the url properly via browser. They blocked GET requests..?

http://api.dailymile.com/people/multiforme/entries.json
Posted: June 3rd, 2013, 08:30 PM

I'm getting a weird bug editing this post. Strange
Code: [Select]
[error][/error]
tags appear.
Title: Re: json_decode and arrays
Post by: Arantor on June 3rd, 2013, 08:34 PM
The cache script doesn't have permission to write to wherever it's trying to write to.
Quote
2013/06/03 20:29:40 error 6002#0: *55092 FastCGI sent in stderr: "PHP message: PHP Warning:  file_put_contents(/var/www/multiformeingegno.it/htdocs/wp-content/themes/multiformeingegno/dailymile_json/7c51bf1c050135a03bde30dda21a977a2e0ed5c8.json): failed to open stream: Permission denied in /var/www/multiformeingegno.it/htdocs/wp-content/themes/multiformeingegno/runs.php on line 11
OT: The tags you're seeing are because the tag closing tool is looking to match bbcode but the opening 'error' bbcode doesn't have a closing tag.

Also, I'm seeing a weird %NEW% indicator in the list of posts here (/do/post2/ showing the post history with an unread post)
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on June 3rd, 2013, 08:56 PM
You're right as always. I gave proper permissions to the dir and now the file is created.
I still get this though:

Code: [Select]
2013/06/03 20:53:23 [error] 6003#0: *56208 FastCGI sent in stderr: "PHP message: PHP Notice:  Undefined index: entries in /BLAHBLAH/runs.php on line 16
PHP message: PHP Warning:  Invalid argument supplied for foreach() in /BLAHBLAH/runs.php on line 16" while reading response header from upstream, client: XXXXX, server: BLAHBLAH request: "GET /BLAHBLAH/runs.php HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "BLAHBLAH"
Posted: June 3rd, 2013, 08:55 PM

Solved. It was foreach ($data_dailymile as $run), not foreach ($data_dailymile['entries'] as $run)
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on June 3rd, 2013, 09:09 PM
I have $date = $run['at'];, which gives me 2013-06-03T16:52:24Z. How can I manipolate it to get for example "d M Y, H:i" ?
Title: Re: json_decode and arrays
Post by: Arantor on June 3rd, 2013, 09:16 PM
Either a regex to scrape the content or something like http://uk3.php.net/manual/en/datetime.createfromformat.php to process it.
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on June 3rd, 2013, 09:23 PM
Quote from Arantor on June 3rd, 2013, 09:16 PM
Either a regex to scrape the content or something like http://uk3.php.net/manual/en/datetime.createfromformat.php to process it.
Is DateTime better than strtotime?

Because this works :)

Code: [Select]
$date = $run['at'];
$time = strtotime($date);

echo date("d M Y, H:i", $time)
Title: Re: json_decode and arrays
Post by: Arantor on June 3rd, 2013, 09:25 PM
I wasn't sure that strtotime would parse that format you have ;)
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on June 3rd, 2013, 09:30 PM
strtotime gives me 03 Jun 2013, 18:52. DateTime gives me 03 Jun 2013, 16:52 (2 hours difference).
One takes server time, the other not?
Posted: June 3rd, 2013, 09:28 PM

I came back to home page after posting and the NEW icon showed up for this topic..
Title: Re: json_decode and arrays
Post by: Arantor on June 3rd, 2013, 09:33 PM
One takes into account server time, the other does not...
Quote
I came back to home page after posting and the NEW icon showed up for this topic..
Known bug.
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on June 3rd, 2013, 09:35 PM
Quote from Arantor on June 3rd, 2013, 09:33 PM
One takes into account server time, the other does not...
Which one takes server time?
Title: Re: json_decode and arrays
Post by: Arantor on June 3rd, 2013, 09:36 PM
I can't remember :/
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on June 3rd, 2013, 09:48 PM
Quote from Arantor on June 3rd, 2013, 09:36 PM
I can't remember :/
I think DateTime does. Because it displayed correct time and strtotime not. Then I added set_locale and strtotime displayed correct time too.
Title: Re: json_decode and arrays
Post by: Arantor on June 3rd, 2013, 10:11 PM
Sounds legit.
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on June 5th, 2013, 08:48 PM
My JSON has

Code: [Select]
        "image":[
           {
              "#text":"http:\/\/userserve-ak.last.fm\/serve\/34s\/3996573.jpg",
              "size":"small"
           },
           {
              "#text":"http:\/\/userserve-ak.last.fm\/serve\/64s\/3996573.jpg",
              "size":"medium"
           },
           {
              "#text":"http:\/\/userserve-ak.last.fm\/serve\/126\/3996573.jpg",
              "size":"large"
           },
           {
              "#text":"http:\/\/userserve-ak.last.fm\/serve\/300x300\/3996573.jpg",
              "size":"extralarge"
           }
        ]

How can I retrieve 'medium' url?

I think it's something like this..?

Code: [Select]
        if ($track['image']['size'] == medium) {
$thumb = $track['image']['#text'];
}
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on June 5th, 2013, 09:24 PM
Some guy suggested me

Code: [Select]
$image = null;
foreach ($track['image'] as $i) {
    if ($i['size'] == 'medium') {
        $image = $i['#text'];
        break;
    }
}

or

Code: [Select]
$image = array_reduce($track['image'], function ($image, array $i) { return $image ?: ($i['size'] == 'medium' ? $i['#text'] : null); });

or

Code: [Select]
$image = array_filter($track['image'], function ($image) { return $image['size'] == 'medium'; });
$image = isset($image[0]['#text']) ? $image[0]['#text'] : null;

The one line solution is cool :D
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on June 6th, 2013, 08:21 PM
Code: [Select]
<?php
// JSON URL which should be requested
$json_url 'https://api.feedbin.me/v2/entries.json';

$username 'username';  // authentication
$password '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

    
$i=0;
    foreach (
json_decode($result) as $obj) {
    if(
$i==5) break;
        
$feedbin_title $obj->title;
        
$feedbin_url $obj->url;
        echo 
'<li><a href="'$feedbin_url'">'$feedbin_title'</a></li>';
    }
?>


It works fine. I get a 100 objects JSON result. I'm trying to limit the objects processed to the first 5. Why doesn't work the $i=0; if($i==5) break; thing? :)
Title: Re: json_decode and arrays
Post by: Alanthar on June 6th, 2013, 09:30 PM
I think you forgot to increase the counter:

  ...
  echo ' ...
  $i++;
}
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on June 6th, 2013, 09:34 PM
Yep :P
Title: Re: json_decode and arrays
Post by: Arantor on June 6th, 2013, 09:37 PM
Hardcore programmers would if ($i++ > 5) ;)
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on June 6th, 2013, 09:49 PM
Code: [Select]
foreach (array_slice(json_decode($data_feedin), 0, 5) as $obj)
Title: Re: json_decode and arrays
Post by: Arantor on June 6th, 2013, 09:50 PM
Now you're just showing off. I'm so proud!
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on June 6th, 2013, 09:52 PM
Quote from Arantor on June 6th, 2013, 09:50 PM
Now you're just showing off. I'm so proud!
shhh, someone told me :P
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on June 6th, 2013, 10:02 PM
Code: [Select]
<?php
$json_url 
'https://api.feedbin.me/v2/entries.json';
 
$username 'username';  // authentication
$password 'password';  // authentication
 
$ch curl_init$json_url );
 
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_USERPWD => $username ":" $password   // authentication
);
 
// Setting curl options
curl_setopt_array$ch$options );
 
$result =  curl_exec($ch); // Getting JSON result string

$cache_feedbin '/var/www/ffio.it/htdocs/'.sha1($json_url).'.json'

if(
file_exists($cache_feedbin) && filemtime($cache_feedbin) > time() - 1000){ 
// if a cache file newer than 1000 seconds exist, use it 
$data_feedbin file_get_contents($cache_feedbin); 
} else { 
$data_feedbin file_get_contents($result); 
file_put_contents($cache_feedbin$data_feedbin); 


foreach (
array_slice(json_decode($data_feedbin), 05) as $obj) { 
$feedbin_title $obj->title
$feedbin_url $obj->url
echo 
'<li><a href="'$feedbin_url'">'$feedbin_title'</a></li>'

?>


Why I'm getting "false" in the locally cached json? Is that json_encode wrong?

EDIT: Forgot to say it works perfectly if I don't try to load it from cache (so it's not something related to cURL or authentication).
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on June 7th, 2013, 12:43 AM
Solved.
It should have been $data_feedbin = $result;, not $data_feedbin = file_get_contents($result); :)
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on June 8th, 2013, 06:22 PM
Code: [Select]
    <?php
    
function get_photos($user_id=XXXX,$count=X,$width=XXX,$height=XXX,$token="XXXX"){
        
$url 'https://api.instagram.com/v1/users/'.$user_id.'/media/recent/?access_token='.$token.'&count='.$count;
        
$cache './BLAH/'.sha1($url).'.json';
        if(
file_exists($cache) && filemtime($cache) > time() - 1000){
            
$jsonData json_decode(file_get_contents($cache), true);
        } else {
            
$jsonData json_decode(file_get_contents($url), true);
            
file_put_contents($cache,json_encode($jsonData));
        }
        
$result '<div id="instagram">'.PHP_EOL;
$i 0;
        foreach (
$jsonData as $value) {
            
$title = (!empty($value->caption->text))?' '.$value->caption->text:'...';
        
BLAHBLAH
        
}
        
$result .= '</div>'.PHP_EOL;
        return 
$result;
    }
    echo 
get_photos();
    
?>

What's wrong with foreach ($jsonData as $value)? I'm grabbing an associative array with the "true" argument in json_decode.. isn't that foreach okay? Or does it grab objects instead?

Here's the json input: http://pastebin.com/EBGG10hx
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on June 9th, 2013, 03:00 AM
Fixed this too :)
Title: Re: json_decode and arrays
Post by: MultiformeIngegno on June 14th, 2013, 01:23 PM
This is the tree of my JSON (stored in $data_delicious):

Code: [Select]
{
   "@attributes":{
      "tag":"",
      "user":"myusername"
   },
   "post":[
      {
         "@attributes":{
            "description":"Fastweb: fibra o VDSL? Disinformazione alla porta",
            "extended":"",
            "hash":"d00d03acd6e01e9c2e899184eab35273",
            "href":"http:\/\/storify.com\/giovannibajo\/fastweb-fibra-o-vdsl",
            "private":"no",
            "shared":"yes",
            "tag":"",
            "time":"2013-06-14T10:30:08Z"
         }
      }
   ]
}

This is the function to grab stuff from it
Code: [Select]
$obj = $data_delicious['post']['@attributes'];

foreach (array_slice(json_decode($data_delicious, true), 0, 5) as $obj) {
    $delicious_title = str_replace('"', '\'', $obj['description']);
    $delicious_url = htmlentities($obj['href'], ENT_QUOTES, "UTF-8");
    $output = "<li><a rel=\"external nofollow\" title=\"$delicious_title\" href=\"$delicious_url\">$delicious_title</a></li>";
    echo $output;
}

Problem is I get these:
Illegal string offset 'post'
Illegal string offset '@attributes'
Undefined index: description
Undefined index: href