PHP 函数
get_defined_functions() 查看已定义的函数,包括系统预定义函数和用户自定义函数
printf('<pre>%s</pre>', print_r(get_defined_functions(), true));
// 输出所有系统预定义函数和用户自定义函数
Array
(
[internal] => Array
(
[0] => zend_version
[1] => func_num_args
[2] => func_get_arg
...
[1393] => memcache_flush
[1394] => memcache_set_sasl_auth_data
)
[user] => Array
(
)
)
function_exists() 判断函数是否已定义
$result = function_exists('ctype_graph');
var_dump($result); // bool(true)
格式:function 函数名(参数) { 函数体 }
function:定义函数关键词
- 定义时的参数为形参
- 函数体必须要有返回值 return,返回值可以是单个值、表达式、数组、对象、json字符串…
4.5.2.2 调用
// 定义命名函数
function sum($a, $b)
{
return $a + $b;
}
调用:函数名(参数)
调用时的参数为实参
var_dump(sum(1,3)); // string(1) "4"
强制规定参数类型和返回值类型
// 不指定参数类型和返回值类型
function sum($a, $b)
{
return $a + $b;
}
var_dump(sum(1,3)); // string(1) "4",数值默认返回字符串
// 强制指定参数类型
function sum(int $a, int $b)
{
return $a + $b;
}
var_dump(sum(1,3)); // int(4),返回类型根据实参类型和执行结构确定
// 强制规定参数类型和返回值类型
function sum(int $a, int $b): string
{
return $a + $b;
}
var_dump(sum(1,3)); // string(1) "4",返回指定的类型
命名函数是全局作用域,可以在函数定义前调用
echo sum(1, 3); // 4
function sum(int $a, int $b): string
{
return $a + $b;
}
回调,可以把一个命名函数当做参数传给另一个函数
call_user_func (函数名, 参数)
第一个参数:函数名,被回调的命名函数的名称,需用单引号括起来
第二个参数:参数,被回调的命名函数所需的参数
// 被回调的匿名函数只有一个参数
function boo($a) {
return $a *= 10;
};
echo call_user_func('boo', 8); // 80
// 被回调的匿名函数有多个参数
function foo($a, $b, $c) {
return array_sum([$a,$b,$c]);
};
echo call_user_func('foo', ...[1,2,3]); // 6
call_user_func_array(函数名, 参数数组)
第一个参数:函数名,被回调的命名函数的名称,需用单引号括起来
第二个参数:参数数组,被回调的命名函数所需的参数所组成的数组
function foo($a, $b, $c) {
return array_sum([$a,$b,$c]);
};
echo call_user_func_array('foo', [1,2,3]); // 6
一般实参数量要与形参数量一致,从左往右与形参对应
默认参数,定义函数时给参数指定默认值,调用时可以不给对应的参数,取默认值
function sum1(int $a, int $b, int $c = 10): int
{
return array_sum([$a, $b, $c]);
}
echo sum1(20, 30); // 60
命名参数(注:php8.0 开始支持)
function sum2(int $a, int $b, int $c = 10, int $d = 20): int
{
return array_sum([$a, $b, $c, $d]);
}
// 第三个参数不给取默认值,第四个参数用命名参数
echo sum2(1, 2, d: 3); // 16
可变参数,参数太多 或者不确定参数的个数 在参数前加
...
标识为可变参数function foo($arg, ...$args) //聚拢 收集
{
var_dump($arg, $args);
}
echo foo(1, 2, 3, 4, 5);
// 输出:int(1) array(4) { [0]=> int(2) [1]=> int(3) [2]=> int(4) [3]=> int(5) }
function boo(...$args)
{
return array_sum($args);
}
echo boo(1, 2, 3, 4, 5); // 15
引用参数,定义函数时,形参前面加
&
,将值传递变为引用传递值传递,复制一份内存地址,函数执行结果不影响被引用的变量
引用传递,两个变量指向同一个内存地址,函数执行结果会改变被引用的变量
// 值传值
function hoo($arg)
{
return $arg += 10;
}
$a = 10;
echo hoo($a); // 20
echo $a; // 10,函数执行结果不影响被引用的变量
// 引用传递
function hoo(&$arg)
{
return $arg += 10;
}
$a = 10;
echo hoo($a); // 20
echo $a; // 20,函数执行结果会改变被引用的变量
引用传值同样适用与变量
$x = 100;
$y = $x; //值传递
$x = 200;
echo $y; // 100
$y = &$x; //引用赋值 $x $y 指向同一个内存地址 互相受影响
$x = 1000;
echo $y; // 1000
$y = 8888;
echo $x; // 8888
函数只允许一条返回语句,return 后面的代码不会被执行
function fn1()
{
return 1 == '1';
return '你好'; // 不会被执行
}
var_dump(fn1()); // bool(true)
返回值可以是单个值、表达式、数组、对象、json字符串…
// 返回 json 字符串
function fn1()
{
return json_encode(['code' => 0, 'msg' => '登录成功']);
}
var_dump(fn1()); // string(43) "{"code":0,"msg":"\u767b\u5f55\u6210\u529f"}"
json_encode() 默认会将中文字符转为 unicode 编码,可以给json_encode() 添加第二个参数:JSON_UNESCAPED_UNICODE 不转义
function fn1()
{
return json_encode(['code' => 0, 'msg' => '登录成功'], JSON_UNESCAPED_UNICODE);
}
var_dump(fn1()); // string(31) "{"code":0,"msg":"登录成功"}"
JSON_UNESCAPED_UNICODE 为系统预定义常量,值等于 256,所以第二个参数可以直接写 256
function fn1()
{
return json_encode(['code' => 0, 'msg' => '登录成功'], 256);
}
var_dump(fn1()); // string(31) "{"code":0,"msg":"登录成功"}"
JSON_UNESCAPED_SLASHES,不转义斜杠
/
,值为 64,应用:url 地址// 默认转义,url 地址不正确
function fn1()
{
return json_encode(['code' => 0, 'rul' => 'https://www.baidu.com']);
}
var_dump(fn1()); // string(42) "{"code":0,"rul":"https:\/\/www.baidu.com"}"
// 添加第二个参数 JSON_UNESCAPED_SLASHES,不转义,url 地址正确
function fn1()
{
return json_encode(['code' => 0, 'rul' => 'https://www.baidu.com'], 64);
}
var_dump(fn1()); // string(40) "{"code":0,"rul":"https://www.baidu.com"}"
同时不转义 unicode 和 斜杠,第二个参数可以设置为 320(256 + 64)
function fn1()
{
return json_encode(['code' => 0, 'msg' => '登录成功/'], 320);
}
var_dump(fn1()); string(32) "{"code":0,"msg":"登录成功/"}"
不指定函数名称,将整个函数赋值给一个变量
格式:变量 = function (参数) { 函数体 }
$boo = function ($a) {
return $a *= 10;
};
传统调用:变量名(参数)
$boo = function ($a) {
return $a *= 10;
};
echo $boo(2); // 20
匿名函数不是全局作用域,定义前不能调用
echo $boo(2); // Undefined variable: boo
$boo = function ($a) {
return $a *= 10;
};
回调,可以把一个匿名函数当做参数传给另一个函数
call_user_func (函数名, 参数)
第一个参数:函数名,被回调的匿名函数的变量名
第二个参数:参数,被回调的匿名函数所需的参数
// 被回调的匿名函数只有一个参数
$boo = function ($a) {
return $a *= 2;
};
echo call_user_func($boo, 2);
// 被回调的匿名函数有多个参数
$boo = function ($a, $b, $c) {
return array_sum([$a,$b,$c]);
};
echo call_user_func($boo, ...[1,2,3]); // 6
call_user_func_array(函数名, 参数数组)
第一个参数:函数名,被回调的匿名函数的变量名
第二个参数:参数数组,被回调的匿名函数所需的参数所组成的数组
$boo = function ($a, $b, $c) {
return array_sum([$a,$b,$c]);
};
echo call_user_func_array($boo, [1,2,3]); // 6
php 是单线程,同步执行(从前往后逐条执行),如果遇到耗时的函数会发生阻塞,应该将它改为异步回调来去执行。
回调:在主线程执行的过程中,跳到预先设置好的函数中去执行(异步,支线程),主线程继续执行,异步执行有结果后返回主线程。
4.5.5 递归函数递归函数(recursion):是指直接或间接地调用函数自身的函数。
必须有一个终止处理或计算的准则。
4.5.6 函数引用全局变量
function demo($a = 1)
{
if ($a <= 5) {
echo "第{$a}次执行" . PHP_EOL;
$a++;
demo($a); // 调用自己
}
}
demo(); // 第1次执行 第2次执行 第3次执行 第4次执行 第5次执行
全局变量不能在函数体内直接调用
$b = 10;
$boo = function ($a) {
return $a *= $b;
};
echo $boo(2);
// Undefined variable: b
使用 use 关键字引入全局变量
$b = 10;
$boo = function ($a) use ($b) {
return $a *= $b;
};
echo $boo(2); // 20