1], Json::decodeObject('{"a":1}')); self::assertSame([], Json::decodeObject('{}')); } public function testRejectsNonObjectTopLevelJson(): void { self::assertNull(Json::decodeObject('[1,2,3]')); self::assertNull(Json::decodeObject('"a string"')); self::assertNull(Json::decodeObject('not json')); } /** A JSON object whose keys are "0", "1", … decodes to a PHP list – re-encoding it would * silently turn it back into a JSON array (Json.php docblock, EmptyArrayCorruptionMigration). */ public function testTreatsAListLikeTopLevelObjectAsOpaqueRatherThanAnArray(): void { self::assertNull(Json::decodeObject('{"0":"a","1":"b"}')); self::assertNull(Json::decodeObject('{"0":"a"}')); } public function testDoesNotFlagAGenuineObjectWithNonSequentialNumericKeys(): void { self::assertSame(['0' => 'a', '2' => 'b'], Json::decodeObject('{"0":"a","2":"b"}')); } public function testEncodeThrowsOnInvalidUtf8(): void { $this->expectException(JsonException::class); Json::encode("\xB1\x31"); } public function testEncodeRoundtripsAnEmptyObject(): void { self::assertSame('{}', Json::encode(new stdClass())); } }