somePrivateProperty + 42; * }); */ namespace FluentBooking\Framework\Support; use Closure; use ReflectionClass; use ReflectionMethod; class Invoker { /** * Get the value of a private or protected property from an object. * * @param object $object The object instance to read property from. * @param string $property The property name to access. * @return mixed The value of the property. */ public static function get($object, $property) { return static::invoke($object, function () use ($property) { // @phpstan-ignore-next-line return $this->$property; }); } /** * Set the value of a private or protected property on an object. * * @param object $object The object instance to set property on. * @param string $property The property name to modify. * @param mixed $value The value to assign to the property. * @return void */ public static function set($object, $property, $value) { static::invoke($object, function () use ($property, $value) { // @phpstan-ignore-next-line $this->$property = $value; }); } /** * Call a private or protected method on an object. * * @param object $object The object instance to call method on. * @param string $method The method name to invoke. * @param array $args Optional array of arguments to pass to the method. * @return mixed The result returned by the method. */ public static function call($object, $method, $args = []) { return static::invoke($object, function () use ($method, $args) { // @phpstan-ignore-next-line return call_user_func_array([$this, $method], $args); }); } /** * Get the value of a private or protected static property on a class. * * @param string $class The fully qualified class name. * @param string $property The static property name. * @return mixed The value of the static property. * @throws \ReflectionException When the property does not exist. */ public static function getStatic($class, $property) { $ref = new ReflectionClass($class); $prop = $ref->getProperty($property); $prop->setAccessible(true); return $prop->getValue(); } /** * Set the value of a private or protected static property on a class. * * @param string $class The fully qualified class name. * @param string $property The static property name. * @param mixed $value The value to assign to the static property. * @return void * @throws \ReflectionException When the property does not exist. */ public static function setStatic($class, $property, $value) { $ref = new ReflectionClass($class); $prop = $ref->getProperty($property); $prop->setAccessible(true); $prop->setValue(null, $value); } /** * Call a private or protected static method on a class. * * @param string $class The fully qualified class name. * @param string $method The static method name to invoke. * @param array $args Optional array of arguments to pass to the method. * @return mixed The result returned by the static method. * @throws \ReflectionException When the method does not exist. */ public static function callStatic($class, $method, $args = []) { $ref = new ReflectionMethod($class, $method); $ref->setAccessible(true); return $ref->invokeArgs(null, $args); } /** * Bind a closure to an object and invoke it with optional arguments. * * @param object $object The object to bind the closure to. * @param Closure $closure The closure to bind and invoke. * @param mixed ...$args Optional arguments to pass to the closure. * @return mixed The result returned by the closure. */ public static function invoke($object, $closure, ...$args) { $bound = Closure::bind($closure, $object, get_class($object)); return call_user_func_array($bound, $args); } }