CakePHP 3.0 "thread class not found" - php

I want to implement the threading concept in CakePHP 3.0 ,
But when I try to extend the thread class, it gives an error of "Thread class not found"
I have also implemented it in core php and its working as expected,
But somehow its not working with cakephp.
Here is the corephp code
<?php
class AsyncOperation extends Thread {
public function __construct($arg) {
$this->arg = $arg;
}
public function run() {
if ($this->arg) {
$sleep = rand(1,60);
for ($i=0; $i < 100 ; $i++) {
sleep(1);
echo $this->arg."----------->".$i."<br/>";
}
}
}
}
class CallingClass {
public function runScript($var)
{
print_r("start run script");
$th = new AsyncOperation($var);
$th->start();
print_r("continue running");
}
}
$wow = new AsyncOperation("First");
$wow->start();
$wow2 = new AsyncOperation("Last");
$wow2->start();
?>
And in CakePHP 3
class AsyncOperation extends Thread

You want to learn about namespaces in php. Cake and almost every lib these days uses them. You need to use the use keyword and import the class from another namespace if it does not exist within the namespace your current class is in. Or, not really best practice, provide the absolute namespace.
Also I'm not sure what you try to do, but instead of threads I would recommend to take a look at work queues likes RabbitMQ or ZeroMQ.

Your php version doesn't have the thread class. By default, if you install it on LINUX, you won't have the thread class.
You need to download the php source code, enable the zts and then compile it.
This is how I did on linux:
Enable zts on redhat - pthreads on php

Just add simple line
use Thread;

Related

How to process multiple task in codeigniter cli at the same time

I am not sure if this is doable or not. I am running cron job to process data and they are all independent of each other.
For example i have a data [x,y,z] and i have a method in the parent controller that does what it needs to do. Process takes little long and hence my queue is piling up since it is doing one at a time. I tried forking process but it loses connection to the mongo database. Therefore, I had to remove fork for now but please let me know if i can reconnect.
Pseudocode
MyTools.php
class MY_Tools extends CI_Controller {
...
public function process($item) {
Make curl request
Update database for the item
}
}
Tools.php
class Tools extends MY_Tools {
...
public function getAllDate() {
$data = fetchDataFromDB() => [X,Y,Z]
$i = 0
while ($i < sizeof($data) {
$this->process($data[$i]);
$i++;
}
}
}
if i can do this without waiting for another process to complete and just keep on going, that will be great
In addition, I am using php7
cimongo library for codeigniter and https://github.com/alcaeus/mongo-php-adapter
Possible Solution
For php7, i have used this for gearman installation
https://techearl.com/php/installing-gearman-module-for-php7-on-ubuntu
Codeigniter gearman library that I used : https://github.com/appleboy/CodeIgniter-Gearman-Library
To overcome static method accessing parent controller, use singleton method
I was struggling with this for a bit and hopefully it will help someone
Example
class MY_Tools extends CI_Controller {
private static $instance;
function __construct() {
parent::__construct();
self::$instance =& $this;
}
public static function get_instance()
{
return self::$instance;
}
}
To Access
MY_Tools::get_instance()->YOUR_PUBLIC_METHODS();
Hope this can help someone

Reusing code in php modules without sharing global namespace

I can't seem to figure out to achieve the following result.
Important: this should work down to php 5.3
Ok, so imagine a situation: you develop a number of php modules, for example WordPress plugins, that are to be run on single setup but do not communicate or know about each other. But some (quite large) parts of codebase are the same and can be reused. How can I achieve the result, when all my modules have "inside of them" this shared library, scoped to each module and not causing conflicts in global space?
For example, see the following:
main.php (some host app, like WordPress)
<?php
require('plugins/first-module/first.php');
require('plugins/second-module/second.php');
$first = new Project1\App();
$first->go();
$second = new Project2\App();
$second->go();
?>
first.php (first module)
<?php
namespace Project1;
require('shared.php');
use CoreLib\Util\Logger\Log;
class App {
public function go() {
$logger = new Log();
$logger->say();
}
}
second.php (second module)
<?php
namespace Project2;
require('shared.php');
use CoreLib\Util\Logger\Log;
class App {
public function go() {
$logger = new Log();
$logger->say();
}
}
shared.php (shared lib)
<?php
namespace CoreLib\Util\Logger;
class Log {
public function say() {
echo 'It works!';
}
}
Right now I have an error, obviously, because of re-declaring Log class.
Any ideas?

Php pthreads and monolog

I cannot use monolog logger inside Thread method run.
class MyThread extends Thread
{
public function run()
{
echo 'hihi', PHP_EOL;
$log = new Logger('MyApp');
$log->pushHandler(
new StreamHandler('php://stdout', Logger::INFO)
);
$log->addInfo("hoho");
echo 'haha', PHP_EOL;
}
}
$thread = new MyThread();
if ($thread->start()) {
$thread->join();
echo 'hehe', PHP_EOL;
}
Output:
hihi
hehe
Here PHP pthreads and SQLite3 and here pthread Thread objects reset their state somebody says that I can only use objects inerited from Stackable, Thread or Worker inside my class inherited from Thread. But what if I cannot change Logger class? I cannot use it?
I want to clarify: I cannot use object not inherited from Stackable, Thread or Worker inside class inherited from Thread at all? It is very strange. In other languages I can.
Win 7 x64 Ultimate, php 7 32 bit with thread safety.

Storing closures in thread fails

I'm trying to use a closure as a callback once a thread is done running. However I'm running into what seems to be a limit/failure of PHP or the pthread extension.
My dev stack is running on Win7 x64 with PHP 5.5.3 x86 TS, pthread version 0.44.
The following code works :
class Test
{
public $callbackVar;
}
$test = new Test();
$callbackVar = function()
{
echo "Callback var invoked.";
};
$test->callbackVar = $callbackVar;
$test->callbackVar->__invoke();
But as soon as I derive Test from Thread, running the script gives an error :
class Test extends Thread
{
public $callbackVar;
public function run() { }
}
$test = new Test();
$callbackVar = function()
{
echo "Callback var invoked.";
};
$test->callbackVar = $callbackVar;
// assert() returns true
assert($test->callbackVar === null);
$test->callbackVar->__invoke();
With the following output
Fatal error: Call to a member function __invoke() on a non-object
Anyone ever had this issue ? Any possible workaround ? I'd rather not use eval if possible... I've tried many workarounds, such as rewrapping into another closure, using a ReflectionFunction, ... nothing cuts it.
Zend does not allow you to serialize closure objects.
So it's not something you should try to work around, possibly at some time in the future Zend will allow serialization of Closures, pthreads will not require changes at that time.
You'll just have to do it the old fashioned way ...

Memcached (not memcache) PHP extension on Windows

I can't seem to find the MemcacheD extension for PHP.
There are a few compilations of php_memcache.dll, but that's not the same.
The main thing I'm missing is getMulti(), which doesn't exist in Memcache.
So far I found this, but there's no DLL:
http://pecl.php.net/package/memcached
Officially - it does not exist. There are several people who have created their own DLL's though. Here is one person's blog who has created the dll:
http://trondn.blogspot.com/2010/07/libmemcached-on-win32.html
Here is a link to the repository with the source so you can build your own DLL for memcached:
http://bazaar.launchpad.net/~trond-norbye/libmemcached/mingw32/files
I know the memcached has some other features but its interface is nearly identical with that of memcache extension. You can very easily get away with such code and in my case it works perfectly well. If you don't have the memcached loaded create this file:
<?php
class Memcached {
const OPT_LIBKETAMA_COMPATIBLE = true;
const OPT_COMPRESSION = true;
const OPT_NO_BLOCK = true;
//if you code relies on any other constants define them to avoid
//undefined constant notice
//http://www.php.net/manual/en/memcached.constants.php
public $_instance;
public function __construct() {
$this->_instance = new Memcache;
}
public function __call($name, $args) {
return call_user_func_array(array($this->_instance, $name), $args);
}
public function setOption() {}
}
Either include it or configure autoloader to pick it up.
Of course you'll need a properly configured memcache instance and addServer calls but such calls should already be in the code if the codebase assumes Memcached.
I hope it helps someone/

Categories