📜 ⬆️ ⬇️

A good example of using closures in PHP

Starting with version 5.3, PHP allows you to create closures. Unfortunately, an example of their use in official documentation http://www.php.net/manual/en/functions.anonymous.php#example-163 (example 3) has a rare sophistication and artificiality. I hope, the example under the cut will help to see another use in closures, except with functions like array_map ().

The most common method for increasing application performance is caching, and usually its implementation is as follows:
<?php Class Cache { static function set( $key, $value) { //     } static function get( $key ) { //     } } Class PostModel { static function getList($dateCreated) { //       } } $dateCreated = date('Ym-d'); $posts = Cache::get("posts_" . $dateCreated); if( !$posts ) { $posts = PostModel::getList($dateCreated); Cache::set( "posts_" . $dateCreated , $posts); } ?> 


We try to get data from the cache, if the data is not found - we make a query to the database and write the result to the cache. The logic is almost the same every time and I would like to write a universal wrapper for such cases, but how to transfer to it not just a variable, but a piece of code that should be executed already inside the wrapper, i.e. delayed?

And here the closures come to the rescue, in order to pass to the function (or method) a piece of code for deferred execution it needs to be wrapped with an anonymous function.
 <?php $dateCreated = date('Ym-d'); $dbQueryCounter = 0; $fallback = function() use($dateCreated, &$dbQueryCounter) { $dbQueryCounter++; //      return PostModel::getList($dateCreated); //   return }; Cache::wrapper( "posts_" . $dateCreated , $fallback ); Class Cache { static function set( $key, $value) { //     } static function get( $key ) { //     } static function wrapper( $key, Closure $fallback ) { $data = self::get( $key ); if( !$data ) { $data = $fallback(); //    self::set( $key, $data); } return $data; } } ?> 

What you need to pay attention to in this code:
  1. Using closures, you can pass to a method (function) or return from it a fragment of ready-to-execute code, with local variables from the environment where this code is declared.
  2. If the code that we pass to the method for deferred execution, must return data - do not forget about the return in the closure.
  3. Together with the code snippet, through the closure, you can pass all the necessary variables from the context where this code is used using the use keyword - this is the fundamental difference between the declaration of an anonymous function in PHP 5.3 and the use of create_function () in earlier versions.
  4. Variables are imported into a closure by value , so if you need to change a variable inside the closure (for example, the $ dbQueryCounter counter), then you need to import it by reference.
  5. Anonymous functions in PHP5.3 are instances of the Closure class — this circumstance can be used to control the type of variable passed to the method.

')

Source: https://habr.com/ru/post/145317/


All Articles