简体   繁体   中英

JSON from PHP to JavaScript

A slightly different question that all the others out there... I am able to easily pass JSON from a PHP page to JavaScript using the jQuery.ajax() method, but here is my situation:

I have a set of contact data in MySQL, each with firstname, lastname, lat, lng. I have created a page that on one half displays the contact data (firstname, lastname) in tabular format. On the other half, I have a Google Map that is populated with markers from the data set (lat, lng). Now, to allow the two halves to share the same dataset, there are two methods but I am happy with neither:

  1. In the PHP file, pull the data from MySQL, use that data set for the table, then convert that data to JSON, write it out to a JavaScript variable and use that variable to populate the Google Map. Don't like doing this, as there are hundreds of data points, meaning the JSON string is very large and bloats the page, along with having all the data in human readable form in the source (I understand the data is there no matter what as in all cases it is on the client side, just more apparent here).

  2. In the PHP file, pull the data from MySQL, use that data set for the table, then in my JavaScript, make an AJAX call via jQuery.ajax() to another PHP file that generates the JSON data. Hate this as it results in two calls to the same datasource.

I am sure I am missing something obvious here, any pointers/help?

EDIT: Per option #1 above, I am well aware of how to echo out JSON from PHP to JavaScript... just unhappy with both solutions (ie JSON is in source, or JSON is effectively a second call to the data source).

Your best bet would be to enable caching on your mysql server and make two identical calls:

http://www.petefreitag.com/item/390.cfm

You can't really put data in two different places without a) making two calls to the database or b) storing the results in a .txt file (or similar) and retrieving it via ajax.

I suppose you could do b) but it seems a little sloppy and would probably create more overhead than simply making 2 DB calls.

Your requirements are self-contradicting:

  • your data is in human-readable form in a table, yet you object to send it via JSON, because it's "in human-readable form [...]"

  • the table is a huge bloat with all the tds, trs, and yet you mind sending the same data over JSON (it would probably take LESS space).

Nevertheless, if you REALLY object to JSON and do not mind the table, you can extract the data from the table (that you send anyway). Rather silly, but here goes:

<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js'></script>
<table id='test'>
    <tr>
        <td>John</td><td>Smith</td>
        <td>354.3</td><td>52.5</td>
    </tr>
    <tr>
        <td>Adam</td><td>Dreger</td>
        <td>12.3</td><td>  52      </td>
    </tr>
    <tr>
        <td>Filip</td><td>Smith</td>
        <td>354.3</td><td>7.5</td>
    </tr>
</table>
<script>
    var data = $("#test tr").map(function(){
        return [$("td", this).map(function(){
            return this.innerHTML.match(/^\s*\d+(.\d+)?\s*$/)? 
                parseFloat(this.innerHTML) : this.innerHTML;
        }).toArray()]
    })
</script>

This is the famous View Controller Model pattern, where the View is queried by the Controller to gather data to be used as a Model ;-)

A much better idea (but you are against sending JSON) would be to send the data with JSON, and generate the table with Javascript. This way you still have a clear separation between model and a view. It's not really a religious thing, but if you decide to, say, add some spans to the displayed data, you will not have to parse it.

Plenty of reasonable plugins out there will help you turn your data into table, but you might get away with:

<div id='another'>
 - - -
</div>
<script>
    // I assume that data is an array of arrays
    $('#another').html(
        [
        '<table border="1">',
        $(data).map(function(){
            return ['<tr>',
            $(this).map(function(){return "<td>" + this + "</td>"}).toArray().join("")
            ,'</tr>']
        }).toArray().join(""),
        '</table>'
        ].join("")
    );

</script>

(note: the two snippets above can be chained and result in duplicating of the first table: fun!)

EDIT:

Even data that is not displayed in the table could be put there (eg. in invisible spans) and made inaccessible for a casual copy/paster using some trivial encoding, like rot13 (not included in the answer, but widely available). Like so:

    <style>.secret {display: none}</style>

    <tr>
        <td>Adam</td><td>Dreger</td>
        <td>12.3</td><td>  52  </td>
            <td><span class='secret'>({frperg:"ovt bar"})</span></td>
    </tr>

And in the code:

<script>
    var data = $("#test tr").map(function(){
        return [$("td", this).map(function(){
            return this.innerHTML.match(/^\s*\d+(.\d+)?\s*$/)? 
                parseFloat(this.innerHTML) : this.innerHTML;
        }).toArray(), 

            eval($(".secret", this).html().rot13())]
    })
</script>

It depends on how large the data set is. If it's a big payload, you might want to source it as an external file (ie make an ajax request) in order to have the browser cache it. However, in most cases, minimize the number of HTTP requests as much as possible. Personally I'd go with embedding the json into HTML unless it's maybe >20 kb zipped.

I would use a variation of #2. Yes, fetch the JSON via AJAX, as that will make the page load faster and will also be more flexible -- perhaps at some point in the future you'll want to be able to display the map without the table, or some such.

But add a PHP class that wraps the call to the datasource and that is used by both the page that generates the HTML and the page that generates the JSON. This will make it easier to cache the results of the query, and will eliminate duplicate code.

good choice I always pass data to the client in JSON, use this command

<?php
$arr = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5);

echo json_encode($arr);
?>

It's as easy as that, print the output and traverse it like any other Javascript object at the client side ;)

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