[Day13]PHP 匿名函式及箭头函式

PHP函数

匿名函数

匿名函数(Anonymous functions),也称作闭包函数(closures),它允许临时创建一个没有指定名称的函数。最经常用作回调函数 callable参数的值。当然,也有其它应用的情况。

1. 匿名函数范例

<?php
// 使用回调执行正则表达式搜索和替换
echo preg_replace_callback('~-([a-z])~', function ($match) {
    return strtoupper($match[1]);  // 将所选的变成大写,从index: 1开始过滤掉原先"-"
}, 'hello-world');
// 输出 helloWorld
?>

闭包函数也可以作为变量的值来使用。 PHP 会自动把此种表达式转换成内置类 Closure 的对象实例。把一个 closure 对象赋值给一个变量的方式与普通变量赋值的语法是一样的,最後也要加上分号 ;

2. 匿名函数变量赋值示例

<?php
$sayHi = function($name)
{
    echo "Hello $name";
}; // 记得加上分号

$sayHi('joe');
$sayHi('cherry');
?>

3. 从父作用域继承变数

闭包可以从父作用域中继承变量。任何此类变量都应该用 use 语言结构传递进去。

PHP 7.1 起,不能传入此类变量: superglobals(超全局便量)、 $this 或者和参数重名。

从 PHP 8.0.0 开始,作用域继承的变量列表可能包含一个尾部的逗号,这个逗号将被忽略

<?php
$message = 'hello';

// 没有 "use" php会不知道这变数从哪来
$example = function () {
    var_dump($message);
};
$example();

// 继承父作用域 $message
$example = function () use ($message) {
    var_dump($message);
};
$example();

// Inherited variable's value is from when the function
// is defined, not when called
$message = 'world';
$example();  // 不会受到改变因为已经在上面先调用了(14行)

// Reset message
$message = 'hello';

// Inherit by-reference
$example = function () use (&$message) {
    var_dump($message);
};
$example();

// The changed value in the parent scope
// is reflected inside the function call
// 父作用域更改值,影响函式回调
$message = 'world';
$example();

// Closures can also accept regular arguments
// 闭包可使用常规变数
$example = function ($arg) use ($message) {
    var_dump($arg . ' ' . $message);
};
$example("hello");
?>

// outputs
// Notice: Undefined variable: ...
// NULL
// string(5) "hello"
// string(5) "hello"
// string(5) "hello"
// string(5) "world"
// string(11) "hello world"

箭头函数

箭头函数是更简洁的匿名函数,都是属於Closure类(闭包)的实现

箭头函数的语法为 fn (argument_list) => expr。

箭头函数支持与 匿名函数 相同的功能,只是其父作用域的变量总是自动的。 当表达式中使用的变量是在父作用域中定义的,它将被隐式地按值捕获。

在下面的例子中,函数 $fn1 和 $fn2 的行为是一样的

1. 箭头函数自动捕捉变数的值

<?php

$y = 1;

$fn1 = fn($x) => $x + $y;

// 相当於 using $y by value:
$fn2 = function ($x) use ($y) {
    return $x + $y;
};

// var_export -- 输出或返回一个变量的字串表示
var_export($fn1(3)); // 4
?>

2. 箭头函数自动捕捉变量的值,即使在嵌套的情况下

通常在A程序执行中,尚未结束前又开始执行B程序,B程序结束後,继续执行A程序,就称为嵌套。

<?php

$z = 1;
$fn = fn($x) => fn($y) => $x * $y + $z;
// 输出 21
var_export($fn(5)(4));
?>

3. 箭头函数有效用法例子

和匿名函数一样,箭头函数语法同样允许标准的函数声明,包括参数和返回类型、缺省值、变量,以及通过引用传递和返回。以下都是箭头函数的有效例子。

<?php

fn(array $x) => $x;
static fn(): int => $x;
fn($x = 42) => $x;
fn(&$x) => $x;
fn&($x) => $x;
fn($x, ...$rest) => $rest;

?>

4. 来自外部范围的值不能在箭头函数内修改

箭头函数会自动绑定上下文变量,这相当於对箭头函数内部使用的每一个变量 $x 执行了一个 use($x)。这意味着不可能修改外部作用域的任何值,若要实现对值的修改,可以使用 匿名函数 来替代。

<?php

$x = 1;
$fn = fn() => $x++; // 不会影响 x 的值
$fn();
var_export($x);  // 输出 1

?>

资料来源: https://www.php.net/


<<:  Day14 测试写起乃-request vs controller test

>>:  DataBinding

Angular Stock实作流程说明(Day20)

介绍完视觉化套件之後,我们就要开始进入实作了,要在十天内做完一个简易登入+资料视觉化呈现对Angul...

Day13 - composition API 初次见面哩贺

今天透过六角的 Vue3 夏令营 Vue 3 Composition API 精髓掌握 初步认识 c...

Day 14【连动 MetaMask - Front-End Request and Fetch】Modern problems require modern solutions

【前言】 嗨嗨感谢大家愿意看到这里,接下来要说的是前端的呼叫以及资料传递。今天的内容大部份都参考来...

【左京淳的JAVA学习笔记】第四章 回圈

while及do-while回圈 文法如下 while (条件式){ 执行内容 } 当条件式为tru...

Day29 ( 游戏设计 ) 太鼓达人

太鼓达人 教学原文参考:太鼓达人 这篇文章会大量使用「阵列」的操作,搭配「变数」、「逻辑判断」、「点...