JS programmers always laugh at PHP for not having closures. Today I took the time to write an article to specifically introduce closures in PHP. PHP has added support for anonymous functions since version 5.3. After several versions and iterations to the current PHP5.6 and PHP7, the closure of the PHP language has been very complete. Combined with the event-driven support provided by Swoole, PHP's closure function is very powerful and elegant.
The anonymous function is the core of the closure. The anonymous function in PHP is actually an object of the Closure class (please note that it is an object) . Different from ordinary object-oriented programming, the code of the anonymous function is written directly at the calling point. There is no need to write an additional class or write the code of the method. The advantage of this is that it is more direct. The following example sets a timer to output hello world every 2 seconds.
Traditional writing method
function timer () { echo "hello world"; } Swoole\Timer::tick(2000, 'timer');
Closure writing method
Swoole\Timer::tick(2000, function () { echo "hello world"; });
Traditional writing method of non-closure, you must declare it first A function, and then enter the function name string. The two pieces of code are separated and not intuitive enough. The closure method writes the declaration of the timer and the code to be executed by the timer together, and the logic is very clear and intuitive. Using closure syntax makes it easy to write callback functions. In scenarios such as event-driven programming, sorting, array_walk, etc. that require users to pass in a piece of execution code, closures are written very elegantly.
The more powerful thing about closure is that it can introduce external variables directly at the call site. The method implemented in PHP is the use keyword.
If the timer just now needs to pass in a variable, the traditional writing method can only be achieved through global variables. Unlike JS, PHP's variable introduction is explicit. If you want to reference external variables, you must use use to declare them. JS is implicit, and external variables can be freely manipulated inside anonymous functions without declaration. The advantage of this is that you write less code, but the disadvantage is that it is risky and confusing.
Traditional writing method
$str = "hello world"; function timer () { global $str; echo $str; } Swoole\Timer::tick(2000, 'timer');
Closure writing method
$str = "hello world"; Swoole\Timer::tick(2000, function () use ($str) { echo $str; });
The closure writing method uses use to directly introduce the current $str variable , without using global global variables. In addition, if you are in the event-driven programming mode of swoole, you cannot achieve asynchronous concurrency using global, because there is only one global global variable. If there are multiple client requests at the same time, each request must query the database and output different content. Traditional The programming method is not easy to implement. You need to use a global variable array to save the respective data with the client's ID as the KEY.
Traditional writing method
$requestArray = array(); $dbResultArray = array(); function my_request($request, $response) { global $dbResultArray, $requestArray; $queryId = $db->query($sql, 'get_result'); $requestArray[$request->fd] = array($request, $response); $dbResultArray[$queryId] = $request->fd; } function get_result($queryId, $queryResult) { global $dbResultArray, $requestArray; list($request, $response) = $requestArray[$dbResultArray[$queryId]]; $response->end($queryResult); } $server->on('request', 'my_request');
Closure writing method
$server->on('request', function ($request, $response) { $queryId = $db->query($sql, function ($queryId, $queryResult) use ($request, $response) { $response->end($queryResult); }); });
The traditional writing method is very complicated and needs to be repeated many times from the global array Save/extract data. The closure is written very concisely and elegantly, and it only takes a few lines of code to achieve the same function. Closure writing is very suitable for writing server programs in asynchronous non-blocking callback mode. Among the currently popular programming languages, only PHP and JS have this capability.
Use anonymous functions in class methods. Versions 5.4 and above do not need to use use to introduce $this, you can directly use anonymous functions Use $this in the function to call the method of the current object. In swoole programming, this feature can be used to reduce the use introduction and passing of the $serv object.
class Server extends Swoole\Server { function onReceive($serv, $fd, $reactorId, $data) { $db->query($sql, function ($queryId, $queryResult) use ($fd) { $this->send($fd, $queryResult); } } }
In addition, if you want to modify external variables in the closure function, you can add the & reference symbol to the variable when using. Note that the object type does not need to be added, because in PHP objects are passed by reference instead of value by default.
For more PHP related knowledge, please visit PHP Chinese website!
The above is the detailed content of How to write closures in PHP+Swoole. For more information, please follow other related articles on the PHP Chinese website!