In PHP, when defining a function what is the maximum number of arguments that you can create?
Would this be purely down a memory limitation? Effectively unlimited?
In PHP, when defining a function what is the maximum number of arguments that you can create?
Would this be purely down a memory limitation? Effectively unlimited?
Arguments to a function are pushed on a stack, after which the function is called which in turn reads the stack and uses those values as parameters.
So as long as the stack isn't full, you can keep adding parameters, but it'll depend on the situation, and at design-time you won't know the stack size.
But I really hope this is pure a technical discussion and you don't need it IRL. ;-)
when defining a function what is the maximum number of arguments that you can create?
I'm not aware of specific limit in the number of arguments as a fixed number. A quick test revealed that I had no problems to define a function with 255 555 arguments. It does take some time to define the function and to execute it. However, it works.
As the number was raised, I was running into a memory limit which could be string limit. You might want to improve the test-case, use a buffer and save the file to disk sequentially and include it then:
$count = 255555;
$code = 'function test(%s) {return 1;}; return test();';
$params = ltrim(implode('=0, $p', range(0, $count)), '0, =').'=0';
echo eval(sprintf($code, $params));
I don't really know what are the limits, but either way, if you create a function with too many arguments your code will not be so easy to read it. In case you like to add many function arguments you can do something like that:
$option = array(
'arg_1' => 'value',
'arg_2' => 'value',
....
'arg_x' => 'value'
);
function function_name($args = "")
{
$defaults = array(
'arg_1' => 'default_value',
'arg_2' => 'default_value'
....
'arg_x' => 'default_value'
);
$arguments = array_merge($defaults, (array)$args);
extract($arguments);
echo $arg_1;
echo $arg_x;
}
roughly 67.1 million before you get a segmentation fault. In my test, I get a segfault at exactly 67,108,849 + 1 arguments. This code:
<?php
$template = <<<'STR'
<?php
declare(strict_types=1);
error_reporting(E_ALL);
ini_set('display_errors', '1');
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
if (error_reporting() & $errno) {
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
});
function f(){
$i = func_num_args();
$s=number_format($i);
var_dump($s);
}
f(
STR;
$start_counter = 67_000_000;
$end_counter = 100_000_000; // unreachable
$incrementer = 1_000_000;
for ($i = $start_counter; $i < $end_counter; $i += $incrementer) {
var_dump($i);
$str = $template . str_repeat('1,', $i) . ");";
file_put_contents("wut2.php", $str);
passthru("php wut2.php", $ret);
var_dump("ret: $ret");
if ($ret != 0) {
var_dump("Failed at $i");
if($incrementer === 1){
break;
}
$i -= $incrementer;
$incrementer /= 10;
}
}
prints
root@DESKTOP-EE15SLU:/wtf# time php wut.php
int(67000000)
string(10) "67,000,000"
string(6) "ret: 0"
int(68000000)
Segmentation fault
string(8) "ret: 139"
string(18) "Failed at 68000000"
int(67100000)
string(10) "67,100,000"
string(6) "ret: 0"
int(67200000)
Segmentation fault
string(8) "ret: 139"
string(18) "Failed at 67200000"
int(67110000)
Segmentation fault
string(8) "ret: 139"
string(18) "Failed at 67110000"
int(67101000)
string(10) "67,101,000"
string(6) "ret: 0"
int(67102000)
string(10) "67,102,000"
string(6) "ret: 0"
(...)
int(67108000)
string(10) "67,108,000"
string(6) "ret: 0"
int(67109000)
Segmentation fault
string(8) "ret: 139"
string(18) "Failed at 67109000"
int(67108100)
string(10) "67,108,100"
string(6) "ret: 0"
(...)
string(10) "67,108,800"
string(6) "ret: 0"
int(67108900)
Segmentation fault
string(8) "ret: 139"
string(18) "Failed at 67108900"
int(67108810)
string(10) "67,108,810"
string(6) "ret: 0"
int(67108820)
string(10) "67,108,820"
string(6) "ret: 0"
int(67108830)
string(10) "67,108,830"
string(6) "ret: 0"
int(67108840)
string(10) "67,108,840"
string(6) "ret: 0"
int(67108850)
Segmentation fault
string(8) "ret: 139"
string(18) "Failed at 67108850"
int(67108841)
string(10) "67,108,841"
string(6) "ret: 0"
int(67108842)
string(10) "67,108,842"
string(6) "ret: 0"
int(67108843)
string(10) "67,108,843"
string(6) "ret: 0"
int(67108844)
string(10) "67,108,844"
string(6) "ret: 0"
int(67108845)
string(10) "67,108,845"
string(6) "ret: 0"
int(67108846)
string(10) "67,108,846"
string(6) "ret: 0"
int(67108847)
string(10) "67,108,847"
string(6) "ret: 0"
int(67108848)
string(10) "67,108,848"
string(6) "ret: 0"
int(67108849)
string(10) "67,108,849"
string(6) "ret: 0"
int(67108850)
Segmentation fault
string(8) "ret: 139"
string(18) "Failed at 67108850"
real 9m56.762s
user 5m49.852s
sys 4m6.763s