stubbles / values
便于使用值的实用类。
Requires
- php: ^8.2
- ext-mbstring: *
Requires (Dev)
- bovigo/assert: ^8.0
- bovigo/callmap: ^8.0
- mikey179/vfsstream: ^1.6.11
- phpunit/phpunit: ^10.5
README
便于使用值的实用类。
构建状态
安装
stubbles/values作为Composer包分发。要将它作为您包的依赖项安装,请使用以下命令
composer require "stubbles/values": "^11.0"
需求
stubbles/values需要至少PHP 8.2。
可用类
stubbles\values\Result
允许封装可能返回null
的返回值。在其他语言或库中,这被称为Optional。要创建一个实例,请调用Result::of(someCallThatMightReturnNull())
。
isPresent()
当结果包含非null
值时返回true
。
isEmpty()
当结果包含空值时返回true
。请注意,即使值是整数,即使它是0,此方法也总是返回false
。
value()
返回实际值。
filter(callable $predicate)
允许过滤值。如果值满足给定的谓词,则返回Result
实例。如果值不满足谓词,则返回Result::of(null)
的等价物。
$filter = fn($value) => 303 === $value; echo Result::of(303)->filter($filter)->value(); // displays 303 echo Result::of(313)->filter($filter)->value(); // displays nothing echo Result::of(null)->filter($filter)->value(); // displays nothing
map(callable $mapper)
使用给定的映射器将值映射到不同的结果。如果值是null
,则返回值仍然是Result::of(null)
的等价物。
$mapper = fn($value) => 'Roland TB 303'; echo Result::of(303)->map($mapper)->value(); // displays "Roland TB 303" echo Result::of(null)->map($mapper)->value(); // displays nothing
whenNull($other)
如果值存在,则返回结果,否则返回其他的结果。
$default = 909; echo Result::of(303)->whenNull($default)->value(); // displays 303 echo Result::of(null)->whenNull($default)->value(); // displays 909
applyWhenNull(callable $other)
如果值存在,则返回结果,否则应用其他的结果。
$default = function() { return 909; }; echo Result::of(303)->applyWhenNull($default)->value(); // displays 303 echo Result::of(null)->applyWhenNull($default)->value(); // displays 909
whenEmpty($other)
如果值不为空,则返回结果,否则返回其他的结果。
$default = 'Roland TB 303'; echo Result::of('Roland 909')->whenEmpty($default)->value(); // displays Roland 909 echo Result::of('')->whenEmpty($default)->value(); // displays Roland TB 303
applyWhenEmpty($other)
如果值不为空,则返回结果,否则应用其他的结果。
$default = fn() => 'Roland TB 303'; echo Result::of('Roland 909')->applyWhenEmpty($default)->value(); // displays Roland 909 echo Result::of('')->applyWhenEmpty($default)->value(); // displays Roland TB 303
stubbles\values\Secret
Secret为安全敏感的字符列表,如密码,提供合理的安全存储。
它通过var_dump()、echo()或将对象强制转换为数组来防止意外在输出中泄露它们。在这些情况下,都不会显示密码或其加密形式。
然而,在密码学意义上,不应将此实现视为安全,因为它不关心非常强的加密,并且在单个PHP实例中与该类的所有实例共享加密密钥。
在使用此类时,您必须确保不要提取受保护的字符串并将其传递到可能发生异常的地方,因为它可能作为方法参数被暴露。
此类的实例不能被序列化。
创建一个秘密
要创建一个秘密,请调用Secret::create('my secret value')
。
请注意,您不能使用此函数创建值为null
的秘密。如果您明确想要这样做,请使用Secret::forNull()
。
isContained(): bool
检查创建时加密是否成功。如果失败,不会抛出错误或异常,因此这是唯一的检查方式。
isNull(): bool
检查实际秘密是否为null
。
unveil(): string
揭露秘密并作为字符串返回。这应该在尽可能晚的时刻调用,以避免不必要地泄露打算安全存储的值。
substring(int $start, int $length = null): Secret
创建秘密值的子字符串作为新的Secret
实例。
请注意,此方法自10.0.0版本发布以来已过时,将在11.0.0版本中删除。
length(): int
返回秘密的长度。允许在不先揭露它的情况下检查它是否适合某个地方。
stubbles\values\Parse
提供将字符串解析为目标类型的各种方法。
Parse::toInt($value)
从给定的字符串解析整数值。
Parse::toFloat($value)
从给定的字符串解析浮点值。
Parse::toBool($string)
从给定的字符串解析布尔值。如果字符串值是 "1"、"yes"、"true" 或 "on",则返回值是 true。在其他任何情况下,返回值将是 false。
Parse::toList($string, string $separator = '|')
将字符串解析为字符串列表。
如果值为空,则返回值将是一个空数组。如果值不为空,则将在 "|"(或提供的任何其他分隔符)处分割。
Parse::toList("foo|bar|baz"); // results in ['foo', 'bar', 'baz']
Parse::toMap($string)
将字符串解析为映射。
如果值为空,则返回值将是一个空映射。如果值不为空,它将在 "|" 处分割。结果列表将根据第一个 ":" 分割,第一个部分成为键,其余部分成为映射中的值。如果没有 ":",则整个值将使用数字键附加到映射中。
Parse::toMap("foo:bar|baz"); // results in ['foo' => 'bar', 'baz']
Parse::toRange($string)
将字符串解析为范围。
范围可以写成 1..5,它将返回一个数组:[1, 2, 3, 4, 5]。它也适用于字母和反向顺序 a..e,e..a 和 5..1。
Parse::toClass($string)
将字符串解析为反射类。
字符串必须具有格式 fully\qualified\Classname.class。如果字符串无法解析,则返回值是 null
。
Parse::toClassname($string)
将字符串解析为现有类名。
字符串必须具有格式 fully\qualified\Classname::class。如果字符串无法解析或类不存在,则返回值是 null
。
stubbles\values\Properties
提供了一种方便的方法来读取属性文件,并使它们的值可访问。属性可以从内存中的字符串或文件中读取
$properties = Properties::fromString($propertyString); $properties = Properties::fromFile('path/to/properties.ini');
属性由部分组成,每个部分都有一个键值对列表。假设以下属性文件
[config] cool.stuff = "Roland TB 303" interesting = "Pink fluffy unicorns dancing on rainbows" [other] the.answer = 42 github = true
在这里,属性由部分 config 和 other 组成,其中两者都有不同的键值对,cool.stuff 和 interesting 属于 config,其余两个属于 other。
你可以获取属性的原始值
$answer = $properties->getValue('other', 'the.answer'); // $answer now has the value "42" of type string
但是,这可能不是你想要达到的目标。相反,你可能希望有一个正确的类型。这就是 parse*() 方法发挥作用的地方。
$answer = $properties->parseInt('other', 'the.answer'); // $answer now has the value 42 of type int
parse(string $section, string $key)->asInt(): ?int
尝试读取值并将其转换为 int。
如果你想在部分或键未设置的情况下使用默认值,请使用 parse($section, $key)->defaultingTo(42)->asInt()
。请注意,提供的默认值必须是类型 int
。
parse(string $section, string $key)->asFloat(): ?float
尝试读取值并将其转换为 float。
如果你想在部分或键未设置的情况下使用默认值,请使用 parse($section, $key)->defaultingTo(3.03)->asFloat()
。请注意,提供的默认值必须是类型 float
。
parse(string $section, string $key)->asBool(): ?bool
尝试读取值并将其转换为布尔值。
以下值内容将被转换为 true
- yes
- true
- on
所有其他值都将评估为 false
。
如果你想在部分或键未设置的情况下使用默认值 true
,请使用 parse($section, $key)->defaultingTo(true)->asBool()
。请注意,提供的默认值必须是类型 bool
。不需要显式指定 false
作为默认值。如果未指定其他值,则如果部分或键未设置,则返回默认值 false
。
parse(string $section, string $key)->asList(): ?array
尝试读取值并将其转换为列表(键为整数的数组)。
如果值为空,则返回空数组。如果值不为空,则使用 | 分割。因此,如果值为 key = foo|bar|baz,则转换为 ['foo', 'bar', 'baz']
。
如果要在未设置部分或键的情况下使用默认值,请使用 parse($section, $key)->defaultingTo(['foo', 'bar'])->asList()
。请注意,提供的默认值必须是 array
类型。
parse(string $section, string $key)->asMap(): ?array
尝试读取值并将其转换为哈希表。
如果值为空,则返回空哈希表。如果值不为空,则使用 | 分割。结果数组将在第一个 : 处分割,第一个部分成为哈希表的键,剩余部分成为值。如果不存在 :,则整个值将使用数字值附加到哈希表中。因此 key = foo:bar|baz 结果为 ['foo' => 'bar', 'baz']
。
如果要在未设置部分或键的情况下使用默认值,请使用 parse($section, $key)->defaultingTo(['foo' => 'bar'])->asMap()
。请注意,提供的默认值必须是 array
类型。
parse(string $section, string $key)->asRange(): ?array
尝试读取值并将其转换为范围。
属性中的范围应写成 key = 1..5,结果值为 [1, 2, 3, 4, 5]
。
这也适用于字母和反向顺序。
letters = a..e
letter_reverse = e..a
numbers_reverse = 5..1
如果要在未设置部分或键的情况下使用默认值,请使用 parse($section, $key)->defaultingTo([1, 2, 3])->asRange()
。请注意,提供的默认值必须是 array
类型。
parse(string $section, string $key)->asClass(): ?ReflectionClass
尝试读取值并将其转换为类名 ReflectionClass
的实例。
属性中的类应写成 _key = foo\bar\Baz.class。
如果要在未设置部分或键的情况下使用默认值,请使用 parse($section, $key)->defaultingTo(new ReflectionClass(stdClass::class))->asClass()
。请注意,提供的默认值必须是 ReflectionClass
类型。
密码
自版本 4.0.0 以来可用
自版本 4.0.0 以来,键为 password
的属性将存储为 stubbles|values\Secret
的实例。这也是请求此类属性值时的返回值。
可修改的属性
自版本 1.7.0 以来可用
默认情况下,属性为只读。如果您需要可修改的属性,请使用 stubbles\values\ModifiableProperties
类。它提供了设置属性值的方法。
setSection(string $section, array $data)
设置具有给定部分名称的完整部分。如果此部分已存在,则将其替换。
setValue(string $section, string $name, $value)
设置单个属性值。
setBooleanValue(string $section, string $name, $value)
以正确的方式设置单个属性为布尔值,以便可以通过 parseBool()
读取。
setArrayValue(string $section, string $name, array $value)
以正确的方式设置数组属性,以便可以通过 parseArray()
读取。
setHashValue(string $section, string $name, array $hash)
以正确的方式设置映射属性,以便可以通过 parseHash()
读取。
setRangeValue(string $section, string $name, array $range)
以正确的方式设置范围属性,以便可以通过 parseRange()
读取。
unmodifiable()
自版本 4.0.0 以来可用
从可修改的属性返回不可修改的实例。
stubbles\values\ResourceLoader
自版本 7.1.0 以来可用
描述
stubbles\values\ResourceLoader
允许从不同位置加载资源。它依赖于以下描述的根路径。
在 stubbles/values 中,资源被定义为当前项目路径 src/main/resources
中或任何其他位于 vendor
中的 Composer 包的 src/main/resources
路径中的任何类型的文件。
open(string $resource, string $withClass = 'stubbles\streams\file\FileInputStream')
使用给定的 $withClass
打开指定的资源以读取其内容。此类必须接受资源路径作为构造函数参数。默认情况下将使用类 stubbles\streams\file\FileInputStream
,但提供此类的包 stubbles/streams 必须在您的项目中引入。
资源可以是资源的完整路径或本地路径。如果是本地路径,则在其当前项目的 src/main/resources
文件夹中搜索。
无法通过提供完整路径来打开根路径之外的资源,完整路径必须始终指向根路径内的资源。
load(string $resource)
加载资源内容。资源可以是资源的完整路径或本地路径。如果是本地路径,则在其当前项目的 src/main/resources
文件夹中搜索。
无法通过提供完整路径来加载根路径之外的资源,完整路径必须始终指向根路径内的资源。
$props = $resourceLoader->load('some/properties.ini');
loadWith(string $resource, callable $loader)
加载资源内容。资源可以是资源的完整路径或本地路径。如果是本地路径,则在其当前项目的 src/main/resources
文件夹中搜索。
无法通过提供完整路径来加载根路径之外的资源,完整路径必须始终指向根路径内的资源。
给定的 $loader
必须接受一个路径,并从加载操作返回结果
$props = $resourceLoader->loadWith( 'some/properties.ini', fn($path) => Properties::fromFile($path) );
availableResourceUris(string $resourceName): array
返回一个资源所有可用 URI 的列表。返回的列表按字母顺序排序,这意味着如果存在,当前项目的本地资源总是作为第一个条目返回,然后是所有供应商资源。供应商资源的顺序也是按供应商/包名称的字母顺序。
stubbles\values\Rootpath
自版本 7.1.0 以来可用
描述
项目内的根路径由 stubbles\values\Rootpath
表示。它定义为整个应用程序所在的路径。当创建实例且未提供任何参数时,类将通过检查以下位置来计算根路径
- 如果应用程序位于 phar 内,则是存储 phar 的目录。
- 尝试定位由 Composer 生成的
vendor/autoload.php
文件,并向上移动到vendor/..
。
对于单元测试,在构造类时可以直接提供用于测试的实际根路径可能很有用。
to(string ...$path): string
返回给定本地路径的绝对路径。支持任意参数列表,例如 $rootpath->to('src', 'main', 'php', 'Example.php')
将返回 /absolute/path/to/root/src/main/php/Example.php
。
contains(string $path): bool
检查给定的路径是否位于根路径内。
sourcePathes(): array
返回为自动加载器定义的所有源路径的列表。它依赖于由 Composer 生成的自动加载器文件。如果不存在此类自动加载器,则源路径列表将为空。
Rootpath::default(): string
自版本 8.1.0 以来可用
一个静态方法,当不需要实例时,直接返回根路径字符串。
stubbles\values\Value
自版本 7.2.0 以来可用
描述
表示单个值,通常是标量值,可以对它们执行某些检查。其中一些检查是内置的,但可以定义额外的检查。
使用 Value::of($someValue)
创建实例。如果 $someValue
是 null
,则将使用固定值实例。对于所有时间,只有一个 Value::of(null)
实例 - 使用 null
的每次创建都将返回相同的实例。
要访问存储的值,请调用 $actualValue = $value->value()
。
contains($needle): bool
检查值是否包含“针”。如果值是字符串,则检查 $needle
是否是值内的子串。如果值是数组或 \Traversable
的实例,则给定的 $needle
必须是数组或可遍历的元素。
containsAnyOf(array $elements): bool
检查值是否包含给定的任何元素。
equals($expected): bool
检查值是否等于预期值。预期值必须是非null标量值。比较使用===
。
isOneOf(array $allowedValues, bool $strict = false): bool
检查值是否等于允许值之一。如果值本身是数组,此方法在包含不在允许值列表中的值时返回false
。
有时需要值类型也必须相等。在这种情况下,应将$strict
标志设置为true
。
isMatchedBy(string $regex): bool
检查值是否可以与给定的正则表达式匹配。
satisfies(callable $check): bool
检查值是否满足给定的调用。给定的调用必须接受一个值,其返回值是返回的。
isNull(): bool
自版本 8.1.0 以来可用
检查值是否为null
。
isEmpty(): bool
自版本 8.1.0 以来可用
检查值是否为空。如果值是null
、空字符串或空数组,则认为是空的。
定义额外的检查
可以定义额外的检查:Values::defineCheck('hasPower', function($value) { return 6100 == $value; });
定义后,此检查可以使用如下方式使用:Value::of($someValue)->hasPower()
不应定义现有的PHP函数,它们是自动可用的:Value::of($someValue)->is_int()
可用函数
stubbles\values\lastErrorMessage(): Result
返回原生PHP函数error_get_last()['message']
的消息,作为stubbles\values\Result
的实例。
stubbles\values\typeOf(&$value): string
返回给定值的正确类型。
对于对象,将返回实际的类名。如果是资源,则返回值将是resource[type_of_resource],例如resource[stream]。对于所有其他类型,结果是调用PHP的本地gettype()
函数。
stubbles\values\pattern($pattern): Pattern
自7.1.0版本起可用。
创建一个正则表达式,用于匹配其他字符串值。
该模式使用preg_match()并检查值是否恰好出现一次。请确保提供的正则表达式包含正确的定界符,它们将不会自动应用。如果正则表达式无效,matches()方法将抛出\RuntimeException异常。