微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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('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

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

匿名函数

// 语法
$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');

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐