fix closure for static method array callables

This commit is contained in:
Kacper Donat 2026-10-27 23:00:21 +01:00
parent 28408baa64
commit a09e6840d4
3 changed files with 28 additions and 4 deletions

View File

@ -41,13 +41,14 @@ function closure($callable)
case is_array($callable):
list($object, $method) = $callable;
$reflection = new \ReflectionObject($object);
$method = $reflection->getMethod($method);
// A static method ([Foo::class, 'method']) is given by its class name, not an object.
$class = is_string($object) ? $object : get_class($object);
$method = new \ReflectionMethod($object, $method);
if (!$method->isPublic()) {
$backtrace = debug_backtrace();
foreach ($backtrace as $trace) {
if (isset($trace['class']) && $trace['class'] === $reflection->name) {
if (isset($trace['class']) && $trace['class'] === $class) {
break;
}
@ -58,7 +59,7 @@ function closure($callable)
}
}
return $method->getClosure($object);
return $method->getClosure(is_string($object) ? null : $object);
default:
return \Closure::fromCallable($callable);

View File

@ -62,6 +62,11 @@ class TransformsTest extends \PHPUnit\Framework\TestCase
$this->assertSeq(['x:1', 'y:2'], c\map(fn ($v, $k) => "$k:$v")(self::gen(['x' => 1, 'y' => 2])));
}
public function testMapWithStaticMethodArrayCallable()
{
$this->assertSame(['a' => 2, 'b' => 4], c\map([TransformsTestHelper::class, 'double'])(['a' => 1, 'b' => 2]));
}
public function testMapOnSetFollowsSetMap()
{
$result = c\map(fn ($v) => $v % 2)(new Set([1, 2, 3]));
@ -418,3 +423,11 @@ class TransformsTest extends \PHPUnit\Framework\TestCase
}
}
}
class TransformsTestHelper
{
public static function double(int $value): int
{
return $value * 2;
}
}

View File

@ -28,10 +28,20 @@ class TestObject
{
return ref([$this, 'priv']);
}
public static function twice($x)
{
return $x * 2;
}
}
class ReferencingTest extends \PHPUnit\Framework\TestCase
{
public function testReferenceStaticMethodArrayCallable()
{
$this->assertSame(4, ref([TestObject::class, 'twice'])(2));
}
public function testReferenceClosure()
{
$f = function () { };