Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 通过引用将数组传递给Laravel事件侦听器_Php_Laravel_Laravel 5_Laravel 5.8 - Fatal编程技术网

Php 通过引用将数组传递给Laravel事件侦听器

Php 通过引用将数组传递给Laravel事件侦听器,php,laravel,laravel-5,laravel-5.8,Php,Laravel,Laravel 5,Laravel 5.8,我想在Laravel listener中修改Laravel应用程序中的一个数组。PHP默认情况下按值传递数组,但是,按照Laravel事件及其侦听器的工作方式,我无法修改原始变量。有没有比我在下面做的更好的方法 从中触发事件的模型 模型:Event.php namespace Vendor\Package\Models use Vendor\Package\Events\PageNodeArrayAfter; use Event; class Page { public functio

我想在Laravel listener中修改Laravel应用程序中的一个数组。PHP默认情况下按值传递数组,但是,按照Laravel事件及其侦听器的工作方式,我无法修改原始变量。有没有比我在下面做的更好的方法

从中触发事件的模型

模型:Event.php

namespace Vendor\Package\Models

use Vendor\Package\Events\PageNodeArrayAfter;
use Event;

class Page
{
   public function toArray()
   {
      $data = []; 

      // do something with the data. 

      Event::fire(new PageNodeToArrayAfter($data))

      // The data should be modified by a listener when I use it here.
   }
}
namespace Vendor\Package\Events;

class PageNodeToArrayAfter
{
    /**
     * Props to be sent to the view
     * @var array $data
     */
    protected $data = [];

    /**
     * @param array $data
     * 
     */
    public function __construct(array &$data)
    {
        $this->data = $data;
    }

    public function getData()
    {
        return $this->data;
    }
}
namespace Vendor\Package\Listeners;

class FlashMessagesListner
{
    protected $data = [];

    public function handle(PageNodeToArrayAfter $event)
    {
       $this->data = $event->getData();
       // The problem here is the $data is no logner a reference here. 
    }
}
事件:PageNodeToArrayAfter.php

namespace Vendor\Package\Models

use Vendor\Package\Events\PageNodeArrayAfter;
use Event;

class Page
{
   public function toArray()
   {
      $data = []; 

      // do something with the data. 

      Event::fire(new PageNodeToArrayAfter($data))

      // The data should be modified by a listener when I use it here.
   }
}
namespace Vendor\Package\Events;

class PageNodeToArrayAfter
{
    /**
     * Props to be sent to the view
     * @var array $data
     */
    protected $data = [];

    /**
     * @param array $data
     * 
     */
    public function __construct(array &$data)
    {
        $this->data = $data;
    }

    public function getData()
    {
        return $this->data;
    }
}
namespace Vendor\Package\Listeners;

class FlashMessagesListner
{
    protected $data = [];

    public function handle(PageNodeToArrayAfter $event)
    {
       $this->data = $event->getData();
       // The problem here is the $data is no logner a reference here. 
    }
}
监听器:FlashMessagesListner.php

namespace Vendor\Package\Models

use Vendor\Package\Events\PageNodeArrayAfter;
use Event;

class Page
{
   public function toArray()
   {
      $data = []; 

      // do something with the data. 

      Event::fire(new PageNodeToArrayAfter($data))

      // The data should be modified by a listener when I use it here.
   }
}
namespace Vendor\Package\Events;

class PageNodeToArrayAfter
{
    /**
     * Props to be sent to the view
     * @var array $data
     */
    protected $data = [];

    /**
     * @param array $data
     * 
     */
    public function __construct(array &$data)
    {
        $this->data = $data;
    }

    public function getData()
    {
        return $this->data;
    }
}
namespace Vendor\Package\Listeners;

class FlashMessagesListner
{
    protected $data = [];

    public function handle(PageNodeToArrayAfter $event)
    {
       $this->data = $event->getData();
       // The problem here is the $data is no logner a reference here. 
    }
}

根据该项目的文档,它是这样说的:

数组赋值总是涉及值复制。使用引用运算符按引用复制数组

因此,将构造函数改为:

// prepend the argument with the reference operator &
public function __construct(array &$data) 

我感谢所有的回复、对问题的反馈以及寻找更好方法的建议

现在,我不再使用监听器,而是尝试了Laravel管道,这是一种通过不同管道传递数据并对其进行过滤的好方法。这篇文章对理解它很有帮助

以下是我的代码的最终版本,以及我如何使用Laravel管道:

节点:Page.php

namespace Vendor\Package\Models

use Vendor\Package\Events\PageNodeArrayAfter;
use Event;

class Page
{
   public function toArray()
   {
      $data = []; 

      // do something with the data. 

      Event::fire(new PageNodeToArrayAfter($data))

      // The data should be modified by a listener when I use it here.
   }
}
namespace Vendor\Package\Events;

class PageNodeToArrayAfter
{
    /**
     * Props to be sent to the view
     * @var array $data
     */
    protected $data = [];

    /**
     * @param array $data
     * 
     */
    public function __construct(array &$data)
    {
        $this->data = $data;
    }

    public function getData()
    {
        return $this->data;
    }
}
namespace Vendor\Package\Listeners;

class FlashMessagesListner
{
    protected $data = [];

    public function handle(PageNodeToArrayAfter $event)
    {
       $this->data = $event->getData();
       // The problem here is the $data is no logner a reference here. 
    }
}

只需在事件的构造函数中使用引用符号:

/**
 * @param array $data
 * 
 */
public function __construct(array &$data)
{
    $this->data = &$data;
                  ^
}
虽然这为问题提供了一个准确的答案,但我不建议在这个特定用例中使用观察者模式


此外,您不需要访问器—只需将
数据
属性设置为公共,并在侦听器中使用
$event->data

触发的初始事件通过引用传递(因为它是一个对象)。在侦听器执行之后,可以访问该对象中已修改的$data属性

  event($e = new PageNodeToArrayAfter($data));
  $data = $e->getData(); 

无需在事件构造函数或getter中通过引用手动传递任何内容。

这并不能回答问题。如何在侦听器中修改引用的变量?我刚刚更新了我的问题,并包含了&操作符,这本来是应该存在的。我现在只是使用setter和getter来修改变量,现在我可能不需要通过引用传递它。它回答了您声明在PHP中默认数组是通过引用传递的部分,而不是通过引用传递的部分。对我来说,首先使用监听器并从监听器内部修改外部变量是没有意义的,因为当你触发一个事件时,这个过程是异步的,即使监听器还没有完成它的工作,事件后的下一行也会被执行。是的,这就是我现在的想法。我可能不需要通过引用将变量传递给侦听器,因此也不需要我之前的注释。您的用例是什么?你为什么要做到这一点?您的主线程(执行事件的线程)将继续运行,即使您的侦听器可能尚未完成。我正在将一些XML节点转换为数组,在此过程中,我希望通过独立的侦听器附加一些自定义数据,如验证消息。我明白了。您需要自定义XML数据,那么为什么要使用侦听器呢?事件/侦听器用于向应用程序的其他部分(或外部API)通知某些内容,但在您的情况下,您希望对您将一直接触的相同数据进行操作。我理解您希望解耦逻辑,以避免用大量代码重新填充函数。因此,您可以将该逻辑提取到一个函数、一个trait或另一个将返回更新的XML文件的类中。我同意@HCK的观点,即观察者模式在这里是一种错误的方法,因为您的转换可能在侦听器完成其工作之前完成。事件和侦听器用于解耦进程。如果只需要将一些验证消息闪存到会话中,我看不出需要如何通过引用传递数组。如果侦听器的逻辑对于应用程序另一部分的处理至关重要,那么无论如何,侦听器是错误的选择。只有当触发流程不关心事件是否被任何其他流程使用时,才应该使用事件侦听器(就业务流程而言,是流程,而不是线程)。即,在用户注册后发送欢迎邮件(此过程完全可选)。