【问题标题】:Call namespaced class's static method within callback function在回调函数中调用命名空间类的静态方法
【发布时间】:2021-11-18 03:05:16
【问题描述】:

遇到了我在编码过程中遇到的最奇怪的错误。

我正在使用:laravel ratchet websocket Laravel Cache 和文件驱动

我正在尝试使用来自工匠命令类的 laravel 缓存从其闭包函数中缓存棘轮 websocket 响应消息。

当我在 websocket 响应中使用 var_dump 时,我会在终端上打印出所有消息。但是当我尝试保存在缓存中时,它返回 true 但缓存为空。不被存储,不显示错误信息。

这是我的代码:

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());
        }
       },);
    }
}

【问题讨论】:

  • $cache$Cache 是两个不同的变量(变量区分大小写)。
  • 在您的第二个示例中(您使用完整的命名空间),您仍然有 use (&$Cache),它在那里不需要(如果您尚未定义 $Cache,则会失败)。在开发过程中,请确保您是displaying all errors and warnings,因为我看不到所有尝试如何在没有错误/警告的情况下失败(特别是当您应该得到“未定义变量”-通知/警告时)
  • 很抱歉,在格式化我的问题时出现了错误。在代码中正确引用它(第一个字母 Cap )
  • 请复制/粘贴您的实际代码,而不是在此处重写。在调试代码时,我们看到您的确切代码至关重要。重写可能会引入其他问题(例如变量大小写),甚至会无意中修复实际问题。
  • 我已经添加了我想要在最后工作的最后一段代码。我只想在闭包内执行缓存 focade。

标签: php caching laravel-8 laravel-cache


【解决方案1】:

您发布的示例代码是一堆相互冲突的约定、名称和引用。一旦您理清了您实际需要什么,以下是实际构造和调用可调用对象的正确形式。

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);
}

输出:

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

您还可以使用 splat 运算符 ... 保存一些击键以将数组解包为参数,因此 call_user_func_array($func, $args) 变为 $func(...$args)

参考:

【讨论】:

  • 非常感谢您的建设性回复。在这个级别上我完全没有问题。当我尝试调用 call_user_func_array($callback_instance_static, $vars_b); 时代码停止工作在闭包函数中。由于范围
  • 请查看我上传的完整代码。使用var_dump,缓存类的put方法返回结果为真。通常它应该已经保存,但没有保存缓存项,也没有错误消息。我相信通过完整的代码,您可以发现错误或在最后重新创建。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-28
  • 1970-01-01
  • 2011-09-28
  • 2014-01-31
相关资源
最近更新 更多