您的位置:首页 > 编程语言 > PHP开发

php基础——函数

2020-06-29 04:51 453 查看

函数介绍

  • 完成某一功能的程序代码集合,称为函数
  • 把一段常用的功能代码,封装到一起,做成一个函数,可以提高代码的复用性和可维护性
  • get_defined_functions() 返回所有已定义函数的数组

函数定义

  • 函数的参数列表可以是多个,并且数据类型可以是任意类型
  • 函数内定义的变量是局部变量,只能在函数内使用,与函数外同名变量不冲突
  • 函数中要使用全局变量,使用global关键字
function 函数名(形参1,形参2,n){    // 参数可以不写
执行语句;
return;      // 返回值写不写看需求,如不写默认返回null
}

函数运行原理

代码示例

$num1 = 10;
$num2 = 10;
//此处传参相当于 $n1=$num1; $n2=$num2 传值赋值
function getSum($n1, $n2){
$res = $n1 + $n2;
return $res;
}

$val = getSum($num1, $num2);
echo $val;

内存示例

变量作用域

函数中定义的变量是局部的,函数外不生效

代码示例

function test(){
$a = 100;
echo $a;
}

test();
echo $a;  // Notice: Undefined variable: a

内存示例

global使用全局变量

函数中要使用全局变量,使用global关键字

  • global $a
    本质上等价于
    $a = &$GLOBAL['a']
    【重要】
  • global $a
    表示希望使用全局区的
    $a
  • 如果没有全局变量
    $a
    ,则会先创建全局变量
    $a=null
  • var_dump($GLOBALS)
    查看所有的全局变量

代码示例

$a = 100;
function test(){
// global $a 表示希望使用全局区的$a
// 如果没有全局变量$a,则会先创建全局变量 $a=null
// global $a 本质上等价于 $a = &$GLOBAL['a'] 引用赋值
global $a;
$a = 10;
echo $a;
}
test();     // 10
echo $a;    // 10
function test(){
// 如果没有全局变量$a,则会先创建全局变量 $a=null
global $a;
var_dump($a);
}

test();         // null
var_dump($a);   // null

内存示例

流程分析

1.主栈

$a
指向100
2.
test()
,调用函数,在栈区新开辟一个新的空间新栈1,入新栈1
3.入栈后执行
global $a
,即函数内希望使用一个全局变量
$a

  • 如果主栈没有
    $a
    则会先创建全局变量
    $a
    值为
    null
    ,然后全局和局部(主栈和新栈)的变量名
    $a
    指向全局区的
    null
  • 如果有则在新栈1创建
    $a变量名
    指向全局区100

4.

$a = 10
,即新栈1中
$a
将全局区的100改为10
5.函数没写返回值,默认返回null,函数结束,出新栈1,新栈1销毁,新栈1中的数据和与新栈1相关的箭头也都没有了
7.
echo $a
,主栈中的
$a
仍指向10,输出10

函数中的静态变量

  • 静态变量的特点,只会被初始化一次
  • 静态区数据在函数执行完后,不销毁,即使不再有变量指向(这是一个特例),直到整个进程结束才销毁

代码示例

function test(){
$b = 10;
static $a = 0;
$a++;
echo $a;
}
test();
test();
test();

内存示例

  • 第一次调用
    test()
    $a
    初始化指向静态区0,
    $a++
    ,静态数据变为1,调用结束,新栈1销毁,静态区并不销毁
  • 第二次调用
    test()
    ,a不再初始化为0,直接找到静态数据1,‘a不再初始化为0,直接找到静态数据1,`a不再初始化为0,直接找到静态数据1,‘a++`,静态数据变为2,调用结束,新栈2销毁,静态区并不销毁
  • 第三次调用
    test()
    ,a不再初始化为0,直接找到静态数据2,‘a不再初始化为0,直接找到静态数据2,`a不再初始化为0,直接找到静态数据2,‘a++`,静态数据变为3,调用结束,新栈2销毁,静态区仍不销毁,直到整个进程结束才销毁

函数传参

函数默认参数的值

// $b的默认值为20,如果调用时不填写,以默认值为准,如果填写,以最新的为准
function test($a, $b=20){
echo $a + $b,'<br>';
}
test(10);       // 30
test(10,1);     // 11

传值赋值
函数参数默认通过值传递

// 函数传参默认值传递  $a = $num
function test($a){
echo ++$a,'<br>';
}
$num = 10;
test($num);     // 10
echo $num;      // 11

引用赋值
可以在形参前加&修改为引用传递

// 函数传参方式修改为引用传递  $a = &$num
function test(&$a){
echo ++$a,'<br>';
}
$num = 10;
test($num);     // 11
echo $num;      // 11

内存示例

函数传参 – 不定长参数

  • func_num_args — 返回传递给函数的参数数量
  • func_get_arg — 返回参数列表的某一项
  • func_get_args — 返回一个包含函数参数列表的数组

代码示例
函数的参数可以是基本数据类型任意

function fun(){
return 'hello';
}

function test(){
$res1 = func_num_args();
$res2 = func_get_arg(1);
$res3 = func_get_args();
var_dump($res1,$res2,$res3);
}

test(1,5,'hi',array(1,2),fun());

练习题

// 传入参数个数不确定,求和
function getSum(){
$arr = func_get_args();
$sum = 0;
foreach ($arr as $value){
$sum += $value;
}
return $sum;
}

echo getSum(1,2,5);
echo getSum(1,-2,5,6);

内部函数

  • 函数和类声明是全局有效的,不管是在多深的函数下声明的类或函数
  • 函数调用时才会会执行函数内部代码 (调用时才入栈执行)

函数内部可以定义函数,供函数内部使用

function test(){
function fun(){
echo 'hello world';
}
// 内部直接调用内部函数
fun();
}

test(); // 'hello world'

函数调用时才会会执行函数内部代码

function test(){
function fun(){
echo 'hello world';
}
}
test(); // 这里调用之后 fun()才被定义
fun();	// 'hello world'

可变函数

  • PHP 支持可变函数的概念
  • 如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它
  • 可变函数可以用来实现包括回调函数,函数表在内的一些用途
function test(){
echo 'hello world';
}

$a = 'test';
$a();   // 先解析$a, test(),若有则执行,若没有则报错

函数面试题

写一个函数,接受两个参数

$a $b
和一个函数
$fun
,要求通过
$fun求$a $b的和

// 新浪面试题:写一个函数,接受两个参数$a $b和一个函数$fun,要求通过$fun求$a $b的和

// 方案一:最容易理解
function test($n1,$n2,$n3){
echo $n3;
}

function getSum($n1,$n2){
return $n1 + $n2;
}

$a = 1; $b = 2;
test($a, $b, getSum($a, $b));

==============================
// 方案二:使用可变函数知识点
function test($n1,$n2,$n3){
echo $n3($n1,$n2);
}

function getSum($m1,$m2){
return $m1 + $m2;
}

$a = 1; $b = 2; $funName = 'getSum';
test($a,$b,$funName);
=============================
// 方案三:方案二的改进使用
function test($n1,$n2,$n3){
function getSum($n1,$n2){
return $n1 + $n2;
}

return $n3($n1,$n2);
}

$a = 1; $b = 2; $funName = 'getSum';
echo test($a, $b, $funName);

匿名函数

  • 匿名函数,也叫闭包函数,允许临时创建一个没有指定名称的函数
  • 最经常用作回调函数参数的值
  • 闭包函数也可以作为变量的值来使用,最后要加上分号:
  • 匿名函数其实是一个对象数据类型

代码示例

$fun1 = function ($n1, $n2){
return $n1 + $n2;
};  // 这里是加;的

// 调用匿名函数
echo $fun1(1,3);

var_dump($fun1);    // object

回调函数

调用某个函数A,而这个函数内又会调用你实现的另一个函数B,那么函数B就是所谓的回调函数

function test($n1,$n2,$n3){
echo $n3($n1,$n2);
}

function getSum($m1,$m2){
return $m1 + $m2;
}

$a = 1; $b = 2; $funName = 'getSum';
test($a,$b,$funName);

匿名函数用作回调函数参数的值(开发中用的挺多)

function test($n1, $n2, $n3){
$sum = $n1 + $n2;
$res = $n3($sum);	// 回调
return $res;
}

echo test(1, 3, function ($v){return $v*2;});   // 第三个参数为匿名函数

递归函数

  • 递归函数即自调用函数,在函数体内部直接或间接的自己调用自己
  • 函数体中会附加一个条件判断,以判断是否需要执行递归调用,并且在特定的条件下终止函数的递归

代码示例

function abc($n){	// 此处是传值赋值
if ($n>2){
abc(--$n);	// $n = $n-1;  abc($n)
}
echo $n,'<br>';
}

abc(4);	// 2 2 3

// 思考: 如果是 $n-- 会怎么?   无限递归

内存示例

递归练习1 :1 ~ n的和

function sum($n){
if ($n == 1){
return 1;
}
return $n+sum($n-1);
}

echo sum(100);

递归练习2 :斐波那契数列

// 斐波那契数列  1 1 2 3 5 8 13
function test($n){
if ($n == 1 || $n == 2){
return 1;
}else{
return test($n-1) + test($n-2);
}
}

$res = test(5);
echo $res;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: