emilianobovetti/php-option

PHP 中的轻量级选项

v0.1.2 2018-02-19 09:13 UTC

This package is auto-updated.

Last update: 2024-09-24 02:01:29 UTC


README

厌倦了 尝试获取非对象的属性 吗?

这是 PHP 中 选项类型 的移植。

安装

composer require emilianobovetti/php-option

// import library
use EmilianoBovetti\PhpOption\Option;
// if you need direct access to Some class
use EmilianoBovetti\PhpOption\Some;

创建选项

您可以通过构造函数(例如 new Some(0)new None)或使用 Option 类的外观方法来创建选项。

Option::none() 返回 None 类的一个实例。由于该类是无状态的,因此不需要每次需要 None 时都创建新对象。

Option::create($value, $empty = null) 返回一个 Option 对象。默认情况下,如果 $valuenull,则返回 None,否则返回 new Some($value)

您可以通过传递 $empty 参数来更改此行为。例如,Option::create(0, 0) === Option::none()

如果向 create 方法传递另一个选项,则返回该选项本身。

如果 $value 是可调用的,则使用其生成的值。

如果 $empty 是可调用的,则将其应用于 $value,如果它生成一个假值,则返回 None。

使用选项

使用方便的语法,您可以使用 PhpOption 从对象获取属性和从数组获取键,同时处理 null

// $user object contains a reference to addres
// which contains a reference to city,
// but the user, the address and the city
// can be null
$city = isset($user->address->city) ? $user->address->city : 'Unknown';

// this line makes the same thing
$city = Option::create($user)->address->city->getOrElse('Unknown');

Option 还提供了许多灵活性。

// we can change this
if (isset($user->address->city)) {
    $city = $user->address->city;
    $result = $city === 'rome' ? 'home' : $city;
} else {
    $result = 'city unknown';
}

// with a little more compact solution
$result = Option::create($user)->address->city
    ->map(function ($city) { return $city === 'rome' ? 'home' : $city; })
    ->getOrElse('city unknown');

等等,但我有一个数组!

// no problem, objects and arrays are treated identically
$user = [ 'defined' => [ 'key' => 0 ] ];

$key = Option::create($user)->defined->key->get(); // $key is 0

$user = null;

$key = Option::create($user)->undefined->key->getOrElse(0); // $key is 0 again

好吧,如果我有一些资源密集型函数呢?

// use callbacks for lazy-evaluation
Option::create($user)->some->property
    ->orElse(function () { return $this->heavyLoad(); })
    ->orElse(function () { return $this->someFallback(); })
    ->getOrElse(function () { return $this->lastChance(); });

如果 $user->some->property 存在并且不是 null,则不会调用任何方法。如果第一个回调被调用并返回一个非 null 值,则不会执行后续函数,依此类推...

如何输出 Option

echo Option::create($user)->address->city->name; // will print city name or empty string

Option 方法

filter(Closure $function)

如果 Option 是 Some 并且给定的 $function 在其值上返回 false,则 filter 方法返回 None。否则返回 Option 本身。

map(Closure $function)

如果 Option 是 Some,则返回另一个 Option,它包装了将 $function 应用到 Option 的值的结果。否则返回 None。

each(Closure $function)

如果 Option 的值非空,则应用给定的 $function,否则不执行任何操作。返回 Option 本身。

get()

获取 Option 的值或如果 Option 是 None,则抛出 NoneValueException

getOrElse(mixed $default)

如果 Option 是 Some,则返回其值,否则返回 $default

$default 可以是

  1. 一个回调 - 如果 Option 是 None,则调用它并返回其结果。
  2. 任何其他 PHP 值 - 如果 Option 是 None,则返回它。

getOrThrow(Exception $e)

获取 Option 的值或如果 Option 是 None,则抛出 $e

getOrCall(Closure $function)

如果 Option 是 Some,则返回其值,否则返回 $function 生成的值。

orElse(mixed $default)

类似于 getOrElse,但返回一个 Option 而不是其值。

isDefined()isEmpty()

前者返回 true 如果 Option 不是 None,后者返回 true 如果它是。

动态方法

__toString()

None 被转换为空字符串,而一个非空 Option 返回其值的 (string) 类型转换。

__get(string $name)

如果选项是一个包含数组或对象的Some,它将查找给定的键或属性。如果存在且不是null,则返回一个包含该值的Option。在其他任何情况下返回None。

__isset(string $name)

检查给定的键或属性是否存在于Option的值中。

例如:

$array = [ 'defined' => [ 'key' => 0 ] ];
isset(Option::create($array)->defined->key); // true

isset(Option::create(null)->undefined->key); // false

__invoke(mixed $default)

使Option可调用。这是get()和getOrElse()方法的快捷方式。

例如:

$option = Option::create(0);
$option(1); // 0
$option();  // 0

$option = Option::none();
$option(1); // 1
$option();  // NoneValueException

与getOrElse()方法类似,$default可以是回调或任何其他PHP值。

运行测试

git clone git@github.com:emilianobovetti/php-option.git
cd php-option
composer install
./vendor/bin/phpunit