About PHP closures
Generally PHP closures are constructions of an anonymous function (a function without a name) stored in variable. For example:
$records=someFunctionToGetAllRecords(); $getRecord = function($recNum)use($records){ return $records[$recNum]; } var_dump($getRecord(10)) //Will return a specified record from records array
Real life example
Let’s look at another real life example. Working with Guzzle http client I need to change proxy if a request failed and try the request again.
In runner class I create a method which accepts proxy list object and returns a logic how to get next proxy:
function nextProxy($proxyList){ return function()use($proxyList){ $proxyList->renewCurrentProxy(); return $proxyList->getCurrentProxy(); }; }
I create Guzzle retry middleware:
private function doRetry(RequestInterface $request, array $options, ResponseInterface $response = null) { .... $new_proxy=call_user_func($this->proxySwitcher); .... }
Here parameter $proxySwitcher contains the closure created above. I pass the closure this way:
function createHttpClient(Logger $logger, $proxyList) { $stack = HandlerStack::create(new CurlHandler()); $stack->push(\App\Scrapers\Middlewares\MyMiddleware::retry( ...... $this->nextProxy($proxyList) ) ); $client = new Client([ 'handler' => $stack, ]); ......... }
And middleware’s constructor
class MyMiddleware{ public function __construct( .... callable $nextProxy, .... ) { .... .... $this->proxySwitcher = $nextProxy; .... }
Conclusion
Regular variable allow you to pass a value or reference into a function. The main advantage of using closures is that you can pass logic of data processing inside another function. It makes your project more compact, readable and flexible.