Skip to end of metadata
Go to start of metadata

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

Zend Framework: Zend_Json_Expr Component Proposal

Proposed Component Name Zend_Json_Expr
Developer Notes http://framework.zend.com/wiki/display/ZFDEV/Zend_Json_Expr
Proposers Oscar Reales
Zend Liaison Matthew Weier O'Phinney
Revision 1.0 - 10 August 2008: Initial Draft. (wiki revision: 13)

Table of Contents

1. Overview

Add the possibility of including functions and native javascripts expressions to be encoded by Zend_Json, generating right syntax in the outputted json. The main idea is follow the Zend_Db_Expr pattern, so to include a Javascript Expression to be encoded in an object/array, will be enough to uses something similar to Zend_Json_Expr('javascript expression').

2. References

3. Component Requirements, Constraints, and Acceptance Criteria

  • This component will allow include Functions and Javascript Expressions in arrays/object to be encoded with Zend_Json
  • This component will require the creation of a new Zend_Json_Expr class, very similar to Zend_Db_Expr
  • This component will need to re-code the Zend_Json encoding proccess and includes 2 private properties to the class that will hold some values temporarily during the encoding proccess
  • This component will be functional with Array/Objects to be encoded. Encoding from XML will need to be handle maybe in other way

4. Dependencies on Other Framework Components

  • Zend_Json

5. Theory of Operation

To include a native Javascript Expression in a PHP Array/Object will be required to use Zend_Json_Expr class, with the following syntax: Zend_Json_Expr('javascript expression').

This Zend_Json_Expr class will be used to find and temporarily replace pre-encoding proccess all the javascript expressions we want to encode.

The value to be encoded in json format will be pre-encoding parsed and all finded Zend_Json_Expr will be temporarily keeped in an array. Each matched Zend_Json_Expr will be replaced by a single id. In this way the encoding can be runned without errors. After encoding proccess finish, it is required to parse the result in the inverse way: replacing the single temporary "ids" by their corresponding original Javascript Expressions.

Because the result it is already a String after the encoding, it is possible to includes the original Javascript Expressions without "'".

6. Milestones / Tasks

  • Milestone 1: [DONE] Create the classes skeleton
  • Milestone 2: [DONE] Working prototype
  • Milestone 3: [DONE] Review code to follow ZF coding conventions
  • Milestone 4: Create - Modify Unit Testing
  • Milestone 5: Documentation

7. Class Index

  • Zend_Json_Expr
  • Zend_Json

8. Use Cases

UC-01

This is a sample of using the Zend_Json_Expr class in a controller that will returns a json encoded object with one simple javascript function:

<?php
class JsonUseCase extends Zend_Controller_Action
{

function indexAction()
{
Zend_Loader::loadClass('Zend_Json_Expr');
$encodedResult = array(
'integer'=>9,
'string'=>'test string',
'function'=>Zend_Json_Expr('function(){window.alert("javascript function encoded by Zend_Json")}')
);

$this->_helper->json->sendJson($resultado);
//it will returns json encoded string:
//{"integer":9,"string":"test string","function":function(){window.alert("javascript function encoded by Zend_Json")}}
}

}

9. Class Skeletons

]]></ac:plain-text-body></ac:macro>

]]></ac:plain-text-body></ac:macro>

Labels:
zend_json zend_json Delete
json json Delete
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Aug 15, 2008

    <p>This is a great proposal. This is a great addition that could be perfectly integrated into my jQuery proposal (or any other javascript helper related helper/library).</p>

    <p>I'd support you in pushing this through for 1.7 <ac:emoticon ac:name="smile" /></p>

    <p>btw, you should move the proposal into ready for review section, since you already posted it on the mailinglist also.</p>

  2. Aug 18, 2008

    <p>Thanks Benjamin. It is my first proposal and I am not very "fluent" with the proccess. I want to "clean" the code and adjust it to the "coding standards" before move it for review. I am needing some help with the PHP Unit Testing because I never used it before. If someone can helps me on that would be good.</p>

    <p>Anyway I will do an effort to place it for review asap.</p>

    <p>Thanks again for your comments.</p>

  3. Oct 31, 2008

    <ac:macro ac:name="note"><ac:parameter ac:name="title">Zend Acceptance</ac:parameter><ac:rich-text-body>
    <p>This proposal has been accepted for immediate development in the standard incubator.</p></ac:rich-text-body></ac:macro>

  4. Jan 14, 2009

    <p>Here is my offer as what shift cart with place.</p>

    <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
    <?php

    require_once 'Zend/Json.php';

    class Zend_Json_Expr
    {
    protected $_expression;

    public function __construct($expression)

    Unknown macro: { $this->_expression = (string) $expression; }

    /**

    • Don't need to to re-code the Zend_Json encoding proccess!!!
    • Currently Zend_Json does not support this feature and
    • this will be not create some problems for earlier created components
      *
    • This feature is specific use only and may used by some needs.
    • Zend_Json does not need to require Zend_Json_Expr.
    • Zend_Json_Expr used by itself Zend_Json.
      */
      public static function encode($valueToEncode, $cycleCheck = false, $options = array())
      {
      $javascriptExpressions = array();
      //pre-proccessing
      $valueToEncode = self::_preprocessValue($valueToEncode, $javascriptExpressions);

    $encodedResult = Zend_Json::encode($valueToEncode, $cycleCheck, $options);

    //post-proccessing
    if(count($javascriptExpressions) > 0) {
    for($i = 0; $i < count($javascriptExpressions); $i++)

    Unknown macro: { $key = $javascriptExpressions[$i]['key']; $value = $javascriptExpressions[$i]['value']; $magicKey = $javascriptExpressions[$i]['magicKey']; $magicValue = $javascriptExpressions[$i]['magicValue']; $encodedResult = str_replace( '"'.$magicKey.'"}

    }

    return $encodedResult;
    }

    /**

    • Support UTF keys and values in arrays
    • Support UTF values in objects
      */
      protected static function _preprocessValue(&$value, array &$javascriptExpressions, &$currentKey = null, $touchKey = false)
      {
      if($value instanceof Zend_Json_Expr) {
      $count = count($javascriptExpressions);

    if($touchKey)

    Unknown macro: { $magicKey = "____Zend_Json_Expression_Index_".($count); }

    else

    Unknown macro: { $magicKey = $currentKey; // We shall always caught this at least once on $magicValue pattern }

    $magicValue = "___Zend_Json_Expression_Value".($count);
    $javascriptExpressions[] = array(
    "key" => $currentKey,
    "value" => $value->__toString(),
    "magicKey" => $magicKey,
    "magicValue" => $magicValue
    );
    // value may contains UTF chars
    // we always replacing value by a trusted (magic) value
    $value = $magicValue;
    // if key an index of array it may contains UTF chars
    // we don't trust it
    // we are replacing original key by your magic (Non-UTF) key if needs
    if($touchKey)

    Unknown macro: { $currentKey = $magicKey; }

    // else leave $currentKey as it is
    } elseif(is_array($value)) {
    // here we save original keys order
    $keys = array_keys($value);
    $value2 = array();
    foreach($keys AS $k1)

    Unknown macro: { $k2 = $k1; // UTF key may be dangerous (and will be lost) and we need temporarily replace it $value2[$k2] = self}

    $value = $value2;
    } elseif(is_object($value)) {
    foreach($value AS $k => $v)

    Unknown macro: { // Don't touch key for object properties $value->$k = self}

    }
    return $value;
    }

    public function __toString()

    Unknown macro: { return $this->_expression; }

    }
    ]]></ac:plain-text-body></ac:macro>

  5. Jan 15, 2009

    <p>Hi Inozemtcev,</p>

    <p>Thanks for your offer. I have checked the code and have interesting points. Anyway I need to analyze it deeper.</p>

    <p>UTF8 supporting is important, and that is good from your code!.</p>

    <p>About having the "encode" method inside Zend_Json_Expr and don´t recode Zend_Json. I am not sure about it. I think that OOP good practice should keep the encode method in Zend_Json object. </p>

    <p>I have not clear when and from where are you going to invoque Zend_Json_Expr->encode method. I mean, if I want to encode lets say an array with javascript expressions to encode, you purpose to use Zend_Json_Expr::encode() instead of Zend_Json::encode(), don´t you?.</p>

    <p>Can you include a User Case for your code?. </p>

    <p>Thanks for your help!</p>

  6. Mar 10, 2009

    <p>Before viewing this proposal, I've written an Issue (<a class="external-link" href="http://framework.zend.com/issues/browse/ZF-5974">http://framework.zend.com/issues/browse/ZF-5974</a>) doing something similar.</p>

    <p>My fix works only with the internal encoder but maybe it's a cleaner way to do it. I've already contacted the maintainer of ext/json to know what will be the future behavior (or at least what it should be) int the php extension.</p>

  7. Mar 18, 2009

    <p>Has this proposal been abandoned? Please reply here.</p>

    1. Mar 19, 2009

      <p>Nope, its finished and waiting in incubator. Its only missing the documentation now, but i plan to add that before 1.8</p>

    2. Mar 19, 2009

      <p>No. As Benjamin states the proposal is finished, and only documentation is missing. I should be working on documentation but I have not much time to finish it and my english is not so fluent. Any help would be very much apprecciated.</p>

  8. Apr 02, 2009

    <p>If it's waiting in incubator, why does the reference guide actually list this functionality and provides an overview of it? There is no note that this feature is not yet available in the redistribution.</p>

  9. Feb 03, 2010

    <p>I like the idea of the proposal, but I think that it is not legal to encode a function name into a JSON object.</p>

    <p><a class="external-link" href="http://www.ietf.org/rfc/rfc4627.txt">http://www.ietf.org/rfc/rfc4627.txt</a></p>

    <p>Specifically, look at section "2.1 Values".</p>

    <p>This means that any compliant JSON parser will fail if you use a Zend_Json_Expr. </p>

    <p>The only workaround is to eval() the expression – but then its not JSON anymore, its just arbitrary javascript.</p>

    1. Feb 04, 2010

      <p>This proposal is already included since version 1.8.</p>

      <p>Also its an optional feature which is required for both the Dojo and the jQuery Server side extensions, because they need to allow to add javascript callbacks to the configuration json options of the corresponding view helpers.</p>