Server::__construct()   C
last analyzed

Complexity

Conditions 12
Paths 264

Size

Total Lines 43
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 1 Features 1
Metric Value
cc 12
eloc 27
c 4
b 1
f 1
nc 264
nop 1
dl 0
loc 43
rs 5.3333

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
0 ignored issues
show
Coding Style introduced by
Missing file doc comment
Loading history...
3
namespace Hhxsv5\LaravelS\Swoole;
4
5
use Hhxsv5\LaravelS\Components\MetricCollectorInterface;
6
use Hhxsv5\LaravelS\Illuminate\LogTrait;
7
use Hhxsv5\LaravelS\Swoole\Process\ProcessTitleTrait;
8
use Hhxsv5\LaravelS\Swoole\Socket\PortInterface;
9
use Hhxsv5\LaravelS\Swoole\Task\BaseTask;
10
use Hhxsv5\LaravelS\Swoole\Task\Event;
11
use Hhxsv5\LaravelS\Swoole\Task\Listener;
12
use Hhxsv5\LaravelS\Swoole\Task\Task;
13
use Hhxsv5\LaravelS\Swoole\Proxy\HttpServerProxy;
14
use Hhxsv5\LaravelS\Swoole\Proxy\WebSocketServerProxy;
15
use Swoole\Http\Request as SwooleRequest;
16
use Swoole\Http\Response as SwooleResponse;
17
use Swoole\Http\Server as HttpServer;
18
use Swoole\Server\Port;
19
use Swoole\Table;
20
use Swoole\WebSocket\Server as WebSocketServer;
21
22
class Server
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class Server
Loading history...
23
{
24
    use LogTrait;
25
    use ProcessTitleTrait;
26
27
    /** Suffix for dynamic table properties to avoid naming conflicts */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Doc comment short description must be on the first line
Loading history...
28
    public const TABLE_PROPERTY_SUFFIX = 'Table';
29
30
    /**@var array */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
31
    protected $conf;
32
33
    /**@var HttpServer|WebSocketServer|HttpServerProxy|WebSocketServerProxy */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
34
    protected $swoole;
35
36
    /**@var bool */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
37
    protected $enableWebSocket = false;
38
39
    protected function __construct(array $conf)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function __construct()
Loading history...
40
    {
41
        $this->conf = $conf;
42
        $this->enableWebSocket = !empty($this->conf['websocket']['enable']);
43
44
        $ip = isset($conf['listen_ip']) ? $conf['listen_ip'] : '127.0.0.1';
45
        $port = isset($conf['listen_port']) ? $conf['listen_port'] : 5200;
46
        $socketType = isset($conf['socket_type']) ? (int)$conf['socket_type'] : SWOOLE_SOCK_TCP;
47
48
        if ($socketType === SWOOLE_SOCK_UNIX_STREAM) {
49
            $socketDir = dirname($ip);
50
            if (!file_exists($socketDir) && !mkdir($socketDir) && !is_dir($socketDir)) {
51
                throw new \RuntimeException(sprintf('Directory "%s" was not created', $socketDir));
52
            }
53
        }
54
55
        $settings = isset($conf['swoole']) ? $conf['swoole'] : [];
56
        $settings['enable_static_handler'] = !empty($conf['handle_static']);
57
58
        // Use proxy classes to support dynamic properties in PHP 8.2+
59
        $serverClass = $this->enableWebSocket
60
            ? WebSocketServerProxy::class
61
            : HttpServerProxy::class;
62
        if (isset($settings['ssl_cert_file'], $settings['ssl_key_file'])) {
63
            $this->swoole = new $serverClass($ip, $port, SWOOLE_PROCESS, $socketType | SWOOLE_SSL);
64
        } else {
65
            $this->swoole = new $serverClass($ip, $port, SWOOLE_PROCESS, $socketType);
66
        }
67
68
        // Disable Coroutine
69
        $settings['enable_coroutine'] = false;
70
71
        $this->swoole->set($settings);
72
73
        $this->bindBaseEvents();
74
        $this->bindHttpEvents();
75
        $this->bindTaskEvents();
76
        $this->bindWebSocketEvents();
77
        $this->bindPortEvents();
78
        $this->bindSwooleTables();
79
80
        // Disable Hook
81
        class_exists('Swoole\Coroutine') && \Swoole\Coroutine::set(['hook_flags' => false]);
82
    }
83
84
    protected function bindBaseEvents()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function bindBaseEvents()
Loading history...
85
    {
86
        $this->swoole->on('Start', [$this, 'onStart']);
87
        $this->swoole->on('Shutdown', [$this, 'onShutdown']);
88
        $this->swoole->on('ManagerStart', [$this, 'onManagerStart']);
89
        $this->swoole->on('ManagerStop', [$this, 'onManagerStop']);
90
        $this->swoole->on('WorkerStart', [$this, 'onWorkerStart']);
91
        $this->swoole->on('WorkerStop', [$this, 'onWorkerStop']);
92
        $this->swoole->on('WorkerError', [$this, 'onWorkerError']);
93
        $this->swoole->on('PipeMessage', [$this, 'onPipeMessage']);
94
    }
95
96
    protected function bindHttpEvents()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function bindHttpEvents()
Loading history...
97
    {
98
        $this->swoole->on('Request', [$this, 'onRequest']);
99
    }
100
101
    protected function bindTaskEvents()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function bindTaskEvents()
Loading history...
102
    {
103
        if (!empty($this->conf['swoole']['task_worker_num'])) {
104
            $this->swoole->on('Task', [$this, 'onTask']);
105
            $this->swoole->on('Finish', [$this, 'onFinish']);
106
        }
107
    }
108
109
    protected function triggerWebSocketEvent($event, array $params)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function triggerWebSocketEvent()
Loading history...
110
    {
111
        return $this->callWithCatchException(function () use ($event, $params) {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
112
            $handler = $this->getWebSocketHandler();
113
114
            if (method_exists($handler, $event)) {
115
                call_user_func_array([$handler, $event], $params);
116
            } elseif ($event === 'onHandShake') {
117
                // Set default HandShake
118
                call_user_func_array([$this, 'onHandShake'], $params);
119
            }
120
        });
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
121
    }
122
123
    protected function bindWebSocketEvents()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function bindWebSocketEvents()
Loading history...
124
    {
125
        if ($this->enableWebSocket) {
126
            $this->swoole->on('HandShake', function () {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
127
                return $this->triggerWebSocketEvent('onHandShake', func_get_args());
128
            });
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
129
130
            $this->swoole->on('Open', function () {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
131
                $this->triggerWebSocketEvent('onOpen', func_get_args());
132
            });
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
133
134
            $this->swoole->on('Message', function () {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
135
                $this->triggerWebSocketEvent('onMessage', func_get_args());
136
            });
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
137
138
            $this->swoole->on('Close', function (WebSocketServer $server, $fd, $reactorId) {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
139
                $clientInfo = $server->getClientInfo($fd);
140
                if (isset($clientInfo['websocket_status']) && $clientInfo['websocket_status'] === \WEBSOCKET_STATUS_FRAME) {
141
                    $this->triggerWebSocketEvent('onClose', func_get_args());
142
                }
143
                // else ignore the close event for http server
144
            });
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
145
        }
146
    }
147
148
    protected function triggerPortEvent(Port $port, $handlerClass, $event, array $params)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function triggerPortEvent()
Loading history...
149
    {
150
        return $this->callWithCatchException(function () use ($port, $handlerClass, $event, $params) {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
151
            $handler = $this->getSocketHandler($port, $handlerClass);
152
153
            if (method_exists($handler, $event)) {
154
                call_user_func_array([$handler, $event], $params);
155
            } elseif ($event === 'onHandShake') {
156
                // Set default HandShake
157
                call_user_func_array([$this, 'onHandShake'], $params);
158
            }
159
        });
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
160
    }
161
162
    protected function bindPortEvents()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function bindPortEvents()
Loading history...
163
    {
164
        $sockets = empty($this->conf['sockets']) ? [] : $this->conf['sockets'];
165
        foreach ($sockets as $socket) {
166
            if (isset($socket['enable']) && !$socket['enable']) {
167
                continue;
168
            }
169
170
            $port = $this->swoole->addListener($socket['host'], $socket['port'], $socket['type']);
171
            if (!($port instanceof Port)) {
172
                $errno = method_exists($this->swoole, 'getLastError') ? $this->swoole->getLastError() : 'unknown';
173
                $errstr = sprintf('listen %s:%s failed: errno=%s', $socket['host'], $socket['port'], $errno);
174
                $this->error($errstr);
175
                continue;
176
            }
177
178
            $port->set(empty($socket['settings']) ? [] : $socket['settings']);
179
180
            $handlerClass = $socket['handler'];
181
182
            $events = [
183
                'Open',
184
                'HandShake',
185
                'Request',
186
                'Message',
187
                'Connect',
188
                'Close',
189
                'Receive',
190
                'Packet',
191
                'BufferFull',
192
                'BufferEmpty',
193
            ];
194
            foreach ($events as $event) {
195
                $port->on($event, function () use ($port, $handlerClass, $event) {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
196
                    $this->triggerPortEvent($port, $handlerClass, 'on' . $event, func_get_args());
197
                });
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
198
            }
199
        }
200
    }
201
202
    protected function getWebSocketHandler()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function getWebSocketHandler()
Loading history...
203
    {
204
        static $handler = null;
205
        if ($handler !== null) {
206
            return $handler;
207
        }
208
209
        $handlerClass = $this->conf['websocket']['handler'];
210
        $t = new $handlerClass();
211
        if (!($t instanceof WebSocketHandlerInterface)) {
212
            throw new \InvalidArgumentException(sprintf('%s must implement the interface %s', get_class($t), WebSocketHandlerInterface::class));
213
        }
214
        $handler = $t;
215
        return $handler;
216
    }
217
218
    protected function getSocketHandler(Port $port, $handlerClass)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function getSocketHandler()
Loading history...
219
    {
220
        static $handlers = [];
221
        $portHash = spl_object_hash($port);
222
        if (isset($handlers[$portHash])) {
223
            return $handlers[$portHash];
224
        }
225
        $t = new $handlerClass($port);
226
        if (!($t instanceof PortInterface)) {
227
            throw new \InvalidArgumentException(sprintf('%s must extend the abstract class TcpSocket/UdpSocket', get_class($t)));
228
        }
229
        $handlers[$portHash] = $t;
230
        return $handlers[$portHash];
231
    }
232
233
    protected function bindSwooleTables()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function bindSwooleTables()
Loading history...
234
    {
235
        $tables = isset($this->conf['swoole_tables']) ? (array)$this->conf['swoole_tables'] : [];
236
        foreach ($tables as $name => $table) {
237
            $t = new Table($table['size']);
238
            foreach ($table['column'] as $column) {
239
                if (isset($column['size'])) {
240
                    $t->column($column['name'], $column['type'], $column['size']);
241
                } else {
242
                    $t->column($column['name'], $column['type']);
243
                }
244
            }
245
            $t->create();
246
            $name .= self::TABLE_PROPERTY_SUFFIX; // Avoid naming conflicts
247
            $this->swoole->{$name} = $t;
248
        }
249
    }
250
251
    public function onStart(HttpServer $server)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function onStart()
Loading history...
252
    {
253
        $this->setProcessTitle(sprintf('%s laravels: master process', $this->conf['process_prefix']));
254
255
        if (version_compare(SWOOLE_VERSION, '1.9.5', '<')) {
256
            file_put_contents($this->conf['swoole']['pid_file'], $server->master_pid);
257
        }
258
    }
259
260
    public function onShutdown(HttpServer $server)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function onShutdown()
Loading history...
261
    {
262
    }
263
264
    public function onManagerStart(HttpServer $server)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function onManagerStart()
Loading history...
265
    {
266
        $this->setProcessTitle(sprintf('%s laravels: manager process', $this->conf['process_prefix']));
267
    }
268
269
    public function onManagerStop(HttpServer $server)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function onManagerStop()
Loading history...
270
    {
271
    }
272
273
    public function onWorkerStart(HttpServer $server, $workerId)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function onWorkerStart()
Loading history...
274
    {
275
        $processName = $workerId >= $server->setting['worker_num'] ? 'task worker' : 'worker';
276
        $this->setProcessTitle(sprintf('%s laravels: %s process %d', $this->conf['process_prefix'], $processName, $workerId));
277
278
        if (function_exists('opcache_reset')) {
279
            opcache_reset();
280
        }
281
        if (function_exists('apc_clear_cache')) {
282
            apc_clear_cache();
283
        }
284
285
        clearstatcache();
286
287
        // Disable Hook
288
        class_exists('Swoole\Runtime') && \Swoole\Runtime::enableCoroutine(false);
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type integer expected by parameter $flags of Swoole\Runtime::enableCoroutine(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

288
        class_exists('Swoole\Runtime') && \Swoole\Runtime::enableCoroutine(/** @scrutinizer ignore-type */ false);
Loading history...
289
    }
290
291
    public function onWorkerStop(HttpServer $server, $workerId)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function onWorkerStop()
Loading history...
292
    {
293
    }
294
295
    public function onWorkerError(HttpServer $server, $workerId, $workerPId, $exitCode, $signal)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function onWorkerError()
Loading history...
296
    {
297
        $this->error(sprintf('worker[%d] error: exitCode=%s, signal=%s', $workerId, $exitCode, $signal));
298
    }
299
300
    public function onPipeMessage(HttpServer $server, $srcWorkerId, $message)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function onPipeMessage()
Loading history...
301
    {
302
        if ($message instanceof BaseTask) {
303
            $server->task($message);
304
            // $this->onTask($server, null, $srcWorkerId, $message);
305
        } elseif ($message instanceof MetricCollectorInterface) {
306
            $message->collect([
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
307
                'process_id'   => $server->worker_id,
308
                'process_type' => $server->taskworker ? 'task' : 'worker',
309
            ]);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
310
        }
311
    }
312
313
    public function onRequest(SwooleRequest $swooleRequest, SwooleResponse $swooleResponse)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function onRequest()
Loading history...
314
    {
315
    }
316
317
    public function onHandShake(SwooleRequest $request, SwooleResponse $response)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function onHandShake()
Loading history...
318
    {
319
        if (!isset($request->header['sec-websocket-key'])) {
320
            // Bad protocol implementation: it is not RFC6455.
321
            $response->end();
322
            return;
323
        }
324
        $secKey = $request->header['sec-websocket-key'];
325
        if (!preg_match('#^[+/0-9A-Za-z]{21}[AQgw]==$#', $secKey) || 16 !== strlen(base64_decode($secKey))) {
326
            // Header Sec-WebSocket-Key is illegal;
327
            $response->end();
328
            return;
329
        }
330
331
        $headers = [
332
            'Upgrade'               => 'websocket',
333
            'Connection'            => 'Upgrade',
334
            'Sec-WebSocket-Accept'  => base64_encode(sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true)),
335
            'Sec-WebSocket-Version' => '13',
336
        ];
337
338
        // WebSocket connection to 'ws://127.0.0.1:5200/'
339
        // failed: Error during WebSocket handshake:
340
        // Response must not include 'Sec-WebSocket-Protocol' header if not present in request: websocket
341
        if (isset($request->header['sec-websocket-protocol'])) {
342
            $headers['Sec-WebSocket-Protocol'] = $request->header['sec-websocket-protocol'];
343
        }
344
345
        foreach ($headers as $key => $value) {
346
            $response->header($key, $value);
347
        }
348
349
        $response->status(101);
350
        $response->end();
351
    }
352
353
    public function onTask(HttpServer $server, $taskId, $srcWorkerId, $data)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function onTask()
Loading history...
354
    {
355
        if ($data instanceof Event) {
356
            $this->handleEvent($data);
357
        } elseif ($data instanceof Task) {
358
            if ($this->handleTask($data) && method_exists($data, 'finish')) {
359
                return $data;
360
            }
361
        }
362
    }
363
364
    public function onFinish(HttpServer $server, $taskId, $data)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function onFinish()
Loading history...
365
    {
366
        if ($data instanceof Task) {
367
            $data->finish();
368
        }
369
    }
370
371
    protected function handleEvent(Event $event)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function handleEvent()
Loading history...
372
    {
373
        $listenerClasses = $event->getListeners();
374
        foreach ($listenerClasses as $listenerClass) {
375
            /**@var Listener $listener */
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
376
            $listener = new $listenerClass();
377
            if (!($listener instanceof Listener)) {
378
                throw new \InvalidArgumentException(sprintf('%s must extend the abstract class %s', $listenerClass, Listener::class));
379
            }
380
381
            $result = $this->callWithCatchException(function () use ($listener, $event) {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
382
                return $listener->handle($event);
383
            }, [], $event->getTries());
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
384
385
            if ($result === false) { // Stop propagating this event to subsequent listeners
386
                break;
387
            }
388
        }
389
    }
390
391
    protected function handleTask(Task $task)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function handleTask()
Loading history...
392
    {
393
        return $this->callWithCatchException(function () use ($task) {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
394
            $task->handle();
395
            return true;
396
        }, [], $task->getTries());
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
397
    }
398
399
    protected function fireEvent($event, $interface, array $arguments)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function fireEvent()
Loading history...
400
    {
401
        if (isset($this->conf['event_handlers'][$event])) {
402
            $eventHandlers = (array)$this->conf['event_handlers'][$event];
403
            foreach ($eventHandlers as $eventHandler) {
404
                if (!isset(class_implements($eventHandler)[$interface])) {
405
                    throw new \InvalidArgumentException(sprintf(
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
406
                            '%s must implement the interface %s',
0 ignored issues
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 24 spaces, but found 28.
Loading history...
407
                            $eventHandler,
0 ignored issues
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 24 spaces, but found 28.
Loading history...
408
                            $interface
0 ignored issues
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 24 spaces, but found 28.
Loading history...
409
                        )
0 ignored issues
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 20 spaces, but found 24.
Loading history...
410
                    );
411
                }
412
                $this->callWithCatchException(function () use ($eventHandler, $arguments) {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
413
                    call_user_func_array([(new $eventHandler), 'handle'], $arguments);
414
                });
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
415
            }
416
        }
417
    }
418
419
    public function run()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function run()
Loading history...
420
    {
421
        $this->swoole->start();
422
    }
423
}
424