smuuf/better-php-exceptions

提供更优和改进的 PHP 异常的包。

0.2.1 2020-12-20 23:59 UTC

This package is auto-updated.

Last update: 2024-09-23 09:01:39 UTC


README

这是什么?

这个小型项目旨在为使用原生 PHP 异常(PHP 解释器在多种情况下抛出)的 PHP 开发者提供改进的用户/开发者体验。

更好的 PHP 异常 可以通过 统一接口 从原生异常创建。

use \Smuuf\BetterExceptions\BetterException;

try {
	...
} catch (\Throwable $ex) {
	$better = BetterException::from($ex);
	...
}

例如,PHP 7.* 和 PHP 8.0 在三种不同的场景下都会抛出 TypeError 异常。

可能抛出 TypeError 的三种场景包括:函数传入的参数类型与声明的参数类型不匹配;函数返回值类型与声明的函数返回类型不匹配;在严格模式下,传递给内置 PHP 函数的参数数量不正确。

~ https://php.ac.cn/manual/en/class.typeerror.php

遗憾的是,PHP 或 TypeError 本身并没有提供任何有关期望类型、传入/返回的类型或调用时传入的错误类型位置的额外信息。

这是参数类型错误吗?返回类型错误吗?是什么……!?

这些信息仅存在于异常消息中,并且需要额外的解析才能获取。 更不用说这些消息的格式从 PHP 7 到 PHP 8 发生了变化,因此需要不同的解析规则……

这就是 更好的 PHP 异常 出现的地方。

示例

<?php

declare(strict_types=1);

include __DIR__ . '/vendor/autoload.php';

use \Smuuf\BetterExceptions\BetterException;

// Yes, it has a wrong return type.
function join_strings(string $a, ?string $b): ?int {
	return "{$a} - {$b}";
}

try {

	// Argument type error.
	join_strings('first', 123);

} catch (\TypeError $ex) {

	// Convert the generic TypeError to something more usable.
	$better = BetterException::from($ex);

	// Now we know that it was an argument type error.
	var_dump($better);
	// object(Smuuf\BetterExceptions\Types\ArgumentTypeError) ...

	// We know that 'string' or 'null' was expected.
	var_dump($better->getExpected());
	// array(2) {
	//   [0]=>
	//   string(6) "string"
	//   [1]=>
	//   string(4) "null"
	// }

	// We know that 'int' was actually passed.
	var_dump($better->getActual());
	// string(3) "int"

	// And it was the second argument that was wrong.
	var_dump($better->getArgumentIndex());
	// int(2)

}

try {

	// Return type error.
	join_strings('first', 'second');

} catch (\TypeError $ex) {

	// Convert the generic TypeError to something more usable.
	$better = BetterException::from($ex);

	// Now we know that it was a return type error.
	var_dump($better);
	// object(Smuuf\BetterExceptions\Types\ReturnTypeError) ...

	// We know that 'int' or 'null' was expected.
	var_dump($better->getExpected());
	// array(2) {
	//   [0]=>
	//   string(3) "int"
	//   [1]=>
	//   string(4) "null"
	// }

	// We know that 'string' was actually passed.
	var_dump($better->getActual());
	// string(6) "string"

}

支持哪些 PHP 版本?

尽管 PHP 8.0 在 2020 年底发布,但 PHP 7 仍然被广泛使用,而 更好的 PHP 异常 旨在为当前的主要 PHP 版本提供更好的异常(至少目前是这样)。

哪些原生 PHP 异常可以改进?

目前只有少数(最初只有一个,因为我需要为我的其他项目:[Primi 语言:用 PHP 编写的脚本语言](https://github.com/smuuf/primi))进行改进。但系统设计得易于添加更多的 更好的异常

所以……是哪些呢?

  • \TypeError 可以转换为

    • \Smuuf\BetterExceptions\Types\ArgumentTypeError
      • 提供方法
        • getExpected():返回期望参数类型的字符串列表。
        • getActual():返回实际参数类型作为字符串。
    • \Smuuf\BetterExceptions\Types\ReturnTypeError
      • \Smuuf\BetterExceptions\Types\ArgumentTypeError 相同。
  • \Error 可以转换为

    • \Smuuf\BetterExceptions\Types\UnknownNamedParameterError
      • 提供方法
        • getParameterName():返回未知参数的名称作为字符串。
  • \ArgumentCountError 可以转换为

    • \Smuuf\BetterExceptions\Types\ArgumentCountError
      • 提供方法
        • getExpected():返回期望的参数数量。
        • getActual():返回实际的参数数量。