Передать массив по ссылке на слушатель событий Laravel - PullRequest
0 голосов
/ 28 мая 2019

У меня есть массив в приложениях 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. 
    }
}

Ответы [ 2 ]

0 голосов
/ 29 мая 2019

Я ценю все ответы, отзывы на вопрос и предложения, чтобы найти лучший способ сделать это.

Теперь вместо использования Listeners я попробовал 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);
    }
}

0 голосов
/ 28 мая 2019

Основываясь на документации для массива , это говорит:

Присвоение массива всегда включает копирование значения. Используйте оператор ссылки, чтобы скопировать массив по ссылке.

Так что измените ваш конструктор на это:

// prepend the argument with the reference operator &
public function __construct(array &$data) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...