PHP closures

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.