JSON
[ class tree: JSON ] [ index: JSON ] [ all elements ]

Source for file json.php

Documentation is available at json.php

  1. <?php
  2. /**
  3. * The content of this file is (c) 2003-2005 digital media center GmbH
  4. * All rights reserved
  5. *
  6. * a JSON parser / generator.
  7. * implemented as 100% compatible port of the original JSON parser
  8. * by Douglas Crockford on http://www.JSON.org.
  9. *
  10. @package      JSON
  11. @access       public
  12. @copyright    Copyright (c) 2005-2006 Dominique Stender - http://sf.net/projects/cpaint
  13. @license      http://www.crockford.com/JSON/license.html
  14. @author       Dominique Stender <dstender@st-webdevelopment.de>
  15. @version      $Id: json.php 315 2006-09-30 08:29:39Z saloon12yrd $
  16. */
  17.  
  18.  
  19.  
  20.   /**
  21.   * a JSON parser / generator
  22.   *
  23.   * @access public
  24.   * @author Dominique Stender <dst@dmc.de>
  25.   * @version 1.0.1
  26.   */
  27.   class JSON {
  28.     /**
  29.     * line counter
  30.     *
  31.     * @access   private
  32.     * @var      integer    $at 
  33.     */
  34.     var $at 0;
  35.  
  36.     /**
  37.     *
  38.     * @access   private
  39.     * @var      string    $ch 
  40.     */
  41.     var $ch ' ';
  42.  
  43.     /**
  44.     * JSON representation
  45.     *
  46.     * @access   private
  47.     * @var      string    $text 
  48.     */
  49.     var $text '';
  50.  
  51.     /**
  52.     * takes an arbitrary PHP data structure and generates a valid JSON representation from it
  53.     *
  54.     * @param    mixed    $arg    an arbitrary PHP data structure
  55.     * @access   public
  56.     * @return   string 
  57.     * @version  1.0.1   fixed tests whether $s has content by using strlen(). this enables the user to use 0 as very first character
  58.     */
  59.     function stringify($arg{
  60.       $returnValue  '';
  61.       $c            '';
  62.       $i            '';
  63.       $l            '';
  64.       $s            '';
  65.       $v            '';
  66.       $numeric      true;
  67.  
  68.       switch (gettype($arg)) {
  69.  
  70.         case 'array':
  71.           // do a test whether all array keys are numeric
  72.           foreach ($arg as $i => $v{
  73.             if (!is_numeric($i)) {
  74.               $numeric false;
  75.               break;
  76.             }
  77.           }
  78.  
  79.           if ($numeric{
  80.  
  81.             foreach ($arg as $i => $v{
  82.               if (strlen($s0{
  83.                 $s .= ',';
  84.               }
  85.  
  86.               $s .= $this->stringify($arg[$i]);
  87.             // end: foreach
  88.  
  89.             $returnValue '[' $s ']';
  90.  
  91.           else {
  92.             // associative array
  93.             foreach ($arg as $i => $v{
  94.               if (strlen($s0{
  95.                 $s .= ',';
  96.               }
  97.               $s .= $this->stringify($i':' $this->stringify($arg[$i]);
  98.             }
  99.             // return as object
  100.             $returnValue '{' $s '}';
  101.           }
  102.           break;
  103.  
  104.         case 'object':
  105.  
  106.           foreach (get_object_vars($argas $i => $v{
  107.             $v $this->stringify($v);
  108.  
  109.             if (strlen($s0{
  110.               $s .= ',';
  111.             }
  112.  
  113.             $s .= $this->stringify($i':' $v;
  114.           }
  115.  
  116.           $returnValue '{' $s '}';
  117.           break;
  118.  
  119.         case 'integer':
  120.         case 'double':
  121.           $returnValue is_numeric($arg? (string) $arg 'null';
  122.           break;
  123.  
  124.         case 'string':
  125.           $l strlen($arg);
  126.           $s '"';
  127.  
  128.           for ($i 0$i $l$i++{
  129.             $c $arg{$i};
  130.  
  131.             if (ord($c>= ord(' ')) {
  132.  
  133.               if ($c == '\\'
  134.                 || $c == '"'{
  135.  
  136.                 $s .= '\\';
  137.               }
  138.               $s .= $c;
  139.  
  140.             else {
  141.  
  142.               switch ($c{
  143.  
  144.                 case '\b':
  145.                   $s .= '\\b';
  146.                   break;
  147.  
  148.                 case '\f':
  149.                   $s .= '\\f';
  150.                   break;
  151.  
  152.                 case '\n':
  153.                   $s .= '\\n';
  154.                   break;
  155.  
  156.                 case '\r':
  157.                   $s .= '\\r';
  158.                   break;
  159.  
  160.                 case '\t':
  161.                   $s .= '\\t';
  162.                   break;
  163.  
  164.                 default:
  165.                   $s .= '\u00' sprintf('%02x'ord($c));
  166.               }
  167.             }
  168.           }
  169.           $returnValue $s '"';
  170.           break;
  171.  
  172.         case 'boolean':
  173.           $returnValue = (string) $arg;
  174.           break;
  175.  
  176.         default:
  177.           $returnValue 'null';
  178.       }
  179.  
  180.       return $returnValue;
  181.     }
  182.  
  183.  
  184.     /**
  185.     * parses the given string into a PHP data structure
  186.     *
  187.     * @param    string    $text    JSON data representation
  188.     * @access   public
  189.     * @return   mixed 
  190.     */
  191.     function parse($text{
  192.       $this->at  0;
  193.       $this->ch  ' ';
  194.       $this->text  $text;
  195.  
  196.       return $this->val();
  197.     }
  198.  
  199.     /**
  200.     * triggers a PHP_ERROR
  201.     *
  202.     * @access   private
  203.     * @param    string    $m    error message
  204.     * @return   void 
  205.     */
  206.     function error($m{
  207.       trigger_error($m ' at offset ' $this->at ': ' $this->textE_USER_ERROR);
  208.     }
  209.  
  210.     /**
  211.     * returns the next character of a JSON string
  212.     *
  213.     * @access  private
  214.     * @return  string 
  215.     */
  216.     function next({
  217.       $this->ch $this->text{$this->at};
  218.       $this->at++;
  219.       return $this->ch;
  220.     }
  221.  
  222.     /**
  223.     * handles whitespace and comments
  224.     *
  225.     * @access  private
  226.     * @return  void 
  227.     */
  228.     function white({
  229.  
  230.       while ($this->ch != ''
  231.         && ord($this->ch<= ord(' ')) {
  232.  
  233.         $this->next();
  234.       }
  235.     }
  236.  
  237.     /**
  238.     * handles strings
  239.     *
  240.     * @access  private
  241.     * @return  void 
  242.     */
  243.     function str({
  244.       $i '';
  245.       $s '';
  246.       $t '';
  247.       $u '';
  248.  
  249.       if ($this->ch == '"'{
  250.  
  251.         while ($this->next(!== null{
  252.  
  253.           if ($this->ch == '"'{
  254.             $this->next();
  255.             return $s;
  256.  
  257.           elseif ($this->ch == '\\'{
  258.  
  259.             switch ($this->next()) {
  260.               case 'b':
  261.                 $s .= '\b';
  262.                 break;
  263.  
  264.               case 'f':
  265.                 $s .= '\f';
  266.                 break;
  267.  
  268.               case 'n':
  269.                 $s .= '\n';
  270.                 break;
  271.  
  272.               case 'r':
  273.                 $s .= '\r';
  274.                 break;
  275.  
  276.               case 't':
  277.                 $s .= '\t';
  278.                 break;
  279.  
  280.               case 'u':
  281.                 $u 0;
  282.  
  283.                 for ($i 0$i 4$i += 1{
  284.                   $t = (integer) sprintf('%01c'hexdec($this->next()));
  285.  
  286.                   if (!is_numeric($t)) {
  287.                     break 2;
  288.                   }
  289.                   $u $u 16 $t;
  290.                 }
  291.  
  292.                 $s .= chr($u);
  293.                 break;
  294.  
  295.               default:
  296.                 $s .= $this->ch;
  297.             }
  298.           else {
  299.             $s .= $this->ch;
  300.           }
  301.         }
  302.       }
  303.  
  304.       $this->error('Bad string');
  305.     }
  306.  
  307.     /**
  308.     * handless arrays
  309.     *
  310.     * @access  private
  311.     * @return  void 
  312.     */
  313.     function arr({
  314.       $a array();
  315.  
  316.       if ($this->ch == '['{
  317.         $this->next();
  318.         $this->white();
  319.  
  320.         if ($this->ch == ']'{
  321.           $this->next();
  322.           return $a;
  323.         }
  324.  
  325.         while ($this->ch{
  326.           array_push($a$this->val());
  327.           $this->white();
  328.  
  329.           if ($this->ch == ']'{
  330.             $this->next();
  331.             return $a;
  332.  
  333.           elseif ($this->ch != ','{
  334.             break;
  335.           }
  336.  
  337.           $this->next();
  338.           $this->white();
  339.         }
  340.  
  341.         $this->error('Bad array');
  342.       }
  343.     }
  344.  
  345.     /**
  346.     * handles objects
  347.     *
  348.     * @access  public
  349.     * @return  void 
  350.     */
  351.     function obj({
  352.       $k '';
  353.       $o new stdClass();
  354.  
  355.       if ($this->ch == '{'{
  356.         $this->next();
  357.         $this->white();
  358.  
  359.         if ($this->ch == '}'{
  360.           $this->next();
  361.           return $o;
  362.         }
  363.  
  364.         while ($this->ch{
  365.           $k $this->str();
  366.           $this->white();
  367.  
  368.           if ($this->ch != ':'{
  369.             break;
  370.           }
  371.  
  372.           $this->next();
  373.           $o->$k $this->val();
  374.           $this->white();
  375.  
  376.           if ($this->ch == '}'{
  377.             $this->next();
  378.             return $o;
  379.  
  380.           elseif ($this->ch != ','{
  381.             break;
  382.           }
  383.  
  384.           $this->next();
  385.           $this->white();
  386.         }
  387.       }
  388.  
  389.       $this->error('Bad object');
  390.     }
  391.  
  392.     /**
  393.     * handles objects
  394.     *
  395.     * @access  public
  396.     * @return  void 
  397.     */
  398.     function assoc({
  399.       $k '';
  400.       $a array();
  401.  
  402.       if ($this->ch == '<'{
  403.         $this->next();
  404.         $this->white();
  405.  
  406.         if ($this->ch == '>'{
  407.           $this->next();
  408.           return $a;
  409.         }
  410.  
  411.         while ($this->ch{
  412.           $k $this->str();
  413.           $this->white();
  414.  
  415.           if ($this->ch != ':'{
  416.             break;
  417.           }
  418.  
  419.           $this->next();
  420.           $a[$k$this->val();
  421.           $this->white();
  422.  
  423.           if ($this->ch == '>'{
  424.             $this->next();
  425.             return $a;
  426.  
  427.           elseif ($this->ch != ','{
  428.             break;
  429.           }
  430.  
  431.           $this->next();
  432.           $this->white();
  433.         }
  434.       }
  435.  
  436.       $this->error('Bad associative array');
  437.     }
  438.  
  439.     /**
  440.     * handles numbers
  441.     *
  442.     * @access  private
  443.     * @return  void 
  444.     */
  445.     function num({
  446.       $n '';
  447.       $v '';
  448.  
  449.       if ($this->ch == '-'{
  450.         $n '-';
  451.         $this->next();
  452.       }
  453.  
  454.       while ($this->ch >= '0'
  455.         && $this->ch <= '9'{
  456.  
  457.         $n .= $this->ch;
  458.         $this->next();
  459.       }
  460.  
  461.       if ($this->ch == '.'{
  462.         $n .= '.';
  463.  
  464.         while ($this->next()
  465.           && $this->ch >= '0'
  466.           && $this->ch <= '9'{
  467.  
  468.             $n .= $this->ch;
  469.           }
  470.         }
  471.  
  472.       if ($this->ch == 'e'
  473.         || $this->ch == 'E'{
  474.  
  475.         $n .= 'e';
  476.         $this->next();
  477.  
  478.         if ($this->ch == '-'
  479.           || $this->ch == '+'{
  480.  
  481.           $n .= $this->ch;
  482.           $this->next();
  483.         }
  484.  
  485.         while ($this->ch >= '0'
  486.           && $this->ch <= '9'{
  487.  
  488.           $n .= $this->ch;
  489.           $this->next();
  490.         }
  491.       }
  492.  
  493.       $v += $n;
  494.  
  495.       if (!is_numeric($v)) {
  496.         $this->error('Bad number');
  497.  
  498.       else {
  499.         return $v;
  500.       // end: if
  501.     }
  502.  
  503.     /**
  504.     * handles words
  505.     *
  506.     * @access  private
  507.     * @return  mixed 
  508.     */
  509.     function word({
  510.       switch ($this->ch{
  511.  
  512.         case 't':
  513.  
  514.           if ($this->next(== 'r'
  515.             && $this->next(== 'u'
  516.             && $this->next(== 'e'{
  517.  
  518.             $this->next();
  519.             return true;
  520.           }
  521.           break;
  522.  
  523.         case 'f':
  524.           if ($this->next(== 'a'
  525.             && $this->next(== 'l'
  526.             && $this->next(== 's'
  527.             && $this->next(== 'e'{
  528.  
  529.             $this->next();
  530.             return false;
  531.           }
  532.           break;
  533.  
  534.         case 'n':
  535.           if ($this->next(== 'u'
  536.             && $this->next(== 'l'
  537.             && $this->next(== 'l'{
  538.  
  539.             $this->next();
  540.             return null;
  541.           }
  542.           break;
  543.       }
  544.  
  545.       $this->error('Syntax error');
  546.     }
  547.  
  548.     /**
  549.     * generic value handler
  550.     *
  551.     * @access  private
  552.     * @return  mixed 
  553.     */
  554.     function val({
  555.       $this->white();
  556.  
  557.       switch ($this->ch{
  558.  
  559.         case '{':
  560.           return $this->obj();
  561.  
  562.         case '[':
  563.           return $this->arr();
  564.  
  565.         case '<':
  566.           return $this->assoc();
  567.  
  568.         case '"':
  569.           return $this->str();
  570.  
  571.         case '-':
  572.           return $this->num();
  573.  
  574.         default:
  575.           return ($this->ch >= '0' && $this->ch <= '9'$this->num($this->word();
  576.       }
  577.     }
  578.   }
  579.  
  580. ?>

Documentation generated on Mon, 03 Aug 2009 21:33:17 +0200 by phpDocumentor 1.4.2