title: How to limit characters per message and make anti-spam?
body: <p>i have this shouwbox script.
  I would like to know how to limit the characters for each message like 70 characters.
  And i would also like to know how to do so you have to wait 3 seconds between each message you post.</p>
  
  <p>Here is my script.</p>
  
  <p><strong>Index.html</strong>
      
      
      </p>
  
  <pre><code>  &lt;meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"&gt;
  &lt;title&gt;jQuery&lt;/title&gt;
    &lt;style type="text/css"&gt;
      #daddy-shoutbox {
      padding: 5px;
      background: #FFF;
      color: #000;
      width: 250px;
      font-family: Arial,Helvetica,sans-serif;
      font-size: 11px;
      }
      .shoutbox-list {
      border-bottom: 1px solid #000;
      padding: 5px;
      display: none;
      }
      #daddy-shoutbox-list {
        text-align: left;
        margin: 0px auto;
      }
      #daddy-shoutbox-form {
        text-align: left;
  
      }
      .shoutbox-list-time {
      color: #000;
      }
      .shoutbox-list-nick {
        margin-left: 5px;
        font-weight: bold;
      }
      .shoutbox-list-message {
        margin-left: 5px;
      }
  
    &lt;/style&gt;
  &lt;script type="text/javascript" src="js/jquery.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript" src="js/jquery.form.js"&gt;&lt;/script&gt;
  &lt;/head&gt;
    &lt;body&gt;
  
  
    &lt;div id="daddy-shoutbox"&gt;   
    &lt;table cellpadding="3" cellspacing="0"&gt;
  
  &lt;form id="daddy-shoutbox-form" action="demos/jquery-shoutbox/daddy-shoutbox.php?action=add" method="post"&gt; 
    &lt;tr&gt; 
    &lt;td&gt;    
      Name: 
      &lt;input type="text" name="nickname" /&gt; 
    &lt;/td&gt;
    &lt;/tr&gt;
      &lt;tr&gt; 
    &lt;td&gt; 
    Message: 
    &lt;input type="text" name="message" /&gt;
   &lt;br /&gt; &lt;br /&gt;
      &lt;input type="submit" value="Submit" /&gt;
      &lt;span id="daddy-shoutbox-response"&gt;&lt;/span&gt;
    &lt;/form&gt; 
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/table&gt;
      &lt;hr size="1" noshade /&gt;
      &lt;div id="daddy-shoutbox-list"&gt;&lt;/div&gt;
      &lt;br /&gt;
  
    &lt;/div&gt;
  
    &lt;script type="text/javascript"&gt;
          var count = 0;
          var files = 'demos/jquery-shoutbox/';
          var lastTime = 0;
  
          function prepare(response) {
            var d = new Date();
            count++;
            d.setTime(response.time*1000);
            var mytime = d.getHours()+':'+d.getMinutes()+':'+d.getSeconds();
            var string = '&lt;div class="shoutbox-list" id="list-'+count+'"&gt;'
                + '&lt;span class="shoutbox-list-time"&gt;'+mytime+'&lt;/span&gt;'
                + '&lt;span class="shoutbox-list-nick"&gt;'+response.nickname+':&lt;/span&gt;'
                + '&lt;span class="shoutbox-list-message"&gt;'+response.message+'&lt;/span&gt;'
                +'&lt;/div&gt;';
            if (count &gt; 11) { x = (count - 11); $('#list-' + x).fadeOut('slow'); x = document.getElementById('list-' + x); x.style.display = "none"; }
            return string;
          }
  
          function success(response, status)  { 
            if(status == 'success') {
              lastTime = response.time;
              $('#daddy-shoutbox-response').html('&lt;img src="'+files+'images/accept.png" /&gt;');
              $('#daddy-shoutbox-list').prepend(prepare(response));
              $('input[@name=message]').attr('value', '').focus();
              $('#list-'+count).fadeIn('slow');
              timeoutID = setTimeout(refresh, 3000);
            }
          }
  
          function validate(formData, jqForm, options) {
            for (var i=0; i &lt; formData.length; i++) { 
                if (!formData[i].value) {
                    alert('Please fill in all the fields'); 
                    $('input[@name='+formData[i].name+']').css('background', 'red');
                    return false; 
                } 
            } 
            $('#daddy-shoutbox-response').html('&lt;img src="'+files+'images/loader.gif" /&gt;');
            clearTimeout(timeoutID);
          }
  
          function refresh() {
            $.getJSON(files+"daddy-shoutbox.php?action=view&amp;time="+lastTime, function(json) {
              if(json.length) {
                for(i=0; i &lt; json.length; i++) {
                  $('#daddy-shoutbox-list').prepend(prepare(json[i]));
                  $('#list-' + count).fadeIn('slow');
                }
                var j = i-1;
                lastTime = json[j].time;
              }
              //alert(lastTime);
            });
            timeoutID = setTimeout(refresh, 3000);
          }
  
          // wait for the DOM to be loaded 
          $(document).ready(function() { 
              var options = { 
                dataType:       'json',
                beforeSubmit:   validate,
                success:        success
              }; 
              $('#daddy-shoutbox-form').ajaxForm(options);
              timeoutID = setTimeout(refresh, 100);
          });
    &lt;/script&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p><strong>daddy-shoutbox.php</strong></p>
  
  <pre><code>&lt;?php
    function replace(&amp;$item, $key) {
      $item = str_replace('|', '-', $item);
    }
  
    if (!function_exists('file_put_contents')) {
          function file_put_contents($fileName, $data) {
              if (is_array($data)) {
                  $data = join('', $data);
              }
              $res = @fopen($fileName, 'w+b');
              if ($res) {
                  $write = @fwrite($res, $data);
                  if($write === false) {
                      return false;
                  } else {
                      return $write;
                  }
              }
          }
      }
  
    //file_put_contents('debug.txt', print_r($_GET, true));
    switch($_GET['action']) {
      case 'add':
        array_walk($_POST, 'replace');
        $arr = file('messages.txt');
  
        if(count($arr) &gt; 10)
          array_shift($arr);
  
        $_POST['nickname'] = htmlentities($_POST['nickname']);
        $_POST['message'] = htmlentities($_POST['message']);
        $time = time();
        $arr[] = $time.'|'.$_POST['nickname'].'|'.$_POST['message'].'|'.$_SERVER['REMOTE_ADDR']."\n";
        file_put_contents('messages.txt', implode('', $arr));
  
        $data['response'] = 'Good work';
        $data['nickname'] = $_POST['nickname'];
        $data['message'] = $_POST['message'];
        $data['time'] = $time;
      break;
  
      case 'view':
        $data = array();
        $arr = file('messages.txt');
        if(!$_GET['time'])
          $_GET['time'] = 0;
        foreach($arr as $row) {
          $aTemp = null;
          list($aTemp['time'], $aTemp['nickname'], $aTemp['message']) = explode('|', $row); 
          if($aTemp['message'] AND $aTemp['time'] &gt; $_GET['time'])
            $data[] = $aTemp;
        }
        //file_put_contents('debug.txt', print_r($data, true));
      break;
    }
  
    require_once('JSON.php');
    $json = new Services_JSON();
    $out = $json-&gt;encode($data);
    print $out;
  ?&gt;
  </code></pre>
  
  <p><strong>JSON.php</strong></p>
  
  <pre><code>&lt;?php
  /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  
  /**
   * Converts to and from JSON format.
   *
   * JSON (JavaScript Object Notation) is a lightweight data-interchange
   * format. It is easy for humans to read and write. It is easy for machines
   * to parse and generate. It is based on a subset of the JavaScript
   * Programming Language, Standard ECMA-262 3rd Edition - December 1999.
   * This feature can also be found in  Python. JSON is a text format that is
   * completely language independent but uses conventions that are familiar
   * to programmers of the C-family of languages, including C, C++, C#, Java,
   * JavaScript, Perl, TCL, and many others. These properties make JSON an
   * ideal data-interchange language.
   *
   * This package provides a simple encoder and decoder for JSON notation. It
   * is intended for use with client-side Javascript applications that make
   * use of HTTPRequest to perform server communication functions - data can
   * be encoded into JSON notation for use in a client-side javascript, or
   * decoded from incoming Javascript requests. JSON format is native to
   * Javascript, and can be directly eval()'ed with no further parsing
   * overhead
   *
   * All strings should be in ASCII or UTF-8 format!
   *
   * LICENSE: Redistribution and use in source and binary forms, with or
   * without modification, are permitted provided that the following
   * conditions are met: Redistributions of source code must retain the
   * above copyright notice, this list of conditions and the following
   * disclaimer. Redistributions in binary form must reproduce the above
   * copyright notice, this list of conditions and the following disclaimer
   * in the documentation and/or other materials provided with the
   * distribution.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
   * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
   * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
   * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
   * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
   * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
   * DAMAGE.
   *
   * @category
   * @package     Services_JSON
   * @author      Michal Migurski &lt;mike-json@teczno.com&gt;
   * @author      Matt Knapp &lt;mdknapp[at]gmail[dot]com&gt;
   * @author      Brett Stimmerman &lt;brettstimmerman[at]gmail[dot]com&gt;
   * @copyright   2005 Michal Migurski
   * @version     CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $
   * @license     http://www.opensource.org/licenses/bsd-license.php
   * @link        http://pear.php.net/pepr/pepr-proposal-show.php?id=198
   */
  
  /**
   * Marker constant for Services_JSON::decode(), used to flag stack state
   */
  define('SERVICES_JSON_SLICE',   1);
  
  /**
   * Marker constant for Services_JSON::decode(), used to flag stack state
   */
  define('SERVICES_JSON_IN_STR',  2);
  
  /**
   * Marker constant for Services_JSON::decode(), used to flag stack state
   */
  define('SERVICES_JSON_IN_ARR',  3);
  
  /**
   * Marker constant for Services_JSON::decode(), used to flag stack state
   */
  define('SERVICES_JSON_IN_OBJ',  4);
  
  /**
   * Marker constant for Services_JSON::decode(), used to flag stack state
   */
  define('SERVICES_JSON_IN_CMT', 5);
  
  /**
   * Behavior switch for Services_JSON::decode()
   */
  define('SERVICES_JSON_LOOSE_TYPE', 16);
  
  /**
   * Behavior switch for Services_JSON::decode()
   */
  define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
  
  /**
   * Converts to and from JSON format.
   *
   * Brief example of use:
   *
   * &lt;code&gt;
   * // create a new instance of Services_JSON
   * $json = new Services_JSON();
   *
   * // convert a complexe value to JSON notation, and send it to the browser
   * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
   * $output = $json-&gt;encode($value);
   *
   * print($output);
   * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
   *
   * // accept incoming POST data, assumed to be in JSON notation
   * $input = file_get_contents('php://input', 1000000);
   * $value = $json-&gt;decode($input);
   * &lt;/code&gt;
   */
  class Services_JSON
  {
     /**
      * constructs a new JSON instance
      *
      * @param    int     $use    object behavior flags; combine with boolean-OR
      *
      *                           possible values:
      *                           - SERVICES_JSON_LOOSE_TYPE:  loose typing.
      *                                   "{...}" syntax creates associative arrays
      *                                   instead of objects in decode().
      *                           - SERVICES_JSON_SUPPRESS_ERRORS:  error suppression.
      *                                   Values which can't be encoded (e.g. resources)
      *                                   appear as NULL instead of throwing errors.
      *                                   By default, a deeply-nested resource will
      *                                   bubble up with an error, so all return values
      *                                   from encode() should be checked with isError()
      */
      function Services_JSON($use = 0)
      {
          $this-&gt;use = $use;
      }
  
     /**
      * convert a string from one UTF-16 char to one UTF-8 char
      *
      * Normally should be handled by mb_convert_encoding, but
      * provides a slower PHP-only method for installations
      * that lack the multibye string extension.
      *
      * @param    string  $utf16  UTF-16 character
      * @return   string  UTF-8 character
      * @access   private
      */
      function utf162utf8($utf16)
      {
          // oh please oh please oh please oh please oh please
          if(function_exists('mb_convert_encoding')) {
              return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
          }
  
          $bytes = (ord($utf16{0}) &lt;&lt; 8) | ord($utf16{1});
  
          switch(true) {
              case ((0x7F &amp; $bytes) == $bytes):
                  // this case should never be reached, because we are in ASCII range
                  // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                  return chr(0x7F &amp; $bytes);
  
              case (0x07FF &amp; $bytes) == $bytes:
                  // return a 2-byte UTF-8 character
                  // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                  return chr(0xC0 | (($bytes &gt;&gt; 6) &amp; 0x1F))
                       . chr(0x80 | ($bytes &amp; 0x3F));
  
              case (0xFFFF &amp; $bytes) == $bytes:
                  // return a 3-byte UTF-8 character
                  // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                  return chr(0xE0 | (($bytes &gt;&gt; 12) &amp; 0x0F))
                       . chr(0x80 | (($bytes &gt;&gt; 6) &amp; 0x3F))
                       . chr(0x80 | ($bytes &amp; 0x3F));
          }
  
          // ignoring UTF-32 for now, sorry
          return '';
      }
  
     /**
      * convert a string from one UTF-8 char to one UTF-16 char
      *
      * Normally should be handled by mb_convert_encoding, but
      * provides a slower PHP-only method for installations
      * that lack the multibye string extension.
      *
      * @param    string  $utf8   UTF-8 character
      * @return   string  UTF-16 character
      * @access   private
      */
      function utf82utf16($utf8)
      {
          // oh please oh please oh please oh please oh please
          if(function_exists('mb_convert_encoding')) {
              return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
          }
  
          switch(strlen($utf8)) {
              case 1:
                  // this case should never be reached, because we are in ASCII range
                  // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                  return $utf8;
  
              case 2:
                  // return a UTF-16 character from a 2-byte UTF-8 char
                  // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                  return chr(0x07 &amp; (ord($utf8{0}) &gt;&gt; 2))
                       . chr((0xC0 &amp; (ord($utf8{0}) &lt;&lt; 6))
                           | (0x3F &amp; ord($utf8{1})));
  
              case 3:
                  // return a UTF-16 character from a 3-byte UTF-8 char
                  // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                  return chr((0xF0 &amp; (ord($utf8{0}) &lt;&lt; 4))
                           | (0x0F &amp; (ord($utf8{1}) &gt;&gt; 2)))
                       . chr((0xC0 &amp; (ord($utf8{1}) &lt;&lt; 6))
                           | (0x7F &amp; ord($utf8{2})));
          }
  
          // ignoring UTF-32 for now, sorry
          return '';
      }
  
     /**
      * encodes an arbitrary variable into JSON format
      *
      * @param    mixed   $var    any number, boolean, string, array, or object to be encoded.
      *                           see argument 1 to Services_JSON() above for array-parsing behavior.
      *                           if var is a strng, note that encode() always expects it
      *                           to be in ASCII or UTF-8 format!
      *
      * @return   mixed   JSON string representation of input var or an error if a problem occurs
      * @access   public
      */
      function encode($var)
      {
          switch (gettype($var)) {
              case 'boolean':
                  return $var ? 'true' : 'false';
  
              case 'NULL':
                  return 'null';
  
              case 'integer':
                  return (int) $var;
  
              case 'double':
              case 'float':
                  return (float) $var;
  
              case 'string':
                  // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
                  $ascii = '';
                  $strlen_var = strlen($var);
  
                 /*
                  * Iterate over every character in the string,
                  * escaping with a slash or encoding to UTF-8 where necessary
                  */
                  for ($c = 0; $c &lt; $strlen_var; ++$c) {
  
                      $ord_var_c = ord($var{$c});
  
                      switch (true) {
                          case $ord_var_c == 0x08:
                              $ascii .= '\b';
                              break;
                          case $ord_var_c == 0x09:
                              $ascii .= '\t';
                              break;
                          case $ord_var_c == 0x0A:
                              $ascii .= '\n';
                              break;
                          case $ord_var_c == 0x0C:
                              $ascii .= '\f';
                              break;
                          case $ord_var_c == 0x0D:
                              $ascii .= '\r';
                              break;
  
                          case $ord_var_c == 0x22:
                          case $ord_var_c == 0x2F:
                          case $ord_var_c == 0x5C:
                              // double quote, slash, slosh
                              $ascii .= '\\'.$var{$c};
                              break;
  
                          case (($ord_var_c &gt;= 0x20) &amp;&amp; ($ord_var_c &lt;= 0x7F)):
                              // characters U-00000000 - U-0000007F (same as ASCII)
                              $ascii .= $var{$c};
                              break;
  
                          case (($ord_var_c &amp; 0xE0) == 0xC0):
                              // characters U-00000080 - U-000007FF, mask 110XXXXX
                              // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                              $char = pack('C*', $ord_var_c, ord($var{$c + 1}));
                              $c += 1;
                              $utf16 = $this-&gt;utf82utf16($char);
                              $ascii .= sprintf('\u%04s', bin2hex($utf16));
                              break;
  
                          case (($ord_var_c &amp; 0xF0) == 0xE0):
                              // characters U-00000800 - U-0000FFFF, mask 1110XXXX
                              // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                              $char = pack('C*', $ord_var_c,
                                           ord($var{$c + 1}),
                                           ord($var{$c + 2}));
                              $c += 2;
                              $utf16 = $this-&gt;utf82utf16($char);
                              $ascii .= sprintf('\u%04s', bin2hex($utf16));
                              break;
  
                          case (($ord_var_c &amp; 0xF8) == 0xF0):
                              // characters U-00010000 - U-001FFFFF, mask 11110XXX
                              // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                              $char = pack('C*', $ord_var_c,
                                           ord($var{$c + 1}),
                                           ord($var{$c + 2}),
                                           ord($var{$c + 3}));
                              $c += 3;
                              $utf16 = $this-&gt;utf82utf16($char);
                              $ascii .= sprintf('\u%04s', bin2hex($utf16));
                              break;
  
                          case (($ord_var_c &amp; 0xFC) == 0xF8):
                              // characters U-00200000 - U-03FFFFFF, mask 111110XX
                              // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                              $char = pack('C*', $ord_var_c,
                                           ord($var{$c + 1}),
                                           ord($var{$c + 2}),
                                           ord($var{$c + 3}),
                                           ord($var{$c + 4}));
                              $c += 4;
                              $utf16 = $this-&gt;utf82utf16($char);
                              $ascii .= sprintf('\u%04s', bin2hex($utf16));
                              break;
  
                          case (($ord_var_c &amp; 0xFE) == 0xFC):
                              // characters U-04000000 - U-7FFFFFFF, mask 1111110X
                              // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                              $char = pack('C*', $ord_var_c,
                                           ord($var{$c + 1}),
                                           ord($var{$c + 2}),
                                           ord($var{$c + 3}),
                                           ord($var{$c + 4}),
                                           ord($var{$c + 5}));
                              $c += 5;
                              $utf16 = $this-&gt;utf82utf16($char);
                              $ascii .= sprintf('\u%04s', bin2hex($utf16));
                              break;
                      }
                  }
  
                  return '"'.$ascii.'"';
  
              case 'array':
                 /*
                  * As per JSON spec if any array key is not an integer
                  * we must treat the the whole array as an object. We
                  * also try to catch a sparsely populated associative
                  * array with numeric keys here because some JS engines
                  * will create an array with empty indexes up to
                  * max_index which can cause memory issues and because
                  * the keys, which may be relevant, will be remapped
                  * otherwise.
                  *
                  * As per the ECMA and JSON specification an object may
                  * have any string as a property. Unfortunately due to
                  * a hole in the ECMA specification if the key is a
                  * ECMA reserved word or starts with a digit the
                  * parameter is only accessible using ECMAScript's
                  * bracket notation.
                  */
  
                  // treat as a JSON object
                  if (is_array($var) &amp;&amp; count($var) &amp;&amp; (array_keys($var) !== range(0, sizeof($var) - 1))) {
                      $properties = array_map(array($this, 'name_value'),
                                              array_keys($var),
                                              array_values($var));
  
                      foreach($properties as $property) {
                          if(Services_JSON::isError($property)) {
                              return $property;
                          }
                      }
  
                      return '{' . join(',', $properties) . '}';
                  }
  
                  // treat it like a regular array
                  $elements = array_map(array($this, 'encode'), $var);
  
                  foreach($elements as $element) {
                      if(Services_JSON::isError($element)) {
                          return $element;
                      }
                  }
  
                  return '[' . join(',', $elements) . ']';
  
              case 'object':
                  $vars = get_object_vars($var);
  
                  $properties = array_map(array($this, 'name_value'),
                                          array_keys($vars),
                                          array_values($vars));
  
                  foreach($properties as $property) {
                      if(Services_JSON::isError($property)) {
                          return $property;
                      }
                  }
  
                  return '{' . join(',', $properties) . '}';
  
              default:
                  return ($this-&gt;use &amp; SERVICES_JSON_SUPPRESS_ERRORS)
                      ? 'null'
                      : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
          }
      }
  
     /**
      * array-walking function for use in generating JSON-formatted name-value pairs
      *
      * @param    string  $name   name of key to use
      * @param    mixed   $value  reference to an array element to be encoded
      *
      * @return   string  JSON-formatted name-value pair, like '"name":value'
      * @access   private
      */
      function name_value($name, $value)
      {
          $encoded_value = $this-&gt;encode($value);
  
          if(Services_JSON::isError($encoded_value)) {
              return $encoded_value;
          }
  
          return $this-&gt;encode(strval($name)) . ':' . $encoded_value;
      }
  
     /**
      * reduce a string by removing leading and trailing comments and whitespace
      *
      * @param    $str    string      string value to strip of comments and whitespace
      *
      * @return   string  string value stripped of comments and whitespace
      * @access   private
      */
      function reduce_string($str)
      {
          $str = preg_replace(array(
  
                  // eliminate single line comments in '// ...' form
                  '#^\s*//(.+)$#m',
  
                  // eliminate multi-line comments in '/* ... */' form, at start of string
                  '#^\s*/\*(.+)\*/#Us',
  
                  // eliminate multi-line comments in '/* ... */' form, at end of string
                  '#/\*(.+)\*/\s*$#Us'
  
              ), '', $str);
  
          // eliminate extraneous space
          return trim($str);
      }
  
     /**
      * decodes a JSON string into appropriate variable
      *
      * @param    string  $str    JSON-formatted string
      *
      * @return   mixed   number, boolean, string, array, or object
      *                   corresponding to given JSON input string.
      *                   See argument 1 to Services_JSON() above for object-output behavior.
      *                   Note that decode() always returns strings
      *                   in ASCII or UTF-8 format!
      * @access   public
      */
      function decode($str)
      {
          $str = $this-&gt;reduce_string($str);
  
          switch (strtolower($str)) {
              case 'true':
                  return true;
  
              case 'false':
                  return false;
  
              case 'null':
                  return null;
  
              default:
                  $m = array();
  
                  if (is_numeric($str)) {
                      // Lookie-loo, it's a number
  
                      // This would work on its own, but I'm trying to be
                      // good about returning integers where appropriate:
                      // return (float)$str;
  
                      // Return float or int, as appropriate
                      return ((float)$str == (integer)$str)
                          ? (integer)$str
                          : (float)$str;
  
                  } elseif (pre
  </code></pre>