简体   繁体   中英

JSON encoded PHP array to JAVASCRIPT variables

Please could somebody kindly show how the following results i have created and outputted into jsondata.php can be put into variables in JavaScript so that i can index through results and use them in Div's throughout my website.

VARIABLES REQUIRED ARE:

Everything in $lastplayed and the result of $secsemain

I have tried to access the data in Javascript using this code below, ... i know its bad!!

TEST1

<script>
url = jsondata.php;
var arr;
arr = <?php echo json_decode($lastplayed,TRUE); ?>;
</script>

BELOW ARE THE FILES TO GENERATE THE JSON DATA

FILE1 (dblastplayedarray.php)

<?php

date_default_timezone_set('Europe/London');

require_once("DbConnect.php");

$sql = "SELECT `artist`, `title`, `label`, `albumyear`, `date_played`, `duration`,
`picture` FROM historylist  ORDER BY `date_played` DESC LIMIT 5 ";

$result = $db->query($sql);

$lastplayed = array();
$i = 1;
while ($row=$result->fetch_object()) {
$lastplayed[$i]['artist']         = $row->artist;
$lastplayed[$i]['title']          = $row->title;
$lastplayed[$i]['label']          = $row->label;
$lastplayed[$i]['albumyear']      = $row->albumyear;
$lastplayed[$i]['date_played']    = $row->date_played;
$lastplayed[$i]['duration']       = $row->duration;
$lastplayed[$i]['picture']        = $row->picture;
$i++;
}

$starttime = strtotime($lastplayed[1]['date_played']);
$curtime = time();
$timeleft = $starttime+round($lastplayed[1]['duration']/1000)-$curtime;
$secsremain = (round($lastplayed[1]['duration'] / 1000)-($curtime-$starttime))
?>

FILE 2 (jsondata.php)

<?php
require_once("dblastplayedarray.php");
echo json_encode($lastplayed);
?>

First, you don't want to generate continuous requests to your PHP script just to get the remaining time of the current song. Better let JavaScript handle that.

Your JavaScript must decide two things:

  1. when to fetch the next batch of song descriptions
  2. how to fetch it

A possible solution is:

Let your JS code compute the time to current song end. When this time reaches zero, query your DB via PHP to fetch the next batch of songs.
Once the update is received, compute the time to current song end again and wait for it to reach zero (using a timer).

To get the results from PHP, you would better use Ajax to avoid refreshing your page entirely.

Putting all this together, you should have something like that:

JavaScript

var PlayList = function (onUpdate, onError)
{
    // store user callbacks
    this.onUpdate = onUpdate; 
    this.onError  = onError;

    // setup internal event handlers
    this.onSongEnd = onSongEnd.bind (this);

    // allocate an Ajax handler
    try
    {
        this.ajax = window.XMLHttpRequest
            ? new XMLHttpRequest()
            : new ActiveXObject("Microsoft.XMLHTTP");
    }
    catch (e)
    {
        // fatal error: could not get an Ajax handler
        this.onError ("could not allocated Ajax handler");
    }
    this.ajax.onreadystatechange = onAjaxUpdate.bind(this);

    // launch initial request
    this.onSongEnd ();

    // ------------------------------------------
    // interface
    // ------------------------------------------

    // try another refresh in the specified amount of seconds
    this.retry = function (delay)
    {
        setTimeout (this.onSongEnd, delay*1000);
    }

    // ------------------------------------------
    // ancillary functions
    // ------------------------------------------

    // called when it's time to refresh the playlist
    function onSongEnd ()
    {
        // ask for a playlist update

        this.ajax.open('GET', 'playlist.php', // <-- reference your PHP script here
                       true);
        this.ajax.send(null);       
    }

    // called to handle Ajax request progress
    function onAjaxUpdate ()
    {       
        if (this.ajax.readyState != 4) return;
        if (this.ajax.status == 200)
        {
            // get our response
            var list = eval ('('+this.ajax.responseText+')');

            // compute milliseconds remaining till the end of the current song
            var start = new Date (list[0].date_played).getTime();
            var now   = new Date (                   ).getTime();
            var d = start - now
                  + parseInt(list[0].duration); // JSON data are plain strings, don't forget
                                                //  to convert then to numbers if need be
            if (d < 0)
            {
                // no new song started, retry in 10 seconds
                d = 10000;
            }
            else
            {
                // notify caller
                this.onUpdate (list);
            }

            // schedule next refresh
            setTimeout (this.onSongEnd, d);

        }
        else
        {
            // Ajax request failed. Most likely a fatal error
            this.onError ("Bloody Ajax request failed");
        }       
    }
}

Note that this is pure, vanilla JavaScript. This is meant as educational code, so you can use it to see an example of barebone Ajax use, if you're interested.

It will not work in IE8- due to the use of bind() , but you can easily add wrapper functions instead if you plan on supporting the old cow.

You can arguably do Ajax queries more easily with the JQuery goo. I never could stand the stuff myself, but no doubt you'll find a lot of people willing to show you how it's done.

Usage

var list = new PlayList (playlistupdate, playlisterror);

function playlistupdate (list)
{
    // do whatever you want with the playlist
    console.log ("Playlist update at "+new Date().toTimeString());
    for (var i = 0 ; i != list.length ; i++)
    {
        var song = list[i];
        console.log (i+" "+song.title);
    }
}

function playlisterror (msg)
{
    // display error message
    console.log ("Ajax error: "+msg);

    // may want to retry, but chances of success are slim
    list.retry (10); // retry in 10 seconds
}

PHP (real database access)

// make this query non cacheable
/*
 * if you don't do this, your browser will cache
 * your first query and ignore the subsequent ones
 */
header("Cache-Control: no-cache");

// open your DB connection
require_once("DbConnect.php");

// fetch playlist
$result = $db->query(
    "SELECT `artist`, `title`, `label`, `albumyear`, `date_played`, `duration`, `picture` "
   ."FROM historylist  ORDER BY `date_played` DESC LIMIT 5 ");

// this little line replaces your bunch of code
while ($row=$result->fetch_object()) $list[] = $row;

// encode and send the result
echo json_encode ($list);

Note the no-cache header. This is the cleanest way of preventing the browser from caching your request.

The aforementioned JQuery goo will provide you with a poor solution consisting of adding some trash behind the query (ie replacing playlist.php with playlist.php?some_random_junk to force the browser to handle each request as unique, thus polluting your browser cache for no good reason).

Since you are in control of the PHP doing the query, better handle the problem at the source.

PHP (simulated)

I wrote a quick & dirty test harness to dispense with a database

// read our dummy DB
if (file_exists ("playlist.txt"))
{
    foreach (explode ("\n", file_get_contents ("playlist.txt")) as $i => $line)
    {
        $line = explode ('|', $line);
        foreach (array ('title', 'date_played', 'duration') as $k =>$f)
        {
            $db[$i]->$f = $line[$k];
        }
    }

    $last_ended = strtotime($db[count($db)-1]->date_played)
                    + $db[count($db)-1]->duration/1000;
}
else $last_ended = time();

function song_name ()
{
    return
        array_rand (array_flip(array("A", "Your", "Some", "This", "No"))). " ".
        array_rand (array_flip(array("beautiful", "weird", "delightful", "doomed", "pink"))). " ".
        array_rand (array_flip(array("love", "kiss", "baby", "monster", "dude", "car")));
}

// add a new dummy song to our DB if the last one has ended
if ($last_ended <= time())
{
    $changed = true;
    $db[] = array ("title" => song_name(), "date_played" => date("M d Y H:i:s", $last_ended), "duration" => rand(10,20)*1000);

        // store only the last 5 songs in the dummy DB
    $db = array_slice ($db, -5);
    foreach ($db as $k => $record)
    {
        $out[$k] = implode ('|', (array)$record);
    }
    file_put_contents ("playlist.txt", implode ("\n", $out));
}

// make this query non cacheable
header("Cache-Control: no-cache");

// get DB output
$list = array_slice (array_reverse ($db), 0, 5);

// encode and send it
echo json_encode ($list);

sample output (from browser console)

   Playlist update at 00:34:26 GMT+0100 (Paris, Madrid)
   0 Your doomed love
   1 Your doomed dude
   2 No beautiful kiss
   3 Some pink baby
   4 Your delightful car
   Playlist update at 00:34:38 GMT+0100 (Paris, Madrid)
   0 No doomed baby
   1 Your doomed love
   2 Your doomed dude
   3 No beautiful kiss
   4 Some pink baby

You can get both test files here .
I did not do a JSFiddle due to the difficulty of simulating Ajax requests in a readable way.

Actual HTML display

As per popular request, here is a sample code that does display something on a web page instead of simply prionting the list to the console.

You only need to change playlistupdate for something like this:

function playlistupdate (list)
{
    // display the playlist inside a table

    // table header
    var table = '<tr>';
    for (var j in list[0]) table += '<th>'+j+'</th>';
    table += '</tr>';

    // list items
    for (var i = 0 ; i != list.length ; i++)
    {
        table += '<tr>';
        for (var j in list[i])
        {
            table += '<td>'+list[i][j]+'</td>';
        }
        table += '</tr>';
    }

    // update table
    document.getElementById ('playlist').innerHTML = table;
}

And you need to define an empty table somewhere in your HTML:

<table id='playlist'></table>

change LIMIT 5 to LIMIT 1 or delete this .I think Your Code have Multi Array's And this Not usable in this source !!! Just i think . And I'm not try it...
TEST1 is php file?
change var arr to var arr = new Array();

Send information's by Ajax And Use it...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM