Skip to content
Advertisement

Add a callback closure to a class constructor

I have a class that someone else wrote. It does a lot of things for me, and one thing it does for me is it makes requests to an external service.

public function makeRequest() {
   ...bunch of curl stuff here
}

So what I wanted to do is modify the constructor of the class so that I could pass in a function, and the function could get called after the curl stuff. I come from a javascript background so I’m definitely doing this the wrong way, but this is what I did:

private $requestLogger;
public function __construct(...other variables, $requestLogger = null) {
   if ($requestLogger) {
      $this->requestLogger = $requestLogger;
   }
}

public function makeRequest() {
   ...bunch of curl stuff here
   if ($this->requestLogger) {
            $curlInfo = curl_getinfo($ch);
            $this->requestLogger($curlInfo['url'], $curlInfo['http_code'], $request, $response);
   }
}

And that when when I make a new instance, I can do it like this

$client = new ApiClient(..., function($url, $responseCode, $requestText, $responseText){
   // do whatever i want here
});

However, this hasn’t worked. I get this message: 500: Call to undefined method ApiClient::requestLogger()

How do I set myself up to pass a callback function to this class?

Advertisement

Answer

When you do: $this->requestLogger(...), PHP thinks you’re trying to call a class method called requestLogger().

If you want to call a function in a class property, you can use call_user_func_array(). Something like this:

call_user_func_array($this->requestLogger, [
    $curlInfo['url'], 
    $curlInfo['http_code'], 
    $request, 
    $response
]);

A tip, before trying to call it, make sure it contains something that’s callable and not just empty:

if (is_callable($this->requestLogger)) {
    call_user_func_array(...);
}
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement