Reputation: 2117
I am making a REST method with Zend Framework 2 which returns JSON response. For that I'm using the following code:
return new JsonModel($result);
In some cases, result is an empty array and JsonModel outputs that as []
. Is it possible to force JsonModel to display empty array as an object, i.e. {}
?
In PHP, you can do the following:
echo json_encode(array(), JSON_FORCE_OBJECT);
Is there a similar option to JSON_FORCE_OBJECT
that I could use with JsonModel in zf2? I have tried all combinations of the following, but with no luck.
return new JsonModel(array(), JSON_FORCE_OBJECT);
Upvotes: 0
Views: 950
Reputation: 623
Use the response object:
$result = array();
$data = json_encode($result, JSON_FORCE_OBJECT);
$response = $this->getResponse();
return $response->setContent($data);
Upvotes: 0
Reputation: 3468
If you'd've followed the code, you would've found that it's not possible with the provided JsonModel
by Zend.
Zend\View\Model\JsonModel
has this serialize function:
public function serialize()
{
$variables = $this->getVariables();
if ($variables instanceof Traversable) {
$variables = ArrayUtils::iteratorToArray($variables);
}
$options = [
'prettyPrint' => $this->getOption('prettyPrint'),
];
if (null !== $this->jsonpCallback) {
return $this->jsonpCallback.'('.Json::encode($variables, false, $options).');';
}
return Json::encode($variables, false, $options);
}
The Json::encode
leads to Zend\Json\Json
, and the encode()
function
public static function encode($valueToEncode, $cycleCheck = false, array $options = [])
{
if (is_object($valueToEncode)) {
if (method_exists($valueToEncode, 'toJson')) {
return $valueToEncode->toJson();
}
if (method_exists($valueToEncode, 'toArray')) {
return static::encode($valueToEncode->toArray(), $cycleCheck, $options);
}
}
// Pre-process and replace javascript expressions with placeholders
$javascriptExpressions = new SplQueue();
if (isset($options['enableJsonExprFinder'])
&& $options['enableJsonExprFinder'] == true
) {
$valueToEncode = static::recursiveJsonExprFinder($valueToEncode, $javascriptExpressions);
}
// Encoding
$prettyPrint = (isset($options['prettyPrint']) && ($options['prettyPrint'] === true));
$encodedResult = self::encodeValue($valueToEncode, $cycleCheck, $options, $prettyPrint);
// Post-process to revert back any Zend\Json\Expr instances.
$encodedResult = self::injectJavascriptExpressions($encodedResult, $javascriptExpressions);
return $encodedResult;
}
As you can see, the encoding function has been commented for you, so we need the self::encodeValue
function, clicking through on that leads to:
private static function encodeValue($valueToEncode, $cycleCheck, array $options, $prettyPrint)
{
if (function_exists('json_encode') && static::$useBuiltinEncoderDecoder !== true) {
return self::encodeViaPhpBuiltIn($valueToEncode, $prettyPrint);
}
return self::encodeViaEncoder($valueToEncode, $cycleCheck, $options, $prettyPrint);
}
Judging by your question, you have json_encode
built-in function available, so we step into the if()
and execute the self::encodeViaPhpBuiltIn()
function:
private static function encodeViaPhpBuiltIn($valueToEncode, $prettyPrint = false)
{
if (! function_exists('json_encode') || static::$useBuiltinEncoderDecoder === true) {
return false;
}
$encodeOptions = JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP;
if ($prettyPrint) {
$encodeOptions |= JSON_PRETTY_PRINT;
}
return json_encode($valueToEncode, $encodeOptions);
}
This has the same check again, but finally ends up with:
return json_encode($valueToEncode, $encodeOptions);
The options are set hardcoded in the function, with the exception of the optional "JSON_PRETTY_PRINT
" option.
The answer you're looking for is: no, it's not possible.
However, you could, technically, write your own replacement for JsonModel
, make sure that your own model is used by the JsonViewStrategy
and use it then... Just an option.
Upvotes: 3