mirror of
https://github.com/codeguy/php-the-right-way.git
synced 2025-08-21 04:41:40 +02:00
Merge pull request #67 from grakic/gh-pages_functional
Extends the functional paradigm section.
This commit is contained in:
@@ -5,8 +5,8 @@ isChild: true
|
||||
## Programming Paradigms
|
||||
|
||||
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
|
||||
5.3 (2009), and traits in PHP 5.4 (2012).
|
||||
the years, notably adding a solid object-oriented model in PHP 5.0 (2004), anonymous functions and namespaces in PHP 5.3
|
||||
(2009), and traits in PHP 5.4 (2012).
|
||||
|
||||
### Object-oriented Programming
|
||||
|
||||
@@ -18,23 +18,22 @@ interfaces, inheritence, constructors, cloning, exceptions, and more.
|
||||
|
||||
### Functional Programming
|
||||
|
||||
PHP has had support for anonymous functions and closures since PHP 5.3:
|
||||
PHP supports first-class function, meaning that a function can be assigned to a variable. Both user defined and built-in
|
||||
functions can be referenced by a variable and invoked dynamically. Functions can be passed as arguments to other
|
||||
functions (feature called Higher-order functions) and function can return other functions.
|
||||
|
||||
{% highlight php %}
|
||||
<?php
|
||||
$greet = function($name)
|
||||
{
|
||||
print("Hello {$name}");
|
||||
};
|
||||
Recursion, a feature that allows a function to call itself is supported by the language, but most of the PHP code focus
|
||||
on iteration.
|
||||
|
||||
$greet('World');
|
||||
{% endhighlight %}
|
||||
New anonymous functions (with support for closures) are present since PHP 5.3 (2009).
|
||||
|
||||
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.
|
||||
|
||||
* Continue reading on [Functional Programming in PHP](/pages/Functional-Programming.html)
|
||||
* [Read about Anonymous Functions][anonymous-functions]
|
||||
* [Read about the Closure class][closure-class]
|
||||
* [More details in the Closures RFC][closures-rfc]
|
||||
* [Read about Callables][callables]
|
||||
* [Read about dynamically invoking functions with `call_user_func_array`][call-user-func-array]
|
||||
|
||||
@@ -58,3 +57,4 @@ available as `__call()` and `__callStatic()`.
|
||||
[reflection]: http://www.php.net/manual/en/intro.reflection.php
|
||||
[traits]: http://www.php.net/traits
|
||||
[call-user-func-array]: http://php.net/manual/en/function.call-user-func-array.php
|
||||
[closures-rfc]: https://wiki.php.net/rfc/closures
|
||||
|
87
pages/Functional-Programming.md
Normal file
87
pages/Functional-Programming.md
Normal file
@@ -0,0 +1,87 @@
|
||||
---
|
||||
layout: page
|
||||
title: Functional Programming in PHP
|
||||
---
|
||||
|
||||
# Functional Programming in PHP
|
||||
|
||||
PHP supports first-class function, meaning that a function can be assigned to a variable. Both user defined and built-in
|
||||
functions can be referenced by a variable and invoked dynamically. Functions can be passed as arguments to other
|
||||
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).
|
||||
|
||||
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.
|
||||
|
||||
The most common usage of higher-order functions is when implementing a strategy pattern. Built-in `array_filter`
|
||||
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 %}
|
||||
<?php
|
||||
$input = array(1, 2, 3, 4, 5, 6);
|
||||
|
||||
// Creates a new anonymous function and assigns it to a variable
|
||||
$filter_even = function($item) {
|
||||
return ($item % 2) == 0;
|
||||
};
|
||||
|
||||
// Built-in array_filter accepts both the data and the function
|
||||
$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);
|
||||
{% endhighlight %}
|
||||
|
||||
Closure is an anonymous function that can access variables imported from the outside scope without using any global
|
||||
variables. Theoretically, a closure is a function with some arguments closed (e.g. fixed) by the environment when it is
|
||||
defined. Closures can work around variable scope restrictions in a clean way.
|
||||
|
||||
In the next example we use closures to define a function returning a single filter function for `array_filter`, out of
|
||||
a family of filter functions.
|
||||
|
||||
{% highlight php %}
|
||||
<?php
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
return function($item) use ($min) {
|
||||
return $item > $min;
|
||||
};
|
||||
}
|
||||
|
||||
$input = array(1, 2, 3, 4, 5, 6);
|
||||
|
||||
// Use array_filter on a input with a selected filter function
|
||||
$output = array_filter($input, criteria_greater_than(3));
|
||||
|
||||
print_r($output); // items > 3
|
||||
{% endhighlight %}
|
||||
|
||||
Each filter function in the family accepts only elements greater than some minimum value. Single filter returned by
|
||||
`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 a reference when importing. Imagine a templating or input validation libraries, where closure is
|
||||
defined to capture variables in scope and access them later when the anonymous function is evaluated.
|
||||
|
||||
* [Read about Anonymous functions][anonymous-functions]
|
||||
* [More details in the Closures RFC][closures-rfc]
|
||||
* [Read about dynamically invoking functions with `call_user_func_array`][call-user-func-array]
|
||||
|
||||
[anonymous-functions]: http://www.php.net/manual/en/functions.anonymous.php
|
||||
[call-user-func-array]: http://php.net/manual/en/function.call-user-func-array.php
|
||||
[closures-rfc]: https://wiki.php.net/rfc/closures
|
Reference in New Issue
Block a user