phpfn / pipe
2.0.1
2020-11-22 21:17 UTC
Requires
- php: >=7.4
- phpfn/placeholder: ^2.0.1
- symfony/polyfill-php80: ^1.0
Requires (Dev)
- laminas/laminas-code: ~3.4
- phpunit/phpunit: ^9.0
- symfony/console: ~4.3|~5.0
- symfony/var-dumper: ~4.3|~5.0
README
基于RFC Pipe Operator的对象导向管道操作符实现。
安装
可以将此库安装到任何PHP应用程序中
$ composer require phpfn/pipe
为了访问库,请确保在您的文件中包含 vendor/autoload.php
。
<?php require __DIR__ . '/vendor/autoload.php';
使用方法
PHP OOP的一种常见模式是使用方法链,也称为“流畅表达式”。这个名称来源于一个方法如何流到下一个方法,形成一个概念上的超表达式。
然而,当使用函数式方法时,这可能会导致可读性降低、符号表污染或类型不一致,例如以下示例
<?php $snakeCase = strtolower( preg_replace('/(.)(?=[A-Z])/u', '$1_', preg_replace('/\s+/u', '', ucwords('HelloWorld') ) ) ); var_dump($snakeCase); // "hello_world"
管道库修复了这个问题,允许你链式执行纯函数
pipe('Hello World') ->ucwords(_) ->preg_replace('/\s+/u', '', _) ->preg_replace('/(.)(?=[A-Z])/u', '$1_', _) ->strtolower(_) ->var_dump; // // string(11) "hello_world" //
另一个示例
见:https://wiki.php.net/rfc/pipe-operator#file_collection_example
<?php $result = array_merge( $result, namespaced\func\get_file_arg( array_map( function ($x) use ($arg) { return $arg . '/' . $x; }, array_filter( scandir($arg), function ($x) { return $x !== '.' && $x !== '..'; } ) ) ) );
使用此库,上述内容可以轻松重写为
<?php $result = pipe($arg) ->scanDir($arg) ->array_filter(_, fn($x): bool => $x !== '.' && $x !== '..') ->array_map(fn($x): string => $arg . '/' . $x, _) ->use('namespaced\func')->get_file_arg ->array_merge($result, _);
处理值
要将值作为参数传递给函数,请使用下划线 (_
) 字符
<?php pipe('hello') ->str_replace('o', '', _) ->var_dump; // "hell"
如果只使用一个参数,则可以省略括号
<?php pipe('some') ->is_array ->var_dump; // bool(false)
要获取值,请使用以下选项之一
<?php $context = pipe('hello')->strtoupper; var_dump($context); // object(Fun\Pipe\Pipe)#8 (1) { ... } var_dump($context()); // string(5) "HELLO"
处理命名空间
让我们用一个简单的例子来说明这种代码
namespace { function foo() { return __FUNCTION__; } } namespace Example { function foo() { return __FUNCTION__; } }
让我们尝试管理命名空间
$context = pipe()->use('Example')->foo; echo $context(); // 'Example\\foo' $context = $context->foo; echo $context(); // 'foo'
请注意,use
函数仅应用于后续函数,所有当前上下文中执行的操作
pipe() ->use('Some\\Namespace')->foo // Call "\Some\Namespace\foo()" ->foo // Call "\foo()" ;
为了在另一个命名空间中执行多个操作,请将匿名函数作为第二个 use
参数。
pipe() ->use('Some\\Namespace', fn($pipe) => $pipe ->a // Call "\Some\Namespace\a()" ->b // Call "\Some\Namespace\b()" ) ->a // Call "a()" ;
请注意,
->use()
方法的行为取决于是否传递了第二个参数。