mirror of
https://github.com/codeguy/php-the-right-way.git
synced 2025-08-06 05:57:26 +02:00
Improve functional programming section
- Change criteria for filter - Extend the first example to show anonymous function without assignment - Add paragraph on recursion - Wrap to 120 chars
This commit is contained in:
@@ -5,8 +5,8 @@ isChild: true
|
|||||||
## Programming Paradigms
|
## Programming Paradigms
|
||||||
|
|
||||||
PHP is a flexible, dynamic language that supports a variety of programming techniques. It has evolved dramatically over
|
PHP is a flexible, dynamic language that supports a variety of programming techniques. It has evolved dramatically over
|
||||||
the years, notably adding a solid object-oriented model in PHP 5.0 (2004), anonymous functions and namespaces in PHP
|
the years, notably adding a solid object-oriented model in PHP 5.0 (2004), anonymous functions and namespaces in PHP 5.3
|
||||||
5.3 (2009), and traits in PHP 5.4 (2012).
|
(2009), and traits in PHP 5.4 (2012).
|
||||||
|
|
||||||
### Object-oriented Programming
|
### Object-oriented Programming
|
||||||
|
|
||||||
@@ -18,41 +18,52 @@ interfaces, inheritence, constructors, cloning, exceptions, and more.
|
|||||||
|
|
||||||
### Functional Programming
|
### Functional Programming
|
||||||
|
|
||||||
PHP supports first-class function, meaning that a function itself can be assigned to a variable, both user-defined and built-in. Those
|
PHP supports first-class function, meaning that a function can be assigned to a variable. Both user defined and built-in
|
||||||
functions referenced by a variable can be invoked dynamically. Functions can be passed as arguments to other functions (feature called
|
functions can be referenced by a variable and invoked dynamically. Functions can be passed as arguments to other
|
||||||
Higher-order functions) and function can return other functions.
|
functions (feature called Higher-order functions) and function can return other functions.
|
||||||
|
|
||||||
|
Recursion, a feature that allows a function to call itself is supported by the language, but most of the PHP code focus
|
||||||
|
on iteration.
|
||||||
|
|
||||||
New anonymous functions (with support for closures) are present since PHP 5.3 (2009).
|
New anonymous functions (with support for closures) are present since PHP 5.3 (2009).
|
||||||
|
|
||||||
The most common usage of higher-order functions is when implementing a strategy pattern. Built-in `array_filter` function asks both
|
The most common usage of higher-order functions is when implementing a strategy pattern. Built-in `array_filter`
|
||||||
for the input array (data) and a function (strategy, callback) used as a filter criteria on each array item.
|
function asks both for the input array (data) and a function (a strategy or a callback) used as a filter function on
|
||||||
|
each array item.
|
||||||
|
|
||||||
{% highlight php %}
|
{% highlight php %}
|
||||||
<?php
|
<?php
|
||||||
$input = array(1, 2, 3, 4, 5, 6);
|
$input = array(1, 2, 3, 4, 5, 6);
|
||||||
|
|
||||||
// Creates new anonymous function and assigns it to a variable
|
// Creates a new anonymous function and assigns it to a variable
|
||||||
$criteria_even = function($item) {
|
$filter_even = function($item) {
|
||||||
return ($item % 2) == 0;
|
return ($item % 2) == 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Built-in array_filter accepts both the data and the function
|
// Built-in array_filter accepts both the data and the function
|
||||||
$output = array_filter($input, $criteria_even);
|
$output = array_filter($input, $filter_even);
|
||||||
|
|
||||||
|
// The function doesn't need to be assigned to a variable. This is valid too:
|
||||||
|
$output = array_filter($input, function($item) {
|
||||||
|
return ($item % 2) == 0;
|
||||||
|
});
|
||||||
|
|
||||||
print_r($output);
|
print_r($output);
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Closure is an anonymous function that can access selected variables imported from the outside scope without using any global variables.
|
Closure is an anonymous function that can access variables imported from the outside scope without using any global
|
||||||
Theoretically, a closure is a function that has some arguments closed (like fixed) by the environment when the function is defined. This
|
variables. Theoretically, a closure is a function with some arguments closed (e.g. fixed) by the environment when it is
|
||||||
can be used to cross the variable scope restrictions in a very clean way.
|
defined. This is used to cross variable scope restrictions in a very clean way.
|
||||||
|
|
||||||
In the next example we use closures to define a function returning a single criteria function for `array_filter`, out of a family of
|
In the next example we use closures to define a function returning a single filter function for `array_filter`, out of
|
||||||
criteria functions.
|
a family of filter functions.
|
||||||
|
|
||||||
{% highlight php %}
|
{% highlight php %}
|
||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Creates an anonymous criteria function accepting items > $min
|
* Creates an anonymous filter function accepting items > $min
|
||||||
|
*
|
||||||
|
* Returns a single filter out of a family of "greater than n" filters
|
||||||
*/
|
*/
|
||||||
function criteria_greater_than($min)
|
function criteria_greater_than($min)
|
||||||
{
|
{
|
||||||
@@ -63,18 +74,19 @@ function criteria_greater_than($min)
|
|||||||
|
|
||||||
$input = array(1, 2, 3, 4, 5, 6);
|
$input = array(1, 2, 3, 4, 5, 6);
|
||||||
|
|
||||||
// Use array_filter on a input with a selected criteria function
|
// Use array_filter on a input with a selected filter function
|
||||||
$output = array_filter($input, criteria_greater_than(3));
|
$output = array_filter($input, criteria_greater_than(3));
|
||||||
|
|
||||||
print_r($output); // items > 3
|
print_r($output); // items > 3
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Each criteria function in the family accepts only elements greater than some minimum value. Single criteria returned by `criteria_greater_than`
|
Each filter function in the family accepts only elements greater than some minimum value. Single filter returned by
|
||||||
is a closure whith `$min` argument closed by the value existing in the scope (given as argument when `criteria_greater_than` is called).
|
`criteria_greater_than` is a closure whith `$min` argument closed by the value in the scope (given as an argument when
|
||||||
|
`criteria_greater_than` is called).
|
||||||
|
|
||||||
Early binding is used by default for importing `$min` variable into the created function. For true closures with late binding one should use
|
Early binding is used by default for importing `$min` variable into the created function. For true closures with late
|
||||||
a reference when importing. This can be used with some templating or input validation libraries, where anonymous function is defined to capture
|
binding one should use a reference when importing. Imagine a templating or input validation libraries, where closure is
|
||||||
out-of-scope variables and access them later when the anonymous function is evaluated.
|
defined to capture variables in scope and access them later when the anonymous function is evaluated.
|
||||||
|
|
||||||
PHP 5.4 added the ability to bind closures to an object's scope and also improved support for callables such that they
|
PHP 5.4 added the ability to bind closures to an object's scope and also improved support for callables such that they
|
||||||
can be used interchangeably with anonymous functions in almost all cases.
|
can be used interchangeably with anonymous functions in almost all cases.
|
||||||
|
Reference in New Issue
Block a user