These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Encore\LumenSwoole; |
||
4 | |||
5 | use Error; |
||
6 | use ErrorException; |
||
7 | use Laravel\Lumen\Exceptions\Handler; |
||
8 | use Symfony\Component\Console\Output\ConsoleOutput; |
||
9 | use Symfony\Component\Debug\Exception\FatalErrorException; |
||
10 | use Symfony\Component\Debug\Exception\FatalThrowableError; |
||
11 | |||
12 | class Command |
||
13 | { |
||
14 | protected $pidFile; |
||
15 | |||
16 | protected $options = []; |
||
17 | |||
18 | protected $host = 'localhost'; |
||
19 | |||
20 | protected $port = 8083; |
||
21 | |||
22 | protected $bootstrap = 'bootstrap/app.php'; |
||
23 | |||
24 | protected $serverOptions = []; |
||
25 | |||
26 | public function __construct() |
||
27 | { |
||
28 | $this->registerErrorHandling(); |
||
29 | } |
||
30 | |||
31 | public static function main($argv) |
||
32 | { |
||
33 | $command = new static(); |
||
34 | |||
35 | return $command->run($argv); |
||
36 | } |
||
37 | |||
38 | public function run($argv) |
||
39 | { |
||
40 | if ($this->handleAction($argv)) { |
||
41 | return; |
||
42 | } |
||
43 | |||
44 | $this->handleArguments(); |
||
45 | |||
46 | $server = new Server($this->host, $this->port); |
||
47 | $server->setApplication(require $this->bootstrap); |
||
48 | |||
49 | $server->options($this->serverOptions)->run(); |
||
50 | } |
||
51 | |||
52 | /** |
||
53 | * @param array $argv |
||
54 | * |
||
55 | * @return bool |
||
56 | */ |
||
57 | public function handleAction($argv) |
||
58 | { |
||
59 | if (count($argv) < 2) { |
||
60 | return false; |
||
61 | } |
||
62 | |||
63 | if (in_array($argv[1], ['stop', 'reload', 'restart'])) { |
||
64 | call_user_func([$this, $argv[1]]); |
||
65 | |||
66 | return true; |
||
67 | } |
||
68 | |||
69 | return false; |
||
70 | } |
||
71 | |||
72 | public function handleArguments() |
||
73 | { |
||
74 | $serverOptions = array_map(function ($option) { |
||
75 | return "$option:"; |
||
76 | }, Server::$validServerOptions); |
||
77 | |||
78 | $longOptions = array_merge(['host:', 'port:', 'help'], $serverOptions); |
||
79 | |||
80 | $options = getopt('dp:h::s:', $longOptions); |
||
81 | |||
82 | foreach ($options as $option => $value) { |
||
83 | switch ($option) { |
||
84 | case 'h': |
||
85 | case 'host': |
||
86 | if ($value) { |
||
87 | $this->host = $value; |
||
88 | } else { |
||
89 | $this->usage(); |
||
90 | } |
||
91 | break; |
||
92 | |||
93 | case 'help': |
||
94 | $this->usage(); |
||
95 | break; |
||
96 | |||
97 | case 'p': |
||
98 | case 'port': |
||
99 | if ($value) { |
||
100 | $this->port = (int) $value; |
||
101 | } |
||
102 | break; |
||
103 | |||
104 | case 's': |
||
105 | if ($value) { |
||
106 | $this->bootstrap = $value; |
||
107 | } |
||
108 | break; |
||
109 | |||
110 | case 'd': |
||
111 | $this->serverOptions['daemonize'] = true; |
||
112 | break; |
||
113 | |||
114 | default: |
||
115 | if (in_array($option, Server::$validServerOptions) && $value) { |
||
116 | $this->serverOptions[$option] = $value; |
||
117 | } |
||
118 | break; |
||
119 | } |
||
120 | } |
||
121 | |||
122 | return $options; |
||
123 | } |
||
124 | |||
125 | /** |
||
126 | * Show usage. |
||
127 | */ |
||
128 | public function usage() |
||
129 | { |
||
130 | exit("Usage: ./vendor/bin/lumen-swoole {stop|restart|reload}\r\n"); |
||
0 ignored issues
–
show
|
|||
131 | } |
||
132 | |||
133 | /** |
||
134 | * Stop the server. |
||
135 | * |
||
136 | * @throws \Exception |
||
137 | * |
||
138 | * @return void |
||
139 | */ |
||
140 | public function stop() |
||
141 | { |
||
142 | $pid = $this->getPid(); |
||
143 | |||
144 | echo "Server is stopping...\r\n"; |
||
145 | |||
146 | posix_kill($pid, SIGTERM); |
||
147 | |||
148 | usleep(500); |
||
149 | |||
150 | posix_kill($pid, SIGKILL); |
||
151 | |||
152 | unlink($this->pidFile); |
||
153 | } |
||
154 | |||
155 | /** |
||
156 | * Reload the server. |
||
157 | * |
||
158 | * @throws \Exception |
||
159 | * |
||
160 | * @return void |
||
161 | */ |
||
162 | public function reload() |
||
163 | { |
||
164 | posix_kill($this->getPid(), SIGUSR1); |
||
165 | } |
||
166 | |||
167 | /** |
||
168 | * Restart the server. |
||
169 | * |
||
170 | * @return void |
||
171 | */ |
||
172 | public function restart() |
||
173 | { |
||
174 | $cmd = exec('ps -eo args | grep lumen-swoole | grep -v grep | head -n 1'); |
||
175 | |||
176 | $this->stop(); |
||
177 | |||
178 | usleep(2000); |
||
179 | |||
180 | echo "Server is starting...\r\n"; |
||
181 | |||
182 | exec($cmd); |
||
183 | } |
||
184 | |||
185 | /** |
||
186 | * Get process identifier of this server. |
||
187 | * |
||
188 | * @throws \Exception |
||
189 | * |
||
190 | * @return bool|string |
||
191 | */ |
||
192 | protected function getPid() |
||
193 | { |
||
194 | $this->pidFile = __DIR__.'/../../../../storage/lumen-swoole.pid'; |
||
195 | |||
196 | if (!file_exists($this->pidFile)) { |
||
197 | throw new \Exception('The Server is not running.'); |
||
198 | } |
||
199 | |||
200 | $pid = file_get_contents($this->pidFile); |
||
201 | |||
202 | if (posix_getpgid($pid)) { |
||
203 | return $pid; |
||
204 | } |
||
205 | |||
206 | unlink($this->pidFile); |
||
207 | |||
208 | return false; |
||
209 | } |
||
210 | |||
211 | /** |
||
212 | * Set the error handling for the application. |
||
213 | * |
||
214 | * @return void |
||
215 | */ |
||
216 | protected function registerErrorHandling() |
||
217 | { |
||
218 | error_reporting(-1); |
||
219 | |||
220 | set_error_handler(function ($level, $message, $file = '', $line = 0) { |
||
221 | if (error_reporting() & $level) { |
||
222 | throw new ErrorException($message, 0, $level, $file, $line); |
||
223 | } |
||
224 | }); |
||
225 | |||
226 | set_exception_handler(function ($e) { |
||
227 | $this->handleUncaughtException($e); |
||
228 | }); |
||
229 | |||
230 | register_shutdown_function(function () { |
||
231 | $this->handleShutdown(); |
||
232 | }); |
||
233 | } |
||
234 | |||
235 | /** |
||
236 | * Handle an uncaught exception instance. |
||
237 | * |
||
238 | * @param \Throwable $e |
||
239 | * |
||
240 | * @return void |
||
241 | */ |
||
242 | protected function handleUncaughtException($e) |
||
243 | { |
||
244 | if ($e instanceof Error) { |
||
245 | $e = new FatalThrowableError($e); |
||
246 | } |
||
247 | |||
248 | (new Handler())->renderForConsole(new ConsoleOutput(), $e); |
||
249 | } |
||
250 | |||
251 | /** |
||
252 | * Handle the application shutdown routine. |
||
253 | * |
||
254 | * @return void |
||
255 | */ |
||
256 | protected function handleShutdown() |
||
257 | { |
||
258 | if (!is_null($error = error_get_last()) && $this->isFatalError($error['type'])) { |
||
259 | $this->handleUncaughtException(new FatalErrorException( |
||
0 ignored issues
–
show
new \Symfony\Component\D...file'], $error['line']) is of type object<Symfony\Component...on\FatalErrorException> , but the function expects a object<Throwable> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
260 | $error['message'], |
||
261 | $error['type'], |
||
262 | 0, |
||
263 | $error['file'], |
||
264 | $error['line'] |
||
265 | )); |
||
266 | } |
||
267 | } |
||
268 | |||
269 | /** |
||
270 | * Determine if the error type is fatal. |
||
271 | * |
||
272 | * @param int $type |
||
273 | * |
||
274 | * @return bool |
||
275 | */ |
||
276 | protected function isFatalError($type) |
||
277 | { |
||
278 | $errorCodes = [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE]; |
||
279 | |||
280 | if (defined('FATAL_ERROR')) { |
||
281 | $errorCodes[] = FATAL_ERROR; |
||
282 | } |
||
283 | |||
284 | return in_array($type, $errorCodes); |
||
285 | } |
||
286 | } |
||
287 |
An exit expression should only be used in rare cases. For example, if you write a short command line script.
In most cases however, using an
exit
expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.