Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Alexey Rogachev <arogachev90@gmail.com> Co-authored-by: Sergei Predvoditelev <sergei@predvoditelev.ru>
- Loading branch information
1 parent
bed164d
commit 34b8c47
Showing
14 changed files
with
481 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,4 +28,4 @@ jobs: | |
os: >- | ||
['ubuntu-latest', 'windows-latest'] | ||
php: >- | ||
['8.0', '8.1'] | ||
['8.0', '8.1', '8.2'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,4 +30,4 @@ jobs: | |
os: >- | ||
['ubuntu-latest'] | ||
php: >- | ||
['8.0', '8.1'] | ||
['8.0', '8.1', '8.2'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,4 +28,4 @@ jobs: | |
os: >- | ||
['ubuntu-latest'] | ||
php: >- | ||
['8.0', '8.1'] | ||
['8.0', '8.1', '8.2'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"symbol-whitelist": [ | ||
"Socket", | ||
"socket_write" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\VarDumper\Handler; | ||
|
||
use Yiisoft\VarDumper\HandlerInterface; | ||
|
||
/** | ||
* `CompositeHandler` allows to use multiple handlers at once. | ||
* It iterates over all handlers and calls their {@see HandlerInterface::handle()} method. | ||
* For example, you may use it to output data to both {@see StreamHandler} and {@see EchoHandler} at once. | ||
*/ | ||
final class CompositeHandler implements HandlerInterface | ||
{ | ||
/** | ||
* @param HandlerInterface[] $handlers | ||
*/ | ||
public function __construct( | ||
private array $handlers | ||
) { | ||
} | ||
|
||
public function handle(mixed $variable, int $depth, bool $highlight = false): void | ||
{ | ||
foreach ($this->handlers as $handler) { | ||
$handler->handle($variable, $depth, $highlight); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\VarDumper\Handler; | ||
|
||
use InvalidArgumentException; | ||
use RuntimeException; | ||
use Socket; | ||
use Yiisoft\VarDumper\HandlerInterface; | ||
|
||
use function fsockopen; | ||
use function fwrite; | ||
use function get_debug_type; | ||
use function is_resource; | ||
use function is_string; | ||
|
||
/** | ||
* Uses stream ({@link https://www.php.net/manual/en/intro.stream.php}) for writing variable's data. Requires "sockets" | ||
* PHP extension when {@see StreamHandler::$uri} is a {@see Socket} instance. | ||
*/ | ||
final class StreamHandler implements HandlerInterface | ||
{ | ||
/** | ||
* @var callable|null | ||
*/ | ||
private mixed $encoder = null; | ||
/** | ||
* @var resource|Socket|null | ||
*/ | ||
private mixed $stream = null; | ||
|
||
/** | ||
* @var resource|Socket|string | ||
*/ | ||
private mixed $uri; | ||
|
||
private const SOCKET_PROTOCOLS = ['udp', 'udg', 'tcp', 'unix']; | ||
|
||
/** | ||
* @param mixed|resource|string $uri | ||
*/ | ||
public function __construct( | ||
mixed $uri = 'udp://127.0.0.1:8890' | ||
) { | ||
if (!is_string($uri) && !is_resource($uri) && !$uri instanceof Socket) { | ||
throw new InvalidArgumentException( | ||
sprintf( | ||
'Argument $uri must be either a string, a resource or a Socket instance, "%s" given.', | ||
get_debug_type($uri) | ||
) | ||
); | ||
} | ||
$this->uri = $uri; | ||
} | ||
|
||
public function __destruct() | ||
{ | ||
if (!is_string($this->uri) || !is_resource($this->stream)) { | ||
return; | ||
} | ||
fclose($this->stream); | ||
} | ||
|
||
/** | ||
* Encodes {@param $variable} with {@see self::$encoder} and sends the result to the stream. | ||
*/ | ||
public function handle(mixed $variable, int $depth, bool $highlight = false): void | ||
{ | ||
$data = ($this->encoder ?? '\json_encode')($variable); | ||
if (!is_string($data)) { | ||
throw new RuntimeException( | ||
sprintf( | ||
'Encoder must return a string, "%s" returned.', | ||
get_debug_type($data) | ||
) | ||
); | ||
} | ||
|
||
if (!is_resource($this->stream) && !$this->stream instanceof Socket) { | ||
$this->initializeStream(); | ||
} | ||
|
||
if (!$this->writeToStream($data)) { | ||
$this->initializeStream(); | ||
|
||
if (!$this->writeToStream($data)) { | ||
throw new RuntimeException('Cannot write a stream.'); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* @param callable(mixed $variable): string $encoder Encoder that will be used to encode variable before sending it to the stream. | ||
*/ | ||
public function withEncoder(callable $encoder): static | ||
{ | ||
$new = clone $this; | ||
$new->encoder = $encoder; | ||
return $new; | ||
} | ||
|
||
private function initializeStream(): void | ||
{ | ||
if (!is_string($this->uri)) { | ||
$this->stream = $this->uri; | ||
} else { | ||
$uriHasSocketProtocol = false; | ||
foreach (self::SOCKET_PROTOCOLS as $protocol) { | ||
if (str_starts_with($this->uri, "$protocol://")) { | ||
$uriHasSocketProtocol = true; | ||
break; | ||
} | ||
} | ||
|
||
$this->stream = $uriHasSocketProtocol ? fsockopen($this->uri) : fopen($this->uri, 'wb+'); | ||
} | ||
|
||
if (!is_resource($this->stream) && !$this->stream instanceof Socket) { | ||
throw new RuntimeException('Cannot initialize a stream.'); | ||
} | ||
} | ||
|
||
private function writeToStream(string $data): bool | ||
{ | ||
if ($this->stream === null) { | ||
return false; | ||
} | ||
|
||
if ($this->stream instanceof Socket) { | ||
socket_write($this->stream, $data, strlen($data)); | ||
|
||
return true; | ||
} | ||
|
||
return @fwrite($this->stream, $data) !== false; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\VarDumper\Tests\Handler; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
use Yiisoft\VarDumper\Handler\CompositeHandler; | ||
use Yiisoft\VarDumper\Tests\Support\InMemoryHandler; | ||
|
||
final class CompositeHandlerTest extends TestCase | ||
{ | ||
public function testComposite(): void | ||
{ | ||
$compositeHandler = new CompositeHandler([ | ||
$inMemoryHandler1 = new InMemoryHandler(), | ||
$inMemoryHandler2 = new InMemoryHandler(), | ||
]); | ||
$variable = 'test'; | ||
|
||
$compositeHandler->handle($variable, 1, true); | ||
|
||
$this->assertEquals([[$variable, 1, true]], $inMemoryHandler1->getVariables()); | ||
$this->assertEquals($inMemoryHandler1->getVariables(), $inMemoryHandler2->getVariables()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\VarDumper\Tests\Handler; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
use Yiisoft\VarDumper\Handler\EchoHandler; | ||
|
||
final class EchoHandlerTest extends TestCase | ||
{ | ||
public function testEcho(): void | ||
{ | ||
$handler = new EchoHandler(); | ||
|
||
$handler->handle('test', 1); | ||
|
||
$this->expectOutputString("'test'"); | ||
} | ||
|
||
public function testHighlight(): void | ||
{ | ||
$handler = new EchoHandler(); | ||
|
||
$handler->handle('test', 1, true); | ||
|
||
$this->expectOutputString( | ||
<<<HTML | ||
<code><span style="color: #000000">\n<span style="color: #0000BB"></span><span style="color: #DD0000">'test'</span>\n</span>\n</code> | ||
HTML | ||
); | ||
} | ||
} |
Oops, something went wrong.