函数

本文详细介绍了PHP函数的多种特性,包括参数传递方式、默认参数、可变参数列表、可变函数、匿名函数及其使用方法,以及如何正确使用闭包。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

函数的参数

通过参数列表可以传递信息到函数,即以逗号作为分隔符的表达式列表。参数是从左向右求值的。

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 将寻找与变量的值同名的函数,并且尝试执行它。可变函数可以用来实现包括回调函数,函数表在内的一些用途。

可变函数:如同可变变量一样,一个变量保存了函数的名字,取得该函数的值即函数的名字,然后将其当做函数解析。

可变函数不能用于例如 echoprintunset()isset()empty()includerequire 以及类似的语言结构。需要使用自己的包装函数来将这些结构用作可变函数。

<?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中的函数的定义在编译阶段,会被系统存放到代码区,可以通过函数名在代码区中找到该函数的代码。若没有名字,则需要通过变量来保存函数的内存地址。

闭包函数也可以作为变量的值来使用。PHP 会自动把此种表达式转换成内置类 Closure 的对象实例。把一个 closure 对象赋值给一个变量的方式与普通变量赋值的语法是一样的,最后也要加上分号:

闭包可以从父作用域中继承变量。 任何此类变量都应该用 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?>


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值