函数的参数
通过参数列表可以传递信息到函数,即以逗号作为分隔符的表达式列表。参数是从左向右求值的。
PHP 支持按值传递参数(默认),通过引用传递参数以及默认参数。也支持可变长度参数列表。
通过引用传递参数
函数在调用的时候,参数会重新开辟内存空间。比如,你传值穿的是$para,但在函数运行的时候会另开辟一个空间,复制一遍$para,之后在函数中操作的内存都是这个函数新开辟的空间。在这个函数消亡的时候,这个空间被释放。
默认情况下,函数参数通过值传递(因而即使在函数内部改变参数的值,它并不会改变函数外部的值)。如果希望允许函数修改它的参数值,必须通过引用传递参数。
如果想要函数的一个参数总是通过引用传递,可以在函数定义中该参数的前面加上符号 &,自 PHP 5 起,传引用的参数也可以有默认值。
默认参数的值默认值必须是常量表达式,不能是诸如变量,类成员,或者函数调用等。PHP 还允许使用数组 array 和特殊类型NULL
作为默认参数。
注意当使用默认参数时,任何默认参数必须放在任何非默认参数的右侧;否则,函数将不会按照预期的情况工作。
<?php
function makecoffee($price,$count = 0,$types = array("cappuccino"), $coffeeMaker = NULL)
{
$device = is_null($coffeeMaker) ? "hands" : $coffeeMaker;
return "Making a cup of ".join(", ", $types)." with $device.\n";
}
echo makecoffee();
echo makecoffee(array("cappuccino", "lavazza"), "teapot");
?>
可变数量的参数列表
PHP 在用户自定义函数中支持可变数量的参数列表。在 PHP 5.6 及以上的版本中,由 ... 语法实现;
<?php
function sum(...$numbers) {
$acc = 0;
foreach ($numbers as $n) {
$acc += $n;
}
return $acc;
}
echo sum(1, 2, 3, 4);
?>
可变函数
PHP 支持可变函数的概念。这意味着如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它。可变函数可以用来实现包括回调函数,函数表在内的一些用途。
可变函数:如同可变变量一样,一个变量保存了函数的名字,取得该函数的值即函数的名字,然后将其当做函数解析。
可变函数不能用于例如 echo,print,unset(),isset(),empty(),include,require 以及类似的语言结构。需要使用自己的包装函数来将这些结构用作可变函数。
<?php
function foo() {
echo "In foo()<br />\n";
}
function bar($arg = '') {
echo "In bar(); argument was '$arg'.<br />\n";
}
$func = 'foo';
$func(); // This calls foo()
$func = 'bar';
$func('test'); // This calls bar()
?>
匿名函数
匿名函数(Anonymous functions),即没有名字的函数,也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数。最经常用作回调函数(callback)参数的值。
<?php
echo preg_replace_callback('~-([a-z])~', function ($match) {
return strtoupper($match[1]);
}, 'hello-world');
// 输出 helloWorld
?>
php中的函数的定义在编译阶段,会被系统存放到代码区,可以通过函数名在代码区中找到该函数的代码。若没有名字,则需要通过变量来保存函数的内存地址。
闭包可以从父作用域中继承变量。 任何此类变量都应该用 use 语言结构传递进去。
但是use所引用的也只不过是变量的一个副本而已。但是我想要完全引用变量,而不是复制。要达到这种效果,其实在变量前加一个 & 符号就可以了。
这些变量都必须在函数或类的头部声明。 从父作用域中继承变量与使用全局变量是不同的。全局变量存在于一个全局的范围,无论当前在执行的是哪个函数。而 闭包的父作用域是定义该闭包的函数(不一定是调用它的函数)。
<?php
$message = 'hello';
$example = function () {
var_dump($message);
};
echo $example();//没用use无法使用message变量
// 继承 $message
$example = function () use ($message) {
var_dump($message);
};
echo $example();//输出 hello
// Inherited variable's value is from when the function
// is defined, not when called
$message = 'world';
echo $example();//输出 hello
// Reset message
$message = 'hello';// Inherit by-reference
$example = function () use (&$message) {
var_dump($message);
};
echo $example();//输出 hello
// The changed value in the parent scope// is reflected inside the function call
$message = 'world';
echo $example();//输出 world
// Closures can also accept regular arguments
$example = function ($arg) use ($message) {
var_dump($arg . ' ' . $message);
};
$example("hello");//输出 hello world?>