neu/pipe7 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

neu/pipe7

Composer 安装命令:

composer require neu/pipe7

包简介

A library for easy and consistent data processing in PHP.

README 文档

README

pipe7 is an Iterator-based data processing library. It aims to tackle some issues one may encounter while using regular higher-order functions built in to PHP (like array_filter, array_map, and array_reduce).

PHPDoc

PHPDocumentor generated docs can be found here: https://docs.pipe7.joern-neumeyer.de/.

Installation

composer require neu/pipe7

Problem statement

PHP already offers some functions to perform data transformations on arrays. However, the given APIs are not consistent and only work on arrays. If one wants to (or has to) use a Generator or Iterator, they cannot use the built-in functions for these data sources.

On top, since functions like array_map return an immediate result, even though more operations may be performed on the array. They may end up using more memory than necessary, because the intermediate arrays are not used, except in the next step of the processing chain.

Solution

pipe7 offers a consistent and predictable API to work with, so your code is easier to understand. It also supports Iterators as data sources (which includes Generators).

In fact, the entire processing mechanism is built on the basis of Iterators. This allows pipe7 to have a low memory footprint, if you are performing a long chain of transformations on your source data structure. That also helps not just with the calculation of a final result set (like a conversion to an array), but it also allows you to only trigger a computation on the elements you really need in something like a foreach loop. If you just need to process the first five elements from your result set, pipe7 will only request enough elements from your original data source, to deliver these five result elements. So no element will be put through a callback (like in array_map), if it is not necessary.

Also...

There are a lot of common operations which you may want to perform on you data (like average calculation, grouping elements, or converting them to strings). For such common use-cases, pipe7 provides a collection of helpers available in the classes Mappers and Reducers.

To see all available helpers, please visit the documentation or build it yourself using phpDocumentor.

Performance

pipe7 is a trade-off. It performs worse than the standard array functions, when it comes down to CPU time. But that's the point. CPU time is exchanged for memory efficiency.

This repository contains a benchmark, which show performance differences between pipe7 and the regular array functions. As a reference, the array functions are used as a baseline for measurement.

use-case CPU (time compared to baseline) RAM (required/used memory to compute the result, compared to baseline)
when applying one transformation ≅250% ≅100%
when applying multiple transformation ≅250% <1%

The values given in the table are only approximations. However, it becomes clear, that pipe7 takes its toll on CPU efficiency, but it is more efficient RAM-wise. As can be seen, the RAM usage is especially low, when using a Generator as a data source.

Since Generators (or Iterators in general) are not directly compatible with functions like array_map, it would either first have to be converted into an array, or an additional data processing mechanism would be necessary.

So pipe7 really shines, when it can be used in combination with Generators.

Usage

Create a new CollectionPipe:

use Neu\Pipe7\CollectionPipe;

$data = [1,2,3];
$p = CollectionPipe::from($data);
// or with the shorthand
$p = pipe($data);

Transforming elements:

$doubled = $p->map(function($x){ return $x * 2; })->toArray();
// if you're using php7.4 or later,
// better use arrow functions for more concise code
$doubled = $p->map(fn($x) => $x * 2)->toArray();

Filtering elements:

$even = $p->filter(fn($x) => $x % 2 === 0)->toArray();

Combining Elements:

$total = $p->reduce(fn($carry, $x) => $carry + $x, 0);

As shown above, the methods map and filter always return a new CollectionPipe, from which the result has to be collected (e.g. via the toArray method). It would also be possible to iterate the new CollectionPipe instance in a foreach loop.

In contrast, reduce only returns a new CollectionPipe if its third parameter is set to true and the carry of the reduce operation is an Iterator. If the third parameter is false, or not set, a reduced array/Iterator would just be returned. If the third parameter is true, and the reduced value is not an array/Iterator, an UnprocessableObject exception will be thrown.

For more information, please have a look at the documentation.

Stateful operators

Some operations cannot easily be expressed in a single function. Such an operation could, for example, be a limitation on the items being processed in a given pipe. So, if you need to implement such an operation, create a class which implements the interface Neu\Pipe7\StatefulOperator.

If you want to save yourself a bit of boilerplate code, consider extending the class Neu\Pipe7\CallableOperator. By doing so, you get an implementation for the __invoke method, and a dummy implementation for the rewind method, if your operation does not require any specific resetting.

Stateful operators can be passed as arguments to pipes in the same way you would otherwise pass a Closure.

How will the passed operations be evaluated?

Depending on the task a particular pipe has to fulfill, it may be important to know how a pipe's logic will be executed.

Mappers

Signature: function(mixed $value, mixed $key, Neu\Pipe7\CollectionPipe $this)

If you created a pipe, which should transform incoming elements, that logic will be executed when the current method on the pipe is called.

Filters

Signature: function(mixed $value, mixed $key, Neu\Pipe7\CollectionPipe $this)

Filters are called, when the next method on the pipe is called, as they determine, whether an element shall be emitted by the pipe or not.

Reducers

Signature: function(mixed #carry, mixed $value, mixed $key, Neu\Pipe7\CollectionPipe $this)

Reducers have another signature than mappers and filters, since it is their job to create a single new value from the elements provided to them. So, they may be used to calculate sums or similar results.

License

pipe7 is available under the terms of the GNU Lesser General Public License in version 3.0 or later.

neu/pipe7 适用场景与选型建议

neu/pipe7 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 20 次下载、GitHub Stars 达 1, 最近一次更新时间为 2021 年 02 月 21 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 neu/pipe7 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 neu/pipe7 我们能提供哪些服务?
定制开发 / 二次开发

基于 neu/pipe7 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 20
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: LGPL-3.0-or-later
  • 更新时间: 2021-02-21