jojo1981 / data-resolver
通用的可扩展数据解析器
2.0.1
2021-09-06 10:03 UTC
Requires
- php: ^7.4|^8.0
- sebastian/comparator: ^4.0
Requires (Dev)
- ext-json: *
- dg/bypass-finals: ^1.1
- friendsofphp/php-cs-fixer: ^2.16
- php-coveralls/php-coveralls: ^2.1
- phpspec/prophecy-phpunit: ^2.0
- phpunit/phpunit: ^9.0
- roave/security-advisories: dev-master
Suggests
- jojo1981/data-resolver-handlers: Add support to work with 3th party libraries
README
作者:Joost Nijhuis <jnijhuis81@gmail.com>
数据解析器是一种声明性创建的解析器,用于从树结构中逐步提取数据。
数据解析器将线性且有序地执行所有提取操作。
下一个操作将在最后一个结果上执行等...
一些操作是从 object 中提取数据,而另一些则是提取 sequence 的数据。
此库具有用于获取解析器构建器和开始构建解析器的工厂类。
还可以注册自定义的 comparator、merge、property 和 sequence 处理器。
提取操作包括
- 使用单个属性通过
get获取下一个值 - 使用多个属性通过
get获取下一个值(数据解析器尝试合并结果) - 使用谓词通过
find、filter或flatten获取下一个值 - 对于序列和
hasProperty对象,使用all、some、none获取下一个值(布尔值) - 使用
count获取下一个值(整数)或使用strlen获取字符串的下一个值 - 使用
sum获取下一个值(浮点数) - 使用
callback获取混合数据的下一个值
谓词包括
- equals($referenceValue)
- notEquals($referenceValue)
- greaterThan($referenceValue)
- greaterThanOrEquals($referenceValue)
- lessThan($referenceValue)
- lessThanOrEquals($referenceValue)
- isTrue()
- isFalse()
- isTruly()
- isFalsely()
- isNull()
- isNotNull()
- callback(callable $callback)
- not(PredicateBuilderInterface $predicateBuilder)
- some(PredicateBuilderInterface $predicateBuilder)
- all(PredicateBuilderInterface $predicateBuilder)
- none(PredicateBuilderInterface $predicateBuilder)
- in(array $expectedValues)
- notIn(array $expectedValues)
- isEmpty()
- isNotEmpty()
- hasCount(int $expectedCount)
- hasNotCount(int $expectedCount)
- stringStartsWith(string $prefix, bool $caseSensitive = true)
- stringEndsWith(string $suffix, bool $caseSensitive = true)
- stringEndsWith(string $suffix, bool $caseSensitive = true)
- stringContains(string $subString, bool $caseSensitive = true)
- stringMatchesRegex(string $pattern)
- hasProperty(string $propertyName)
流程
- 创建1个通用工厂实例,并可选地添加自定义配置。
- 使用
getResolverBuilderFactory获取1个解析器构建器工厂
(通用工厂将被冻结,无法再进行自定义,这样通用工厂将始终提供具有相同设置的解析器构建器工厂) - 从解析器构建器工厂中为每个要构建的解析器获取一个新鲜的解析器构建器,使用
create、compose、get、filter、flatten、find、all、none、some、count或strlen - 必须构建解析器构建器才能获取解析器。此解析器是不可变的,只能用于从树结构中解析数据。
- 使用
resolve方法使用解析器,并传递一些数据
要创建谓词构建器,请在解析器构建器上调用 or、and、not 或 where
设置通用工厂实例
- 调用
registerPropertyHandler来注册自定义属性处理器 - 调用
registerSequenceHandler来注册自定义序列处理器 - 当您有自定义属性处理器并使用
registerPropertyHandler进行注册时,请调用useDefaultPropertyHandlers。
如果没有注册自定义属性处理器,则不需要这样做。
您可以在注册自定义属性处理器之前或之后调用此方法,以确定处理器的优先级。
当此方法未调用且已注册自定义属性处理器时,默认属性处理器未注册。 - 当您有自定义序列处理器并使用
registerSequenceHandler进行注册时,请调用useDefaultSequenceHandlers。
如果没有注册自定义序列处理器,则不需要这样做。
您可以在注册序列属性处理器之前或之后调用此方法,以确定处理器的优先级。
当此方法未调用且已注册自定义序列处理器时,默认序列处理器未注册。 - 调用
setMergeHandler以注入自定义合并处理器(替换默认处理器) - 调用
setNamingStrategy以注入自定义命名策略(替换默认策略) - 调用
setComparator以注入自定义比较器(替换默认比较器)
从通用工厂获取解析器构建器工厂
- 调用
getResolverBuilderFactory以获取解析器构建器工厂,可用于创建多个解析器构建器
创建自定义配置
- 属性处理器是一个实现接口的类:
\Jojo1981\DataResolver\Handler\PropertyHandlerInterface - 序列处理器是一个实现接口的类:
\Jojo1981\DataResolver\Handler\SequenceHandlerInterface - 合并处理器是一个实现接口的类:
\Jojo1981\DataResolver\Handler\MergeHandlerInterface - 命名策略是一个实现接口的类:
\Jojo1981\DataResolver\NamingStrategy\NamingStrategyInterface - 比较器是一个实现接口的类:
\Jojo1981\DataResolver\Comparator\ComparatorInterface
安装
库
git clone https://github.com/jojo1981/data-resolver.git
Composer
composer require jojo1981/data-resolver
基本用法
使用解析器的一个简单示例。
将来将在文档中添加更复杂的示例。
<?php require 'vendor/autoload.php'; $testData = [ 'data' => [ ['name' => 'John', 'age' => 40, 'gender' => 'M'], ['name' => 'Jane', 'age' => 35, 'gender' => 'F'], ['name' => 'Rachel', 'age' => 15, 'gender' => 'F'], ['name' => 'Dennis', 'age' => 12, 'gender' => 'M'], ['name' => 'Bob', 'age' => 6, 'gender' => 'M'] ] ]; $genericFactory = new \Jojo1981\DataResolver\Factory(); $resolverBuilderFactory = $genericFactory->getResolverBuilderFactory(); $dataResolverBuilder = $resolverBuilderFactory->get('data'); $agePredicateBuilder1 = $resolverBuilderFactory->where('age')->greaterThanOrEquals(35); $agePredicateBuilder2 = $resolverBuilderFactory->where('age')->greaterThanOrEquals(45); // will be all persons \print_r($dataResolverBuilder->build()->resolve($testData)); // Will be 5 \var_dump($dataResolverBuilder->count()->resolve($testData)); // filtered data contains John and Jane \print_r($dataResolverBuilder->filter($agePredicateBuilder1)->build()->resolve($testData)); // empty array \print_r($dataResolverBuilder->filter($agePredicateBuilder2)->build()->resolve($testData)); // Will be true \var_dump($dataResolverBuilder->some($agePredicateBuilder1)->resolve($testData)); // Will be false \var_dump($dataResolverBuilder->all($agePredicateBuilder1)->resolve($testData)); // Will be false \var_dump($dataResolverBuilder->none($agePredicateBuilder1)->resolve($testData)); // Will be 3 \var_dump( $resolverBuilderFactory ->find($resolverBuilderFactory->where('age')->equals(6)) ->get('name') ->strlen() ->resolve($testData['data']) ); // more examples to come...