开发者

JSON transformation for PHP

Is there any reliable standardized way to transform JSON on the server side? (JSONT perhaps)

Can't really think of a way to use XSLT for that, or is there?

Edit: I should've been more specific. A somewhat standardized transformation is what I'm looking for: using json_decode and json_encode doe开发者_如何学Gosn't do that, it converts between formats. Converting one JSON string into another is what I'm curious about.


PHP offers json_encode(), see the php manual on json_decode().
If you're receiving JSON values you can decode them with json_decode().
Those function require the JSON-extension installed (which is a default).

JSONT is a client side library to transform JSON data into HTML, to use it your client webpage has to implement http://goessner.net/download/prj/jsont/jsont.js. You just need to feed it with an json object containing the information.

For example if you want to add an link to this question:

<div id="jsont-space">
<?php
$jsontLink = new stdClass();
$jsontLink->uri = 'http://stackoverflow.com/questions/4656055/json-transformation-for-php';
$jsontLink->title = 'Question on Stackoverflow about: JSON transformation for PHP';
?>
<script type="text/javascript">
var transforms = { "self": "<a href=\"{uri}\" title='{title}'>{$.title}</a>" };
var data = <?php echo json_encode($jsontLink); ?>;
document.write(jsonT(data, transforms));
</script>
</div>

This is of course something very quick&dirty. But it should explain the whole variant of

  • defining the data
  • defining transformations
  • applying those to a page

here are some additional examples on JSONT (look @ source)

Edit:
Added information about JSONT & implementation example


$my_array=array("first", "second", "third"); 

json_encode($my_array); //["first","second","third"]

As of php version 5.3 you can:

json_encode($my_array, JSON_FORCE_OBJECT); // {"0":"first", "1":"second","2":"third"}


Apparently, no php-based solutions are known to the community.


Well it depends what you want to transform it into. But as Samuel says, your best bet to get you on the right road is indeed json_encode() or json_decode() as this will allow you to transform an array or object into JSON string, or from a string into an object (using decode)


Original jsonT client side

    /*  This work is licensed under Creative Commons GNU LGPL License.

    License: http://creativecommons.org/licenses/LGPL/2.1/
   Version: 0.9
    Author:  Stefan Goessner/2006
    Web:     http://goessner.net/ 
*/

function jsonT(self, rules) {
   var T = {
      output: false,
      init: function() {
         for (var rule in rules)
            if (rule.substr(0,4) != "self")
               rules["self."+rule] = rules[rule];
         return this;
      },
      apply: function(expr) {
         var trf = function(s){ return s.replace(/{([A-Za-z0-9_\$\.\[\]\'@\(\)]+)}/g, 
                                  function($0,$1){return T.processArg($1, expr);})},
             x = expr.replace(/\[[0-9]+\]/g, "[*]"), res;
         if (x in rules) {
            if (typeof(rules[x]) == "string")
               res = trf(rules[x]);
            else if (typeof(rules[x]) == "function")
               res = trf(rules[x](eval(expr)).toString());
         }
         else 
            res = T.eval(expr);
         return res;
      },
      processArg: function(arg, parentExpr) {
         var expand = function(a,e){return (e=a.replace(/^\$/,e)).substr(0,4)!="self" ? ("self."+e) : e; },
             res = "";
         T.output = true;
         if (arg.charAt(0) == "@")
            res = eval(arg.replace(/@([A-za-z0-9_]+)\(([A-Za-z0-9_\$\.\[\]\']+)\)/, 
                                   function($0,$1,$2){return "rules['self."+$1+"']("+expand($2,parentExpr)+")";}));
         else if (arg != "$")
            res = T.apply(expand(arg, parentExpr));
         else
            res = T.eval(parentExpr);
         T.output = false;
         return res;
      },
      eval: function(expr) {
         var v = eval(expr), res = "";
         if (typeof(v) != "undefined") {
            if (v instanceof Array) {
               for (var i=0; i<v.length; i++)
                  if (typeof(v[i]) != "undefined")
                     res += T.apply(expr+"["+i+"]");
            }
            else if (typeof(v) == "object") {
               for (var m in v)
                  if (typeof(v[m]) != "undefined")
                     res += T.apply(expr+"."+m);
            }
            else if (T.output)
               res += v;
         }
         return res;
      }
   };
   return T.init().apply("self");
}

/*
////////////////////////////////
// SAMPLE SECTION
////////////////////////////////

<html>
<head>
<title> JSONT - Tests </title>
<script type="text/javascript" src="jsont.js"></script>
<script type="text/javascript">

var o = [], t = [];

t[1] = { "self": "<table>{pnt}</table>",
         "pnt": "<tr><td>{pnt.x}</td><td>{pnt.y}</td></tr>" };
o[1] = { pnt: { x:2, y:3 }};

t[2] = { "self": "<table><tr>{$}</tr></table>",
         "self[*]": "<td>{$}</td>" };
o[2] = [ 1, 2 ];

t[3] = { "self": "<table>\n{$}\n</table>",
          "self[*]": "<tr>{$}</tr>\n",
          "self[*][*]": "<td>{$}</td>" };
o[3] = [[1,2],[3,4]];

t[4] = { "self": "<div>\n{p}\n</div>",
          "p": "<table><tr>{$}</tr></table>\n",
          "p[*]": "<td>{$.x}</td><td>{$.y}</td>" };
o[4] = {a:"hello", p:[{x:1,y:2},{x:3,y:4}]};

t[5] = { "self": "<a href=\"{uri}\" title='{title}'>{$.title}</a>" };
o[5] = { uri:"http://somewhere.org", title:"somewhere homepage" };

t[6] = { "menu": "<menu>\n  <header>{menu.header}</header>\n{menu.items}</menu>",
         "menu.items[*]": function(x){
                            return x ? "  <item action=\""+x.id+" id=\""+x.id+"\">"+(x.label||x.id)+"</li>\n" 
                                     : "  <separator/>\n";} };
o[6] = {"menu": {
          "header": "SVG Viewer",
          "items": [
            {"id": "Open"},
            {"id": "OpenNew", "label": "Open New"},
            null,
            {"id": "ZoomIn", "label": "Zoom In"},
            {"id": "ZoomOut", "label": "Zoom Out"},
            {"id": "OriginalView", "label": "Original View"},
            null,
            {"id": "Quality"},
            {"id": "Pause"},
            {"id": "Mute"},
            null,
            {"id": "Find", "label": "Find..."},
            {"id": "FindAgain", "label": "Find Again"},
            {"id": "Copy"},
            {"id": "CopyAgain", "label": "Copy Again"},
            {"id": "CopySVG", "label": "Copy SVG"},
            {"id": "ViewSVG", "label": "View SVG"},
            {"id": "ViewSource", "label": "View Source"},
            {"id": "SaveAs", "label": "Save As"},
            null,
            {"id": "Help"},
            {"id": "About", "label": "About Adobe CVG Viewer..."}
    ]}};

t[7] = { "self": "<p> {a} {b} {c} {d} </p>" };
o[7] = { a:false, b:null, d:true };

t[8] = { "self": "<p> {a} </p>",
         "a": function(x) {return x ? 'black' : 'white';} };
o[8] = { "a": true };

t[9] = { "A": "<div>{A.a1} and {A.a2}</div>" };
o[9] = { "A" : { "a1": "a1val", "a2": "a2val" },
         "B" : { "b1": "b1val", "b2": "b2val" } };

o[10] = { "line": { "p1": {"x":2, "y":3},
                    "p2": {"x":4, "y":5} }};
t[10] = { "self": "<svg>{line}</svg>",
             "line": "<line x1=\"{$.p1.x}\" y1=\"{$.p1.y}\"" +
                           "x2=\"{$.p2.x}\" y2=\"{$.p2.y}\" />" };

o[11] = ["red", "green", "blue"];
t[11] = {"self": "<ul>\n{$}</ul>\n",
            "self[*]": "  <li>{$}</li>\n"};
o[12] = { "color": "blue",
          "closed": true,
          "points": [[10,10],[20,10],[20,20],[10,20]] };
t[12] = { "self": "<svg><{closed} stroke=\"{color}\" points=\"{points}\" /></svg>",
          "closed": function(x){return x ? "polygon" : "polyline";}, 
          "points[*][*]": "{$} " };

o[13] = {"menu": {
  "id": "file",
  "value": "File:",
  "popup": {
    "menuitem": [
      {"value": "New", "onclick": "CreateNewDoc()"},
      {"value": "Open", "onclick": "OpenDoc()"},
      {"value": "Close", "onclick": "CloseDoc()"}
    ]
  }
}};

t[13] = { "menu": "<menu id=\"{$.id}\" value=\"{$.value}\">\n"+
                  "  <popup>\n{$.popup.menuitem}  </popup>\n</menu>",
          "menu.popup.menuitem[*]": "    <menuitem value=\"{$.value}\""+
                                    "onclick=\"{$.onclick}\" />\n" };

o[14] = [{"u":"http://www.ericclapton.com/hello",
            "d":"Eric Clapton",
            "t":["guitarist","blues","rock"]},
           {"u":"http://www.bbking.com/",
            "d":"B.B. King : Official Site",
            "t":["guitarist","blues"]},
           {"u":"http://www.stevieraysbluesbar.com/",
            "d":"Louisville's House of Blues",
            "t":["guitarist","blues","rock"]}];

t[14] = { "self": "<ul>\n{$}</ul>",
          "self[*]": " <li>\n"+
                     "  <img style='position:absolute;display:none;'"+
                     "    width='16' height='16'\n"+
                     "    onload='showImage(this)' src='{@icon($.u)}'/>\n"+
                     "  <a style='margin-left:20px;' href='{$.u}'>{$.d}</a>\n"+
                     " </li>\n",
          "icon": function(x){return x.split('/').splice(0,3).join('/')+'/favicon.ico';}           
           };

t[15] = { "self": "<p> {$.a} </p>",
          "a": function(x){return x ? 'black' : 'white'} }
o[15] = { "a": true };

t[16] = { "self": "<p> {a}, {b}, {b.x} </p>",
          "b": "hello",
          "b.x": "" };
o[16] = { "a": false, "b": null };

t[17] = { "self": function(x){ return x.length; } }
o[17] = [ 1, 2, 1 ];

function test()
{
    var N1 = 1; // 1
    var N2 = 17; // 17

    for(i=N1; i<N2+1; i++ )
    {
        show(jsonT(o[i], t[i]));
    }
}

function show(s) { document.getElementById("out").innerHTML += (s+"\n").replace(/&/g, "&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\n/g, "<br/>") + "<hr/>"; }
window.onload = test;
</script>
</head>

<body>
<pre id="out"></pre>
</body>
</html> 

*/


    <?php

/*  This work is licensed under Creative Commons GNU LGPL License.

    License: http://creativecommons.org/licenses/LGPL/2.1/
   Version: 0.9
    Author:  Stefan Goessner/2006
    Web:     http://goessner.net/ 

    TRANSLATED TO PHP BY ANONYMOUS, 19:45 05.12.2015
*/

class jsont_class
{
    //SET TO true FOR GET ERROR MESSAGES
    var $debug = false;

    private $output = false;

    private $pa_h1e = "";
    private $pa_h2e = "";

    private $rules = null;
    private $self = null;

    private function ecran_js2php($s)
    {
        if(is_string($s))
        {
            $s = str_replace("[", ".", $s);
            $s = str_replace("]", ".", $s);
            $s = str_replace("..", ".", $s);
            $s = trim($s, ".");
        }
        return $s;
    }

    private function init(&$rules, &$self)
    {
        //////////////////////////////////
        // IN PHP Object and Array FROM Javascript THE SAME
        // MAKING x[i] AS x.i
        //////////////////////////////////
        $r = array();
        $s = array();

        foreach ($rules as $key => $value)
        {
            $nk = $this->ecran_js2php($key);
            $r[$nk] = $value;
        }
        foreach ($self as $key => $value)
        {
            $nk = $this->ecran_js2php($key);
            $s[$nk] = $value;
        }

        $rules = $r;
        $self = $s;
        //////////////////////////////////

        foreach ($rules as $rule => $___)
        {
            if (substr($rule, 0, 4) != "self")
            {
                $rules['self.' . $rule] = $rules[$rule];
            }
        }
    }

    private function check_is_func($str_f) { return (substr($str_f, 0, 8) == "function"); }

    private function run_func($str_f, $expr)
    {
        if ($this->check_is_func($str_f))
        {
            //return " FBODY: [" . $str_f . "] ARGS: [" . ($expr != null) ? $expr:$obj . "] ";

            //ORIGINAL: $param = eval($expr);
            $param = null;
            $this->expand_chain($expr, $param);

            $body = strstr($str_f, "{");

            $func = create_function('', $body);
            return $func($param);
        }

        return $this->debug ? ("ERR: run_func(). NOT FUNCTION: FBODY: [" . $str_f . "] ARGS: [" . $expr . "] "):"";
    }

    private function expand($a, $e)
    {
        return (substr($e = preg_replace('/^\$/', $e, $a, 1), 0, 4) != "self") ? 'self.' . $e : $e;
    }

    private function pa_h1($p)
    {
        return $this->processArg($p[1], $this->pa_h1e);
    }
    private function pa_h2($p)
    {
        //IN ORIGINAL HERE CALCULATING (!)STRING FUNC/FUNC_ARG WICH RUN AFTER THAT BY eval
        //ORIGINAL: return $this->rules['self.' . $p[1] . '](' . $this->expand($p[2], $this->pa_h2e . ')' );

        //BUT IN PHP VERSION WE RUN FUNCTION HERE
        return $this->run_func($this->rules['self.' . $p[1]], $this->expand($p[2], $this->pa_h2e) );
    }
    private function trf($expr, $s)
    {
        $this->pa_h1e = $expr;
        return preg_replace_callback('/{([A-Za-z0-9_\$\.\[\]\'@\(\)]+)}/', array($this, 'pa_h1'), $s);
    }

    private function apply($expr)
    {
        //ORIGINAL: $x = preg_replace('/\[[0-9]+\]/', "[*]", $expr);
        $x = preg_replace('/.[0-9]+/', ".*", $expr);

        $res = null;
        if (isset($this->rules[$x]))
        {
            $rx = $this->rules[$x];

            if(gettype($rx) == "string")
            {
                if ($this->check_is_func($rx))
                {
                    //ORIGINAL: $res = $this->trf($expr, (string)$rx(eval(expr))));
                    $res = $this->trf($expr, (string)$this->run_func($rx, $expr));
                }
                else { $res = $this->trf($expr, $rx); }
            }
        }
        else { $res = $this->jst_eval($expr); }

        return $res;
    }

    private function processArg($arg, $parentExpr)
    {
        $res = "";
        $this->output = true;
        if ($arg[0] == "@")
        {
            $this->pa_h2e = $parentExpr;

            //ORIGINAL: $res = eval(preg_replace_callback('/@([A-za-z0-9_]+)\(([A-Za-z0-9_\$\.\[\]\']+)\)/', array($this, 'pa_h2'), $arg, 1));

            $res = preg_replace_callback('/@([A-za-z0-9_]+)\(([A-Za-z0-9_\$\.\[\]\']+)\)/', array($this, 'pa_h2'), $arg, 1);
        }
        else if ($arg != "$")
        {
            $res = $this->apply($this->expand($arg, $parentExpr));
        }
        else
        {
            $res = $this->jst_eval($parentExpr);
        }

        $this->output = false;
        return $res;
    }

    private function expand_chain($chain_, &$ret_val)
    {
        $ok = false;
        $ret_val = null;

        //$chain_ = str_replace(" ", "", $chain_);
        $chain = explode(".", $chain_);

        if($sc = sizeof($chain))
        {
            $rt = null;
            for($i = 0; $i<$sc; $i++)
            {
                $key = $chain[$i];

                if($key == "self") { $rt = $this->self; $ok = true; continue; }

                if(!array_key_exists($key, $rt)) { $rt = null; $ok = false; break; }

                $rt = $rt[$key];
            }

            $ret_val = $rt;
        }

        if($this->debug && !$ok) { print("ERROR: expand_chain() CAN'T EXPAND THE PARAM: [" . $chain_ . "] CHECK YOU JSONT SCRIPT SYNTAX" ); };

        return $ok;
    }

    private function jst_eval($expr)
    {
        $res = "";
        if($this->expand_chain($expr, $v))
        {
            if(is_array($v))
            {
                foreach($v as $key => $value)
                {
                    $res .= $this->apply($expr . '.' . $key  );
                }
            }
            else  { if ($this->output) { $res .= $v; } }
        }

        return $res;
    }

    function jsonT($self_, $rules_)
    {
        $this->rules = $rules_;
        $this->self = $self_;

        $this->init($this->rules, $this->self);

        return $this->apply("self");
    }
}


//////////////////////////////////////////
// SAMPLE HERE
//////////////////////////////////////////
function j2o($j2o_, &$arr, &$json_str)
{
    if($j2o_) $arr = json_decode($json_str, TRUE);
    else $json_str = json_encode($arr);
}


function show($s)
{
    return preg_replace('/\n/', "<br/>", preg_replace('/>/', "&gt;", preg_replace('/</', "&lt;", preg_replace('/&/', "&amp;", $s . "\n")))) . "<hr/>";
}


main();

function main()
{
$t = array();
$o = array();

$t[1] = '{ "self": "<table>{pnt}</table>",
         "pnt": "<tr><td>{pnt.x}</td><td>{pnt.y}</td></tr>" }';
$o[1] = '{ "pnt": { "x":2, "y":3 }}';

$t[2] = '{ "self": "<table><tr>{$}</tr></table>",
         "self[*]": "<td>{$}</td>" }';
$o[2] = '[ 1, 2 ]';

$t[3] = '{ "self": "<table>\n{$}\n</table>",
          "self[*]": "<tr>{$}</tr>\n",
          "self[*][*]": "<td>{$}</td>" }';
$o[3] = '[[1,2],[3,4]]';

$t[4] = '{ "self": "<div>\n{p}\n</div>",
          "p": "<table><tr>{$}</tr></table>\n",
          "p[*]": "<td>{$.x}</td><td>{$.y}</td>" }';
$o[4] = '{"a":"hello", "p":[{"x":1,"y":2},{"x":3,"y":4}]}';

$t[5] = '{ "self": "<a href=\"{uri}\" title=\"{title}\">{$.title}</a>" }';
$o[5] = '{ "uri":"http://somewhere.org", "title":"somewhere homepage" }';

$t[6] = '{ "menu": "<menu>\n  <header>{menu.header}</header>\n{menu.items}</menu>",
         "menu.items[*]": "function(){$x = func_get_args(); return $x[0] ? \"  <item action=\" . $x[0][\"id\"] . \" id=\" . $x[0][\"id\"] . \">\" . (array_key_exists(\"label\", $x[0]) ? $x[0][\"label\"]:$x[0][\"id\"]) . \"</li>\n\" : \"  <separator/>\n\";}" }';
$o[6] = '{"menu": {
          "header": "SVG Viewer",
          "items": [
            {"id": "Open"},
            {"id": "OpenNew", "label": "Open New"},
            null,
            {"id": "ZoomIn", "label": "Zoom In"},
            {"id": "ZoomOut", "label": "Zoom Out"},
            {"id": "OriginalView", "label": "Original View"},
            null,
            {"id": "Quality"},
            {"id": "Pause"},
            {"id": "Mute"},
            null,
            {"id": "Find", "label": "Find..."},
            {"id": "FindAgain", "label": "Find Again"},
            {"id": "Copy"},
            {"id": "CopyAgain", "label": "Copy Again"},
            {"id": "CopySVG", "label": "Copy SVG"},
            {"id": "ViewSVG", "label": "View SVG"},
            {"id": "ViewSource", "label": "View Source"},
            {"id": "SaveAs", "label": "Save As"},
            null,
            {"id": "Help"},
            {"id": "About", "label": "About Adobe CVG Viewer..."}
    ]}}';

$t[7] = '{ "self": "<p> {a} {b} {c} {d} </p>" }';
$o[7] = '{ "a":false, "b":null, "d":true }';

$t[8] = '{ "self": "<p> {a} </p>",
         "a": "function() {$x = func_get_args(); return $x[0] ? \"black\" : \"white\";}" }';
$o[8] = '{ "a": true }';

$t[9] = '{ "A": "<div>{A.a1} and {A.a2}</div>" }';
$o[9] = '{ "A" : { "a1": "a1val", "a2": "a2val" },
         "B" : { "b1": "b1val", "b2": "b2val" } }';

$o[10] = '{ "line": { "p1": {"x":2, "y":3},
                    "p2": {"x":4, "y":5} }}';
$t[10] = '{ "self": "<svg>{line}</svg>",
             "line": "<line x1=\"{$.p1.x}\" y1=\"{$.p1.y}\" x2=\"{$.p2.x}\" y2=\"{$.p2.y}\" />" }';

$o[11] = '["red", "green", "blue"]';
$t[11] = '{"self": "<ul>\n{$}</ul>\n",
            "self[*]": "  <li>{$}</li>\n"}';
$o[12] = '{ "color": "blue",
          "closed": true,
          "points": [[10,10],[20,10],[20,20],[10,20]] }';
$t[12] = '{ "self": "<svg><{closed} stroke=\"{color}\" points=\"{points}\" /></svg>",
          "closed": "function(){$x = func_get_args(); return $x[0] ? \"polygon\" : \"polyline\";}", 
          "points[*][*]": "{$} " }';

$o[13] = '{"menu": {
  "id": "file",
  "value": "File:",
  "popup": {
    "menuitem": [
      {"value": "New", "onclick": "CreateNewDoc()"},
      {"value": "Open", "onclick": "OpenDoc()"},
      {"value": "Close", "onclick": "CloseDoc()"}
    ]
  }
}}';

$t[13] = '{ "menu": "<menu id=\"{$.id}\" value=\"{$.value}\">\n <popup>\n{$.popup.menuitem}  </popup>\n</menu>",
          "menu.popup.menuitem[*]": "    <menuitem value=\"{$.value}\" onclick=\"{$.onclick}\" />\n" }';

$o[14] = '[{"u":"http://www.ericclapton.com/hello",
            "d":"Eric Clapton",
            "t":["guitarist","blues","rock"]},
           {"u":"http://www.bbking.com/",
            "d":"B.B. King : Official Site",
            "t":["guitarist","blues"]},
           {"u":"http://www.stevieraysbluesbar.com/",
            "d":"Louisville\'s House of Blues",
            "t":["guitarist","blues","rock"]}]';

$t[14] = '{ "self": "<ul>\n{$}</ul>",
          "self[*]": " <li>\n <img style=\"position:absolute;display:none;\" width=\"16\" height=\"16\"\n  onload=\"showImage(this)\" src=\"{@icon($.u)}\"/>\n   <a style=\"margin-left:20px;\" href=\"{$.u}\">{$.d}</a>\n </li>\n",
          "icon": "function(){$x = func_get_args(); $pieces = explode(\"/\", $x[0]); return join(\"/\", array_splice($pieces, 0, 3)) . \"/favicon.ico\";}"}';

$t[15] = '{ "self": "<p> {$.a} </p>",
          "a": "function(){$x = func_get_args(); return $x[0] ? \"black\" : \"white\"; }" }';
$o[15] = '{ "a": true }';

$t[16] = '{ "self": "<p> {a}, {b}, {b.x} </p>",
          "b": "hello",
          "b.x": "" }';
$o[16] = '{ "a": false, "b": null }';

$t[17] = '{ "self": "function(){ $x = func_get_args(); return count($x[0]); }" }';
$o[17] = '[ 1, 2, 1 ]';

    $jstc = new jsont_class();

    $jst = array();
    $jso = array();

    $N1 = 1; // 1
    $N2 = 17; // 17

    for($i=$N1; $i<$N2+1; $i++ )
    {
        j2o(true, $jso[$i], $o[$i]);
        j2o(true, $jst[$i], $t[$i]);

        print(show($jstc->jsonT($jso[$i], $jst[$i])));
    }
} 

?>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜