From 7570dd0da119627ff83bc6db3be06b51eb5b366b Mon Sep 17 00:00:00 2001 From: epriestley Date: Thu, 11 Mar 2021 11:20:17 -0800 Subject: [PATCH] Improve "PhutilJSON" handling of PHP-object JSON values Summary: Ref T13635. PHP native JSON functions sometimes represent JSON objects as PHP "stdClass" objects. Accept this representation and emit it correctly in "PhutilJSON". Test Plan: Added a test, made it pass. Maniphest Tasks: T13635 Differential Revision: https://secure.phabricator.com/D21604 --- src/parser/PhutilJSON.php | 8 +++++- src/parser/__tests__/PhutilJSONTestCase.php | 29 +++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/parser/PhutilJSON.php b/src/parser/PhutilJSON.php index 0bcc4f76..5f43a625 100644 --- a/src/parser/PhutilJSON.php +++ b/src/parser/PhutilJSON.php @@ -19,7 +19,7 @@ final class PhutilJSON extends Phobject { * @param dict An object to encode in JSON. * @return string Pretty-printed object representation. */ - public function encodeFormatted(array $object) { + public function encodeFormatted($object) { return $this->encodeFormattedObject($object, 0)."\n"; } @@ -47,6 +47,10 @@ final class PhutilJSON extends Phobject { * @task internal */ private function encodeFormattedObject($object, $depth) { + if ($object instanceof stdClass) { + $object = (array)$object; + } + if (empty($object)) { return '{}'; } @@ -123,6 +127,8 @@ final class PhutilJSON extends Phobject { } else { return $this->encodeFormattedObject($value, $depth); } + } else if (is_object($value)) { + return $this->encodeFormattedObject($value, $depth); } else { if (defined('JSON_UNESCAPED_SLASHES')) { // If we have a new enough version of PHP, disable escaping of slashes diff --git a/src/parser/__tests__/PhutilJSONTestCase.php b/src/parser/__tests__/PhutilJSONTestCase.php index 295d7b55..63630a9d 100644 --- a/src/parser/__tests__/PhutilJSONTestCase.php +++ b/src/parser/__tests__/PhutilJSONTestCase.php @@ -18,4 +18,33 @@ EOJSON; pht('Empty arrays should serialize as `%s`, not `%s`.', '[]', '{}')); } + public function testNestedObjectEncoding() { + $expect = <<duck = 'quack'; + + $input = (object)array( + 'empty-object' => $empty_object, + 'pair-object' => $pair_object, + ); + + $serializer = new PhutilJSON(); + + $this->assertEqual( + $expect, + $serializer->encodeFormatted($input), + pht('Serialization of PHP-object JSON values.')); + } + }