$propName ?? null; } /** * Set the given dynamic property to the given value on an object. * @param object $owner Object to set the dynamic property on * @param string $propName Name of the dynamic property to set * @param mixed $value The property value to set; must not be null * @return void */ public static function setDynamicProperty( object $owner, string $propName, $value ): void { // getDynamicProperty() uses a null return value as an idiom for "property does not exist", // which precludes supporting null values for dynamic properties without a separate method // to check for the existence of a possibly nullable property. // Since existing test cases do not seem to extensively rely on setting null values, // explicitly forbid them here. Assert::parameter( $value !== null, '$value', 'must not be null' ); if ( class_exists( WeakMap::class ) ) { self::$properties[$propName] ??= new WeakMap(); self::$properties[$propName][$owner] = $value; } else { $owner->$propName = $value; } } /** * Unset the given dynamic property on the given object. * @param object $owner Object to unset the dynamic property on * @param string $propName Name of the dynamic property to unset * @return void */ public static function unsetDynamicProperty( object $owner, string $propName ): void { if ( class_exists( WeakMap::class ) ) { self::$properties[$propName] ??= new WeakMap(); unset( self::$properties[$propName][$owner] ); } else { unset( $owner->$propName ); } } } // phpcs:enable