|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #77535 Invalid callback, h2 server push
Submitted: 2019-01-28 19:21 UTC Modified: 2019-03-15 18:22 UTC
From: tobias dot nyholm at gmail dot com Assigned: pmmaga (profile)
Status: Closed Package: cURL related
PHP Version: master-Git-2019-01-28 (Git) OS:
Private report: No CVE-ID: None
 [2019-01-28 19:21 UTC] tobias dot nyholm at gmail dot com
When I set my callback in a different function I get a warning. I cannot figure out why. 

If I move the contents of addServerPushCallback() to sendRequest() then I wont have the same issue. 

Test script:

class MyHttpClient
    private $mh;
    private $curl;

    public function sendRequest()
        if (false === $this->mh = curl_multi_init()) {
            throw new \RuntimeException('Unable to create a new cURL multi handle');

        // FIXME Using a function like this does not work. If we inline the contents of addServerPushCallback(), then we got no problem

        $this->curl = curl_init();
        curl_setopt($this->curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
        curl_setopt($this->curl, CURLOPT_HEADER, false);
        curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, false);
        curl_setopt($this->curl, CURLOPT_FAILONERROR, false);
        curl_setopt($this->curl, CURLOPT_URL, '');
        curl_setopt($this->curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);

        curl_setopt($this->curl, CURLOPT_HEADERFUNCTION, function ($ch, $data) {
            return \strlen($data);

        curl_setopt($this->curl, CURLOPT_WRITEFUNCTION, function ($ch, $data) {
            return \strlen($data);

        curl_multi_add_handle($this->mh, $this->curl);

        $stillRunning = null;
        while (true) {
            do {
                $mrc = curl_multi_exec($this->mh, $stillRunning);
            } while (CURLM_CALL_MULTI_PERFORM === $mrc);

            $info = curl_multi_info_read($this->mh);
            while (false !== $info && $info['msg'] == CURLMSG_DONE) {
                if (CURLMSG_DONE !== $info['msg']) {
                die("Start handle request. ");

    private function addServerPushCallback(): void

        $callback = static function () {
            return CURL_PUSH_OK;

        curl_multi_setopt($this->mh, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
        curl_multi_setopt($this->mh, CURLMOPT_PUSHFUNCTION, $callback);

$buzz = new MyHttpClient();

Expected result:
Output only "Start handle request."

Actual result:
Warning: Invalid callback , no array or string given in /usr/src/myapp/test.php on line 40

Warning: curl_multi_exec(): Cannot call the CURLMOPT_PUSHFUNCTION in /usr/src/myapp/test.php on line 40


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2019-01-28 20:41 UTC]
What about if you have the code in sendRequest and use

curl_multi_setopt($this->mh, CURLMOPT_PUSHFUNCTION, static function () {
  return CURL_PUSH_OK;

without putting the callback into a variable?
 [2019-01-28 20:53 UTC] tobias dot nyholm at gmail dot com

If I don't use a variable and I set CURLMOPT_PUSHFUNCTION in sendRequest() then I also get the warning.
 [2019-01-28 21:05 UTC] tobias dot nyholm at gmail dot com
Btw, You can test this with this repo:

There is a test called "test77535.php"
 [2019-01-28 21:12 UTC]
IIRC, and according to the warning, the current implementation is only accepting callables but not Closures. If you make the callback as a named function it should be possible to set it up.
 [2019-01-28 21:39 UTC] tobias dot nyholm at gmail dot com
Using a callback like "[$this, '_callback']" does not work. I did manage to declare a global function foobar() and use "foobar" as callback. But that seams suboptimal.
 [2019-02-02 13:04 UTC] tobias dot nyholm at gmail dot com
I think I've figured it out. (Or, I got help figure this out)

It is related to the garbage collector. If I do $this->tmp   $callback = function.... Then I've got not issues.
 [2019-03-15 16:10 UTC]
I've committed to fix this, but don't have a curl to test with (segfaults for other reasons).
 [2019-03-15 18:22 UTC]
-Status: Open +Status: Closed -Assigned To: +Assigned To: pmmaga
 [2019-03-15 18:22 UTC]
This issue has been fixed by the commit from NikiC and I've pushed a test via
PHP Copyright © 2001-2023 The PHP Group
All rights reserved.
Last updated: Wed Jun 07 22:03:40 2023 UTC