使用JsonModel返回一个空数组作为对象

时间:2018-12-14 07:51:51

标签: php json zend-framework2

我正在使用Zend Framework 2做一个REST方法,该方法返回JSON响应。为此,我使用以下代码:

return new JsonModel($result);

在某些情况下,结果为空数组,JsonModel将其输出为[]。是否可以强制JsonModel将空数组显示为对象,即{}

在PHP中,您可以执行以下操作:

echo json_encode(array(), JSON_FORCE_OBJECT);

我可以在zf2中的JsonModel中使用与JSON_FORCE_OBJECT类似的选项吗?我尝试了以下所有组合,但没有运气。

return new JsonModel(array(), JSON_FORCE_OBJECT);

2 个答案:

答案 0 :(得分:2)

如果您遵循了该代码,则将发现Zend提供的JsonModel不可能


Zend\View\Model\JsonModel具有以下序列化功能:

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);
}

Json::encode指向Zend\Json\Json,而encode()函数

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;
}

如您所见,编码功能已为您注释,因此我们需要self::encodeValue功能,单击该功能会导致:

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);
}

根据您的问题判断,您拥有json_encode内置函数,因此我们将插入 if()并执行self::encodeViaPhpBuiltIn()函数:

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);
}

再次进行相同的检查,但最终结果为:

return json_encode($valueToEncode, $encodeOptions);

除了可选的“ JSON_PRETTY_PRINT”选项外,这些选项都在函数中进行了硬编码设置。


您要查找的答案是:,这是不可能的。


但是,您可以,从技术上讲,自己编写JsonModel的替代品,确保JsonViewStrategy使用您自己的模型然后使用它...只是一个选择。

答案 1 :(得分:0)

使用响应对象:

    $result   = array();
    $data     = json_encode($result, JSON_FORCE_OBJECT);
    $response = $this->getResponse();
    return $response->setContent($data);