缘由
在 Lavavel 框架中,有不少函数支持多种参数,例如:
1
2
3
4
5
6
7
8
|
collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Chair', 'price' => 100],
])->contains('product', 'Bookcase');
collect([1, 2, 3, 4, 5])->contains(function ($value, $key) {
return $value > 5;
});
|
看起来就好像进行了方法重载,但是 PHP 语法不支持方法重载。那这到底是怎么实现的?
可变参数相关函数
PHP 语法虽然不支持方法重载,但是可以使用可变参数
来实现重载
的功能
func_num_args()、func_get_arg()、func_get_args()
func_num_args(): 获取参数数量
func_get_arg(int $arg_num): 获取某个参数
func_get_args(): 获取所有参数
例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<?php
function sum()
{
$items = func_get_args();
echo '共有'.func_num_args()."个参数\n";
echo '第一个参数是'.func_get_arg(0)."\n";
$result = 0;
foreach ($items as $value) {
$result = $result + $value;
}
return $result;
}
var_dump(sum(1,2,3));
var_dump(sum(1,2));
|
可以看到,sum
函数支持多种不同的参数列表,实现了重载的功能
注意,这三个函数,只能用在函数、方法内部而不能在全局作用域中使用,例如:
1
2
|
<?php
$items = func_get_args();
|
这样会报错!
也许您是想获取 php 脚本的参数,那么请看下一节。
…$args(…语法)
PHP 5.6 以后,新增了 … 语法糖,来实现可变参数相关功能。用法请看示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<?php
function sum(...$items)
{
$result = 0;
foreach ($items as $value) {
$result = $result + $value;
}
return $result;
}
$arr = [4,5,6];
var_dump(sum(1,2,3));
var_dump(sum(...$arr)); // 等价于 var_dump(sum(4,5,6));
|
个人感觉,…语法比func_num_args()
等函数好用多了,清晰明了。
注意,…只能作为实参、形参在参数列表中使用,其它地方不能用。
形参与实参的数量
本文之前的一个例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<?php
function sum()
{
$items = func_get_args();
echo '共有'.func_num_args()."个参数\n";
echo '第一个参数是'.func_get_arg(0)."\n";
$result = 0;
foreach ($items as $value) {
$result = $result + $value;
}
return $result;
}
var_dump(sum1(1,2,3));
|
我们把代码稍微改动一下,如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<?php
function sum($a,$b) // 改了形参
{
$items = func_get_args();
echo '共有'.func_num_args()."个参数\n";
echo '第一个参数是'.func_get_arg(0)."\n";
$result = 0;
foreach ($items as $value) {
$result = $result + $value;
}
return $result;
}
var_dump(sum(1)); // 改了实参
|
这样会报错,因为我们传入的参数1
比接收的参数$a,$b
个数要少,导致$b
这个参数拿不到值,且$b
又没默认值。
用一句比较难懂的话来说就是:实参的数量 要大于或等于 无默认值的形参的数量
cli 模式下命令行参数的获取
写好了 PHP 脚本,但是在运行的时候想传入参数.例如想执行一个脚本,例如用脚本清空某个数据表:
1
|
php clear_table.php user
|
那么这个参数user
该怎么拿到?
思维活跃的人可能就想着用func_get_args
来获取命令行参数,但这样是不行的,因为它只能在函数、方法内部使用。
有如下两种方法:
使用 argv 数组
1
2
|
<?php
var_dump($argv);
|
命令行中执行
1
|
php clear_table.php user
|
就会输出
1
2
3
4
5
|
Array
(
[0] => clear_table.php
[1] => user
)
|
使用 getopt 方法
该方法的优点是能够解析命令行参数:
1
2
3
|
<?php
$param = getopt('a🅱️c:d::e');
print_r($param);
|
命令行中执行
1
|
php clear_table.php -table_name user -dbname=mydb
|
脚本执行结果为:
1
2
3
4
5
|
Array
(
[table_name] => user
[dbname] => mydb
)
|
参考资料
https://blog.csdn.net/fdipzone/article/details/51945892
https://www.cnblogs.com/xdao/p/php_var_args.html