我在Laravel应用程序中有一个数组,我想在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.
}
}
事件: PageNodeToArrayAfter.php
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;
}
}
侦听器: FlashMessagesListner.php
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.
}
}
答案 0 :(得分:0)
根据array的文档,内容如下:
数组分配始终涉及值复制。使用引用运算符按引用复制数组。
因此将您的构造方法改为:
// prepend the argument with the reference operator &
public function __construct(array &$data)
答案 1 :(得分:0)
我感谢所有答复,对问题的反馈和建议,以寻求更好的解决方法。
现在,我尝试使用Laravel Pipeline,而不是使用侦听器,这是一种通过不同管道传递数据并过滤数据的好方法。本文对于了解它https://jeffochoa.me/understanding-laravel-pipelines
很有帮助。这是代码的最终版本,以及我如何使用Laravel Pipeline:
节点: Page.php
<?php declare(strict_types=1);
namespace Vendor\Package\Nodes;
class Page extends ReactPage
{
public function toArray() : array
{
$data = parent::toArray();
$pipes = [
AppendFlashMessage::class,
RemoveEmptyLayoutNode::class
];
// Filter data through the pipelines.
$data = app(Pipeline::class)
->send($data)
->through($pipes)
->via('filter')
->then(function($data) {
return $data;
});
return $data;
}
}
管道: AppendFlashMessage.php
<?php declare(strict_types=1);
namespace Vendor\Package\Pipeline;
use Closure;
class AppendFlashMessage
{
public function filter(array $data, Closure $next) : array
{
// step 1: pull the errors from session.
$errors = [
'type' => 'error',
'message' => 'Invalid User Name'
];
$data['messages'] = $errors;
return $next($data);
}
}
答案 2 :(得分:0)
只需在事件的构造函数中使用参考符号:
/**
* @param array $data
*
*/
public function __construct(array &$data)
{
$this->data = &$data;
^
}
尽管这可以为问题提供准确的答案,但我不建议针对此特定用例使用观察者模式。
此外,您不需要访问器-只需公开data
属性并在侦听器中使用$event->data
。
答案 3 :(得分:0)
被触发的初始事件是通过引用传递的(因为它是一个对象)。侦听器执行后可以访问该对象中修改后的 $data 属性。
import platform
if platform.system == "Windows":
os.environ['SDL_VIDEODRIVER'] = 'windib'
无需在事件构造函数或 getter 中通过引用手动传递任何内容。