The new version of PHP5.3 follows a number of new features, one of the more eye-catching features that support closures. So can we write cool code like those guys who write Ruby, Javascript, and so on in the High-tech language? Well, in fact most of the time it is possible, and some aspects are still very disturbing, the following slowly.
The new version of PHP5.3 follows a number of new features, one of the more eye-catching features that support closures. So can we write very cool code like the guys who write Ruby, Javascript, etc. "High-tech languages"? Well, in fact most of the time it is possible, and some aspects are still very disturbing, the following slowly.
Many languages provide a very elegant and beautiful way to manipulate arrays. In the following example, the closure features provided in PHP5.3 and other languages are used to show how to "objectively" manipulate an iterative group of algebras.
The original author compares Mars, I do not know Groovy and Scala language, so here I add Javascript implementation.
Before you begin, this example simply clarifies the point of view and does not take into account other factors such as performance.
"Compare"
Starting with a simple example, there are the following arrays:
$nums = Array (10, 20, 30, 40);
You need to find an item that is greater than 15 in the array. So, without considering closures, we might write this:
$res = Array ();
foreach ($nums as $n) {
if ($n > 15) {
$res [] = $n;
}
}
If the language itself is supported by closures, it may be written like this (Groovy language)
def res = Nums.findall {it > 15}
or use the Scala language
Val res = nums Filter (_ > 15)
Javascript 1.6 would be as follows
var res = Nums.filter (function (c) {return c > 15});
Because loops are abstracted, you can see Groovy, Scala (and Javascript) as pretty as you can get it done in one line.
Of course, if you use a PHP5.3 closure, you can also do
$res = Array_filter ($nums, function ($v) {return $v > 15;});
PHP uses more characters than Scala in this area, but compared to previous examples, it's shorter and better read.
By the way, the PHP code above is actually using LAMBDA parsing, not a real closure, which is not the focus of our current focus. Detailed description of the PHP closures and Lambda analytic data, you can refer to here.
It seems to be all right at the moment, so we add a bit more difficulty to the topic: find all items greater than 15, then multiply by 2 and then return with a variable value in the scope.
Groovy's implementation:
def x = 1
def res = nums. findall {it >}. collect {It * 2 + x}
Scala's implementation:
val x = 1
Val res = nums Filter (_ >) Map (_ * 2 + x)
The realization of Javascript:
var i = 1;
var res = Nums.filter (function (c) {return c >}). 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;})
);
Light from the amount of code, it now seems that PHP is different from other languages. The first thing to do is to put aside the aesthetic of the code literally, the PHP code above has an additional problem.
For example, what if you need to use an array of keys instead of a value for comparison? Yes, the code above can't be done. At the same time, from a grammatical point of view, the above code is very difficult to read.
Back to basics, then still have to return to the old-fashioned way of thinking to solve the problem:
$x = 1;
$res = Array ();
foreach ($nums as $n) {
if ($n > 15) {
$res [] = $n * 2 + $x;
}
}
Hoo, it looks so clear again. But this time you may be confused again: "That is also a blind toss what, this is not the array operation?" ”。
Yes, the show is still behind me. This is the time to get some of PHP's advanced features out there to take care of this "boring problem" that seems to be a self-inflicted tendency.
encapsulation of arrayobject– arrays
PHP has a standard library called SPL, which contains a class called Arrayobject, which provides the ability to "manipulate classes like arrays", such as
$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 any other class class operation.
ARR-icing on the bag
Now that we have the Arrayobject and closure features, we can start trying 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;
}
}
All right, everything's ready. The following rewrite of the PHP code can solve the problem mentioned above, and looks syntactically "almost":
$res = Arr::make ($nums)
->filter (function ($k, $v) {return $v > 15;})
->map (function ($k, $v) {return $v * 2;});
How does the above code differ from the traditional approach? First, they can be recursive to form action-chained calls, so you can add more similar operations.
At the same time, you can manipulate the key of the array and its items-$k corresponding keys and $v corresponding values-by using the callback's two parameters. This allows us to use the key value in the closure, which is not possible in the traditional PHP function Array_fliter.
Another added bonus is a more consistent API invocation. Using traditional PHP function operations, it is possible that the first parameter is a closure, or a array, or multiple arrays ... Anyway, who knows?
This is the complete source code for the Arr class and includes other useful functions (such as reduce and walk), but they are actually implemented in the same way as the code.
Game
This is a difficult question to answer-it depends on the context of the code and many factors, such as the programmer itself. In fact, when I first saw PHP's closure implementation, I felt like I was back in the Java period that long ago, when I started using anonymous built-in classes (anonymous inner classes) to implement closures. Of course, although this can be done, but it seems to be a little superfluous. The PHP closure itself is true, but its implementation and syntax make me feel very confused.
Other languages that have closure characteristics, which can easily invoke closures and have elegant syntax at the same time. In the example above, using a traditional loop in Scala can work, but do you write that? On the other side, it is said that the above topic can also be implemented using a PHP closure, but would you normally write this?
It is certain that a PHP closure can be a sharp saber in some cases (such as deferred execution and resource invocation), but it is somewhat awkward in the face of traditional iterations and array operations. Don't be discouraged anyway, writing a compatible, refreshing code and API is the most important.
Concluding remarks
Like all the syntax features that were added later (remember the generics features of Java?) As well as the PHP OOP features of previous years), they all need time to break and eventually stabilize. As PHP5.3 and even future PHP6 become popular, more and more skills and features are believed to be gradually tapped by intelligent programmers in the near future.
Back to the beginning of the original article, the topic, contrast
$res = Arr::make ($nums)
->filter (function ($k, $v) {return $v > 15;})
->map (function ($k, $v) {return $v * 2;});
And
Val res = nums Filter (_ >) Map (_ * 2)
The difference between the two. In the final analysis, they are only grammar, and in essence they solve the same problem. The application characteristics of the program language are different, the nature is superior to the inferior is also impossible to compare.
Finally, here's a code example for this article, and I'm sure we can find out more about how to use PHP for functional iterations (not just those).
--Split--
The main experience of the unreliable bloggers
Frankly, although PHP5.0 before the proposed new closures and other functions, but see PHP5.3 provided by the closure and Lambda function, with the original psychological expectations or some discrepancy.
Even the closure of the familiar javascript,php seems to me to be the product of the mentality of "other languages are there, so I have to have".
But as noted above, PHP is different from other development languages in terms of its own application and philosophy of implementation than other dynamic languages such as JavaScript.
Therefore, the way in which some features are invoked and implemented is different, which makes it difficult for people familiar with other languages with similar functions to feel uncomfortable.
Since the launch of the PHP5.3, less than half a year, compared to JavaScript, such as these already have closures and other characteristics of the dynamic language, natural is very immature.
At the same time, the vast majority of developers are still on the sidelines for PHP5.3 's new features, including closures. PHP's closure characteristics are still present in the laboratory, its application in practical development such as to break through not only the language characteristics, but also through efficiency, security and other aspects of the test.
But believe that, as the original author said, with the PHP version of the push, PHP closures will be more frequent applications. As PHP4 converted to PHP5, adapting to the new features of the language is a process of pain and happiness.