PHP7 and inherited class

Issue #37 invalid
Anonymous created an issue

Hello, found a bug with PHP 7.0, and EventBufferEvent object created in inherited class. Here is the code with Redis connection example:

class Generic
{
    public $base = NULL;
    public function start()
    {
        $this->base = new \EventBase();
        $this->onStart();

        // move onStart code here to fix //

    $this->base->dispatch();
    }
}

class Worker extends Generic
{
    protected function onStart()
    {
        $redis = new \EventBufferEvent($this->base);

        $redis->setCallbacks(
                function ($bev, $events, $unused=null)
                {
                        echo "onRead\n";
                        while (($line = $bev->input->readLine(\EventBuffer::EOL_ANY)) !== null) {
                                echo $line."\r\n";
                        }
                },
                null,
                function ($bev, $events, $unused=null)
                {
                        echo "onEvent\n";

                        if ($events & (\EventBufferEvent::EOF | \EventBufferEvent::ERROR)) {
                                $bev->free();
                                $bev = NULL;
                        } elseif ($events & \EventBufferEvent::CONNECTED) {
                                echo "redis: connected\n";

                                $command = 'PSUBSCRIBE';
                                $args = ['*'];
                                $data = '*' . (count($args) + 1) . "\r\n$" . strlen($command) . "\r\n" . $command . "\r\n";
                                foreach ($args as $arg) {
                                        $data .= '$' . strlen($arg) . "\r\n" . $arg . "\r\n";
                                }

                                $bev->write($data);
                        }
                }
        );

        if (!$redis->connect('127.0.0.1:6379')) {
                trigger_error("conn: Failed to connect to socket", E_USER_ERROR);
        } else {
                echo("socket to redis connected\n");
        }

        if (!$redis->enable(\Event::READ|\Event::WRITE|\Event::TIMEOUT|\Event::PERSIST)) {
                trigger_error("conn: Failed to enable socket", E_USER_ERROR);
        } else {
                echo("socket to redis event enabled\n");
        }
        $redis->setWatermark(\Event::READ, 16, 0xFFFF);
        $redis->setTimeouts(0, 0);
    }
}

$worker = new Worker();
$worker->start();

note when the code moved from onStart() to start(), the problem is fixed.

Comments (4)

  1. Fred Brown

    Ah ok, that's interesting. I'm only familiar with event on php >7.0. Glad you sorted it.

    I think it makes more sense that you should have to maintain a reference to your EventBufferEvent object. Seems a bit ambiguous how it would work otherwise, as the object would become hidden away in a scope of its own with no way to further interact with it - in effect it would be leaked, and we don't want that.

  2. Log in to comment