Using PHP threads, I've met a few times issues with "Serialization of Closure" fatal error. However I don't understand how it happens : I don't pass closure or any kind of callable to another thread, sometimes when I take of the code outside the project and run it alone it works, but fails into the project.
So I tried to make a script fail by serialization of closure, to understand how it actually works.
This code uses closures and actually works :
<?php
class MyWorker extends Worker {
protected $kernel;
protected $container;
public function __construct($closure)
{
echo "Worker::__construct()";
echo PHP_EOL;
echo $closure();
echo PHP_EOL;
}
public function run()
{
echo "Worker::run()";
echo PHP_EOL;
}
}
class Toto {
protected $c;
public function __construct()
{
$this->c = function() {
return "CLOSURE";
};
}
public function go()
{
$c = $this->c;
$pool = new Pool(4, MyWorker::class, [function(){
return "WORKER_CLOSURE";
}]);
$pool->submit(new class ($c) extends Threaded {
public function __construct($c)
{
$this->c = $c;
}
public function run()
{
$c = $this->c;
echo $c();
echo "Threaded::run()";
echo PHP_EOL;
}
});
}
}
$toto = new Toto;
$toto->go();
When running alone. But inside a Symfony command, the following code simply fails. I don't understand why therefore I cannot fix it :
<?php
use Threaded;
use Thread;
class Foo
{
public function run()
{
$t = new Thread;
$t->start();
$t->join();
}
}
So I thought maybe it's because this code executed in a closure (I don't know but maybe), so I tried this :
$c = function() {
$t = new class extends Thread {
public function run()
{
echo "yo";
}
};
$t->start();
$t->join();
};
$c();
And it works. So passing closure to a thread works, building, starting and joining a thread from inside a closure also works, I don't know where to look now ...
I've look at this too : Storing closures in thread fails, but the code is outdated and it now ( PHP 7, pthreads 3.x ) works. So here I am asking for help to understand what is actually the problem with Closure...