tconway1 / mattyrad-support
PHP 支持类和特质的集合
v1.0.0
2024-02-07 14:30 UTC
Requires
- php: >=5.6
Requires (Dev)
- phpunit/phpunit: ^5
This package is auto-updated.
Last update: 2024-09-07 17:18:52 UTC
README
安装
composer require mattyrad/support
目录
确认特质
从未排序的数组中实例化对象
use MattyRad\Support\Conformation; class Sample { use Conformation; private $arg1; private $arg2; private $arg3; private $arg4; private $optional1; private $optional2; private function __construct( string $arg1, int $arg2, bool $arg3, float $arg4, string $optional1 = '', int $optional2 = 1 ) { $this->arg1 = $arg1; $this->arg2 = $arg2; $this->arg3 = $arg3; $this->arg4 = $arg4; $this->optional1 = $optional1; $this->optional2 = $optional2; } }
$sample = Sample::fromArray([ 'optional2' => 777, 'arg2' => 1, 'arg3' => false, 'arg1' => 'example', 'arg4' => 2.0, ]);
未能提供所有必要的参数将抛出异常
$sample = Sample::fromArray([ 'arg1' => 'example', 'arg2' => 1, ]);
PHP 致命错误:未捕获的 InvalidArgumentException:缺少样本关键字:arg3, arg4
结果对象
对于 API 来说,通常需要可扩展的结果对象以处理成功和失败情况,这非常常见。
定义结果
您可以使用通用的成功结果立即开始
$json_response_data = ['user' => ['name' => 'John', 'email' => 'user@example.com', 'posts' => [['name' => 'A'], ['name' => 'B']]]]; $result = new \MattyRad\Support\Result\Success($json_response_data); $result->isSuccess(); // true $result->isFailure(); // false $result->get('user.email'); // dot syntax enabled $result->get('user.posts.*.name'); // wildcard enabled, ['A', 'B']
为了更高的精度,您可以扩展成功结果
class WidgetPurchased extends Result\Success { public function __construct(Widget $widget) { $this->widget = $widget; } public function getWidget(): Widget { return $this->widget; } } $result = new Result\Success\WidgetPurchased($widget); $result->getWidget(); // Widget object $result->isSuccess(); // true $result->isFailure(); // false
失败结果需要更加具体
namespace MattyRad\Support\Result\Stripe; use MattyRad\Support\Result; class ChargeFailed extends Result\Failure { protected static $message = 'Stripe charge failed, delinquent card'; public function __construct($last_four_digits) { $this->last_four_digits = $last_four_digits; } public function getContext() { return ['last_four_digits' => $this->last_four_digits]; } } $result->isSuccess(); // false $result->isFailure(); // true $result->get('widget.name'); // throws exception with message 'Stripe charge failed, delinquent card' $result->getWidget(); // also throws exception with message 'Stripe charge failed, delinquent card' $result->getMessage(); // 'Stripe charge failed, delinquent card' $result->getContext(); // ['last_four_digits' => '1234'] $result->getReason(); // 'Stripe charge failed, delinquent card; {"last_four_digits":"1234"}'
实例化和返回结果
use MattyRad\Support\Result; function purchaseWidget($user, string $widget_name): Result { if ($existing_widget = $this->db->getWidgetByName($widget_name)) { return new Result\Failure\WidgetExists($existing_widget); } try { $user->charge(100); // API call, this could be any interface to stripe } catch (\Stripe\Error\Card $e) { return new Result\Failure\Stripe\ChargeFailed($e->getLastFour()); // pretend that getLastFour exists } $widget = new Widget($widget_name); return new Result\Success\WidgetPurchased($widget); }
消费结果
您可以手动检查失败
$result = purchaseWidget(Auth::user(), 'my_cool_new_widget'); if ($result->isFailure()) { return new JsonResponse(['error' => $result->getReason()], 422); } return new JsonResponse($result->getWidget());
或者,您可以利用异常并省略成功/失败的检查。尝试从失败结果中访问数据将导致它抛出异常
$result = purchaseWidget(Auth::user(), 'my_cool_new_widget'); // returns ChargeFailed return new Response($result->getWidget()); // Throws exception
Laravel 的异常处理器默认处理多种异常(如 HttpResponseException),我们可以通过覆盖失败结果的默认 toException 函数来利用这一点
class ChargeFailed extends Result\Failure { // ... public function toException() { $response = new JsonResponse(['error' => static::$message], 422); return new HttpResponseException($response); }
并且错误处理将内置,我们可以专注于成功路径。任何非内置异常都可以在异常处理器的 render() 函数中捕获。