diff --git a/tests/wip/php/funcTest.php b/tests/wip/php/funcTest.php index 9e164f0..f8c3dcc 100644 --- a/tests/wip/php/funcTest.php +++ b/tests/wip/php/funcTest.php @@ -20,6 +20,7 @@ namespace nur\sery\wip\php { use nur\sery\wip\php\impl\C0; use nur\sery\wip\php\impl\C1; use nur\sery\wip\php\impl\SC; + use ReflectionException; class funcTest extends TestCase { const FUNCTION_TESTS = [ @@ -1028,5 +1029,41 @@ namespace nur\sery\wip\php { $i1 = $func->invoke([1, 2]); self::assertInstanceOf(C1::class, $i1); self::assertSame(1, $i1->first); } + + function testInvokeStatic() { + $func = func::with([SC::class, "tstatic"]); + self::assertSame(10, $func->invoke()); + + $func = func::with([SC::class, "tmethod"]); + self::assertException(ReflectionException::class, function() use ($func) { + $func->invoke(); + }); + + $func = func::with([null, "tstatic"]); + self::assertException(ReflectionException::class, function() use ($func) { + $func->invoke(); + }); + + $func = func::with([null, "tmethod"]); + self::assertException(ReflectionException::class, function() use ($func) { + $func->invoke(); + }); + } + + function testInvokeMethod() { + $func = func::with([SC::class, "tstatic"]); + self::assertSame(10, $func->invoke()); + + $func = func::with([new SC(), "tstatic"]); + self::assertSame(10, $func->invoke()); + + $func = func::with([SC::class, "tmethod"]); + self::assertException(ReflectionException::class, function() use ($func) { + $func->invoke(); + }); + + $func = func::with([new SC(), "tmethod"]); + self::assertSame(11, $func->invoke()); + } } } diff --git a/wip/php/func.php b/wip/php/func.php index 1444ce0..08b3f97 100644 --- a/wip/php/func.php +++ b/wip/php/func.php @@ -435,15 +435,27 @@ class func { static function with($func, bool $strict=true): self { if ($func instanceof Closure) { - return new self($func); + return new self($func, false, null); } elseif (self::verifix_function($func, $strict, $reason)) { - return new self($func); + return new self($func, false, $reason); } elseif (self::verifix_class($func, $strict, $reason)) { - return new self($func); - } elseif (self::verifix_static($func, $strict, $bound, $reason)) { - return new self($func); - } elseif (self::verifix_method($func, $strict, $bound, $reason)) { - return new self($func); + return new self($func, false, $reason); + } else { + $valid = true; + if (is_array($func) && array_key_exists(0, $func) && is_object($func[0])) { + if (self::verifix_method($func, $strict, $bound, $reason)) { + } elseif (self::verifix_static($func, $strict, $bound, $reason)) { + } else { + $valid = false; + } + } else { + if (self::verifix_static($func, $strict, $bound, $reason)) { + } elseif (self::verifix_method($func, $strict, $bound, $reason)) { + } else { + $valid = false; + } + } + if ($valid) return new self($func, $bound, $reason); } if ($reason === null) { $msg = var_export($func, true); @@ -456,67 +468,11 @@ class func { return self::with($func)->invoke($args); } - static function with_object($func, object $object, bool $rebind=false, bool $strict=true): self { - if ($func instanceof Closure) { - return new self($func); - } elseif (self::verifix_function($func, $strict, $reason)) { - return new self($func); - } elseif (self::verifix_class($func, $strict, $reason)) { - return new self($func); - } elseif (self::verifix_method($func, $strict, $bound, $reason)) { - if (!$bound || $rebind) $func[0] = $object; - return new self($func); - } elseif (self::verifix_static($func, $strict, $bound, $reason)) { - if (!$bound || $rebind) $func[0] = $object; - return new self($func); - } - if ($reason === null) { - $msg = var_export($func, true); - $reason = "$msg: not a callable"; - } - throw new ValueException($reason); - } - - static function call_object($func, $object, ...$args) { - return self::with_object($func, $object)->invoke($args); - } - - static function with_class($func, $class, bool $rebind=false, bool $strict=true): self { - if ($func instanceof Closure) { - return new self($func); - } elseif (self::verifix_function($func, $strict, $reason)) { - return new self($func); - } elseif (self::verifix_class($func, $strict, $reason)) { - return new self($func); - } elseif (self::verifix_method($func, $strict, $bound, $reason)) { - if (!$bound || $rebind) { - if (is_object($class)) $class = get_class($class); - $func[0] = $class; - } - return new self($func); - } elseif (self::verifix_static($func, $strict, $bound, $reason)) { - if (!$bound || $rebind) { - if (is_object($class)) $class = get_class($class); - $func[0] = $class; - } - return new self($func); - } - if ($reason === null) { - $msg = var_export($func, true); - $reason = "$msg: not a callable"; - } - throw new ValueException($reason); - } - - static function call_class($func, $class, ...$args) { - return self::with_class($func, $class)->invoke($args); - } - ############################################################################# const TYPE_CLOSURE = 0, TYPE_SIMPLE = 1, TYPE_CLASS = 2, TYPE_STATIC = 3, TYPE_METHOD = 4; - function __construct($func) { + protected function __construct($func, bool $bound=false, ?string $reason=null) { $object = null; $prefixArgs = []; if ($func instanceof Closure) { @@ -548,7 +504,7 @@ class func { $reflection = new ReflectionClass($c); } elseif ($c !== null) { # methode - $reflection = new ReflectionMethod($func); + $reflection = new ReflectionMethod($c, $f); if (is_object($c)) { $type = self::TYPE_METHOD; $object = $c; @@ -601,6 +557,14 @@ class func { protected array $prefixArgs; + function bind($objectOrClass, bool $rebind=false): self { + + } + + function bindClass($objectOrClass, bool $rebind=false): self { + + } + function invoke(?array $args=null) { $args = array_merge($this->prefixArgs, $args ?? []); if (!$this->variadic) $args = array_slice($args, 0, $this->maxArgs); @@ -613,10 +577,10 @@ class func { $closure = $this->object; return $closure(...$args); case self::TYPE_SIMPLE: - case self::TYPE_STATIC: /** @var ReflectionFunction $function */ $function = $this->reflection; return $function->invoke(...$args); + case self::TYPE_STATIC: case self::TYPE_METHOD: /** @var ReflectionMethod $method */ $method = $this->reflection;