-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathStdoutHandler.php
More file actions
86 lines (72 loc) · 2.26 KB
/
StdoutHandler.php
File metadata and controls
86 lines (72 loc) · 2.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<?php
declare(strict_types=1);
namespace Spiral\RoadRunner\Internal;
use Symfony\Component\VarDumper\Dumper\AbstractDumper;
use Symfony\Component\VarDumper\Dumper\CliDumper;
use Symfony\Component\VarDumper\Dumper\HtmlDumper;
/**
* @internal StdoutHandler is an internal library class, please do not use it in your code.
* @psalm-internal Spiral\RoadRunner
*/
final class StdoutHandler
{
/**
* @var string
*/
private const PIPE_OUT = 'php://stderr';
/**
* @var string
*/
private const ERROR_WRITING_HEADER =
'Could not explicitly send a headers "%s" using PHP header() function. ' .
'Please use RoadRunner response object instead';
/**
* @var positive-int|0
*/
private const OB_CHUNK_SIZE = 1;
/**
* @param positive-int|0 $chunkSize
*/
public static function register(int $chunkSize = self::OB_CHUNK_SIZE): void
{
\assert($chunkSize >= 0, 'Invalid chunk size argument value');
self::restreamOutputBuffer($chunkSize);
self::restreamHeaders();
// Vendor packages
self::restreamSymfonyDumper();
}
/**
* Intercept all output headers writing.
*/
private static function restreamHeaders(): void
{
\header_register_callback(static function (): void {
$headers = \headers_list();
if ($headers !== []) {
\file_put_contents(self::PIPE_OUT, self::ERROR_WRITING_HEADER);
}
});
}
/**
* Intercept all output buffer write.
*
* @param int<0, max> $chunkSize
*/
private static function restreamOutputBuffer(int $chunkSize): void
{
\ob_start(static function (string $chunk, int $phase): void {
$isWrite = ($phase & \PHP_OUTPUT_HANDLER_WRITE) === \PHP_OUTPUT_HANDLER_WRITE;
if ($isWrite && $chunk !== '') {
\file_put_contents(self::PIPE_OUT, $chunk);
}
}, $chunkSize);
}
private static function restreamSymfonyDumper(): void
{
if (\class_exists(AbstractDumper::class)) {
AbstractDumper::$defaultOutput = self::PIPE_OUT;
CliDumper::$defaultOutput = self::PIPE_OUT;
HtmlDumper::$defaultOutput = self::PIPE_OUT;
}
}
}