ifixit/php7-optional

PHP 7 可选包装器,提供对 null 的替代方案

3.0 2022-12-16 02:26 UTC

This package is auto-updated.

Last update: 2024-09-21 07:09:00 UTC


README

License: MIT Tests Stable Version Downloads codecov psalm psalm Pull Requests

安装

composer require ifixit/php7-optional

使用方法

有三个主要的类

  • Optional\Option
    • 概念上:一些或无。这是一个可选地包含值的盒子。使用它来替换 null。
  • Optional\Either
    • 概念上:左或右。这是一个双态盒子。可以是左或右,但不能同时是两者,也不能是无。你可以对左右两边应用相同的转换。
  • Optional\Result
    • 概念上:正常或错误。这是一个双态盒子,但倾向于正常状态。错误状态是有限的,因为我们希望使这个对象易于映射或转储错误。
    • 所有可调用对象在链的末尾都会自动包装并抛出 Throwable
  • Optional\UnsafeResult
    • 概念上:正常或错误。这是一个双态盒子,但倾向于正常状态。错误状态是有限的,因为我们希望使这个对象易于映射或转储错误。
    • 所有可调用对象都没有自动包装 Throwable。因此,将立即抛出异常。

阅读完整文档

使用 Option

要使用 Optional,只需导入以下命名空间

use Optional\Option;

创建可选值

examples 下有示例。

以下是一个示例,它将展示你可以多么流畅地描述你想要应用的变化。

use Optional\Result;

class Curl {
   public static function request(string $url): array {
      return [
         'code' => 200,
         'url' => $url,
         'data' =>
            '{
               "environment_config": {
                 "app": {
                   "name": "Sample App",
                   "url": "http://10.0.0.120:8080/app/"
                 },
                 "database": {
                   "name": "mysql database",
                   "host": "10.0.0.120",
                   "port": 3128,
                   "username": "root",
                   "password": "toor"
                 },
                 "rest_api": "http://10.0.0.120:8080/v2/api/"
               }
             }'
      ];
   }
}

$responseToResult = function (array $response): Result {
   $wasGood = $response['code'] == 200;

   if ($wasGood) {
      return SimpleResult::okay($response);
   } else {
      $url = $response['url'];
      $code = $response['code'];
      return SimpleResult::error("The request to $url failed with code $code!");
   }
};

$response = Curl::request('http:://www.github.com');

$result = $responseToResult($response);

$dbConnectionStr = $result
   ->map(function ($result) {
      return json_decode($result['data'], true);
   })
   ->notFalsy("Json failed to decode!")
   ->map(function(array $json) {
      $dbData = $json['environment_config']['database'];

      $host = $dbData['host'];
      $port = $dbData['port'];
      $username = $dbData['username'];
      $password = $dbData['password'];

      return "Server=$host;Port=$port;Uid=$username;Pwd=$password;";
   })
   ->dataOrThrow();

echo "Connection str: $dbConnectionStr \n";


$dbConnectionResult = $result
   ->map(function ($result) {
      return false;
   })
   ->notFalsy("Json failed to decode!")
   ->map(function(array $json) {
      $dbData = $json['environment_config']['database'];

      $host = $dbData['host'];
      $port = $dbData['port'];
      $username = $dbData['username'];
      $password = $dbData['password'];

      return "Server=$host;Port=$port;Uid=$username;Pwd=$password;";
   });

   try {
      $dbConnectionResult->dataOrThrow();
   } catch (Throwable $ex) {
      // Don't want to kill the example
      echo "Example of a wrapped exception: {$ex->getMessage()}\n";
   }

   $defaultValue = $dbConnectionResult
   ->orSetDataTo('Server=myServerAddress;Port=1234;Database=myDataBase;Uid=myUsername;Pwd=myPassword;')
   ->dataOrThrow();

   echo "Example of setting to a default: $defaultValue\n";

使用 Either

要使用 Either,只需导入以下命名空间

use Optional\Either;

使用 Result

要使用 Result,只需导入以下命名空间

use Optional\Result;

Result 方法

创建(装箱)

  • static okay($data): Result
  • static error(Throwable $errorData): Result
  • static okayWhen($data, Throwable $errorValue, callable $filterFunc): Result
  • static errorWhen($data, Throwable $errorValue, callable $filterFunc): Result
  • static okayNotNull($data, Throwable $errorValue): Result
  • static fromArray(array $array, $key, Throwable $rightValue = null): Result

翻转

  • toError($errorValue): Result
  • toOkay($dataValue): Result

解包

  • dataOrThrow()

状态

  • isOkay(): bool
  • isError(): bool
  • contains($value): bool
  • errorContains($value): bool
  • exists(callable $existsFunc): bool

转换

  • orSetDataTo($data): Result
  • orCreateResultWithData(callable $alternativeFactory): Result
  • okayOr(self $alternativeResult): Result
  • createIfError(callable $alternativeResultFactory): Result
  • map(callable $mapFunc): Result
  • mapError(callable $mapFunc): Result
  • andThen(callable $mapFunc): Result
  • flatMap(callable $mapFunc): Result
  • toErrorIf(callable $filterFunc, Throwable $errorValue): Result
  • toOkayIf(callable $filterFunc, $data): Result
  • notNull(Throwable $errorValue): Result
  • notFalsy(Throwable $errorValue): Result

副作用

  • run(callable $dataFunc, callable $errorFunc)
  • runOnOkay(callable $dataFunc): void
  • runOnError(callable $errorFunc): void

许可证

MIT

特别感谢

受到 https://github.com/nlkl/Optional 的极大启发。实际上,这是一个这个库的移植版本。