From c18222a1a2c8eb7cb9031f4eafd3b014c240d6f5 Mon Sep 17 00:00:00 2001 From: tw Date: Mon, 25 Aug 2025 10:42:29 +0800 Subject: [PATCH 1/5] Performance optimization --- src/JsonMapper.php | 43 +++++++++++++++++++++++++++++-------------- src/JsonProperty.php | 30 ++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 14 deletions(-) create mode 100644 src/JsonProperty.php diff --git a/src/JsonMapper.php b/src/JsonMapper.php index 25534d0a6..d8d99975e 100644 --- a/src/JsonMapper.php +++ b/src/JsonMapper.php @@ -176,10 +176,11 @@ public function map($json, $object) // again for subsequent objects of the same type if (!isset($this->arInspectedClasses[$strClassName][$key])) { $this->arInspectedClasses[$strClassName][$key] - = $this->inspectProperty($rc, $key); + = $this->inspectBuildProperty($rc, $key); } - list($hasProperty, $accessor, $type, $isNullable) + /** @var JsonProperty $jsonProperty */ + list($hasProperty, $accessor, $type, $isNullable, $jsonProperty) = $this->arInspectedClasses[$strClassName][$key]; if (!$hasProperty) { @@ -195,8 +196,8 @@ public function map($json, $object) ); if (is_string($undefinedPropertyKey)) { - list($hasProperty, $accessor, $type, $isNullable) - = $this->inspectProperty($rc, $undefinedPropertyKey); + list($hasProperty, $accessor, $type, $isNullable, $jsonProperty) + = $this->inspectBuildProperty($rc, $undefinedPropertyKey); } } else { $this->log( @@ -231,7 +232,6 @@ public function map($json, $object) $this->setProperty($object, $accessor, null); continue; } - $type = $this->removeNullable($type); } else if ($jvalue === null) { throw new JsonMapper_Exception( 'JSON property "' . $key . '" in class "' @@ -239,9 +239,6 @@ public function map($json, $object) ); } - $type = $this->getFullNamespace($type, $strNs); - $type = $this->getMappedType($type, $jvalue); - if ($type === null || $type === 'mixed') { //no given type - simply set the json data $this->setProperty($object, $accessor, $jvalue); @@ -249,10 +246,10 @@ public function map($json, $object) } else if ($this->isObjectOfSameType($type, $jvalue)) { $this->setProperty($object, $accessor, $jvalue); continue; - } else if ($this->isSimpleType($type) - && !(is_array($jvalue) && $this->hasVariadicArrayType($accessor)) + } else if ($jsonProperty->isSimpleType + && !(is_array($jvalue) && $jsonProperty->hasVariadicArrayType) ) { - if ($this->isFlatType($type) + if ($jsonProperty->isFlatType && !$this->isFlatType(gettype($jvalue)) ) { throw new JsonMapper_Exception( @@ -282,18 +279,18 @@ public function map($json, $object) $array = null; $subtype = null; - if ($this->isArrayOfType($type)) { + if ($jsonProperty->isArrayOfType) { //array $array = array(); $subtype = substr($type, 0, -2); - } else if (substr($type, -1) == ']') { + } else if ($jsonProperty->isParenthesesEnd) { list($proptype, $subtype) = explode('[', substr($type, 0, -1)); if ($proptype == 'array') { $array = array(); } else { $array = $this->createInstance($proptype, false, $jvalue); } - } else if (is_array($jvalue) && $this->hasVariadicArrayType($accessor)) { + } else if (is_array($jvalue) && $jsonProperty->hasVariadicArrayType) { $array = array(); $subtype = $type; } else { @@ -512,6 +509,24 @@ public function mapArray($json, $array, $class = null, $parent_key = '') return $array; } + protected function inspectBuildProperty(ReflectionClass $rc, $name) + { + list($hasProperty, $accessor, $type, $isNullable) = $this->inspectProperty($rc, $name); + $jsonProperty = new JsonProperty(); + if ($isNullable || !$this->bStrictNullTypes) { + $type = $this->removeNullable($type); + } + $strNs = $rc->getNamespaceName(); + $type = $this->getFullNamespace($type, $strNs); + $jsonProperty->isSimpleType = $this->isSimpleType($type); + $jsonProperty->hasVariadicArrayType = $this->hasVariadicArrayType($accessor); + $jsonProperty->isFlatType = $this->isFlatType($type); + + $jsonProperty->isArrayOfType = $this->isArrayOfType($type); + $jsonProperty->isParenthesesEnd = substr($type, -1) == ']'; + + return array($hasProperty, $accessor, $type, $isNullable, $jsonProperty); + } /** * Try to find out if a property exists in a given class. * Checks property first, falls back to setter method. diff --git a/src/JsonProperty.php b/src/JsonProperty.php new file mode 100644 index 000000000..970cde3e7 --- /dev/null +++ b/src/JsonProperty.php @@ -0,0 +1,30 @@ + Date: Mon, 25 Aug 2025 10:54:00 +0800 Subject: [PATCH 2/5] Optimize the judgment sequence --- src/JsonMapper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/JsonMapper.php b/src/JsonMapper.php index d8d99975e..ed0e643f7 100644 --- a/src/JsonMapper.php +++ b/src/JsonMapper.php @@ -247,7 +247,7 @@ public function map($json, $object) $this->setProperty($object, $accessor, $jvalue); continue; } else if ($jsonProperty->isSimpleType - && !(is_array($jvalue) && $jsonProperty->hasVariadicArrayType) + && $jsonProperty->hasVariadicArrayType && !(is_array($jvalue)) ) { if ($jsonProperty->isFlatType && !$this->isFlatType(gettype($jvalue)) @@ -290,7 +290,7 @@ public function map($json, $object) } else { $array = $this->createInstance($proptype, false, $jvalue); } - } else if (is_array($jvalue) && $jsonProperty->hasVariadicArrayType) { + } else if ($jsonProperty->hasVariadicArrayType && is_array($jvalue)) { $array = array(); $subtype = $type; } else { From 653e62f91cf75e4a909a40f5fb9e7ab45c052009 Mon Sep 17 00:00:00 2001 From: tw Date: Mon, 25 Aug 2025 16:25:04 +0800 Subject: [PATCH 3/5] Optimize the judgment sequence --- src/JsonMapper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/JsonMapper.php b/src/JsonMapper.php index ed0e643f7..cec485e7b 100644 --- a/src/JsonMapper.php +++ b/src/JsonMapper.php @@ -247,7 +247,7 @@ public function map($json, $object) $this->setProperty($object, $accessor, $jvalue); continue; } else if ($jsonProperty->isSimpleType - && $jsonProperty->hasVariadicArrayType && !(is_array($jvalue)) + && !($jsonProperty->hasVariadicArrayType && is_array($jvalue)) ) { if ($jsonProperty->isFlatType && !$this->isFlatType(gettype($jvalue)) From 341609da97eef0b8b83fc12f096ca4aa0f450d81 Mon Sep 17 00:00:00 2001 From: tw Date: Tue, 26 Aug 2025 08:38:56 +0800 Subject: [PATCH 4/5] Optimize inspectBuildProperty function --- src/JsonMapper.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/JsonMapper.php b/src/JsonMapper.php index cec485e7b..1f9172b2f 100644 --- a/src/JsonMapper.php +++ b/src/JsonMapper.php @@ -522,8 +522,10 @@ protected function inspectBuildProperty(ReflectionClass $rc, $name) $jsonProperty->hasVariadicArrayType = $this->hasVariadicArrayType($accessor); $jsonProperty->isFlatType = $this->isFlatType($type); - $jsonProperty->isArrayOfType = $this->isArrayOfType($type); - $jsonProperty->isParenthesesEnd = substr($type, -1) == ']'; + if (is_string($type)) { + $jsonProperty->isArrayOfType = $this->isArrayOfType($type); + $jsonProperty->isParenthesesEnd = substr($type, -1) == ']'; + } return array($hasProperty, $accessor, $type, $isNullable, $jsonProperty); } From 42fb0970188d339688a419277e9ed0596236778b Mon Sep 17 00:00:00 2001 From: tw Date: Fri, 12 Sep 2025 10:30:20 +0800 Subject: [PATCH 5/5] use array --- src/JsonMapper.php | 41 +++++++++++++++++++++++------------------ src/JsonProperty.php | 30 ------------------------------ 2 files changed, 23 insertions(+), 48 deletions(-) delete mode 100644 src/JsonProperty.php diff --git a/src/JsonMapper.php b/src/JsonMapper.php index 1f9172b2f..b372f9967 100644 --- a/src/JsonMapper.php +++ b/src/JsonMapper.php @@ -179,8 +179,10 @@ public function map($json, $object) = $this->inspectBuildProperty($rc, $key); } - /** @var JsonProperty $jsonProperty */ - list($hasProperty, $accessor, $type, $isNullable, $jsonProperty) + /** + * @var array{isSimpleType: bool, hasVariadicArrayType: bool, isFlatType: bool, isArrayOfType: bool, isParenthesesEnd: bool} $typeAttribute + */ + list($hasProperty, $accessor, $type, $isNullable, $typeAttribute) = $this->arInspectedClasses[$strClassName][$key]; if (!$hasProperty) { @@ -196,7 +198,7 @@ public function map($json, $object) ); if (is_string($undefinedPropertyKey)) { - list($hasProperty, $accessor, $type, $isNullable, $jsonProperty) + list($hasProperty, $accessor, $type, $isNullable, $typeAttribute) = $this->inspectBuildProperty($rc, $undefinedPropertyKey); } } else { @@ -246,10 +248,10 @@ public function map($json, $object) } else if ($this->isObjectOfSameType($type, $jvalue)) { $this->setProperty($object, $accessor, $jvalue); continue; - } else if ($jsonProperty->isSimpleType - && !($jsonProperty->hasVariadicArrayType && is_array($jvalue)) + } else if ($typeAttribute['isSimpleType'] + && !($typeAttribute['hasVariadicArrayType'] && is_array($jvalue)) ) { - if ($jsonProperty->isFlatType + if ($typeAttribute['isFlatType'] && !$this->isFlatType(gettype($jvalue)) ) { throw new JsonMapper_Exception( @@ -279,18 +281,18 @@ public function map($json, $object) $array = null; $subtype = null; - if ($jsonProperty->isArrayOfType) { + if ($typeAttribute['isArrayOfType']) { //array $array = array(); $subtype = substr($type, 0, -2); - } else if ($jsonProperty->isParenthesesEnd) { + } else if ($typeAttribute['isParenthesesEnd']) { list($proptype, $subtype) = explode('[', substr($type, 0, -1)); if ($proptype == 'array') { $array = array(); } else { $array = $this->createInstance($proptype, false, $jvalue); } - } else if ($jsonProperty->hasVariadicArrayType && is_array($jvalue)) { + } else if ($typeAttribute['hasVariadicArrayType'] && is_array($jvalue)) { $array = array(); $subtype = $type; } else { @@ -512,22 +514,25 @@ public function mapArray($json, $array, $class = null, $parent_key = '') protected function inspectBuildProperty(ReflectionClass $rc, $name) { list($hasProperty, $accessor, $type, $isNullable) = $this->inspectProperty($rc, $name); - $jsonProperty = new JsonProperty(); + $typeAttribute = [ + 'isArrayOfType' => false, + 'isParenthesesEnd' => false, + ]; if ($isNullable || !$this->bStrictNullTypes) { $type = $this->removeNullable($type); } - $strNs = $rc->getNamespaceName(); - $type = $this->getFullNamespace($type, $strNs); - $jsonProperty->isSimpleType = $this->isSimpleType($type); - $jsonProperty->hasVariadicArrayType = $this->hasVariadicArrayType($accessor); - $jsonProperty->isFlatType = $this->isFlatType($type); + $strNs = $rc->getNamespaceName(); + $type = $this->getFullNamespace($type, $strNs); + $typeAttribute['isSimpleType'] = $this->isSimpleType($type); + $typeAttribute['hasVariadicArrayType'] = $this->hasVariadicArrayType($accessor); + $typeAttribute['isFlatType'] = $this->isFlatType($type); if (is_string($type)) { - $jsonProperty->isArrayOfType = $this->isArrayOfType($type); - $jsonProperty->isParenthesesEnd = substr($type, -1) == ']'; + $typeAttribute['isArrayOfType'] = $this->isArrayOfType($type); + $typeAttribute['isParenthesesEnd'] = substr($type, -1) == ']'; } - return array($hasProperty, $accessor, $type, $isNullable, $jsonProperty); + return array($hasProperty, $accessor, $type, $isNullable, $typeAttribute); } /** * Try to find out if a property exists in a given class. diff --git a/src/JsonProperty.php b/src/JsonProperty.php deleted file mode 100644 index 970cde3e7..000000000 --- a/src/JsonProperty.php +++ /dev/null @@ -1,30 +0,0 @@ -