Skip to content

Commit fc6c49c

Browse files
committed
ext/zend_test: Test zend_call_method_if_exists()
1 parent a9f3e3c commit fc6c49c

17 files changed

+391
-1
lines changed

ext/zend_test/test.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,28 @@ static ZEND_FUNCTION(zend_object_init_with_constructor)
514514
ZVAL_COPY_VALUE(return_value, &obj);
515515
}
516516

517+
static ZEND_FUNCTION(zend_call_method_if_exists)
518+
{
519+
zend_object *obj = NULL;
520+
zend_string *method_name;
521+
uint32_t num_args = 0;
522+
zval *args = NULL;
523+
ZEND_PARSE_PARAMETERS_START(2, -1)
524+
Z_PARAM_OBJ(obj)
525+
Z_PARAM_STR(method_name)
526+
Z_PARAM_VARIADIC('*', args, num_args)
527+
ZEND_PARSE_PARAMETERS_END();
528+
529+
zend_result status = zend_call_method_if_exists(obj, method_name, return_value, num_args, args);
530+
if (status == FAILURE) {
531+
ZEND_ASSERT(Z_ISUNDEF_P(return_value));
532+
if (EG(exception)) {
533+
RETURN_THROWS();
534+
}
535+
RETURN_NULL();
536+
}
537+
}
538+
517539
static ZEND_FUNCTION(zend_get_unit_enum)
518540
{
519541
ZEND_PARSE_PARAMETERS_NONE();

ext/zend_test/test.stub.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,8 @@ function zend_call_method(object|string $obj_or_class, string $method, mixed $ar
293293

294294
function zend_object_init_with_constructor(string $class, mixed ...$args): mixed {}
295295

296+
function zend_call_method_if_exists(object $obj, string $method, mixed ...$args): mixed {}
297+
296298
function zend_test_zend_ini_parse_quantity(string $str): int {}
297299
function zend_test_zend_ini_parse_uquantity(string $str): int {}
298300

ext/zend_test/test_arginfo.h

Lines changed: 9 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
zend_call_method_if_exists() with existing non public methods
3+
--EXTENSIONS--
4+
zend_test
5+
--FILE--
6+
<?php
7+
8+
class A {
9+
protected function foo() {
10+
return __METHOD__;
11+
}
12+
private function bar() {
13+
return __METHOD__;
14+
}
15+
}
16+
17+
$a = new A();
18+
19+
$r = zend_call_method_if_exists($a, 'foo');
20+
var_dump($r);
21+
22+
$r = zend_call_method_if_exists($a, 'bar');
23+
var_dump($r);
24+
?>
25+
--EXPECT--
26+
NULL
27+
NULL
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
zend_call_method_if_exists() with existing public method
3+
--EXTENSIONS--
4+
zend_test
5+
--FILE--
6+
<?php
7+
8+
class C {
9+
private function priv() {
10+
var_dump(__METHOD__);
11+
}
12+
public function test() {
13+
// this should call $c->priv()
14+
zend_call_method_if_exists($this, 'priv');
15+
}
16+
}
17+
18+
$c = new C();
19+
$c->test();
20+
21+
?>
22+
--EXPECT--
23+
string(7) "C::priv"
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
zend_call_method_if_exists() with existing public method
3+
--EXTENSIONS--
4+
zend_test
5+
--FILE--
6+
<?php
7+
8+
class A {
9+
public function foo() {
10+
return __METHOD__;
11+
}
12+
}
13+
14+
$a = new A();
15+
16+
$r = zend_call_method_if_exists($a, 'foo');
17+
var_dump($r);
18+
19+
?>
20+
--EXPECT--
21+
string(6) "A::foo"
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
zend_call_method_if_exists() with existing non public static methods
3+
--EXTENSIONS--
4+
zend_test
5+
--FILE--
6+
<?php
7+
8+
class A {
9+
protected static function foo() {
10+
return __METHOD__;
11+
}
12+
private static function bar() {
13+
return __METHOD__;
14+
}
15+
}
16+
17+
$a = new A();
18+
19+
$r = zend_call_method_if_exists($a, 'foo');
20+
var_dump($r);
21+
22+
$r = zend_call_method_if_exists($a, 'bar');
23+
var_dump($r);
24+
?>
25+
--EXPECT--
26+
NULL
27+
NULL
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
zend_call_method_if_exists() with existing static public method
3+
--EXTENSIONS--
4+
zend_test
5+
--FILE--
6+
<?php
7+
8+
class A {
9+
public static function foo() {
10+
return __METHOD__;
11+
}
12+
}
13+
14+
$a = new A();
15+
16+
$r = zend_call_method_if_exists($a, 'foo');
17+
var_dump($r);
18+
19+
?>
20+
--EXPECT--
21+
string(6) "A::foo"
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
zend_call_method_if_exists() with non existing method on extended class with a trampoline
3+
--EXTENSIONS--
4+
zend_test
5+
--FILE--
6+
<?php
7+
8+
class A {
9+
public function __call(string $name, array $arguments): string {
10+
return "In A trampoline for $name!";
11+
}
12+
}
13+
14+
class B extends A {
15+
public function __call(string $name, array $arguments): string {
16+
return "In B trampoline for $name!";
17+
}
18+
}
19+
20+
$b = new B();
21+
22+
$r = zend_call_method_if_exists($b, 'bar');
23+
var_dump($r);
24+
25+
?>
26+
--EXPECT--
27+
string(24) "In B trampoline for bar!"
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
zend_call_method_if_exists() with non existing method on extended class with a trampoline
3+
--EXTENSIONS--
4+
zend_test
5+
--FILE--
6+
<?php
7+
8+
class A {
9+
public function __call(string $name, array $arguments): string {
10+
return "In A trampoline for $name!";
11+
}
12+
}
13+
14+
class B extends A {}
15+
16+
$b = new B();
17+
18+
$r = zend_call_method_if_exists($b, 'bar');
19+
var_dump($r);
20+
21+
?>
22+
--EXPECT--
23+
string(24) "In A trampoline for bar!"

0 commit comments

Comments
 (0)