【问题标题】:Laravel Pusher array_merge: Expected parameter 2 to be an array, null givenLaravel Pusher array_merge:预期参数 2 是一个数组,给定 null
【发布时间】:2021-05-31 15:44:50
【问题描述】:

我正在按照推送者的教程在网站上显示通知。一切都与教程一致,但是当我尝试访问localhost:8000/test 上的通知时出现了这个特殊错误,我不知道如何修复它。

the error message

预期结果:通知发送消息

输出:array_merge() 错误

相关教程:https://pusher.com/tutorials/web-notifications-laravel-pusher-channels

相关文件:C:\xampp\htdocs\inventory-prototype\vendor\pusher\pusher-php-server\src\Pusher.php:518

这是我的Events/ItemAdd

class ItemAdd implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $user;
    public $message;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct($user)
    {
        $this->user = $user;
        $this->message = '{ $user } added an item';
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return ['item-add'];
    }
}

这是我的web.php

Route::get('test', function () {
    dd(event(new App\Events\ItemAdd('Someone')));
    return "Event has been sent!";
});

vendor/pusher/src/Pusher.php -> 触发器

    /**
     * Trigger an event by providing event name and payload.
     * Optionally provide a socket ID to exclude a client (most likely the sender).
     *
     * @param array|string $channels        A channel name or an array of channel names to publish the event on.
     * @param string       $event
     * @param mixed        $data            Event data
     * @param array        $params          [optional]
     * @param bool         $already_encoded [optional]
     *
     * @throws PusherException   Throws PusherException if $channels is an array of size 101 or above or $socket_id is invalid
     * @throws ApiErrorException Throws ApiErrorException if the Channels HTTP API responds with an error
     *
     * @return object
     */
    public function trigger($channels, $event, $data, $params = array(), $already_encoded = false)
    {
        if (is_string($channels) === true) {
            $channels = array($channels);
        }

        $this->validate_channels($channels);
        if (isset($params['socket_id'])) {
            $this->validate_socket_id($params['socket_id']);
        }

        $has_encrypted_channel = false;
        foreach ($channels as $chan) {
            if (PusherCrypto::is_encrypted_channel($chan)) {
                $has_encrypted_channel = true;
            }
        }

        if ($has_encrypted_channel) {
            if (count($channels) > 1) {
                // For rationale, see limitations of end-to-end encryption in the README
                throw new PusherException('You cannot trigger to multiple channels when using encrypted channels');
            } else {
                $data_encoded = $this->crypto->encrypt_payload($channels[0], $already_encoded ? $data : json_encode($data));
            }
        } else {
            $data_encoded = $already_encoded ? $data : json_encode($data);
        }

        $query_params = array();

        $path = $this->settings['base_path'].'/events';

        // json_encode might return false on failure
        if (!$data_encoded) {
            $this->log('Failed to perform json_encode on the the provided data: {error}', array(
                'error' => print_r($data, true),
            ), LogLevel::ERROR);
        }

        $post_params = array();
        $post_params['name'] = $event;
        $post_params['data'] = $data_encoded;
        $post_params['channels'] = array_values($channels);

        $all_params = array_merge($post_params, $params);

        $post_value = json_encode($all_params);

        $query_params['body_md5'] = md5($post_value);

        $ch = $this->create_curl($this->channels_url_prefix(), $path, 'POST', $query_params);

        $this->log('trigger POST: {post_value}', compact('post_value'));

        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_value);

        $response = $this->exec_curl($ch);

        if ($response['status'] !== 200) {
            throw new ApiErrorException($response['body'], $response['status']);
        }

        $result = json_decode($response['body']);

        if (property_exists($result, 'channels')) {
            $result->channels = get_object_vars($result->channels);
        }

        return $result;
    }

任何帮助将不胜感激

【问题讨论】:

  • 我没有看到错误消息中 $params 的初始化位置
  • @ibrahim-dogan 我添加了声明 $params 的函数
  • 你能试试$all_params = array_merge($post_params, $params ?? []);,让我知道它是否有效,你期望 $params 作为一个数组,但也许你调用触发器的地方它传递为 null(顺便说一句,如果你的 PHP 版本小于 7 它不会工作)
  • 我确实尝试过,它会抛出ApiErrorException,这也好不到哪里去,而且我认为我不应该与这些供应商的东西混在一起。

标签: php laravel websocket pusher


【解决方案1】:

我随便说一下,我刚刚降级到 pusher 4.1,在 composer.json 上查找 pusher 并将版本更改为 4.1,以防我以外的任何人遇到同样的错误。

【讨论】:

    【解决方案2】:

    此错误已在 pusher-http-php 库 v5.0.1 和 Laravel v8.29.0 中得到解决。 https://github.com/pusher/pusher-http-php/issues/288

    【讨论】:

      【解决方案3】:

      你可以在这个commentben-pusher到issueerror array_merge - laravel 8 - php74 #278找到这个问题的解决方案:

      您可能需要使用composer require pusher/pusher-php-server ^4.1- Laravel 尚未添加对该库 v5.0.0 的支持。

      【讨论】:

      • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
      猜你喜欢
      • 2021-06-04
      • 2020-09-25
      • 1970-01-01
      • 2022-06-22
      • 1970-01-01
      • 1970-01-01
      • 2021-01-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多