찾다
백엔드 개발PHP 튜토리얼谈PHP 闭包特性在实际应用中的问题_PHP教程

谈PHP 闭包特性在实际应用中的问题_PHP教程

Jul 13, 2016 pm 05:38 PM
php존재하다실제애플리케이션새 버전새로운 특성비교하다특성따르다폐쇄질문

PHP5.3 新版本跟随了很多新特性, 其中比较惹眼的特性之一就是支持了闭包。那么以后,我们也可以和那帮写 Ruby、Javascript 等等“高科技语言”的家伙们一样,写出非常酷的代码吗?呃,其实大部分情况下是可以的,而有些方面还是令人非常的困扰,下面慢慢道来。

很多语言的都提供了非常优雅和漂亮的操作数组的方法。在下面的例子中,会使用 PHP5.3 以及其他语言提供的闭包功能,用于展示如何“客观的”操作迭代数组。

译注:原文作者比较火星,我不了解 Groovy 以及 Scala 语言,所以这里我加上 Javascript 的实现。

在开始之前先说明下,本例子仅仅是阐明观点,并没有考虑性能等其他方面的因素。

“货比三家”

用个简单的例子开始,有下面个数组:

$nums = array(10, 20, 30, 40);

需要找出数组中大于 15 的项。那么,不考虑闭包的情况下,我们或许会这样写:

$res = array();<br>foreach ($nums as $n) {<br>    if ($n > 15) {<br>        $res[] = $n;<br>    }<br>}

如果语言本身有闭包支持的,那么或许会这样写(Groovy 语言)

def res = nums.findAll { it > 15 }

或者使用 Scala 语言

val res = nums filter (_ > 15)

译注:Javascript 1.6 的话会是如下

var res = nums.filter(function(c){return c > 15});

因为循环操作已被抽象起来,所以可以看到 Groovy 、Scala (以及 Javascript) 都很漂亮得用一行就可以搞定。

当然,如果使用 PHP5.3 的闭包,也可以做到

$res = array_filter($nums, function($v) { return $v > 15; });

PHP 在这方面使用了比 Scala 更多的字符,但对比先前的例子,它更简短并且能更好得阅读。

顺便说下,上面的 PHP 代码实际上是使用了 Lambda 解析式,并不是个真正的闭包,这个 并不是我们目前关注的重点。详细阐述 PHP 闭包以及 Lambda 解析式的资料,可以参考这里。

目前看来感觉都还不错,那么我们再的题目增加点难度:找到所有大于 15 的项, 然后乘以 2 再加上作用域中的的某个变量值以后再返回。

Groovy 的实现:

def x = 1<br>def res = nums .findAll { it > 15 } .collect { it * 2 + x }

Scala 的实现:

val x = 1<br>val res = nums filter (_ > 15) map (_ * 2 + x)

译注,Javascript 的实现:

var i = 1;<br>var res = nums.filter(function(c){return c > 15}).map(function(c){return c * 2 + i});

以及 PHP:

$x = 1;<br>$res = array_map(<br>    function($v) use ($x) { return $v * 2 + $x; },<br>    array_filter(<br>        $nums,<br>        function($v) { return $v > 15; })<br>);

光从代码量方面,现在看起来 PHP 与其他语言有出入了。先抛开代码字面上本身 的审美不谈,上面的 PHP 代码还有个额外的问题。

例如,如果需要使用数组的键而非值作比较,怎么办?是的,上面的代码就办不到了。同时,从语法角度上说,上面的代码非常难以阅读。

返璞归真,这时还是得返回老土的思路去解决问题:

$x = 1;<br>$res = array();<br>foreach ($nums as $n) {<br>    if ($n > 15) {<br>        $res[] = $n * 2 + $x;<br>    }<br>}

呼,这样看起来又很清楚了。但这个时候你或许又会迷惑了:“那还瞎折腾啥,这不就是个数组操作吗?”。

是的,好戏还在后头。这个时候该让 PHP 的某些高级特性出场,来搞定这看似有自残倾向 的“无聊问题”。

ArrayObject – 对数组的封装

PHP 有个称作 SPL 的标准库,其中包含了个叫做 ArrayObject 的类,它能提供“像数组一 样操作类”的功能,例如

$res = new ArrayObject(array(10, 20, 30, 40));<br>foreach ($res as $v) {<br>    echo "$vn";<br>}

ArrayObject 是个内置的类,所以你可以像其他类类操作一样封装它。

Arr - 包上糖衣

既然我们已经有了 ArrayObject 以及闭包这些特性,我们就可以开始尝试封装它:

class Arr extends ArrayObject<br>{<br>    static function make($array)<br>    {<br>        return new self($array);<br>    }<br><br>    function map($func)<br>    {<br>        $res = new self();<br>        foreach ($this as $k => $v) {<br>            $res[$k] = $func($k, $v);<br>        }<br>        return $res;<br>    }<br><br>    function filter($func)<br>    {<br>        $res = new self();<br>        foreach ($this as $k => $v) {<br>            if ($func($k, $v)) {<br>                $res[$k] = $v;<br>            }<br>        }<br>        return $res;<br>    }<br>}

好了,万事俱备。下面重写的 PHP 代码就可以解决上面提到的问题,并且看起来语法上“差 不多”了:

$res = Arr::make($nums)<br>    ->filter(function($k, $v) { return $v > 15; })<br>    ->map(function($k, $v) { return $v * 2; });

上面的代码与传统方式有何不同呢?首先,它们可以递归并形成作用链式的调用,因此可以 添加更多的类似操作。

同时,可以通过回调的两个参数分别操作数组的键以及值其项 - $k 对应键以及 $v 对应值 。这使得我们可以在闭包中使用键值,这在传统的 PHP 函数 array_fliter 中是无法实现的。

另外个带来的额外好处就是更加一致 API 调用。使用传统的 PHP 函数操作,它们有可能第一个参数是个闭包,或者是个数组,抑或是多个数组…总之谁知道呢?

这里是 Arr 类的完整源代码,还包含了其他有用的函数(类似 reduce 以及 walk),其实它 们的实现其实方式和代码类似。

博弈

这个问题其实很难回答 - 这需要根据代码的上下文以及程序员自身等众多因素决定。其实 ,当我第一眼看见 PHP 的闭包实现时,我感觉似乎回到了那很久以前的 Java 时期,当时 我在开始使用匿名内置类(anonymous inner classes)来实现闭包。当然,这虽然可以做到, 但看起来实在是些画蛇添足。PHP 闭包本身是没错,只是它的实现以及语法让我感到非常的困惑。

其他具有闭包特性的语言,它们可以非常方便的调用闭包并同时具有优雅的语法。在上面的例子 中,在 Scala 中使用传统的循环也可以工作,但你会这样写吗?而从另个方面,那么有人 说上面这个题目使用 PHP 的闭包也可以实现,但一般情况下你会这样写吗?

可以确定,PHP 闭包在些情况下可以成为锐利的军刀(例如延时执行以及资源调用方面), 但在传统的迭代以及数组操作面前就显得有些为难。不要气馁不管怎么样, 返璞归真编写具有兼容性的、清爽的代码以及 API 是最重要的。

结束语

像所有后来加上的语法特性一样(记得当年 Java 的 Generics 特性不?以及前几年的 PHP OOP 特性),它们都需要时间磨合以及最终稳定下来。随着 PHP5.3 甚至将来的 PHP6 逐渐普及,越来越多的技巧和特性相信在不远的将来逐渐的被聪明的程序员挖掘出来。

回到最初文章开头那个题目,对比

$res = Arr::make($nums)<br>    ->filter(function($k, $v) { return $v > 15; })<br>    ->map(function($k, $v) { return $v * 2; });

以及

val res = nums filter (_ > 15) map (_ * 2)

两者之间的区别。归根结底它们仅是语法而已,本质上都是殊途同归解决了同个问题。程序 语言的应用特性不同,自然孰优孰劣也就无从比较。

最后,这里有此篇文章的代码示例, 相信可以找到更多如何使用 PHP 进行函数式迭代(当然不仅仅是这些)的心得。

-- Split --

不靠谱之博主心得

坦白讲,虽然在 PHP5.0 之前就了解过提出的新增闭包等功能,但在看到 PHP5.3 提供的闭 包以及 Lambda 功能后,与原本心理期待的还是有些出入。

甚至相对于熟悉的 JavaScript,PHP 的闭包在我看来,像是“别的语言都有了,所以我也要有” 的这种心态下的产物。

但正如上文中所言,相比 JavaScript 等其他动态语言,PHP 出于自身的应用以及实现的哲学 出发,与其他开发语言不尽相同。

因此在某些特性的调用方式、实现方法也会不一样,这难免会让熟悉另外具有类似功能的语言 的人感到的不适应。

从 PHP5.3 推出至今,还不到半年的时间,相比 JavaScript 等这些早已具有闭包等特性的 动态语言相比,自然是显得非常稚嫩。

同时,广大的开发者对于 PHP5.3 提供的包括闭包在内的新特性还在持观望态度。PHP 的闭包特性目前还是存在于实验室中,其应用于实际开发如要突破的不仅仅是语言特性 ,还要经过效率、安全性等方面的考验。

但相信,如原文作者所言,随着 PHP 版本的推进,PHP 的闭包应用场合会越来越频繁。像 当年 PHP4 转换到 PHP5 一样,对语言新特性的适应,其实是种痛并快乐着的过程。

文章来源: www.2cto.com

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/486467.htmlTechArticlePHP5.3 新版本跟随了很多新特性, 其中比较惹眼的特性之一就是支持了闭包。那么以后,我们也可以和那帮写 Ruby、Javascript 等等高科技语言...
성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
PHP 실행 : 실제 예제 및 응용 프로그램PHP 실행 : 실제 예제 및 응용 프로그램Apr 14, 2025 am 12:19 AM

PHP는 전자 상거래, 컨텐츠 관리 시스템 및 API 개발에 널리 사용됩니다. 1) 전자 상거래 : 쇼핑 카트 기능 및 지불 처리에 사용됩니다. 2) 컨텐츠 관리 시스템 : 동적 컨텐츠 생성 및 사용자 관리에 사용됩니다. 3) API 개발 : 편안한 API 개발 및 API 보안에 사용됩니다. 성능 최적화 및 모범 사례를 통해 PHP 애플리케이션의 효율성과 유지 보수 성이 향상됩니다.

PHP : 대화식 웹 컨텐츠를 쉽게 만들 수 있습니다PHP : 대화식 웹 컨텐츠를 쉽게 만들 수 있습니다Apr 14, 2025 am 12:15 AM

PHP를 사용하면 대화식 웹 컨텐츠를 쉽게 만들 수 있습니다. 1) HTML을 포함하여 컨텐츠를 동적으로 생성하고 사용자 입력 또는 데이터베이스 데이터를 기반으로 실시간으로 표시합니다. 2) 프로세스 양식 제출 및 동적 출력을 생성하여 htmlspecialchars를 사용하여 XSS를 방지합니다. 3) MySQL을 사용하여 사용자 등록 시스템을 작성하고 Password_Hash 및 전처리 명세서를 사용하여 보안을 향상시킵니다. 이러한 기술을 마스터하면 웹 개발의 효율성이 향상됩니다.

PHP 및 Python : 두 가지 인기있는 프로그래밍 언어를 비교합니다PHP 및 Python : 두 가지 인기있는 프로그래밍 언어를 비교합니다Apr 14, 2025 am 12:13 AM

PHP와 Python은 각각 고유 한 장점이 있으며 프로젝트 요구 사항에 따라 선택합니다. 1.PHP는 웹 개발, 특히 웹 사이트의 빠른 개발 및 유지 보수에 적합합니다. 2. Python은 간결한 구문을 가진 데이터 과학, 기계 학습 및 인공 지능에 적합하며 초보자에게 적합합니다.

PHP의 지속적인 관련성 : 여전히 살아 있습니까?PHP의 지속적인 관련성 : 여전히 살아 있습니까?Apr 14, 2025 am 12:12 AM

PHP는 여전히 역동적이며 현대 프로그래밍 분야에서 여전히 중요한 위치를 차지하고 있습니다. 1) PHP의 단순성과 강력한 커뮤니티 지원으로 인해 웹 개발에 널리 사용됩니다. 2) 유연성과 안정성은 웹 양식, 데이터베이스 작업 및 파일 처리를 처리하는 데 탁월합니다. 3) PHP는 지속적으로 발전하고 최적화하며 초보자 및 숙련 된 개발자에게 적합합니다.

PHP의 현재 상태 : 웹 개발 동향을 살펴보십시오PHP의 현재 상태 : 웹 개발 동향을 살펴보십시오Apr 13, 2025 am 12:20 AM

PHP는 현대 웹 개발, 특히 컨텐츠 관리 및 전자 상거래 플랫폼에서 중요합니다. 1) PHP는 Laravel 및 Symfony와 같은 풍부한 생태계와 강력한 프레임 워크 지원을 가지고 있습니다. 2) Opcache 및 Nginx를 통해 성능 최적화를 달성 할 수 있습니다. 3) PHP8.0은 성능을 향상시키기 위해 JIT 컴파일러를 소개합니다. 4) 클라우드 네이티브 애플리케이션은 Docker 및 Kubernetes를 통해 배포되어 유연성과 확장 성을 향상시킵니다.

PHP 대 기타 언어 : 비교PHP 대 기타 언어 : 비교Apr 13, 2025 am 12:19 AM

PHP는 특히 빠른 개발 및 동적 컨텐츠를 처리하는 데 웹 개발에 적합하지만 데이터 과학 및 엔터프라이즈 수준의 애플리케이션에는 적합하지 않습니다. Python과 비교할 때 PHP는 웹 개발에 더 많은 장점이 있지만 데이터 과학 분야에서는 Python만큼 좋지 않습니다. Java와 비교할 때 PHP는 엔터프라이즈 레벨 애플리케이션에서 더 나빠지지만 웹 개발에서는 더 유연합니다. JavaScript와 비교할 때 PHP는 백엔드 개발에서 더 간결하지만 프론트 엔드 개발에서는 JavaScript만큼 좋지 않습니다.

PHP vs. Python : 핵심 기능 및 기능PHP vs. Python : 핵심 기능 및 기능Apr 13, 2025 am 12:16 AM

PHP와 Python은 각각 고유 한 장점이 있으며 다양한 시나리오에 적합합니다. 1.PHP는 웹 개발에 적합하며 내장 웹 서버 및 풍부한 기능 라이브러리를 제공합니다. 2. Python은 간결한 구문과 강력한 표준 라이브러리가있는 데이터 과학 및 기계 학습에 적합합니다. 선택할 때 프로젝트 요구 사항에 따라 결정해야합니다.

PHP : 웹 개발의 핵심 언어PHP : 웹 개발의 핵심 언어Apr 13, 2025 am 12:08 AM

PHP는 서버 측에서 널리 사용되는 스크립팅 언어이며 특히 웹 개발에 적합합니다. 1.PHP는 HTML을 포함하고 HTTP 요청 및 응답을 처리 할 수 ​​있으며 다양한 데이터베이스를 지원할 수 있습니다. 2.PHP는 강력한 커뮤니티 지원 및 오픈 소스 리소스를 통해 동적 웹 컨텐츠, 프로세스 양식 데이터, 액세스 데이터베이스 등을 생성하는 데 사용됩니다. 3. PHP는 해석 된 언어이며, 실행 프로세스에는 어휘 분석, 문법 분석, 편집 및 실행이 포함됩니다. 4. PHP는 사용자 등록 시스템과 같은 고급 응용 프로그램을 위해 MySQL과 결합 할 수 있습니다. 5. PHP를 디버깅 할 때 error_reporting () 및 var_dump ()와 같은 함수를 사용할 수 있습니다. 6. 캐싱 메커니즘을 사용하여 PHP 코드를 최적화하고 데이터베이스 쿼리를 최적화하며 내장 기능을 사용하십시오. 7

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
4 몇 주 전By尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

VSCode Windows 64비트 다운로드

VSCode Windows 64비트 다운로드

Microsoft에서 출시한 강력한 무료 IDE 편집기

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

WebStorm Mac 버전

WebStorm Mac 버전

유용한 JavaScript 개발 도구

안전한 시험 브라우저

안전한 시험 브라우저

안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경