bind($p1, $p2, ...$params); } } public function bind($p1, $p2 = null, ...$params): self { $this->params = $params; $this->targetObject = null; $this->className = null; $this->methodName = null; $this->functionName = null; $this->callable = null; if (\is_string($p1) && $p2 === null && \function_exists($p1)) { $this->handleType = self::HANDLE_FUNCTION; $this->functionName = $p1; $this->callable = $p1; return $this; } if (\is_string($p1) && \is_string($p2) && \class_exists($p1) && \method_exists($p1, $p2)) { $this->handleType = self::HANDLE_STATIC_METHOD; $this->className = $p1; $this->methodName = $p2; $this->callable = array($p1, $p2); return $this; } if (\is_object($p1) && \is_string($p2) && \method_exists($p1, $p2)) { $this->handleType = self::HANDLE_OBJECT_METHOD; $this->className = \get_class($p1); $this->methodName = $p2; $this->targetObject = $p1; $this->callable = array($p1, $p2); return $this; } throw new \InvalidArgumentException('Unsupported callback signature'); } public function addParam($param): void { $this->params[] = $param; } public function callback(...$args) { if (!\is_callable($this->callable)) { throw new \RuntimeException('Callback not callable'); } return \call_user_func_array( $this->callable, \array_merge($this->params, $args) ); } public function __serialize(): array { return array( 'handleType' => $this->handleType, 'className' => $this->className, 'methodName' => $this->methodName, 'functionName' => $this->functionName, 'targetObject' => $this->targetObject, 'params' => $this->params, ); } public function __unserialize(array $data): void { $this->handleType = $data['handleType'] ?? ''; $this->className = $data['className'] ?? null; $this->methodName = $data['methodName'] ?? null; $this->functionName = $data['functionName'] ?? null; $this->targetObject = $data['targetObject'] ?? null; $this->params = $data['params'] ?? array(); switch ($this->handleType) { case self::HANDLE_FUNCTION: $this->callable = $this->functionName; break; case self::HANDLE_STATIC_METHOD: $this->callable = array($this->className, $this->methodName); break; case self::HANDLE_OBJECT_METHOD: $this->callable = array($this->targetObject, $this->methodName); break; default: throw new \RuntimeException('Unknown serialized callback type'); } if (!\is_callable($this->callable)) { throw new \RuntimeException('Unserialized callback is not callable'); } } public function printHandle(bool $withParams = false): string { $s = '|'.$this->handleType.':'; switch ($this->handleType) { case self::HANDLE_FUNCTION: $s .= $this->functionName; break; case self::HANDLE_STATIC_METHOD: $s .= $this->className.'::'.$this->methodName; break; case self::HANDLE_OBJECT_METHOD: $s .= $this->className.'->'.$this->methodName; break; default: $s .= 'unknown'; } if ($withParams) { $s .= '(' . \count($this->params) . ' params)'; } return $s . '|'; } }