函式就像是一个小程序一样,把多个指令包装在一块,用简单的方式就能使用
函式主要有两种:
// 非匿名
function sum($a, $b) {
return $a + $b;
}
echo sum(1, 2); // 3
// 匿名
$sum = function ($a, $b) {
return $a + $b;
};
echo $sum(1, 2); // 3
函式通常是非匿名方式定义的,名称可以自己决定,建议动词开头取名,取成这个函式的功能,让人一眼就知道怎麽用这个函式
匿名函式则比较少见,你可以发现它本身是没有名字的,有名字的是装着它的变数
函式的参数可以设定预设值,并且在呼叫时可以不填
function sum($a, $b = 2) { // b 预设为 2
return $a + $b;
}
echo sum(1); // 3
可以限制参数的型别 int
float
array
...,不可使用 null
function sum(int $a, int $b) {
return $a + $b;
}
echo sum(1, 2); // 3
echo sum(null, 2); // error
在型别前面加上 ?
表示参数可以是 null
function sum(?int $a, int $b) {
return ($a ?? 1) + $b;
}
echo sum(null, 2); // 3
返回值也可以设定型别,void
表示不返回东西
function sum($a, $b): float {
return $a + $b;
}
var_dump(sum(1, 2)); // float(3)
可以使用 ...
让函式拥有可变长度参数列表
function sum($a, $b, ...$c) {
print_r($c);
// [0] => 3
// [1] => 4
// [2] => 5
return $a + $b + array_sum($c);
}
echo sum(1, 2, 3, 4, 5); // 15
函式不能有多个返回值
function sum($a, $b) {
return $a, $b; // syntax error
}
sum(1, 2);
但是可以用阵列包起来,再用阵列取值的方式拿出来
function sum($a, $b) {
return [$a, $b];
}
[$x, $y] = sum(1, 2);
echo $x, "\n"; // 1
echo $y, "\n"; // 2
使用函式时可以利用阵列解包填入参数
function sum($a, $b) {
return $a + $b;
}
$x = [1, 2];
echo sum(...$x); // 3
一般函式的功能它都有,它还有一个额外的关键字 use
,让它可以使用外面的变数,但是是复制一份进去,并不是原本的那个
$x = 1;
$addX = function () use ($x) {
$x++;
echo $x, "\n"; // 2
};
$addX();
echo $x, "\n"; // 1
匿名函式可以做为函式的参数 Callback Function
function callback(callable $a) {
$a();
}
$x = function () {
echo 'Hello, World!';
};
callback($x); // Hello, World!
匿名函式也可以做为函式的返回值,制作闭包 Closure
function makeClosure($a) {
return function ($b) use ($a) {
return $a . ', ' . $b . '!';
};
}
$closure = makeClosure('Hello'); // 把 Hello 关在里面
echo $closure('World'); // Hello, World!
另外还有一种简化的匿名函式:
箭头函式 Arrow Function
会自动返回结果,不用打 return
不需要 use
就能使用外面的变数,但一样是复制过後的
$x = 1;
$add = fn () => $x += 1;
echo $add(), "\n"; // 2
echo $x, "\n"; // 1
在函式中是不能存取外面的变数的,这个特性可以防止意外的改动
$x = 1;
function readX() {
echo $x; // error
}
readX();
常数没有这个限制,因为原本就改不了
const X = 1;
function readX() {
echo X; // 1
}
readX();
加一行 global 的话就能够修改外面的变数(建议不要这样做)
$x = 1;
function readX() {
global $x;
echo $x; // 1
}
readX();
建议将变数透过参数传入使用,这样虽然会无法修改外面的变数,但可以让程序比较乾净
$x = 1;
function readX($a) {
echo ++$a, "\n"; // 2
}
readX($x);
echo $x; // 1
可以透过传参考 Call By Reference,在参数前加 &
,使得两个变数指向同一个记忆体位置
$x = 1;
function readX(&$a) {
echo ++$a, "\n"; // 2
}
readX($x);
echo $x; // 2
返回值也可以设定成传参考,函式名称前要加 &
,不论是在定义还是使用时
$x = 1;
function &readX(&$a) {
echo ++$a, "\n"; // 2
return $a;
}
$i = &readX($x);
echo $x, "\n"; // 2
echo $i, "\n"; // 2
$i++;
echo $x, "\n"; // 3
echo $i, "\n"; // 3
匿名函式的 use
中的参数也可以传参考
$x = 1;
$addX = function () use (&$x) {
$x++;
};
$addX();
echo $x; // 2
函式中函式 Functions Within Function
函式可以在函式里定义,而且不论在哪里定义,都可以在全域使用
但是要执行函式(createSum)才会定义函式(sum)
function createSum() {
function sum($a, $b) {
return $a + $b;
}
}
echo sum(1, 2); // error
createSum();
echo sum(1, 2); // 3
递回函式 Recursive Function
函式可以呼叫自己,例如制作 f(x) = x + f(x - 1)
function sum($a) {
if ($a <= 0) {
return 0;
}
return $a + sum($a - 1);
}
echo sum(10); // 55
变数函式 Variable Function
如果变数後面附加了括号,PHP 会找与值相同名称的函式,并尝试执行它
function sum($a, $b) {
return $a + $b;
}
$a = 'sum';
echo $a(1, 2);
关於函式的内建函式 Function Handling Function
函式 | 说明 | 用法 |
---|---|---|
function_exists() |
检查函式是否存在 | function_exists($fn_name) |
get_defined_functions() |
查看所有已定义函式 | get_defined_functions() |
function createSum() {
function sum($a, $b) {
return $a + $b;
}
}
var_dump(function_exists('sum')); // bool(false)
createSum();
var_dump(function_exists('sum')); // bool(true)
其他内建函式:https://www.php.net/manual/en/ref.funchand.php
<<: [Day22] - 介绍 LitElement 如何使用
前言 上一篇文章讲到 Dictionary, 今天讲另一个值的集合 - Array。 Array 和...
引言 今天是机派X系列文章的第十五天。 昨天刚组装好无人机,今天要为飞行控制器做初始设定以及校正。 ...
这边会给大家一些练习题, 以及参考解答, 过程可能会与大家有些不尽相同, 还请各位多多包涵, 我会先...
今天要来介绍这个主题最後一个单元了,废话不多说就直接进入正题吧! 抽象(Abstract)类别与方法...
前言 最後四篇篇幅我们以实作一个会员网站为例子,想做这个主题原因在於会员网站在 WP 中算是个少见的...