Introduction to the PHP closure feature in Practical application

Source: Internet
Author: User
Tags php oop
The new version of PHP5.3 follows many new features. one of the most eye-catching features is the support for closures. In the future, can we write cool code like those who write Ruby, Javascript, and other "high-tech languages? Er, in most cases, it is possible, but some aspects are still very troublesome. let's take a look at it.
Many languages provide very elegant and beautiful methods for operating arrays. In the following example, the closure function provided by PHP5.3 and other languages is used to demonstrate how to "objectively" operate iterative arrays.
The author of the original article compares Mars. I don't know Groovy and Scala, so here I add Javascript implementation.
Before you start, let's explain that this example only clarifies your point of view and does not consider performance and other factors.

"Goods comparison three"

Starting with a simple example, we have the following array:
$ Nums = array (10, 20, 30, 40); you need to find more than 15 items in the array. If we do not consider the closure, we may write as follows:
$ Res = array (); foreach ($ nums as $ n) {if ($ n> 15) {$ res [] = $ n ;}} if the language itself supports closures, it may be written like this (Groovy language)
Def res = nums. findAll {it> 15} or use Scala
Val res = nums filter (_> 15) Annotation: Javascript 1.6 will be as follows
Var res = nums. filter (function (c) {return c> 15}); because loop operations have been abstracted, you can see Groovy, Scala (and Javascript) they can be done in a row.
Of course, if you use the closure of PHP5.3, you can also
$ Res = array_filter ($ nums, function ($ v) {return $ v> 15 ;}); PHP uses more characters than Scala in this respect, however, compared with the previous example, it is shorter and easier to read.

By the way, the above PHP code actually uses the Lambda analytical expression, not a real closure, which is not the focus of our current attention. For details about the PHP closure and Lambda analysis, refer to here.
At present, it seems that it is not bad, so we will make it more difficult to solve the problem: find all the items greater than 15, multiply by 2 and add a variable value in the scope, and then return.

Groovy implementation:
Def x = 1def res = nums. findAll {it> 15}. collect {it * 2 + x} Scala implementation:
Val x = 1val res = nums filter (_> 15) map (_ * 2 + x) annotation, Javascript implementation:
Var I = 1; var res = nums. filter (function (c) {return c> 15 }). map (function (c) {return c * 2 + I}); and PHP:
$ X = 1; $ res = array_map (function ($ v) use ($ x) {return $ v * 2 + $ x ;}, array_filter ($ nums, function ($ v) {return $ v> 15 ;}); from the aspect of the amount of code, it seems that PHP is different from other languages. Aside from the literal aesthetic of the code, the above PHP code has an additional problem.
For example, what if we need to use the array key instead of the value for comparison? Yes, the above code cannot be done. At the same time, from the syntax point of view, the above code is very difficult to read.

Back to the original, you still have to return to the old ideas to solve the problem:
$ X = 1; $ res = array (); foreach ($ nums as $ n) {if ($ n> 15) call {$ res [] = $ n * 2 + $ x;}, which looks clear again. But at this time, you may be confused: "What is it? isn't it an array operation ?".
Yes, it's still the beginning. At this time, some advanced features of PHP should be introduced to solve this seemingly self-defeating "Boring Problem ".

ArrayObject-encapsulation of arrays
PHP has a standard library called SPL, which contains a class called ArrayObject. it can provide the "like an array operation class" function, for example
$ Res = new ArrayObject (array (10, 20, 30, 40); foreach ($ res as $ v) {echo "$ vn ";} arrayObject is a built-in class, so you can encapsulate it like other class operations.

Arr-sugar coated

Now that we have the features of ArrayObject and closure, we can try to encapsulate it:
Class Arr extends ArrayObject {static function make ($ array) {return new self ($ array);} function map ($ func) {$ res = new self (); foreach ($ this as $ k =>$ v) {$ res [$ k] = $ func ($ k, $ v);} return $ res ;} function filter ($ func) {$ res = new self (); foreach ($ this as $ k => $ v) {if ($ func ($ k, $ v )) {$ res [$ k] = $ v;} return $ res ;}} now, everything is ready. The PHP code rewritten below can solve the problem mentioned above, and it seems that the syntax is "not much:

$ Res = Arr: make ($ nums)-> filter (function ($ k, $ v) {return $ v> 15 ;}) -> map (function ($ k, $ v) {return $ v * 2 ;}); what is the difference between the above code and the traditional method? First, they can be recursive and form a function chain call, so more similar operations can be added.

At the same time, you can use the two callback parameters to operate the keys of the array and the keys corresponding to the-$ k key and the corresponding values of $ v. This allows us to use the key value in the closure, which cannot be implemented in the traditional PHP function array_fliter.
The additional benefit is more consistent API calls. Using traditional PHP functions, they may be a closure, an array, or multiple arrays... Who knows?
Here is the complete source code of the Arr class, and it also contains other useful functions (similar to reduce and walk). In fact, their implementation method is similar to the code.

Game

This is actually hard to answer-it depends on the context of the code and the programmer's own and many other factors. In fact, when I first saw the PHP closure implementation, I felt like I was back to the Java period a long time ago. at that time, I began to use the anonymous built-in class (anonymous inner classes) to implement the closure. Of course, although this can be done, it seems to be a little superfluous. PHP closure itself is correct, but its implementation and syntax make me very confused.
Other languages with the closure feature can conveniently call the closure and have elegant syntax at the same time. In the above example, the traditional loop can also work in Scala, but will you write it like this? On the other hand, some people say that the above question can also be implemented using the closure of PHP, but will you write it like this in general?
It can be determined that the PHP closure can become a sharp military knife (such as delayed execution and resource calling) in some cases, but it is difficult for traditional iterations and array operations. Don't be discouraged. writing compatible and refreshing code and APIs is the most important thing.

Conclusion

Just like all the syntax features added later (do you remember the Java Generics feature? And the php oop features of the past few years), they all need time to work together and ultimately stabilize. As PHP5.3 and PHP6 become more popular in the future, more and more skills and features are believed to be gradually mined by smart programmers in the near future.
Return to the question at the beginning of the first article, and compare
$ Res = Arr: make ($ nums)-> filter (function ($ k, $ v) {return $ v> 15 ;}) -> map (function ($ k, $ v) {return $ v * 2 ;}); and
Val res = nums filter (_> 15) map (_ * 2. In the final analysis, they are just syntaxes. in essence, they all solve the same problem. If the application features of programming languages are different, the advantages and disadvantages of programming languages cannot be compared.
Finally, here is an example of the code in this article. I believe we can find more ideas on how to use PHP for functional iteration (not just that of course.

Experiences of unreliable bloggers
Frankly speaking, although I have learned about the new functions such as closures before PHP5.0, but after seeing the closed packages and Lambda functions provided by PHP5.3, it is somewhat different from what I originally expected.
Even compared to the familiar JavaScript, the closure of PHP seems to me to be a product of the mentality of "other languages are available, so I have.

However, as mentioned above, PHP is different from other development languages in terms of its own application and implementation philosophy than other dynamic languages such as JavaScript.

Therefore, the calling methods and implementation methods of some features are also different, which will inevitably make people familiar with other languages with similar functions uncomfortable.

It has been less than half a year since PHP5.3 was launched. compared with JavaScript and other dynamic languages that already have features such as closures, it is naturally very immature.

At the same time, the majority of developers are still waiting for the new features provided by PHP5.3, including closures. The closure feature of PHP still exists in the lab. it is applied to actual development. to break through not only the language features, but also the efficiency and security tests.
But I believe that, as the author of the original article said, with the advancement of the PHP version, the closure application of PHP will become more and more frequent. Like converting PHP4 to PHP5 in the past, adapting to new language features is actually a painful and happy process.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.