Code Coverage |
||||||||||||||||
Lines |
Branches |
Paths |
Functions and Methods |
Classes and Traits |
||||||||||||
| Total | |
100.00% |
43 / 43 |
|
91.84% |
45 / 49 |
|
57.14% |
20 / 35 |
|
50.00% |
4 / 8 |
CRAP | |
0.00% |
0 / 1 |
| FrankenPhpWorker | |
100.00% |
43 / 43 |
|
91.84% |
45 / 49 |
|
57.14% |
20 / 35 |
|
100.00% |
8 / 8 |
55.71 | |
100.00% |
1 / 1 |
| __construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| configure | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| serve | |
100.00% |
10 / 10 |
|
100.00% |
5 / 5 |
|
75.00% |
3 / 4 |
|
100.00% |
1 / 1 |
2.06 | |||
| retires | |
100.00% |
7 / 7 |
|
100.00% |
9 / 9 |
|
55.56% |
5 / 9 |
|
100.00% |
1 / 1 |
7.19 | |||
| requestsSetting | |
100.00% |
6 / 6 |
|
87.50% |
7 / 8 |
|
60.00% |
3 / 5 |
|
100.00% |
1 / 1 |
3.58 | |||
| memorySetting | |
100.00% |
8 / 8 |
|
87.50% |
7 / 8 |
|
60.00% |
3 / 5 |
|
100.00% |
1 / 1 |
3.58 | |||
| setting | |
100.00% |
3 / 3 |
|
90.00% |
9 / 10 |
|
33.33% |
2 / 6 |
|
100.00% |
1 / 1 |
5.67 | |||
| defaultMaxMemory | |
100.00% |
3 / 3 |
|
85.71% |
6 / 7 |
|
50.00% |
2 / 4 |
|
100.00% |
1 / 1 |
4.12 | |||
| 1 | <?php |
| 2 | |
| 3 | declare(strict_types=1); |
| 4 | |
| 5 | namespace Celema\Core\Runtime; |
| 6 | |
| 7 | use Celema\Core\App; |
| 8 | use Celema\Core\Exception\RuntimeException; |
| 9 | use Closure; |
| 10 | |
| 11 | /** |
| 12 | * Handles requests in a FrankenPHP worker until FrankenPHP stops it or it |
| 13 | * retires: after a request that left the app unusable, after a configured |
| 14 | * number of requests, or above a memory threshold. FrankenPHP then starts |
| 15 | * a fresh worker. |
| 16 | * |
| 17 | * @internal |
| 18 | */ |
| 19 | final class FrankenPhpWorker |
| 20 | { |
| 21 | public const string MAX_REQUESTS = 'CELEMA_WORKER_MAX_REQUESTS'; |
| 22 | public const string MAX_MEMORY = 'CELEMA_WORKER_MAX_MEMORY'; |
| 23 | |
| 24 | /** |
| 25 | * @param Closure(callable(): void): bool $handleRequest Waits for a request and runs the |
| 26 | * callback for it; returns false when the worker should stop (frankenphp_handle_request). |
| 27 | */ |
| 28 | public function __construct( |
| 29 | private readonly Closure $handleRequest, |
| 30 | public readonly int $maxRequests, |
| 31 | public readonly int $maxMemory, |
| 32 | ) {} |
| 33 | |
| 34 | /** |
| 35 | * Explicit limits win over the worker's environment (for example the |
| 36 | * `env` directive of a Caddyfile worker block). Without either, the |
| 37 | * request limit is off and the memory limit is 80 % of memory_limit. |
| 38 | * |
| 39 | * @param Closure(callable(): void): bool $handleRequest |
| 40 | */ |
| 41 | public static function configure( |
| 42 | Closure $handleRequest, |
| 43 | ?int $maxRequests = null, |
| 44 | ?int $maxMemory = null, |
| 45 | ): self { |
| 46 | return new self( |
| 47 | $handleRequest, |
| 48 | $maxRequests ?? self::requestsSetting() ?? 0, |
| 49 | $maxMemory ?? self::memorySetting() ?? self::defaultMaxMemory(), |
| 50 | ); |
| 51 | } |
| 52 | |
| 53 | public function serve(App $app): false |
| 54 | { |
| 55 | // A client that disconnects must not abort a request halfway, as |
| 56 | // its teardown has to run before the worker takes the next one. |
| 57 | ignore_user_abort(true); |
| 58 | $handled = 0; |
| 59 | |
| 60 | do { |
| 61 | $running = ($this->handleRequest)(static function () use ($app): void { |
| 62 | // PHP's stat cache would keep file sizes and modification |
| 63 | // times from earlier requests. |
| 64 | clearstatcache(); |
| 65 | $app->run(); |
| 66 | }); |
| 67 | $handled++; |
| 68 | gc_collect_cycles(); |
| 69 | } while ($running && !$this->retires($app, $handled)); |
| 70 | |
| 71 | return false; |
| 72 | } |
| 73 | |
| 74 | private function retires(App $app, int $handled): bool |
| 75 | { |
| 76 | return ( |
| 77 | !$app->reusable() |
| 78 | || $this->maxRequests > 0 |
| 79 | && $handled >= $this->maxRequests |
| 80 | || $this->maxMemory > 0 |
| 81 | && memory_get_usage(true) >= $this->maxMemory |
| 82 | ); |
| 83 | } |
| 84 | |
| 85 | private static function requestsSetting(): ?int |
| 86 | { |
| 87 | $value = self::setting(self::MAX_REQUESTS); |
| 88 | |
| 89 | if ($value === null) { |
| 90 | return null; |
| 91 | } |
| 92 | |
| 93 | if (preg_match('/^\d+$/', $value) !== 1) { |
| 94 | throw new RuntimeException(self::MAX_REQUESTS . ' must be a number of requests, 0 for no limit'); |
| 95 | } |
| 96 | |
| 97 | return (int) $value; |
| 98 | } |
| 99 | |
| 100 | private static function memorySetting(): ?int |
| 101 | { |
| 102 | $value = self::setting(self::MAX_MEMORY); |
| 103 | |
| 104 | if ($value === null) { |
| 105 | return null; |
| 106 | } |
| 107 | |
| 108 | if (preg_match('/^\d+[KMG]?$/i', $value) !== 1) { |
| 109 | throw new RuntimeException( |
| 110 | self::MAX_MEMORY . ' must be a number of bytes, optionally with K, M or G, 0 for no limit', |
| 111 | ); |
| 112 | } |
| 113 | |
| 114 | return ini_parse_quantity($value); |
| 115 | } |
| 116 | |
| 117 | /** @return ?non-empty-string */ |
| 118 | private static function setting(string $name): ?string |
| 119 | { |
| 120 | $value = $_SERVER[$name] ?? $_ENV[$name] ?? getenv($name); |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 122 | |
| 123 | return $value === '' ? null : $value; |
| 124 | } |
| 125 | |
| 126 | private static function defaultMaxMemory(): int |
| 127 | { |
| 128 | $limit = (string) ini_get('memory_limit'); |
| 129 | $bytes = $limit === '' ? 0 : ini_parse_quantity($limit); |
| 130 | |
| 131 | return $bytes > 0 ? intdiv($bytes * 4, 5) : 0; |
| 132 | } |
| 133 | } |
Below are the source code lines that represent each code path as identified by Xdebug. Please note a path is not
necessarily coterminous with a line, a line may contain multiple paths and therefore show up more than once.
Please also be aware that some paths may include implicit rather than explicit branches, e.g. an if statement
always has an else as part of its logical flow even if you didn't write one.
| 29 | private readonly Closure $handleRequest, |
| 30 | public readonly int $maxRequests, |
| 31 | public readonly int $maxMemory, |
| 32 | ) {} |
| 42 | Closure $handleRequest, |
| 43 | ?int $maxRequests = null, |
| 44 | ?int $maxMemory = null, |
| 45 | ): self { |
| 46 | return new self( |
| 47 | $handleRequest, |
| 48 | $maxRequests ?? self::requestsSetting() ?? 0, |
| 49 | $maxMemory ?? self::memorySetting() ?? self::defaultMaxMemory(), |
| 50 | ); |
| 51 | } |
| 128 | $limit = (string) ini_get('memory_limit'); |
| 129 | $bytes = $limit === '' ? 0 : ini_parse_quantity($limit); |
| 129 | $bytes = $limit === '' ? 0 : ini_parse_quantity($limit); |
| 129 | $bytes = $limit === '' ? 0 : ini_parse_quantity($limit); |
| 130 | |
| 131 | return $bytes > 0 ? intdiv($bytes * 4, 5) : 0; |
| 131 | return $bytes > 0 ? intdiv($bytes * 4, 5) : 0; |
| 131 | return $bytes > 0 ? intdiv($bytes * 4, 5) : 0; |
| 132 | } |
| 128 | $limit = (string) ini_get('memory_limit'); |
| 129 | $bytes = $limit === '' ? 0 : ini_parse_quantity($limit); |
| 129 | $bytes = $limit === '' ? 0 : ini_parse_quantity($limit); |
| 129 | $bytes = $limit === '' ? 0 : ini_parse_quantity($limit); |
| 130 | |
| 131 | return $bytes > 0 ? intdiv($bytes * 4, 5) : 0; |
| 131 | return $bytes > 0 ? intdiv($bytes * 4, 5) : 0; |
| 131 | return $bytes > 0 ? intdiv($bytes * 4, 5) : 0; |
| 132 | } |
| 128 | $limit = (string) ini_get('memory_limit'); |
| 129 | $bytes = $limit === '' ? 0 : ini_parse_quantity($limit); |
| 129 | $bytes = $limit === '' ? 0 : ini_parse_quantity($limit); |
| 129 | $bytes = $limit === '' ? 0 : ini_parse_quantity($limit); |
| 130 | |
| 131 | return $bytes > 0 ? intdiv($bytes * 4, 5) : 0; |
| 131 | return $bytes > 0 ? intdiv($bytes * 4, 5) : 0; |
| 131 | return $bytes > 0 ? intdiv($bytes * 4, 5) : 0; |
| 132 | } |
| 128 | $limit = (string) ini_get('memory_limit'); |
| 129 | $bytes = $limit === '' ? 0 : ini_parse_quantity($limit); |
| 129 | $bytes = $limit === '' ? 0 : ini_parse_quantity($limit); |
| 129 | $bytes = $limit === '' ? 0 : ini_parse_quantity($limit); |
| 130 | |
| 131 | return $bytes > 0 ? intdiv($bytes * 4, 5) : 0; |
| 131 | return $bytes > 0 ? intdiv($bytes * 4, 5) : 0; |
| 131 | return $bytes > 0 ? intdiv($bytes * 4, 5) : 0; |
| 132 | } |
| 102 | $value = self::setting(self::MAX_MEMORY); |
| 103 | |
| 104 | if ($value === null) { |
| 105 | return null; |
| 102 | $value = self::setting(self::MAX_MEMORY); |
| 103 | |
| 104 | if ($value === null) { |
| 108 | if (preg_match('/^\d+[KMG]?$/i', $value) !== 1) { |
| 108 | if (preg_match('/^\d+[KMG]?$/i', $value) !== 1) { |
| 108 | if (preg_match('/^\d+[KMG]?$/i', $value) !== 1) { |
| 109 | throw new RuntimeException( |
| 110 | self::MAX_MEMORY . ' must be a number of bytes, optionally with K, M or G, 0 for no limit', |
| 102 | $value = self::setting(self::MAX_MEMORY); |
| 103 | |
| 104 | if ($value === null) { |
| 108 | if (preg_match('/^\d+[KMG]?$/i', $value) !== 1) { |
| 108 | if (preg_match('/^\d+[KMG]?$/i', $value) !== 1) { |
| 108 | if (preg_match('/^\d+[KMG]?$/i', $value) !== 1) { |
| 114 | return ini_parse_quantity($value); |
| 115 | } |
| 102 | $value = self::setting(self::MAX_MEMORY); |
| 103 | |
| 104 | if ($value === null) { |
| 108 | if (preg_match('/^\d+[KMG]?$/i', $value) !== 1) { |
| 108 | if (preg_match('/^\d+[KMG]?$/i', $value) !== 1) { |
| 108 | if (preg_match('/^\d+[KMG]?$/i', $value) !== 1) { |
| 109 | throw new RuntimeException( |
| 110 | self::MAX_MEMORY . ' must be a number of bytes, optionally with K, M or G, 0 for no limit', |
| 102 | $value = self::setting(self::MAX_MEMORY); |
| 103 | |
| 104 | if ($value === null) { |
| 108 | if (preg_match('/^\d+[KMG]?$/i', $value) !== 1) { |
| 108 | if (preg_match('/^\d+[KMG]?$/i', $value) !== 1) { |
| 108 | if (preg_match('/^\d+[KMG]?$/i', $value) !== 1) { |
| 114 | return ini_parse_quantity($value); |
| 115 | } |
| 87 | $value = self::setting(self::MAX_REQUESTS); |
| 88 | |
| 89 | if ($value === null) { |
| 90 | return null; |
| 87 | $value = self::setting(self::MAX_REQUESTS); |
| 88 | |
| 89 | if ($value === null) { |
| 93 | if (preg_match('/^\d+$/', $value) !== 1) { |
| 93 | if (preg_match('/^\d+$/', $value) !== 1) { |
| 93 | if (preg_match('/^\d+$/', $value) !== 1) { |
| 94 | throw new RuntimeException(self::MAX_REQUESTS . ' must be a number of requests, 0 for no limit'); |
| 87 | $value = self::setting(self::MAX_REQUESTS); |
| 88 | |
| 89 | if ($value === null) { |
| 93 | if (preg_match('/^\d+$/', $value) !== 1) { |
| 93 | if (preg_match('/^\d+$/', $value) !== 1) { |
| 93 | if (preg_match('/^\d+$/', $value) !== 1) { |
| 97 | return (int) $value; |
| 98 | } |
| 87 | $value = self::setting(self::MAX_REQUESTS); |
| 88 | |
| 89 | if ($value === null) { |
| 93 | if (preg_match('/^\d+$/', $value) !== 1) { |
| 93 | if (preg_match('/^\d+$/', $value) !== 1) { |
| 93 | if (preg_match('/^\d+$/', $value) !== 1) { |
| 94 | throw new RuntimeException(self::MAX_REQUESTS . ' must be a number of requests, 0 for no limit'); |
| 87 | $value = self::setting(self::MAX_REQUESTS); |
| 88 | |
| 89 | if ($value === null) { |
| 93 | if (preg_match('/^\d+$/', $value) !== 1) { |
| 93 | if (preg_match('/^\d+$/', $value) !== 1) { |
| 93 | if (preg_match('/^\d+$/', $value) !== 1) { |
| 97 | return (int) $value; |
| 98 | } |
| 74 | private function retires(App $app, int $handled): bool |
| 75 | { |
| 76 | return ( |
| 77 | !$app->reusable() |
| 78 | || $this->maxRequests > 0 |
| 79 | && $handled >= $this->maxRequests |
| 79 | && $handled >= $this->maxRequests |
| 79 | && $handled >= $this->maxRequests |
| 80 | || $this->maxMemory > 0 |
| 81 | && memory_get_usage(true) >= $this->maxMemory |
| 81 | && memory_get_usage(true) >= $this->maxMemory |
| 81 | && memory_get_usage(true) >= $this->maxMemory |
| 82 | ); |
| 83 | } |
| 74 | private function retires(App $app, int $handled): bool |
| 75 | { |
| 76 | return ( |
| 77 | !$app->reusable() |
| 78 | || $this->maxRequests > 0 |
| 79 | && $handled >= $this->maxRequests |
| 79 | && $handled >= $this->maxRequests |
| 79 | && $handled >= $this->maxRequests |
| 80 | || $this->maxMemory > 0 |
| 81 | && memory_get_usage(true) >= $this->maxMemory |
| 81 | && memory_get_usage(true) >= $this->maxMemory |
| 82 | ); |
| 83 | } |
| 74 | private function retires(App $app, int $handled): bool |
| 75 | { |
| 76 | return ( |
| 77 | !$app->reusable() |
| 78 | || $this->maxRequests > 0 |
| 79 | && $handled >= $this->maxRequests |
| 79 | && $handled >= $this->maxRequests |
| 79 | && $handled >= $this->maxRequests |
| 81 | && memory_get_usage(true) >= $this->maxMemory |
| 82 | ); |
| 83 | } |
| 74 | private function retires(App $app, int $handled): bool |
| 75 | { |
| 76 | return ( |
| 77 | !$app->reusable() |
| 78 | || $this->maxRequests > 0 |
| 79 | && $handled >= $this->maxRequests |
| 79 | && $handled >= $this->maxRequests |
| 80 | || $this->maxMemory > 0 |
| 81 | && memory_get_usage(true) >= $this->maxMemory |
| 81 | && memory_get_usage(true) >= $this->maxMemory |
| 81 | && memory_get_usage(true) >= $this->maxMemory |
| 82 | ); |
| 83 | } |
| 74 | private function retires(App $app, int $handled): bool |
| 75 | { |
| 76 | return ( |
| 77 | !$app->reusable() |
| 78 | || $this->maxRequests > 0 |
| 79 | && $handled >= $this->maxRequests |
| 79 | && $handled >= $this->maxRequests |
| 80 | || $this->maxMemory > 0 |
| 81 | && memory_get_usage(true) >= $this->maxMemory |
| 81 | && memory_get_usage(true) >= $this->maxMemory |
| 82 | ); |
| 83 | } |
| 74 | private function retires(App $app, int $handled): bool |
| 75 | { |
| 76 | return ( |
| 77 | !$app->reusable() |
| 78 | || $this->maxRequests > 0 |
| 79 | && $handled >= $this->maxRequests |
| 79 | && $handled >= $this->maxRequests |
| 81 | && memory_get_usage(true) >= $this->maxMemory |
| 82 | ); |
| 83 | } |
| 74 | private function retires(App $app, int $handled): bool |
| 75 | { |
| 76 | return ( |
| 77 | !$app->reusable() |
| 79 | && $handled >= $this->maxRequests |
| 80 | || $this->maxMemory > 0 |
| 81 | && memory_get_usage(true) >= $this->maxMemory |
| 81 | && memory_get_usage(true) >= $this->maxMemory |
| 81 | && memory_get_usage(true) >= $this->maxMemory |
| 82 | ); |
| 83 | } |
| 74 | private function retires(App $app, int $handled): bool |
| 75 | { |
| 76 | return ( |
| 77 | !$app->reusable() |
| 79 | && $handled >= $this->maxRequests |
| 80 | || $this->maxMemory > 0 |
| 81 | && memory_get_usage(true) >= $this->maxMemory |
| 81 | && memory_get_usage(true) >= $this->maxMemory |
| 82 | ); |
| 83 | } |
| 74 | private function retires(App $app, int $handled): bool |
| 75 | { |
| 76 | return ( |
| 77 | !$app->reusable() |
| 79 | && $handled >= $this->maxRequests |
| 81 | && memory_get_usage(true) >= $this->maxMemory |
| 82 | ); |
| 83 | } |
| 53 | public function serve(App $app): false |
| 54 | { |
| 55 | // A client that disconnects must not abort a request halfway, as |
| 56 | // its teardown has to run before the worker takes the next one. |
| 57 | ignore_user_abort(true); |
| 58 | $handled = 0; |
| 59 | |
| 60 | do { |
| 61 | $running = ($this->handleRequest)(static function () use ($app): void { |
| 61 | $running = ($this->handleRequest)(static function () use ($app): void { |
| 62 | // PHP's stat cache would keep file sizes and modification |
| 63 | // times from earlier requests. |
| 64 | clearstatcache(); |
| 65 | $app->run(); |
| 66 | }); |
| 67 | $handled++; |
| 68 | gc_collect_cycles(); |
| 69 | } while ($running && !$this->retires($app, $handled)); |
| 69 | } while ($running && !$this->retires($app, $handled)); |
| 69 | } while ($running && !$this->retires($app, $handled)); |
| 71 | return false; |
| 72 | } |
| 53 | public function serve(App $app): false |
| 54 | { |
| 55 | // A client that disconnects must not abort a request halfway, as |
| 56 | // its teardown has to run before the worker takes the next one. |
| 57 | ignore_user_abort(true); |
| 58 | $handled = 0; |
| 59 | |
| 60 | do { |
| 61 | $running = ($this->handleRequest)(static function () use ($app): void { |
| 61 | $running = ($this->handleRequest)(static function () use ($app): void { |
| 62 | // PHP's stat cache would keep file sizes and modification |
| 63 | // times from earlier requests. |
| 64 | clearstatcache(); |
| 65 | $app->run(); |
| 66 | }); |
| 67 | $handled++; |
| 68 | gc_collect_cycles(); |
| 69 | } while ($running && !$this->retires($app, $handled)); |
| 69 | } while ($running && !$this->retires($app, $handled)); |
| 69 | } while ($running && !$this->retires($app, $handled)); |
| 61 | $running = ($this->handleRequest)(static function () use ($app): void { |
| 62 | // PHP's stat cache would keep file sizes and modification |
| 63 | // times from earlier requests. |
| 64 | clearstatcache(); |
| 65 | $app->run(); |
| 66 | }); |
| 67 | $handled++; |
| 68 | gc_collect_cycles(); |
| 69 | } while ($running && !$this->retires($app, $handled)); |
| 69 | } while ($running && !$this->retires($app, $handled)); |
| 71 | return false; |
| 72 | } |
| 53 | public function serve(App $app): false |
| 54 | { |
| 55 | // A client that disconnects must not abort a request halfway, as |
| 56 | // its teardown has to run before the worker takes the next one. |
| 57 | ignore_user_abort(true); |
| 58 | $handled = 0; |
| 59 | |
| 60 | do { |
| 61 | $running = ($this->handleRequest)(static function () use ($app): void { |
| 61 | $running = ($this->handleRequest)(static function () use ($app): void { |
| 62 | // PHP's stat cache would keep file sizes and modification |
| 63 | // times from earlier requests. |
| 64 | clearstatcache(); |
| 65 | $app->run(); |
| 66 | }); |
| 67 | $handled++; |
| 68 | gc_collect_cycles(); |
| 69 | } while ($running && !$this->retires($app, $handled)); |
| 69 | } while ($running && !$this->retires($app, $handled)); |
| 71 | return false; |
| 72 | } |
| 53 | public function serve(App $app): false |
| 54 | { |
| 55 | // A client that disconnects must not abort a request halfway, as |
| 56 | // its teardown has to run before the worker takes the next one. |
| 57 | ignore_user_abort(true); |
| 58 | $handled = 0; |
| 59 | |
| 60 | do { |
| 61 | $running = ($this->handleRequest)(static function () use ($app): void { |
| 61 | $running = ($this->handleRequest)(static function () use ($app): void { |
| 62 | // PHP's stat cache would keep file sizes and modification |
| 63 | // times from earlier requests. |
| 64 | clearstatcache(); |
| 65 | $app->run(); |
| 66 | }); |
| 67 | $handled++; |
| 68 | gc_collect_cycles(); |
| 69 | } while ($running && !$this->retires($app, $handled)); |
| 69 | } while ($running && !$this->retires($app, $handled)); |
| 61 | $running = ($this->handleRequest)(static function () use ($app): void { |
| 62 | // PHP's stat cache would keep file sizes and modification |
| 63 | // times from earlier requests. |
| 64 | clearstatcache(); |
| 65 | $app->run(); |
| 66 | }); |
| 67 | $handled++; |
| 68 | gc_collect_cycles(); |
| 69 | } while ($running && !$this->retires($app, $handled)); |
| 69 | } while ($running && !$this->retires($app, $handled)); |
| 69 | } while ($running && !$this->retires($app, $handled)); |
| 71 | return false; |
| 72 | } |
| 118 | private static function setting(string $name): ?string |
| 119 | { |
| 120 | $value = $_SERVER[$name] ?? $_ENV[$name] ?? getenv($name); |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 122 | |
| 123 | return $value === '' ? null : $value; |
| 123 | return $value === '' ? null : $value; |
| 123 | return $value === '' ? null : $value; |
| 124 | } |
| 118 | private static function setting(string $name): ?string |
| 119 | { |
| 120 | $value = $_SERVER[$name] ?? $_ENV[$name] ?? getenv($name); |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 122 | |
| 123 | return $value === '' ? null : $value; |
| 123 | return $value === '' ? null : $value; |
| 123 | return $value === '' ? null : $value; |
| 124 | } |
| 118 | private static function setting(string $name): ?string |
| 119 | { |
| 120 | $value = $_SERVER[$name] ?? $_ENV[$name] ?? getenv($name); |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 122 | |
| 123 | return $value === '' ? null : $value; |
| 123 | return $value === '' ? null : $value; |
| 123 | return $value === '' ? null : $value; |
| 124 | } |
| 118 | private static function setting(string $name): ?string |
| 119 | { |
| 120 | $value = $_SERVER[$name] ?? $_ENV[$name] ?? getenv($name); |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 122 | |
| 123 | return $value === '' ? null : $value; |
| 123 | return $value === '' ? null : $value; |
| 123 | return $value === '' ? null : $value; |
| 124 | } |
| 118 | private static function setting(string $name): ?string |
| 119 | { |
| 120 | $value = $_SERVER[$name] ?? $_ENV[$name] ?? getenv($name); |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 122 | |
| 123 | return $value === '' ? null : $value; |
| 123 | return $value === '' ? null : $value; |
| 123 | return $value === '' ? null : $value; |
| 124 | } |
| 118 | private static function setting(string $name): ?string |
| 119 | { |
| 120 | $value = $_SERVER[$name] ?? $_ENV[$name] ?? getenv($name); |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 121 | $value = is_string($value) ? trim($value) : ''; |
| 122 | |
| 123 | return $value === '' ? null : $value; |
| 123 | return $value === '' ? null : $value; |
| 123 | return $value === '' ? null : $value; |
| 124 | } |
| 61 | $running = ($this->handleRequest)(static function () use ($app): void { |
| 62 | // PHP's stat cache would keep file sizes and modification |
| 63 | // times from earlier requests. |
| 64 | clearstatcache(); |
| 65 | $app->run(); |
| 66 | }); |