Skip to content

Commit 8c16891

Browse files
committed
add isCallable helper
1 parent 302766f commit 8c16891

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

src/Illuminate/Support/Reflector.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,52 @@
33
namespace Illuminate\Support;
44

55
use ReflectionClass;
6+
use ReflectionMethod;
67
use ReflectionNamedType;
78

89
class Reflector
910
{
11+
/**
12+
* This is a PHP 7.4 compatible implementation of is_callable.
13+
*
14+
* @param mixed $var
15+
* @param bool $syntaxOnly
16+
* @return bool
17+
*/
18+
public static function isCallable($var, $syntaxOnly = false)
19+
{
20+
if (! is_array($var)) {
21+
return is_callable($var, $syntaxOnly);
22+
}
23+
24+
if (! isset($var[0]) && ! isset($var[1]) ||
25+
! is_string($var[1])) {
26+
return false;
27+
}
28+
29+
$class = is_object($var[0]) ? get_class($var[0]) : $var[0];
30+
31+
$method = $var[1];
32+
33+
if (! class_exists($class)) {
34+
return false;
35+
}
36+
37+
if (method_exists($class, $method)) {
38+
return (new ReflectionMethod($class, $method))->isPublic();
39+
}
40+
41+
if (is_object($var[0]) && method_exists($class, '__call')) {
42+
return (new ReflectionMethod($class, '__call'))->isPublic();
43+
}
44+
45+
if (! is_object($var[0]) && method_exists($class, '__callStatic')) {
46+
return (new ReflectionMethod($class, '__callStatic'))->isPublic();
47+
}
48+
49+
return false;
50+
}
51+
1052
/**
1153
* Get the class name of the given parameter's type, if possible.
1254
*

tests/Support/SupportReflectorTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,16 @@ public function testUnionTypeName()
5757

5858
$this->assertNull(Reflector::getParameterClassName($method->getParameters()[0]));
5959
}
60+
61+
public function testIsCallable()
62+
{
63+
$this->assertTrue(Reflector::isCallable(function () {}));
64+
$this->assertTrue(Reflector::isCallable([B::class, 'f']));
65+
$this->assertFalse(Reflector::isCallable([TestClassWithCall::class, 'f']));
66+
$this->assertTrue(Reflector::isCallable([new TestClassWithCall, 'f']));
67+
$this->assertTrue(Reflector::isCallable([TestClassWithCallStatic::class, 'f']));
68+
$this->assertFalse(Reflector::isCallable([new TestClassWithCallStatic, 'f']));
69+
}
6070
}
6171

6272
class A
@@ -82,3 +92,19 @@ public function f(A|Model $x)
8292
}'
8393
);
8494
}
95+
96+
class TestClassWithCall
97+
{
98+
public function __call($method, $parameters)
99+
{
100+
101+
}
102+
}
103+
104+
class TestClassWithCallStatic
105+
{
106+
public static function __callStatic($method, $parameters)
107+
{
108+
109+
}
110+
}

0 commit comments

Comments
 (0)