We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

[PHP7 ZTS pthreads] Uncaught Error: Access to undeclared static property: Phalcon\Di::$_default

Hi there,

I installed PHP 7 TZS (Thread safe / pthreads) and Phalcon 3.

I putted a Phalcon Model into a class extends "Threaded":

class ResponseObject extends \Threaded {
    private $nestedObject;

    public function __construct(\Model $myModel) {
        $this->nestedObject = $myModel;
    }

    public function shout() {
        echo "***** SHOUT **** (" .$this->nestedObject->getId(). ")\n";
    }
}

When I call the "shout()" function above, and the script tries to get access to the "getId()" function of the Phalcon Model, I get the error below:

PHP Fatal error:  Uncaught Error: Access to undeclared static property: Phalcon\Di::$_default in ***/ResponseObject.php:15

Stack trace:
#0 [internal function]: Phalcon\Di::getDefault()
#1 ***/ResponseObject.php(15): Phalcon\Mvc\Model->unserialize('a:30:{s:4:"iiid...')
#2 ***/Response.php(39): ***/ResponseObject->shout()
#3 [internal function]: ***\Response->run()
#4 {main}
thrown in ***/ResponseObject.php on line 15

I executed the function via PHP CLI

The only thing, that doesn't work, is that the Phalcon\Di has problems in the run() method of the Thread.

Phalcon Methods running fine, but when the code wants to get access to Di, this error appears:

Next Error: Access to undeclared static property: Phalcon\Di::$_default in /***/MyResponse.php:126
Stack trace:
#0 [internal function]: Phalcon\Di->__construct()
#1 [internal function]: Phalcon\Di\FactoryDefault->__construct()

Really strange. Anybody now a solution?

edited Nov '17

Pthread creates a new program context, so static di from the parent context is lost

You must implement your own DiInterface for threaded applications, even if it's cli api. Parallel programming is a soab :P



13.8k

That means that I have to set this:

class MyClass extends \Thread implements \Phalcon\DiInterface

And implement all these functions by my own, that I can found here:

https://github.com/phalcon/cphalcon/blob/master/phalcon/di.zep

Is this right?

Not quite, when a new thread is spun off, you lose some of the context of the parent thread. You should read up on that.

What you have to do, is create a DiInterface class (like FactoryDefault), which is aware of the threaded environment, and does not lose the already defined services.

pthreads requires you to use TS version of PHP binary. Personally I dislike that idea especially nowdays when we have things like nginx + ReactPHP, i.e. messing around with real threads seems too much hassle for disputable results. Even w/o ReactPHP, nginx and PhalconPHP gives absolutely superb results.



13.8k

"Every time I talk about asynchronous PHP, there’s always that one person who is like “Why don’t you just use NodeJS for that?”"

;)

edited Nov '17

And from a pragmatic point of view, they are totally right. It's cheaper in work hours to create queues and socket/tcp/http endpoints for parallel processing, even if it's less efficient. If you want to pursue that end, you should be coding websites in ASM, or at least in C.

From krakjoe's repo title:

Threading for PHP - Share Nothing, Do Everything :)

SHARE NOTHING. No global vars, no implicit class members. And Phalcon's dependency injector (DiInterface) is for sharing, so the two concepts collide. Heck, they don't just collide, they bloody crash head-on.

This article deals with a threaded file descriptor:

https://stackoverflow.com/questions/32679030/pthreads-access-to-resource-globally-in-php#answers

Note that in the answer only a string is passed into Threaded class, not the resource itself. Also note that even a simple logger requires synchronization of spawned threads.

What is the purpose of PHP? It is historically a CGI module for webservers, and that environment is NOT suitable for threaded applications. Pthreads v3 doesn't even start in a CGI/FPM environment.

What is the purpose of Phalcon? Providing a framework for WEB applications. Phalcon was never designed to be used in threaded environments, thus the current DI is inappropriate for that.

TL;DR;

First you have to understand the problem of simple logger in a threaded environment, then you have to ask yourself: do I really want to create a wrapper class for every single service i want to use?

EDIT:

If you really want to pursue parallel programming, PHP is not for you, since it can only handle a limited number of patterns / use-cases.

I'd advise you start learning golang, it is designed from the bottom for parallel processing, and it's core lib contains a http server which you can spin up with like 5 lines of code.



13.8k
edited Nov '17

I did some research, so now I am doing it with "zeromq":

https://zeromq.org/bindings:php

And using this plugin for it:

https://github.com/asyncphp/remit

Really works awesome for me! Thx for your hints.

So you ended up with:

  • pthreads
  • MQ broker (zero MQ)
  • Distributed event emitter (remit)
  • PhalconPHP as a framework

Now I'm curious how will that work, are there "any" bugs out there etc.

Good luck!



4.0k

With PHP CLI you have also the possibility to use Phalcon with Beanstalk queues. If you install Phalcon Incubator with composer you will have the ability to create several parallelized queues and let them process jobs. As Beanstalk is a service listening to a port, you can dispatch your workers on several servers accross a private network to balance the global load.

@mikachou: with a note that Beanstalk project unfortunately, have been abandoned.



4.0k

what a pity, i didn't know, although there has been no update on github repository since 2014