This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | namespace PHPDaemon\Request; |
||
3 | |||
4 | use PHPDaemon\Core\AppInstance; |
||
5 | use PHPDaemon\Core\Daemon; |
||
6 | use PHPDaemon\Core\EventLoop; |
||
7 | |||
8 | abstract class Generic |
||
9 | { |
||
10 | use \PHPDaemon\Traits\ClassWatchdog; |
||
11 | use \PHPDaemon\Traits\StaticObjectWatchdog; |
||
12 | use \PHPDaemon\Traits\EventHandlers; |
||
13 | |||
14 | /** |
||
15 | * State: finished. |
||
16 | * @var integer |
||
17 | */ |
||
18 | const STATE_FINISHED = 1; |
||
19 | |||
20 | /** |
||
21 | * State: waiting. |
||
22 | * @var integer |
||
23 | */ |
||
24 | const STATE_WAITING = 2; |
||
25 | |||
26 | /** |
||
27 | * State: running. |
||
28 | * @var integer |
||
29 | */ |
||
30 | const STATE_RUNNING = 3; |
||
31 | |||
32 | /** |
||
33 | * Related Application instance |
||
34 | * @var \PHPDaemon\Core\AppInstance |
||
35 | */ |
||
36 | public $appInstance; |
||
37 | |||
38 | /** |
||
39 | * Is this request aborted? |
||
40 | * @var boolean |
||
41 | */ |
||
42 | protected $aborted = false; |
||
43 | |||
44 | /** |
||
45 | * State |
||
46 | * @var integer (self::STATE_*) |
||
47 | */ |
||
48 | protected $state = self::STATE_WAITING; |
||
49 | |||
50 | /** |
||
51 | * Attributes |
||
52 | * @var \StdCLass |
||
53 | */ |
||
54 | public $attrs; |
||
55 | |||
56 | /** |
||
57 | * Registered shutdown functions |
||
58 | * @var array |
||
59 | */ |
||
60 | protected $shutdownFuncs = []; |
||
61 | |||
62 | /** |
||
63 | * Is this request running? |
||
64 | * @var boolean |
||
65 | */ |
||
66 | protected $running = false; |
||
67 | |||
68 | /** |
||
69 | * Upstream |
||
70 | * @var object |
||
71 | */ |
||
72 | protected $upstream; |
||
73 | |||
74 | /** |
||
75 | * Event |
||
76 | * @var object |
||
77 | */ |
||
78 | protected $ev; |
||
79 | |||
80 | /** |
||
81 | * Current sleep() time |
||
82 | * @var float |
||
83 | */ |
||
84 | protected $sleepTime = 0; |
||
85 | |||
86 | /** |
||
87 | * Priority |
||
88 | * @var integer |
||
89 | */ |
||
90 | protected $priority = null; |
||
91 | |||
92 | /** |
||
93 | * Current code point |
||
94 | * @var mixed |
||
95 | */ |
||
96 | protected $codepoint; |
||
97 | |||
98 | protected $autoinit = false; // @TODO: remove this option in future version |
||
99 | |||
100 | /** |
||
101 | * Log |
||
102 | * @param string $msg Message |
||
103 | * @return void |
||
104 | */ |
||
105 | public function log($msg) |
||
106 | { |
||
107 | Daemon::log(get_class($this) . ': ' . $msg); |
||
108 | } |
||
109 | |||
110 | /** |
||
111 | * Constructor |
||
112 | * @param AppInstance $appInstance Parent AppInstance. |
||
113 | * @param IRequestUpstream $upstream Upstream. |
||
114 | * @param object $parent Source request. |
||
0 ignored issues
–
show
|
|||
115 | */ |
||
116 | public function __construct($appInstance, IRequestUpstream $upstream, $parent = null) |
||
117 | { |
||
118 | ++Daemon::$process->reqCounter; |
||
119 | $this->appInstance = $appInstance; |
||
120 | $this->upstream = $upstream; |
||
121 | $this->ev = EventLoop::$instance->timer([$this, 'eventCall']); |
||
122 | if ($this->priority !== null) { |
||
123 | $this->ev->priority = $this->priority; |
||
124 | } |
||
125 | $this->preinit($parent); |
||
126 | if ($this->autoinit) { |
||
127 | $this->callInit(); |
||
128 | } |
||
129 | } |
||
130 | |||
131 | public function callInit() |
||
132 | { |
||
133 | $this->onWakeup(); |
||
134 | try { |
||
135 | $this->init(); |
||
136 | } catch (\Throwable $e) { |
||
0 ignored issues
–
show
The class
Throwable does not exist. Did you forget a USE statement, or did you not list all dependencies?
Scrutinizer analyzes your It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis. ![]() |
|||
137 | Daemon::uncaughtExceptionHandler($e); |
||
138 | $this->finish(); |
||
139 | return; |
||
140 | } |
||
141 | $this->onSleep(); |
||
142 | } |
||
143 | |||
144 | /** |
||
145 | * Uncaught exception handler |
||
146 | * @param $e |
||
147 | * @return boolean|null Handled? |
||
148 | */ |
||
149 | public function handleException($e) |
||
0 ignored issues
–
show
|
|||
150 | { |
||
151 | } |
||
152 | |||
153 | /** |
||
154 | * Is this request aborted? |
||
155 | * @return boolean |
||
156 | */ |
||
157 | public function isAborted() |
||
158 | { |
||
159 | return $this->aborted; |
||
160 | } |
||
161 | |||
162 | /** |
||
163 | * Is this request finished? |
||
164 | * @return boolean |
||
165 | */ |
||
166 | public function isFinished() |
||
167 | { |
||
168 | return $this->state === static::STATE_FINISHED; |
||
169 | } |
||
170 | |||
171 | /** |
||
172 | * Is this request running? |
||
173 | * @return boolean |
||
174 | */ |
||
175 | public function isRunning() |
||
176 | { |
||
177 | return $this->running; |
||
178 | } |
||
179 | |||
180 | /** |
||
181 | * Output some data |
||
182 | * @param string $s String to out |
||
183 | * @param bool $flush |
||
184 | * @return boolean|null Success |
||
185 | */ |
||
186 | public function out($s, $flush = true) |
||
187 | { |
||
188 | } |
||
189 | |||
190 | /** |
||
191 | * Called when request iterated. |
||
192 | * @return integer Status. |
||
0 ignored issues
–
show
|
|||
193 | */ |
||
194 | protected function run() |
||
195 | { |
||
196 | } |
||
197 | |||
198 | /** |
||
199 | * Event handler of Request, called by Evtimer |
||
200 | * @param $arg |
||
201 | * @return void |
||
202 | */ |
||
203 | public function eventCall($arg) |
||
0 ignored issues
–
show
|
|||
204 | { |
||
205 | try { |
||
206 | if ($this->state === Generic::STATE_FINISHED) { |
||
207 | $this->finish(); |
||
208 | $this->free(); |
||
209 | return; |
||
210 | } |
||
211 | $this->state = Generic::STATE_RUNNING; |
||
212 | $this->onWakeup(); |
||
213 | $throw = false; |
||
214 | try { |
||
215 | $ret = $this->run(); |
||
216 | if (($ret === Generic::STATE_FINISHED) || ($ret === null)) { |
||
217 | $this->finish(); |
||
218 | } elseif ($ret === Generic::STATE_WAITING) { |
||
219 | $this->state = $ret; |
||
220 | } |
||
221 | } catch (RequestSleep $e) { |
||
222 | $this->state = Generic::STATE_WAITING; |
||
223 | } catch (RequestTerminated $e) { |
||
224 | $this->state = Generic::STATE_FINISHED; |
||
225 | } catch (\Throwable $e) { |
||
0 ignored issues
–
show
The class
Throwable does not exist. Did you forget a USE statement, or did you not list all dependencies?
Scrutinizer analyzes your It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis. ![]() |
|||
226 | if (!$this->handleException($e)) { |
||
0 ignored issues
–
show
The expression
$this->handleException($e) of type boolean|null is loosely compared to false ; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.
If an expression can have both $a = canBeFalseAndNull();
// Instead of
if ( ! $a) { }
// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
![]() |
|||
227 | $throw = true; |
||
228 | } |
||
229 | } |
||
230 | if ($this->state === Generic::STATE_FINISHED) { |
||
231 | $this->finish(); |
||
232 | } |
||
233 | $this->onSleep(); |
||
234 | if ($throw) { |
||
235 | throw $e; |
||
236 | } |
||
237 | } catch (\Throwable $e) { |
||
0 ignored issues
–
show
The class
Throwable does not exist. Did you forget a USE statement, or did you not list all dependencies?
Scrutinizer analyzes your It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis. ![]() |
|||
238 | Daemon::uncaughtExceptionHandler($e); |
||
239 | $this->finish(); |
||
240 | return; |
||
241 | } |
||
242 | if ($this->state === Generic::STATE_WAITING) { |
||
243 | $this->ev->add($this->sleepTime); |
||
244 | } |
||
245 | } |
||
246 | |||
247 | /** |
||
248 | * Frees the request |
||
249 | * @return void |
||
250 | */ |
||
251 | public function free() |
||
252 | { |
||
253 | if ($this->ev) { |
||
254 | $this->ev->free(); |
||
255 | $this->ev = null; |
||
256 | } |
||
257 | if (isset($this->upstream)) { |
||
258 | $this->upstream->freeRequest($this); |
||
259 | $this->upstream = null; |
||
260 | } |
||
261 | } |
||
262 | |||
263 | /** |
||
264 | * Sets the priority |
||
265 | * @param integer Priority |
||
266 | * @return void |
||
267 | */ |
||
268 | public function setPriority($p) |
||
269 | { |
||
270 | $this->priority = $p; |
||
271 | if ($this->ev !== null) { |
||
272 | $this->ev->priority = $p; |
||
273 | } |
||
274 | } |
||
275 | |||
276 | /** |
||
277 | * Preparing before init |
||
278 | * @param object Source request |
||
279 | * @return void |
||
280 | */ |
||
281 | protected function preinit($req) |
||
282 | { |
||
283 | if ($req === null) { |
||
284 | $req = new \stdClass; |
||
285 | $req->attrs = new \stdClass; |
||
286 | } |
||
287 | |||
288 | $this->attrs = $req->attrs; |
||
289 | } |
||
290 | |||
291 | /** |
||
292 | * This magic method called when the object casts to string |
||
293 | * @return string Description |
||
294 | */ |
||
295 | public function __toString() |
||
296 | { |
||
297 | return 'Request of type ' . get_class($this); |
||
298 | } |
||
299 | |||
300 | /** |
||
301 | * Called when request constructs |
||
302 | * @return void |
||
303 | */ |
||
304 | protected function init() |
||
305 | { |
||
306 | } |
||
307 | |||
308 | /** |
||
309 | * Get string value from the given variable |
||
310 | * @param Reference of variable. |
||
311 | * @param array Optional. Possible values. |
||
312 | * @return string Value. |
||
313 | */ |
||
314 | public static function getString(&$var, $values = null) |
||
315 | { |
||
316 | if (!is_string($var)) { |
||
317 | $var = ''; |
||
318 | } |
||
319 | View Code Duplication | if ($values !== null) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
320 | return in_array($var, $values, true) ? $var : $values[0]; |
||
321 | } |
||
322 | |||
323 | return $var; |
||
324 | } |
||
325 | |||
326 | /** |
||
327 | * Get string value from the given variable |
||
328 | * @param Reference of variable. |
||
329 | * @return string Value. |
||
330 | */ |
||
331 | public static function getMixed(&$var) |
||
332 | { |
||
333 | return $var; |
||
334 | } |
||
335 | |||
336 | /** |
||
337 | * Get array value from the given variable |
||
338 | * @param Reference of variable. |
||
339 | * @param array Optional. Filter callback. |
||
340 | * @return string Value. |
||
0 ignored issues
–
show
|
|||
341 | */ |
||
342 | public static function getArray(&$var, $filter = null) |
||
343 | { |
||
344 | if (!is_array($var)) { |
||
345 | return []; |
||
346 | } |
||
347 | if ($filter !== null) { |
||
348 | return array_filter($var, $filter); |
||
349 | } |
||
350 | |||
351 | return $var; |
||
352 | } |
||
353 | |||
354 | /** |
||
355 | * Get integer value from the given variable |
||
356 | * @param Reference of variable. |
||
357 | * @param array Optional. Possible values. |
||
358 | * @return string Value. |
||
359 | */ |
||
360 | public static function getInteger(&$var, $values = null) |
||
361 | { |
||
362 | if (is_string($var) && ctype_digit($var)) { |
||
363 | $var = (int)$var; |
||
364 | } |
||
365 | if (!is_int($var)) { |
||
366 | return 0; |
||
367 | } |
||
368 | View Code Duplication | if ($values !== null) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
369 | return in_array($var, $values, true) ? $var : $values[0]; |
||
370 | } |
||
371 | |||
372 | return $var; |
||
373 | } |
||
374 | |||
375 | /** |
||
376 | * Called when the connection is ready to accept new data |
||
377 | * @return void |
||
378 | */ |
||
379 | public function onWrite() |
||
380 | { |
||
381 | } |
||
382 | |||
383 | /** |
||
384 | * Adds new callback called before the request finished |
||
385 | * @param callable $callback |
||
386 | * @return void |
||
387 | */ |
||
388 | public function registerShutdownFunction($callback) |
||
389 | { |
||
390 | $this->shutdownFuncs[] = $callback; |
||
391 | } |
||
392 | |||
393 | /** |
||
394 | * Remove the given callback |
||
395 | * @param callable $callback |
||
396 | * @return void |
||
397 | */ |
||
398 | public function unregisterShutdownFunction($callback) |
||
399 | { |
||
400 | if (($k = array_search($callback, $this->shutdownFuncs)) !== false) { |
||
401 | unset($this->shutdownFuncs[$k]); |
||
402 | } |
||
403 | } |
||
404 | |||
405 | /** |
||
406 | * Helper for easy switching between several interruptable stages of request's execution |
||
407 | * @param string Name |
||
408 | * @return boolean Execute |
||
409 | */ |
||
410 | public function codepoint($p) |
||
411 | { |
||
412 | if ($this->codepoint !== $p) { |
||
413 | $this->codepoint = $p; |
||
414 | return true; |
||
415 | } |
||
416 | |||
417 | return false; |
||
418 | } |
||
419 | |||
420 | /** |
||
421 | * Delays the request execution for the given number of seconds |
||
422 | * |
||
423 | * @param integer $time Time to sleep in seconds |
||
424 | * @param boolean $set Set this parameter to true when use call it outside of Request->run() or if you don't want to interrupt execution now |
||
425 | * @throws RequestSleep |
||
426 | * @return void |
||
427 | */ |
||
428 | public function sleep($time = 0, $set = false) |
||
429 | { |
||
430 | if ($this->state === Generic::STATE_FINISHED) { |
||
431 | return; |
||
432 | } |
||
433 | if ($this->state !== Generic::STATE_RUNNING) { |
||
434 | $set = true; |
||
435 | } |
||
436 | |||
437 | $this->sleepTime = $time; |
||
0 ignored issues
–
show
The property
$sleepTime was declared of type double , but $time is of type integer . Maybe add a type cast?
This check looks for assignments to scalar types that may be of the wrong type. To ensure the code behaves as expected, it may be a good idea to add an explicit type cast. $answer = 42;
$correct = false;
$correct = (bool) $answer;
![]() |
|||
438 | |||
439 | if (!$set) { |
||
440 | throw new RequestSleep; |
||
441 | } else { |
||
442 | $this->ev->del(); |
||
443 | $this->ev->add($this->sleepTime); |
||
444 | } |
||
445 | |||
446 | $this->state = Generic::STATE_WAITING; |
||
447 | } |
||
448 | |||
449 | /** |
||
450 | * Throws terminating exception |
||
451 | * @param $s |
||
452 | * @throws RequestTerminated |
||
453 | * @return void |
||
454 | */ |
||
455 | public function terminate($s = null) |
||
456 | { |
||
457 | if (is_string($s)) { |
||
458 | $this->out($s); |
||
459 | } |
||
460 | |||
461 | throw new RequestTerminated; |
||
462 | } |
||
463 | |||
464 | /** |
||
465 | * Cancel current sleep |
||
466 | * @return void |
||
467 | */ |
||
468 | public function wakeup() |
||
469 | { |
||
470 | if ($this->state === Generic::STATE_WAITING) { |
||
471 | $this->ev->del(); |
||
472 | $this->ev->add(0); |
||
473 | } |
||
474 | } |
||
475 | |||
476 | /** |
||
477 | * Called to check if Request is ready |
||
478 | * @return boolean Ready? |
||
479 | */ |
||
480 | public function checkIfReady() |
||
481 | { |
||
482 | return true; |
||
483 | } |
||
484 | |||
485 | /** |
||
486 | * Called when the request aborted |
||
487 | * @return void |
||
488 | */ |
||
489 | public function onAbort() |
||
490 | { |
||
491 | } |
||
492 | |||
493 | /** |
||
494 | * Called when the request finished |
||
495 | * @return void |
||
496 | */ |
||
497 | public function onFinish() |
||
498 | { |
||
499 | } |
||
500 | |||
501 | /** |
||
502 | * Called when the request wakes up |
||
503 | * @return void |
||
504 | */ |
||
505 | public function onWakeup() |
||
506 | { |
||
507 | $this->running = true; |
||
508 | Daemon::$req = $this; |
||
509 | Daemon::$context = $this; |
||
510 | Daemon::$process->setState(Daemon::WSTATE_BUSY); |
||
0 ignored issues
–
show
The method
setState does only exist in PHPDaemon\Thread\Worker , but not in PHPDaemon\Thread\IPC and PHPDaemon\Thread\Master .
It seems like the method you are trying to call exists only in some of the possible types. Let’s take a look at an example: class A
{
public function foo() { }
}
class B extends A
{
public function bar() { }
}
/**
* @param A|B $x
*/
function someFunction($x)
{
$x->foo(); // This call is fine as the method exists in A and B.
$x->bar(); // This method only exists in B and might cause an error.
}
Available Fixes
![]() |
|||
511 | } |
||
512 | |||
513 | /** |
||
514 | * Called when the request starts sleep |
||
515 | * @return void |
||
516 | */ |
||
517 | public function onSleep() |
||
518 | { |
||
519 | Daemon::$req = null; |
||
520 | Daemon::$context = null; |
||
521 | $this->running = false; |
||
522 | Daemon::$process->setState(Daemon::WSTATE_IDLE); |
||
0 ignored issues
–
show
The method
setState does only exist in PHPDaemon\Thread\Worker , but not in PHPDaemon\Thread\IPC and PHPDaemon\Thread\Master .
It seems like the method you are trying to call exists only in some of the possible types. Let’s take a look at an example: class A
{
public function foo() { }
}
class B extends A
{
public function bar() { }
}
/**
* @param A|B $x
*/
function someFunction($x)
{
$x->foo(); // This call is fine as the method exists in A and B.
$x->bar(); // This method only exists in B and might cause an error.
}
Available Fixes
![]() |
|||
523 | } |
||
524 | |||
525 | /** |
||
526 | * Aborts the request |
||
527 | * @return void |
||
528 | */ |
||
529 | public function abort() |
||
530 | { |
||
531 | if ($this->aborted) { |
||
532 | return; |
||
533 | } |
||
534 | |||
535 | $this->aborted = true; |
||
536 | $this->onWakeup(); |
||
537 | $this->onAbort(); |
||
538 | |||
539 | if ((ignore_user_abort() === 1) |
||
540 | && (($this->state === Generic::STATE_RUNNING) || ($this->state === Generic::STATE_WAITING)) |
||
541 | && !Daemon::$compatMode |
||
542 | ) { |
||
543 | $this->upstream->endRequest($this); |
||
544 | } else { |
||
545 | $this->finish(-1); |
||
546 | } |
||
547 | |||
548 | $this->onSleep(); |
||
549 | } |
||
550 | |||
551 | /** |
||
552 | * Finish the request |
||
553 | * @param integer Optional. Status. 0 - normal, -1 - abort, -2 - termination |
||
554 | * @param boolean Optional. Zombie. Default is false |
||
555 | * @return void |
||
556 | */ |
||
557 | public function finish($status = 0, $zombie = false) |
||
558 | { |
||
559 | if ($this->state === Generic::STATE_FINISHED) { |
||
560 | return; |
||
561 | } |
||
562 | |||
563 | if (!$zombie) { |
||
564 | $this->state = Generic::STATE_FINISHED; |
||
565 | } |
||
566 | |||
567 | if (!($r = $this->running)) { |
||
568 | $this->onWakeup(); |
||
569 | } |
||
570 | |||
571 | while (($cb = array_shift($this->shutdownFuncs)) !== null) { |
||
572 | try { |
||
573 | $cb($this); |
||
574 | } catch (\Throwable $e) { |
||
0 ignored issues
–
show
The class
Throwable does not exist. Did you forget a USE statement, or did you not list all dependencies?
Scrutinizer analyzes your It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis. ![]() |
|||
575 | Daemon::uncaughtExceptionHandler($e); |
||
576 | // @TODO: break? |
||
577 | } |
||
578 | } |
||
579 | |||
580 | if (!$r) { |
||
581 | $this->onSleep(); |
||
582 | } |
||
583 | |||
584 | $this->event('finish'); |
||
585 | $this->onFinish(); |
||
586 | $this->cleanupEventHandlers(); |
||
587 | |||
588 | if (Daemon::$compatMode) { |
||
589 | return; |
||
590 | } |
||
591 | |||
592 | ++Daemon::$process->counterGC; |
||
593 | |||
594 | if (Daemon::$compatMode) { |
||
595 | return; |
||
596 | } |
||
597 | |||
598 | if (!Daemon::$obInStack) { // preventing recursion |
||
599 | ob_flush(); |
||
600 | } |
||
601 | |||
602 | if ($status !== -1) { |
||
603 | $appStatus = 0; |
||
604 | $this->postFinishHandler(function () use ($appStatus, $status) { |
||
605 | $this->upstream->endRequest($this, $appStatus, $status); |
||
606 | $this->free(); |
||
607 | }); |
||
608 | } else { |
||
609 | $this->free(); |
||
610 | } |
||
611 | } |
||
612 | |||
613 | /** |
||
614 | * Called after request finish |
||
615 | * @param callable $cb |
||
0 ignored issues
–
show
Should the type for parameter
$cb not be callable|null ?
This check looks for It makes a suggestion as to what type it considers more descriptive. Most often this is a case of a parameter that can be null in addition to its declared types. ![]() |
|||
616 | * @return void |
||
617 | */ |
||
618 | protected function postFinishHandler($cb = null) |
||
619 | { |
||
620 | if ($cb !== null) { |
||
621 | $cb(); |
||
622 | } |
||
623 | } |
||
624 | } |
||
625 |
This check looks for
@param
annotations where the type inferred by our type inference engine differs from the declared type.It makes a suggestion as to what type it considers more descriptive.
Most often this is a case of a parameter that can be null in addition to its declared types.