@@ -352,6 +352,7 @@ static HashTable *date_object_get_gc(zend_object *object, zval **table, int *n);
352352static HashTable * date_object_get_properties_for (zend_object * object , zend_prop_purpose purpose );
353353static HashTable * date_object_get_gc_interval (zend_object * object , zval * * table , int * n );
354354static HashTable * date_object_get_properties_interval (zend_object * object );
355+ static HashTable * date_object_get_properties_for_interval (zend_object * object , zend_prop_purpose purpose );
355356static HashTable * date_object_get_gc_period (zend_object * object , zval * * table , int * n );
356357static HashTable * date_object_get_properties_for_timezone (zend_object * object , zend_prop_purpose purpose );
357358static HashTable * date_object_get_gc_timezone (zend_object * object , zval * * table , int * n );
@@ -1816,6 +1817,7 @@ static void date_register_classes(void) /* {{{ */
18161817 date_object_handlers_interval .read_property = date_interval_read_property ;
18171818 date_object_handlers_interval .write_property = date_interval_write_property ;
18181819 date_object_handlers_interval .get_properties = date_object_get_properties_interval ;
1820+ date_object_handlers_interval .get_properties_for = date_object_get_properties_for_interval ;
18191821 date_object_handlers_interval .get_property_ptr_ptr = date_interval_get_property_ptr_ptr ;
18201822 date_object_handlers_interval .get_gc = date_object_get_gc_interval ;
18211823 date_object_handlers_interval .compare = date_interval_compare_objects ;
@@ -2155,6 +2157,7 @@ static zend_object *date_object_new_interval(zend_class_entry *class_type) /* {{
21552157
21562158 zend_object_std_init (& intern -> std , class_type );
21572159 object_properties_init (& intern -> std , class_type );
2160+ intern -> props_cache = NULL ;
21582161
21592162 return & intern -> std ;
21602163} /* }}} */
@@ -2240,6 +2243,48 @@ static HashTable *date_object_get_properties_interval(zend_object *object) /* {{
22402243 return props ;
22412244} /* }}} */
22422245
2246+ static HashTable * date_object_get_properties_for_interval (zend_object * object , zend_prop_purpose purpose ) /* {{{ */
2247+ {
2248+ HashTable * props ;
2249+ php_interval_obj * intervalobj ;
2250+
2251+ switch (purpose ) {
2252+ case ZEND_PROP_PURPOSE_DEBUG :
2253+ case ZEND_PROP_PURPOSE_SERIALIZE :
2254+ case ZEND_PROP_PURPOSE_VAR_EXPORT :
2255+ case ZEND_PROP_PURPOSE_JSON :
2256+ case ZEND_PROP_PURPOSE_ARRAY_CAST :
2257+ break ;
2258+ default :
2259+ return zend_std_get_properties_for (object , purpose );
2260+ }
2261+
2262+ intervalobj = php_interval_obj_from_obj (object );
2263+
2264+ if (!intervalobj -> initialized ) {
2265+ return zend_array_dup (zend_std_get_properties (object ));
2266+ }
2267+
2268+ /* If cache exists and is actively in use (refcount > 1), we're in a recursive
2269+ * call (e.g., circular reference during json_encode). Return the same cache
2270+ * so that circular reference detection works correctly. */
2271+ if (intervalobj -> props_cache && GC_REFCOUNT (intervalobj -> props_cache ) > 1 ) {
2272+ GC_ADDREF (intervalobj -> props_cache );
2273+ return intervalobj -> props_cache ;
2274+ }
2275+
2276+ /* Create new cache or replace stale one */
2277+ if (intervalobj -> props_cache ) {
2278+ zend_hash_release (intervalobj -> props_cache );
2279+ }
2280+ props = zend_array_dup (zend_std_get_properties (object ));
2281+ date_interval_object_to_hash (intervalobj , props );
2282+ intervalobj -> props_cache = props ;
2283+
2284+ GC_ADDREF (props );
2285+ return props ;
2286+ } /* }}} */
2287+
22432288static zend_object * date_object_new_period (zend_class_entry * class_type ) /* {{{ */
22442289{
22452290 php_period_obj * intern = zend_object_alloc (sizeof (php_period_obj ), class_type );
@@ -2306,6 +2351,10 @@ static void date_object_free_storage_interval(zend_object *object) /* {{{ */
23062351 zend_string_release (intern -> date_string );
23072352 intern -> date_string = NULL ;
23082353 }
2354+ if (intern -> props_cache ) {
2355+ zend_hash_release (intern -> props_cache );
2356+ intern -> props_cache = NULL ;
2357+ }
23092358 timelib_rel_time_dtor (intern -> diff );
23102359 zend_object_std_dtor (& intern -> std );
23112360} /* }}} */
0 commit comments