mkjpryor / option
为PHP提供的简单选项和结果类型
dev-master
2015-03-31 15:23 UTC
Requires (Dev)
- mockery/mockery: 0.9.*
- phpunit/phpunit: 4.5.*
- satooshi/php-coveralls: dev-master
This package is not auto-updated.
Last update: 2024-09-24 03:33:44 UTC
README
PHP的简单选项和结果类,受Scala的Option、Haskell的Maybe和Rust的Result启发。
Option类型在处理可能存在或不存在值的操作时,提供了比可空类型额外的功能。
Result类型还包括失败的原因(异常),允许错误在不担心特定处理的情况下传播。
安装
可以通过Composer安装mkjpryor/option。
php composer.phar require mkjpryor/option dev-master
用法
创建Option或Result
<?php use Mkjp\Option\Option; use Mkjp\Option\Result; // Creates a non-empty option containing the value 10 $o1 = Option::just(10); // Creates an empty option $o2 = Option::none(); // Creates an option from a nullable value // If null is given, an empty option is created $o3 = Option::from(10); $o3 = Option::from(null); // Create a successful result with the given value $r1 = Result::success(42); // Create an errored result with the given error $r2 = Result::error(new \Exception("Some error occurred")); // Create a result by trying some operation that might fail // Creates a success if the function returns successfully // Creates an error if the function throws an exception $r3 = Result::_try(function() { // Some operation that might fail with an exception });
从Option或Result中检索值
可以从Option中以不安全或安全的方式检索底层值
<?php // UNSAFE - throws a LogicException if the option is empty $val = $option->get(); // Returns the option's value if it is non-empty, 0 otherwise $val = $option->getOrDefault(0); // Returns the option's value if it is non-empty, otherwise the result of evaluating the given function // Useful if the default value is expensive to compute $val = $option->getOrElse(function() { return 0; }); // Return the option's value if it is non-empty, null otherwise $val = $option->getOrNull();
类似地,可以通过不安全或安全的方式检索Result的底层值(或错误)
<?php // UNSAFE - if the result is an error, the exception that caused the error is thrown $val = $result->get(); // UNSAFE - if the result is a success, a LogicException is thrown $err = $result->getError(); // Returns the result's value if it is a success, 0 if it is an error $val = $result->getOrDefault(0); // Returns the result's value if it is a success, otherwise the result of evaluating // the given function with the exception that caused the error // Useful if the default value is expensive to compute or depends on the type of error $val = $result->getOrElse(function(\Exception $error) { if( $error instanceof MyException ) return 0; return -1; }); // Return the result's value if it is a success, null otherwise $val = $result->getOrNull();
操作选项和结果
Option和Result有几种方法可以安全地操作,例如map、filter。请参阅代码以获取更多详细信息。
示例
在以下示例中,我们想要从数据库中通过id检索一个用户并欢迎他们。如果用户不存在,我们希望欢迎他们作为客人。
<?php use Mkjp\Option\Option; use Mkjp\Option\Result; /** * Simple user class */ class User { public $id; public $username; public function __construct($id, $username) { $this->id = $id; $this->username = $username; } } /** * Fetches a user from a database by their id * * Note how we return a Result containing an Option * This is because there are three possible outcomes that are semantically different: * 1. We successfully find a user * 2. The user doesn't exist in the database (this isn't an error - it is expected and must be handled) * 3. There is an error querying the database */ function findUserById($id) { // Assume DB::execute throws a DBError if there is an error while querying $result = Result::_try(function() use($id) { return DB::execute("SELECT * FROM users WHERE id = ?", $id); }); // Use the error propagation to our advantage return $result->map(function($data) { if( count($data) > 0 ) { return Option::just(new User($data[0]["id"], $data[0]["username"])); } else { return Option::none(); } }); } $id = 1234; // This would come from request params or something similar // Print an appropriate welcome message for the user echo "Hello, " . findUserById($id) // In this case, treat a DB error like not finding a user // // toOption converts the Result<Option<User>> into an // Option<Option<User>>, which we flatten to an Option<User> ->toOption()->flatten() // Get the username from the user ->map(function($u) { return $u->username; }) // If we didn't find a user, use a default name ->getOrDefault("Guest");
许可证
此代码根据MIT许可证的条款进行许可。