IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> PHP中特殊形式的函数 -> 正文阅读

[PHP知识库]PHP中特殊形式的函数


??函数就是实现特定功能的代码块,我们定义函数的直接目的就是将程序按功能进行分块,以此呢,方便程序的使用、管理、阅读和调试。
??函数大致可分为系统函数与自定义函数,当系统中提供给我们的函数不能实现你想要实现的一个特定功能的时候,就需要你自己去定义一个函数了,这称之为自定义函数,当然PHP中还有一些特殊形式的函数,比如递归函数,回调函数等。

可变函数(变量函数)

如果一个变量名后面有圆括号,PHP引擎将寻找与该变量的值同名的函数,并且尝试解析并执行这个函数

// 用于自定义函数
function test() {
    echo "this is a test";
}
$demo = "test";
echo $demo; // 输出 test
echo $demo(); // 输出 this is a test

// 也可用于系统函数
$md5 = "md5";
echo $md5; // 输出 md5
echo $md5('123456'); // 输出 e10adc3949ba59abbe56e057f20f883e

回调函数

回调函数就是调用函数的时候将另一个函数的名称当作参数传递进去,并且在函数体中进行调用

function study($name) {
    echo "$name is studying PHP basic courses";
}

function sing($name) {
    echo "$name is singing an English song";
}

function play($name) {
    echo "$name is playing video game";
}

使用可变函数声明和应用回调函数

function doWhat($funcName, $name) {
    $funcName($name);
}

// 函数doWhat就是我们自己定义的、可以应用回调函数的函数,将自定义的函数名称传递进来,即可调用回调函数
doWhat('study', 'Lucy');  // Lucy is studying PHP basic courses
doWhat('sing', 'Lucy');   // Lucy is singing an English song
doWhat('play', 'Lucy');   // Lucy is playing video game

如何调用回调函数?

  • call_user_func() 第一个参数 callback 是被调用的回调函数,其余参数是回调函数的参数
  • call_user_func_array() 把第一个参数作为回调函数(callback)调用,把参数数组作(param_arr)为回调函数的参数传入
call_user_func('study', 'Lucy'); // Lucy is studying PHP basic courses
call_user_func_array('study', array('Lucy')); // Lucy is studying PHP basic courses

// 系统函数作为回调函数
echo call_user_func('md5', '123456'); // e10adc3949ba59abbe56e057f20f883e
echo call_user_func_array('md5', array('123456')); // e10adc3949ba59abbe56e057f20f883e

array_map

为数组的每个元素应用回调函数。返回数组,包含回调函数处理之后数组的所有元素

$arr = array(1, 2, 3 ,4, 5);
function toDouble($i): int
{
    $i *= 2;
    return $i;
}
$res = array_map('toDouble', $arr);
print_r($arr);  // 1 2 3 4 5
print_r($res);  // 2 6 4 8 10

array_walk

  • 使用用户自定义函数对数组中的每个元素做回调处理
  • 参数:array, callback(典型情况下 callback 接受两个参数。array 参数的值作为第一个,键名作为第二个)
  • 如果 callback 需要直接作用于数组中的值,则给 callback 的第一个参数指定为引用。这样任何对这些单元的改变也将会改变原始数组本身。
  • 只有 array 的值才可以被改变,用户不应在回调函数中改变该数组本身的结构。例如增加/删除单元,unset 单元等等。
  • 返回: 成功时返回 true, 失败时返回 false
$arr = array(1, 2, 3, 4, 5);
function toThreeTimes(&$i): int
{
    $i *= 3;
    return $i;
}
$res = array_walk($arr, 'toThreeTimes');
var_dump($res); // true
print_r($arr);  // 3 6 9 12 15

array_filter

  • 用回调函数过滤数组中的单元
  • 依次将 array 数组中的每个值传递到 callback 函数。如果 callback 函数返回 true,则 array 数组的当前值会被包含在返回的结果数组中。数组的键名保留不变。
  • 返回:返回过滤后的数组
$arr = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
function toEvent($i) {
    if ($i % 2 == 0) return $i;
}
$res = array_filter($arr, 'toEvent');
print_r($res); // Array ( [1] => 2 [3] => 4 [5] => 6 [7] => 8 [9] => 10 )

递归函数

  • 递归函数即自调用函数,在函数体内部直接或者间接的自己调用自己,即函数的嵌套调用是函数本身
  • 通常在此类型的函数提之中会附加一个条件判断叙述,以判断是否需要执行递归调用,并且在特定的条件下终止函数的递归调用动作,把目前流程的主控权交回到上一层函数来执行。
  • 以此,当某个执行递归调用的函数没有附加条件判断叙述时,可能会造成无限循环的错误情形。

php实现递归的三种方法

利用引用做参数

  • 引用不过是指两个不同名的变量指向同一块存储地址。
  • 本来每个变量有各自的存储地址,赋值删除各行其道。
  • 现在需要两个变量共享一块存储地址,因而任何对存储地址数值的改变都会影响两个值
function test1($i = 0, &$result = array()) {
    $i ++;
    if ($i < 10) {
        $result[] = $i;
        test1($i, $result);
    }
    # 输出:10987654321(意料之中 12345678910,其实不然) 真正执行 echo $i 是当 a < 10 条件不满足的时候
    # 通过 Xdebug 调试可以看到其实有两层循环体,条件满足执行递归,条件不满足开始执行本层函数体循环
    echo $i;
    return $result;
}

var_dump(test1());  // array 1 2 3 4 5 6 7 8 9

利用全局变量

  • 利用全局变量完成递归函数,global在函数内申明变量不过是外部变量的同名引用,变量的作用范围仍然在本函数范围内
  • 改变这些变量的值,外部同名变量的值自然也改变了
function test2($i = 0, $result = array()) {
    global $result;
    $i ++;
    if ($i < 10) {
        $result[] = $i;
        test2($i, $result);
    }
    return $result;
}

var_dump(test2());  // array 1 2 3 4 5 6 7 8 9

利用静态变量 static

仅在第一次调用函数的时候对变量进行初始化,并且保留变量值

# 首先第一次调用,static 对 $i 进行初始化
# 其后每一次执行完都会保留 $i 的值,不再进行初始化
# 相当于直接忽略了 static $i = 0; 这一句
function test3() {
    static $i = 0;
    echo $i;
    $i ++;
}

test3(); // 0
test3(); // 01
test3(); // 012
test3(); // 0123
test3(); // 01234

function test4($i = 0, $result = array()) {
    static $result;
    $i ++;
    if ($i < 10) {
        $result[] = $i;
        test4($i, $result);
    }
    return $result;
}

var_dump(test4()); // array 1 2 3 4 5 6 7 8 9

总结:所谓递归函数,重点是如何处理函数调用自身是如何保证所需要的结果得以在函数间合理"传递"

匿名函数

  • 匿名函数,也叫闭包函数,允许临时创建一个没有指定名称的函数
  • 经常用作回调函数 callable 参数的值
  • 非匿名函数在定义时就创建函数对象和作用域对象,以后即使未调用,也占空间
  • 匿名函数只有在调用时,才会创建函数对象和作用域对象。调用完后立即释放,节省内存
// 语法
$func = function () {

};

// 1、函数里定义一个匿名函数,并且调用它
function content1() {
    $func = function ($param) {
        echo $param;
    };
    $func('hello world');
}
content1(); // hello world

// 2、函数中把匿名函数返回,返回后调用它
function content2(): Closure
{
    return $func = function ($param) {
        echo $param;
    };
}
$data = content2();
$data('hello world'); // hello world

function callbackFunc($func) {
    $func('hello world');
}
$func = function ($param) {
    echo $param;
};

// 3、把匿名函数当做参数传递,并且调用它
callbackFunc($func); // hello world

// 4、或者直接将匿名函数进行传递
callbackFunc(function ($param) {
    echo $param; // hello world
});

// 5、闭包使用 use 关键字,use: 连接闭包和外界变量
# 将外层变量传进内层匿名函数,并且调用
function func($param): Closure
{
    return function () use ($param) {
        echo $param;
    };
}
$func('hello world'); // hello world

php函数使用可变数量的参数

php在用户自定义函数中支持可变数量的参数列表

在php5.5及更早的版本中,使用 func_num_args(), func_get_arg(), func_get_args() 函数实现

function func() {
    // 获取参数数量
    echo func_num_args();

    // 获取第一个参数的值
    print_r(func_get_arg(0));

    // 获取所有参数的值
    print_r(func_get_args());
}

func('a'); // 1 a Array ( [0] => a )
func(1, 2, 3); // 3 1 Array ( [0] => 1 [1] => 2 [2] => 3 )
func(array('a', 'b'), 'c'); // 2  Array ( [0] => a [1] => b )  Array ( [0] => Array ( [0] => a [1] => b ) [1] => c )

在php5.6及以上的版本中,可以使用 语法实现

// 使用 ...$params 代替任意数量参数
function func(...$params) {
    // 获取参数数量
    echo count($params);

    // 获取第一个参数的值
    print_r($params[0]);

    // 获取所有参数的值
    print_r($params);
}

# 输出结果与php5.5使用 func_num_args(), func_get_arg(), func_get_args() 函数一致
func('a');
func(1, 2, 3);
func(array('a', 'b'), 'c');
  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2021-12-26 21:55:54  更:2021-12-26 21:56:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 15:35:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码