fix(php): 解决可选参数传入null时使用C++默认值的问题

- 当可选参数显式传入null时跳过该参数,使C++默认值生效
- 添加对substr、strpos、stripos、strrpos、strstr、explode等函数的null参数处理
- 确保null参数行为与PHP原生函数一致
- 新增测试用例验证各种可选参数为null时的正确行为
pull/2/head
韩天峰 2 months ago
parent 10fd8fe0ce
commit f0c4b6bc98
  1. 11
      src/Php/Optimizer/FuncCallOptimizer.php
  2. 51
      tests/aot/stdlib/null_optional_arg.phpt

@ -393,6 +393,17 @@ trait FuncCallOptimizer
} }
continue; continue;
} }
// When null is explicitly passed to an optional parameter, skip it
// so the C++ default value takes effect (PHP null = "use default").
if ($optional && $argCount > $i && isset($expr->args[$i])) {
$argVal = $expr->args[$i]->value;
if ($argVal instanceof Node\Expr\ConstFetch && strtolower($argVal->name->toString()) === 'null') {
if (isset($defaults[$i])) {
$args[] = $defaults[$i];
}
continue;
}
}
$args[] = $this->resolveArg($expr, $i, $type); $args[] = $this->resolveArg($expr, $i, $type);
} }

@ -0,0 +1,51 @@
--TEST--
Passing null to optional parameters should use C++ default values
--FILE--
<?php
// substr: null length should take rest of string, not return empty
$s = 'hello world';
var_dump(substr($s, 6, null));
var_dump(substr($s, 6) === substr($s, 6, null));
var_dump(substr($s, 0, null) === $s);
var_dump(substr($s, null) === $s);
// strpos: null offset should default to 0
var_dump(strpos($s, 'o', null));
var_dump(strpos($s, 'o', null) === strpos($s, 'o'));
// stripos: null offset should default to 0
var_dump(stripos($s, 'O', null));
var_dump(stripos($s, 'O', null) === stripos($s, 'O'));
// strrpos: null offset should default to 0 (search from end)
var_dump(strrpos('hello hello', 'o', null));
var_dump(strrpos('hello hello', 'o', null) === strrpos('hello hello', 'o'));
// strstr: null before_needle should default to false
var_dump(strstr($s, 'o', null));
var_dump(strstr($s, 'o', null) === strstr($s, 'o'));
// str_repeat: ensure non-null still works
var_dump(str_repeat('ab', 3));
// explode with null limit should default to PHP_INT_MAX (no limit)
$arr = explode(' ', 'a b c d', null);
var_dump(count($arr));
?>
--EXPECT--
string(5) "world"
bool(true)
bool(true)
bool(true)
int(4)
bool(true)
int(4)
bool(true)
int(10)
bool(true)
string(7) "o world"
bool(true)
string(6) "ababab"
int(4)
Loading…
Cancel
Save