kuria/debug

实用调试工具集合

v4.0.1 2018-09-19 20:37 UTC

This package is auto-updated.

Last update: 2024-09-22 17:37:10 UTC


README

实用调试工具集合。

https://travis-ci.cn/kuria/debug.svg?branch=master

内容

要求

PHP 7.1+

数据转储器

用于检查任意值的工具。

转储任何值

以嵌套和字符串长度限制转储任意PHP值。

<?php

use Kuria\Debug\Dumper;

$values = [
    'foo bar',
    123,
    -123,
    1.53,
    -1.53,
    true,
    false,
    fopen('php://stdin', 'r'),
    null,
    array(1, 2, 3),
    new \stdClass(),
];

echo Dumper::dump($values);

输出

array[11] {
    [0] => "foo bar"
    [1] => 123
    [2] => -123
    [3] => 1.530000
    [4] => -1.530000
    [5] => true
    [6] => false
    [7] => resource(stream#10)
    [8] => NULL
    [9] => array[3]
    [10] => object(stdClass)
}
  • 查看dump()的其他参数以获取嵌套和字符串限制
  • 如果对象实现了__debugInfo()方法,将使用其输出而不是属性
  • 如果对象实现了__toString()方法,如果
    1. 没有属性
    2. 由于嵌套限制,属性无法显示
  • 如果对象实现了\DateTimeInterface,其值将以字符串格式化

转储字符串

安全地转储任意字符串。所有ASCII < 32都将使用C样式转义。

<?php

use Kuria\Debug\Dumper;

echo Dumper::dumpString("Foo\nBar");

输出

Foo\nBar

以十六进制形式转储字符串

用于转储二进制数据或检查文本的实际字节。

<?php

use Kuria\Debug\Dumper;

echo Dumper::dumpStringAsHex("Lorem\nIpsum\nDolor\nSit\nAmet\n");

输出

 0 : 4c 6f 72 65 6d 0a 49 70 73 75 6d 0a 44 6f 6c 6f [Lorem.Ipsum.Dolo]
10 : 72 0a 53 69 74 0a 41 6d 65 74 0a                [r.Sit.Amet.]

获取对象属性

<?php

use Kuria\Debug\Dumper;

class Foo
{
    public static $staticProperty = 'lorem';
    public $publicProperty = 'ipsum';
    private $privateProperty = 'dolor';
}

print_r(Dumper::getObjectProperties(new Foo()));

输出

Array
(
    [staticProperty] => ReflectionProperty Object
        (
            [name] => staticProperty
            [class] => Foo\Foo
        )

    [publicProperty] => ReflectionProperty Object
        (
            [name] => publicProperty
            [class] => Foo\Foo
        )

    [privateProperty] => ReflectionProperty Object
        (
            [name] => privateProperty
            [class] => Foo\Foo
        )

)

输出

与PHP输出系统相关的工具。

清理输出缓冲区

<?php

use Kuria\Debug\Output;

// clean all buffers
Output::cleanBuffers();

// clean buffers up to a certain level
Output::cleanBuffers(2);

// clean all buffers and catch exceptions
$bufferedOutput = Output::cleanBuffers(null, true);

捕获输出缓冲区

<?php

use Kuria\Debug\Output;

// capture all buffers
Output::captureBuffers();

// capture buffers up to a certain level
Output::captureBuffers(2);

// capture all buffers and catch exceptions
$bufferedOutput = Output::captureBuffers(null, true);

替换所有头信息

替换所有头信息(除非它们已经发送)

<?php

use Kuria\Debug\Output;

Output::replaceHeaders(['Content-Type: text/plain; charset=UTF-8']);

错误

PHP错误工具。

获取PHP错误代码的名称

<?php

use Kuria\Debug\Error;

var_dump(Error::getName(E_USER_ERROR));

输出

string(10) "E_USER_ERROR"

异常

异常工具。

渲染异常

<?php

use Kuria\Debug\Exception;

$invalidArgumentException = new \InvalidArgumentException('Bad argument', 123);
$runtimeException = new \RuntimeException('Something went wrong', 0, $invalidArgumentException);

echo Exception::render($runtimeException);

输出

RuntimeException: Something went wrong in example.php on line 6
#0 {main}

包括所有先前异常,不包括跟踪信息

<?php

echo Exception::render($runtimeException, false, true);

输出

[1/2] RuntimeException: Something went wrong in example.php on line 6
[2/2] InvalidArgumentException (123): Bad argument in example.php on line 5

获取所有先前异常的列表

<?php

use Kuria\Debug\Exception;

try {
    try {
        throw new \InvalidArgumentException('Invalid parameter');
    } catch (\InvalidArgumentException $e) {
        throw new \RuntimeException('Something went wrong', 0, $e);
    }
} catch (\RuntimeException $e) {
    $exceptions = Exception::getChain($e);

    foreach ($exceptions as $exception) {
        echo $exception->getMessage(), "\n";
    }
}

输出

Something went wrong
Invalid parameter

连接异常链

在异常处理代码中,连接异常链有一些用途,其中可能会抛出其他异常。

<?php

use Kuria\Debug\Exception;

$c = new \Exception('C');
$b = new \Exception('B', 0, $c);
$a = new \Exception('A', 0, $b);

$z = new \Exception('Z');
$y = new \Exception('Y', 0, $z);
$x = new \Exception('X', 0, $y);

// print current chains
echo "A's chain:\n", Exception::render($a, false, true), "\n\n";
echo "X's chain:\n", Exception::render($x, false, true), "\n\n";

// join chains (any number of exceptions can be passed)
// from right to left: the last previous exception is joined to the exception on the left
Exception::joinChains($a, $x);

// print the modified X chain
echo "X's modified chain:\n", Exception::render($x, false, true), "\n";

输出

A's chain:
[1/3] Exception: A in example.com on line 7
[2/3] Exception: B in example.com on line 6
[3/3] Exception: C in example.com on line 5

X's chain:
[1/3] Exception: X in example.com on line 11
[2/3] Exception: Y in example.com on line 10
[3/3] Exception: Z in example.com on line 9

X's modified chain:
[1/6] Exception: X in example.com on line 11
[2/6] Exception: Y in example.com on line 10
[3/6] Exception: Z in example.com on line 9
[4/6] Exception: A in example.com on line 7
[5/6] Exception: B in example.com on line 6
[6/6] Exception: C in example.com on line 5

简化现实世界示例

不连接异常链
<?php

use Kuria\Debug\Exception;

// print uncaught exceptions
set_exception_handler(function ($uncaughtException) {
    echo Exception::render($uncaughtException, false, true);
});

try {
    // some code which may throw an exception
    throw new \Exception('Initial exception');
} catch (\Exception $exception) {
    // handle the exception
    try {
        // some elaborate exception-handling code which may also throw an exception
        throw new \Exception('Exception-handler exception');
    } catch (\Exception $additionalException) {
        // the exception-handling code has crashed
        throw new \Exception('Final exception', 0, $additionalException);
    }
}

输出

[1/2] Exception: Final exception in example.php on line 20
[2/2] Exception: Exception-handler exception in example.php on line 17

注意,关于初始异常的信息完全丢失。

我们可以将初始异常的信息粘接到最终异常的消息上,但这会很丑陋且难以阅读。

连接异常链
<?php

try {
    // some code which may throw an exception
    throw new \Exception('Initial exception');
} catch (\Exception $exception) {
    // handle the exception
    try {
        // some elaborate exception-handling code which may also throw an exception
        throw new \Exception('Exception-handler exception');
    } catch (\Exception $additionalException) {
        // the exception-handling code has crashed

        // join exception chains
        Exception::joinChains($exception, $additionalException);

        throw new \Exception('Something went wrong while handling an exception', 0, $additionalException);
    }
}

输出

[1/3] Exception: Something went wrong while handling an exception in example.php on line 24
[2/3] Exception: Exception-handler exception in /example.php on line 17
[3/3] Exception: Initial exception in example.php on line 12

现在可以访问初始异常作为先前的异常之一。