Call namespaced class's static method within callback function

167 Views Asked by At

Having the most strange error I've ever encountered in my coding journey.

I am using: laravel ratchet websocket Laravel Cache with file driver

I am trying to cache ratchet websocket response messages from within its closure function using laravel cache from an artisan command's class.

When I use var_dump on the websocket response, I get all the messages printed out on my terminal. But when I try to save in cache, it return true but the cache is empty. Not get stored, no error message is displayed.

This is my code:

use Illuminate\Support\Facades\Cache as Cache;


class Ticker extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'daemon:t';

    /**
     * The console command description.
     *
     * @var string
     */
    
    protected $description = 'Listens to websockets t';
    /**
     * Create a new command instance.
     *
     * @return void
     */
     protected $cah;
    public function __construct(Cache $Cache)
    {
        $this->cah = new $Cache();
        parent::__construct();
        

    }
    
  


    public function mini(callable $callback)
    {

        // phpunit can't cover async function
        \Ratchet\Client\connect('wss://stream......')->then(function ($ws) use ($callback) {
            $ws->on('message', function ($data) use ($ws, $callback) {
                
                $json = json_decode($data, true);

                return call_user_func($callback, $this->cah, $json);
            });
            $ws->on('close', function ($code = null, $reason = null) {
                // WPCS: XSS OK.
                echo "....: WebSocket Connection closed! ({$code} - {$reason})" . PHP_EOL;
            });
        }, function ($e) {
            // WPCS: XSS OK.
            echo "....: Could not connect: {$e->getMessage()}" . PHP_EOL;
        });
        
    }
       
       
    // save 
    
    public function saveT($t){
      //$this->alert($t);
      
      try{
         foreach ($t as $obj) {
              $this->cah::put($obj['s'], $obj, now()->addSeconds(5));
          }
      // used in testing
      //print_r($t);
 
      } catch (\Exception $exception) {
          $this->alert($exception->getMessage());
      }
    }
    
    
    /**
     * Execute the console command.
     *
     * @return mixed
     * @throws \Exception
     */
            
    public function handle()
    {
        
        $this->mini(function ($api,$json){
          
           // saving directly though the $api object 
           $api::put(['s' => $json], now()->addSeconds(10));
         
            // when savingnthrough saveT function 
          // $this->saveT($json);
          
         
         try{
           // call_user_func_array(array($this->cah::class,'put'),array('test','tested',now()->addSeconds(5)));
        } catch (\Exception $exception) {
             $this->alert($exception->getMessage());
        }
       },);
    }
}

1

There are 1 best solutions below

2
Sammitch On

The example code you've posted is a tangle of conflicting conventions, names, and references. Once you sort out what it is that you actually need, here are the correct forms for actually constructing and and invoking the callables.

namespace foo {
    class Cache {
        public static function put_static($a, $b, $c='optional?') {
            echo "put_static: $a $b $c\n";
        }
        
        public function put_instance($a, $b, $c='optional?') {
            echo "put_instance: $a $b $c\n";
        }
    }
}

namespace {
    use foo\Cache as Cache;
    $c = new Cache();
    
    $callback_static          = [Cache::class, 'put_static'];
    $callback_instance        = [$c,           'put_instance'];
    $callback_instance_static = [$c::class,    'put_static'];
    
    $vars_a = ['a', 'b'];
    $vars_b = ['a', 'b', 'c'];
    
    call_user_func_array($callback_static, $vars_a);
    call_user_func_array($callback_static, $vars_b);
    
    call_user_func_array($callback_instance, $vars_a);
    call_user_func_array($callback_instance, $vars_b);
    
    call_user_func_array($callback_instance_static, $vars_a);
    call_user_func_array($callback_instance_static, $vars_b);
}

Output:

put_static: a b optional?
put_static: a b c
put_instance: a b optional?
put_instance: a b c
put_static: a b optional?
put_static: a b c

You can also save some keystrokes with the splat operator ... to unpack the array as arguments, so call_user_func_array($func, $args) becomes $func(...$args)

Ref: