|
| 1 | +# Advanced Usage |
| 2 | + |
| 3 | +## JSON Objects |
| 4 | + |
| 5 | +When encoding *PHP* objects as *JSON*, all public properties of that object will be encoded in a |
| 6 | +*JSON* object. |
| 7 | + |
| 8 | +*JSON* does not allow object references, so care should be taken not to encode objects with |
| 9 | +recursive references. If you have issues with recursion, `Zend\Json\Json::encode()` and |
| 10 | +`Zend\Json\Encoder::encode()` allow an optional second parameter to check for recursion; if an |
| 11 | +object is serialized twice, an exception will be thrown. |
| 12 | + |
| 13 | +Decoding *JSON* objects poses an additional difficulty, however, since JavaScript objects correspond |
| 14 | +most closely to *PHP*'s associative array. Some suggest that a class identifier should be passed, |
| 15 | +and an object instance of that class should be created and populated with the key/value pairs of the |
| 16 | +*JSON* object; others feel this could pose a substantial security risk. |
| 17 | + |
| 18 | +By default, `Zend\Json\Json` will decode *JSON* objects as `stdClass` objects. However, if you |
| 19 | +desire an associative array returned, you can specify this: |
| 20 | + |
| 21 | +```php |
| 22 | +// Decode JSON objects as PHP array |
| 23 | +$phpNative = Zend\Json\Json::decode($encodedValue, Zend\Json\Json::TYPE_ARRAY); |
| 24 | +``` |
| 25 | + |
| 26 | +Any objects thus decoded are returned as associative arrays with keys and values corresponding to |
| 27 | +the key/value pairs in the *JSON* notation. |
| 28 | + |
| 29 | +The recommendation of Zend Framework is that the individual developer should decide how to decode |
| 30 | +*JSON* objects. If an object of a specified type should be created, it can be created in the |
| 31 | +developer code and populated with the values decoded using `Zend\Json`. |
| 32 | + |
| 33 | +## Encoding PHP objects |
| 34 | + |
| 35 | +If you are encoding *PHP* objects by default the encoding mechanism can only access public |
| 36 | +properties of these objects. When a method `toJson()` is implemented on an object to encode, |
| 37 | +`Zend\Json\Json` calls this method and expects the object to return a *JSON* representation of its |
| 38 | +internal state. |
| 39 | + |
| 40 | +`Zend\Json\Json` can encode PHP objects recursively but does not do so by default. This can be |
| 41 | +enabled by passing `true` as a second argument to `Zend\Json\Json::encode()`. |
| 42 | + |
| 43 | +```php |
| 44 | +// Encode PHP object recursively |
| 45 | +$jsonObject = Zend\Json\Json::encode($data, true); |
| 46 | +``` |
| 47 | + |
| 48 | +When doing recursive encoding of objects, as JSON does not support cycles, an |
| 49 | +`Zend\Json\Exception\RecursionException` will be thrown. If you wish, you can silence these |
| 50 | +exceptions by passing the `silenceCyclicalExceptions` option: |
| 51 | + |
| 52 | +```php |
| 53 | +$jsonObject = Zend\Json\Json::encode( |
| 54 | + $data, |
| 55 | + true, |
| 56 | + array('silenceCyclicalExceptions' => true) |
| 57 | +); |
| 58 | +``` |
| 59 | + |
| 60 | +## Internal Encoder/Decoder |
| 61 | + |
| 62 | +`Zend\Json` has two different modes depending if ext/json is enabled in your *PHP* installation or |
| 63 | +not. If ext/json is installed by default `json_encode()` and `json_decode()` functions are used for |
| 64 | +encoding and decoding *JSON*. If ext/json is not installed a Zend Framework implementation in *PHP* |
| 65 | +code is used for en-/decoding. This is considerably slower than using the *PHP* extension, but |
| 66 | +behaves exactly the same. |
| 67 | + |
| 68 | +Still sometimes you might want to use the internal encoder/decoder even if you have ext/json |
| 69 | +installed. You can achieve this by calling: |
| 70 | + |
| 71 | +```php |
| 72 | +Zend\Json\Json::$useBuiltinEncoderDecoder = true; |
| 73 | +``` |
| 74 | + |
| 75 | +## JSON Expressions |
| 76 | + |
| 77 | +JavaScript makes heavy use of anonymous function callbacks, which can be saved within *JSON* object |
| 78 | +variables. Still they only work if not returned inside double quotes, which `Zend\Json` naturally |
| 79 | +does. With the Expression support for `Zend\Json` support you can encode *JSON* objects with valid |
| 80 | +JavaScript callbacks. This works for both `json_encode()` or the internal encoder. |
| 81 | + |
| 82 | +A JavaScript callback is represented using the `Zend\Json\Expr` object. It implements the value |
| 83 | +object pattern and is immutable. You can set the JavaScript expression as the first constructor |
| 84 | +argument. By default `Zend\Json\Json::encode` does not encode JavaScript callbacks, you have to pass |
| 85 | +the option `enableJsonExprFinder` and set it to `TRUE` into the `encode` function. If enabled the |
| 86 | +expression support works for all nested expressions in large object structures. A usage example |
| 87 | +would look like: |
| 88 | + |
| 89 | +```php |
| 90 | +$data = array( |
| 91 | + 'onClick' => new Zend\Json\Expr('function() {' |
| 92 | + . 'alert("I am a valid JavaScript callback ' |
| 93 | + . 'created by Zend\Json"); }'), |
| 94 | + 'other' => 'no expression', |
| 95 | +); |
| 96 | +$jsonObjectWithExpression = Zend\Json\Json::encode( |
| 97 | + $data, |
| 98 | + false, |
| 99 | + array('enableJsonExprFinder' => true) |
| 100 | +); |
| 101 | +``` |
0 commit comments