Home >Backend Development >PHP Tutorial >Functional Programming in PHP: Higher-order Functions
In-depth understanding of higher-order functions in PHP: improving code flexibility and reusability
Advanced functions are widely used in many large applications and frameworks. JavaScript, Java, .NET, Python and even PHP all support the concept of higher-order functions. But what are higher-order functions? Why do we use it? What are its advantages? How to simplify code with it? This article will focus on higher-order functions in PHP and compare them with other languages.
callable
can be used to identify higher-order functions. If a function or method has a callable
parameter, it means it accepts a function as input. array_map
and array_filter
. These functions take a callback function as an argument and apply it to elements of the array in different ways. calc()
takes several input functions and operates on several parameters. Before understanding higher-order functions, you must first understand the language characteristics that support first-class functions (also known as first-order functions). This means that the language treats the function as a first-class citizen. In other words, the language handles functions the same way as variables. You can store functions in variables, pass them as variables to other functions, return them from functions like variables, and even store them in arrays or object properties like you would with variables. Today, most modern languages have this feature by default. You just need to know that functions can be passed and used like variables.
This article will focus mainly on passing functions as parameters and returning functions as results, and briefly introduce the concepts of non-local variables and closures. (You can read more about these concepts in Sections 1.1, 1.4 and 1.3 of the Wikipedia articles linked to in the previous paragraph.)
Advanced-order functions have two main characteristics. Advanced functions can implement one or two of the following characteristics: accept one or more functions as input, or return a function as output. In PHP, there is a keyword that clearly shows that a function is a higher-order function: the keyword callable
. While this keyword does not necessarily exist, it makes it easy to recognize higher-order functions. If you see a function or method with callable
parameter, it means it accepts a function as input. Another simple flag is if you see a function using its return
statement to return a function. The return
statement may be just the name of the function, or it may be an anonymous/inline function. Here are some examples of each type.
<code class="language-php">// 我们将传递给高阶函数的简单用户定义函数 function echoHelloWorld() { echo "Hello World!"; } // 接受函数作为输入并调用它的高阶函数 function higherOrderFunction(callable $func) { $func(); } // 调用我们的高阶函数并传入我们的echoHelloWorld()函数。 // 请注意,我们只将名称作为字符串传递,没有括号。 // 这将输出 "Hello World!" higherOrderFunction('echoHelloWorld'); </code>
The following are some simple examples of higher-order functions that return functions:
<code class="language-php">// 返回PHP中名为trim()的现有函数。注意它是一个简单的字符串,没有括号。 function trimMessage1() { return 'trim'; } // 这是一个使用匿名内联函数的示例 function trimMessage2() { return function($text) { return trim($text); }; } // 返回'trim'函数 $trim1 = trimMessage1(); // 使用我们的字符串进行修剪并调用它 echo $trim1(' hello world '); // 返回内部调用'trim'的匿名函数 $trim2 = trimMessage1(); // 使用我们的字符串进行修剪并再次调用它 echo $trim2(' hello world ');</code>
You can imagine that you can pass in a function and use it to generate another returned function. Very clever trick, right? But why do you do this? It sounds like something that will make things more complicated.
There are many reasons why you may need to create higher-order functions in your code. From code flexibility, code reuse, code extension to code solutions that mimic the code you see in other programs, there are a lot of things. Although there are many reasons, we will introduce several of them here.
High-order functions add a lot of flexibility. Based on the previous example, you may have seen some uses. You can write a single function that takes a whole set of different functions and uses them without having to write code to execute them individually.
Maybe the higher-order function itself does not know what type of function it will receive. Who says a function must know any information about the function it receives? The input function may be a add()
function for a while, and the next moment it may be a divide()
function. In either case, it works fine.
This feature also makes it easier to add other input functions later. Suppose you have add()
and divide()
, but you need to add sum()
functions later. You can write sum()
functions and pass them through higher order functions without changing them. In the examples later, we will demonstrate how to use this function to create our own calc()
function.
Another reason you might want to use higher-order functions in PHP is to simulate the behavior of decorators in Python. You "wrape" one function in another to modify the behavior of that function. For example, you could write a function to time other functions. You can write a higher-order function that takes a function, starts a timer, calls it, and then ends the timer to see how much time has elapsed.
Search for finding higher-order functions in PHP is very simple. Check the PHP documentation and find a function/method that accepts the callable
input parameters and you've found one. Here are some examples of commonly used higher-order functions. You may have even used them without your knowledge.
array_map
and array_filter
<code class="language-php">// 我们将传递给高阶函数的简单用户定义函数 function echoHelloWorld() { echo "Hello World!"; } // 接受函数作为输入并调用它的高阶函数 function higherOrderFunction(callable $func) { $func(); } // 调用我们的高阶函数并传入我们的echoHelloWorld()函数。 // 请注意,我们只将名称作为字符串传递,没有括号。 // 这将输出 "Hello World!" higherOrderFunction('echoHelloWorld'); </code>
Let's see how to use another function, this time using the filter function we defined separately:
<code class="language-php">// 返回PHP中名为trim()的现有函数。注意它是一个简单的字符串,没有括号。 function trimMessage1() { return 'trim'; } // 这是一个使用匿名内联函数的示例 function trimMessage2() { return function($text) { return trim($text); }; } // 返回'trim'函数 $trim1 = trimMessage1(); // 使用我们的字符串进行修剪并调用它 echo $trim1(' hello world '); // 返回内部调用'trim'的匿名函数 $trim2 = trimMessage1(); // 使用我们的字符串进行修剪并再次调用它 echo $trim2(' hello world ');</code>
array_filter
and array_map
are two very popular higher order functions you will find in many code projects. Another function you might use is call_user_func
, which takes a function and a list of parameters and calls that function. This is essentially a custom higher-order function. Its entire purpose is to call other user-defined functions:
<code class="language-php">$arrayOfNums = [1,2,3,4,5]; // array_map:使用内联匿名函数的示例 $doubledNums = array_map(function($num) { return $num * 2; }, $arrayOfNums); var_dump($doubledNums); // 输出包含 [2, 4, 6, 8, 10] 的数组</code>
We have shown many examples of how higher-order functions work in PHP, and we have created some custom functions to demonstrate their various uses. But let's further demonstrate its flexibility with a new function called calc()
. This function will receive two parameters and a function, which will operate on these two parameters to give us a result:
<code class="language-php">$arrayOfNums = [1,2,3,4,5]; // 创建函数并将其提供给高阶函数array_filter()的示例 function isEven($num) { return ($num % 2) === 0; } // array_filter是一个高阶函数 $evenNums = array_filter($arrayOfNums, 'isEven'); var_dump($evenNums); // 输出包含 [2, 4] 的数组</code>
Note that our calc()
functions are written in a very general way, allowing you to receive a set of other functions and call them with the parameters $n1
and $n2
. In this case, our computed function does not care what the function it receives does. It just passes the argument to the function and returns the result.
But wait: Our boss just asked us to add a function to the existing system to add two strings together. But concatenating strings are not your typical math operation. However, with our settings here, we just need to add the string concatenation and pass it through calc()
:
<code class="language-php">function printCustomMessage($message) { echo "$message"; } call_user_func('printCustomMessage', '通过使用call_user_func调用自定义消息!');</code>
Although this example is far-fetched, it demonstrates how you can use this concept in a large project. Perhaps higher-order functions determine how events are processed. Perhaps, depending on the triggered event, you can route it through the handler function you passed in. The possibilities are endless.
Let's take a simple decorator in Python as an example and compare it with JavaScript and then compare it with PHP. That way, if you know Python or JS, you can see that it is equivalent.
<code class="language-php">function add($a, $b) { return $a + $b; } function subtract($a, $b) { return $a - $b; } function multiply($a, $b) { return $a * $b; } // 传递$n1和$n2的高阶函数 function calc($n1, $n2, $math_func) { return $math_func($n1, $n2); } $addedNums = calc(1, 5, 'add'); $subtractedNums = calc(1, 5, 'subtract'); $multipliedNums = calc(1, 5, 'multiply'); // 输出 6 echo "相加的数字:$addedNums\n"; // 输出 -4 echo "相减的数字:$subtractedNums\n"; // 输出 5 echo "相乘的数字:$multipliedNums\n";</code>
Now let's see how to implement this in JavaScript higher-order functions:
<code class="language-php">function addTwoStrings($a, $b) { return $a . " " . $b; } // 输出 "Hello World!" $concatenatedStrings = calc('Hello', 'World!', 'addTwoStrings');</code>
Finally, let's compare it to PHP:
<code class="language-python">def say_message(func): def wrapper(): print('调用函数之前打印') func() print('调用函数之后打印') return wrapper def say_hello_world(): print("Hello World!") # 将我们的hello world函数传递给say_message函数。 # 它返回一个函数,然后我们可以调用它 # 注意:这一行可以用say_hello_world方法上的@say_message(派语法)代替 say_hello_world = say_message(say_hello_world) # 调用创建的函数 say_hello_world() # 输出... # 调用函数之前打印 # Hello World! # 调用函数之后打印</code>
From the side-by-side comparison, we can see that the PHP version is very similar to the JavaScript syntax. However, if you know a little about Python and decorator, you can see how to convert a decorator to one of two other programming languages.
When using higher order functions, you often see the use of inline anonymous functions (also known as lambdas). In the example we saw above, I have used this format. Apart from that, I also used a more explicit version of first defining the function and then passing it to a higher order function. This is to get used to seeing both versions. Most of the time, you will see inline lambda versions in frameworks that use high-order functions. Don't let this format scare you. They just create a simple function without a name and use it for where you provide the independent function name.
In this article, we introduce the basic definition of making a function a higher-order function. Any function that accepts or returns a function (or both) can be considered a higher-order function. We also discuss why you might want to create these types of functions and their advantages.
Then, we show some examples of existing higher-order functions in PHP, such as array_map
and array_filter
, and then proceed to create our own higher-order function called calc()
, which accepts several inputs function and operate on several parameters. We then did a side-by-side comparison to show how PHP's solution compares to Python decorator and JavaScript implementations. I hope you can learn more about higher order functions and why you might need to consider them in your next large solution. They can provide many advantages and reduce boilerplate code that may be redundant.
If you want to learn more about functional programming in PHP, you can refer to our tutorial.
Thank you for reading!
High-order functions in PHP are a basic concept in functional programming. They are functions that can operate on other functions by taking them as arguments or returning them as results. This allows for more abstract and concise code, thus improving readability and maintainability. Advanced-order functions can help reduce code duplication and complexity, making your code more efficient and easier to debug.
Normal functions in PHP perform specific tasks and return results. On the other hand, higher-order functions can take one or more functions as parameters, return functions as results, or have these two characteristics at the same time. This allows for greater flexibility and abstraction in your code, allowing you to create more complex functions with less code.
Of course, let's consider the array_map
function in PHP, which is a higher order function. It takes the callback function and array as parameters, applies the callback function to each element of the array, and returns a new array containing the results.
<code class="language-php">// 我们将传递给高阶函数的简单用户定义函数 function echoHelloWorld() { echo "Hello World!"; } // 接受函数作为输入并调用它的高阶函数 function higherOrderFunction(callable $func) { $func(); } // 调用我们的高阶函数并传入我们的echoHelloWorld()函数。 // 请注意,我们只将名称作为字符串传递,没有括号。 // 这将输出 "Hello World!" higherOrderFunction('echoHelloWorld'); </code>
High-order functions in PHP provide multiple benefits. They allow for more abstract and concise code, which can improve readability and maintainability. They can also help reduce code duplication and complexity, making your code more efficient and easier to debug. Furthermore, higher-order functions can facilitate code reuse because you can pass different functions to higher-order functions to achieve different behaviors.
While higher-order functions provide many benefits, they may also have some disadvantages. They sometimes make code difficult to understand and debug, especially for developers who are not familiar with the concept of functional programming. Furthermore, using higher-order functions can sometimes lead to performance overhead, as they often involve creating and calling other functions.
Creating your own higher-order function in PHP requires defining a function that can accept one or more functions as parameters, return the function as a result, or have both characteristics. Here is a simple example of a simple higher order function that takes a function as an argument and applies it to a value:
<code class="language-php">// 返回PHP中名为trim()的现有函数。注意它是一个简单的字符串,没有括号。 function trimMessage1() { return 'trim'; } // 这是一个使用匿名内联函数的示例 function trimMessage2() { return function($text) { return trim($text); }; } // 返回'trim'函数 $trim1 = trimMessage1(); // 使用我们的字符串进行修剪并调用它 echo $trim1(' hello world '); // 返回内部调用'trim'的匿名函数 $trim2 = trimMessage1(); // 使用我们的字符串进行修剪并再次调用它 echo $trim2(' hello world ');</code>
Yes, higher-order functions in PHP can return multiple functions. This is usually done by returning an array of functions. However, remember that each returned function has its own scope and does not share variables with other returned functions.
Yes, higher-order functions in PHP can accept functions from different scopes. This is because PHP supports first-class functions, which means that functions can be passed as parameters to other functions, returned by other functions, and assigned to variables.
Closures in PHP are an anonymous function that capture variables in surrounding scopes. They are often used with higher-order functions because they allow the creation of functions that access more data than their parameters. This is very useful for creating more flexible and reusable code.
Yes, PHP provides some built-in higher-order functions. Some examples include array_map
, array_filter
and array_reduce
. These functions take the callback function as an argument and apply it to the elements of the array in various ways.
The above is the detailed content of Functional Programming in PHP: Higher-order Functions. For more information, please follow other related articles on the PHP Chinese website!