自2000年以来我一贯在利用PHP,并且利用JavaScript的韶光更长。在过去的十年里,JavaScript已经发生了巨大的变革。它从一开始就有一个很有出息的设计,并且随着转向ES2015(Harmony)而得到了目前令人难以置信的形状。PHP虽然没有改变那么多。显然,它注定会永久遭受自己的遗产。它到达90年代中期,作为一个大略的CGI运用程序来掩护Rasmus Lerdorf的主页,并且更像是自发地发展起来的。这导致语法不一致,功能和基于OOP的资产稠浊在一起,缺少体面的措辞规范。以是每次我切换到PHP时,我都会错过JavaScript的合理性,可预测性和灵巧性。这让我想到了一个可以为PHP带来类似JavaScript的开拓体验的库。终极,利用JavaScript(Underscore除外)方法扩展PHP类型的Extras,解锁链接,并引入PlainObject代表工具笔墨的 类型。
JavaScript会见PHP
该库利用JavaScript和Underscore.js方法丰富了以下PHP类型:数组(包括顺序和关联),字符串,数字(整数,浮点数,NaN),函数(可调用),凑集(Iterable,ArrayObject,Iterator)和布尔值。每个添加的方法都是表示类型的类的静态方法。因此,我们可以直接访问任何内容,而不须要创建链 Arrays::map。
这有什么好处?我们来看看下面的代码片段:
<?php
use \Dsheiko\Extras\Arrays;
function numToArray(int $value, int $index, array $array): array
{
return [$value];
}
$res = Arrays::map(range(1,3), \"大众numToArray\"大众); // [[1],[2],[3]]
不同的是\array_map, 库方法的接口与任何其他数组extras同等。第一个参数始终是源数组,接下来会迭代/预测回调,如果须要则返回其他任何内容。更?利用PHP数组函数,我们须要记住哪一个只接管源或引用的引用。 Arrays::方法总是接管独立的值和引用。
你有没有把稳到回调参数列表?是的,它根据ECMAScript规范进行了扩展。除了值之外,它总是吸收元素索引(关联数组中的键)和初始数组。
其余,所有添加的方法都可以连接在一起:
<?php
use \Dsheiko\Extras\Arrays;
$res = Arrays::chain([1, 2, 3])
->map(function($num){ return $num + 1; })
->filter(function($num){ return $num > 1; })
->reduce(function($carry, $num){ return $carry + $num; }, 0)
->value();
对我来说,它看起来比以下更干净:
$array = [1, 2, 3];
$array = \array_map(function($num){ return $num + 1; }, $array);
$array = \array_filter($array, function($num){ return $num > 1; });
$array = \array_reduce($array, function($carry, $num){ return $carry + $num; }, 0);
什么其他类型呢?如果我们接管一个字符串,它的事情事理是一样的:
<?php
use \Dsheiko\Extras\Strings;
function sanitizeSearchTerm(string $value, int $maxLength): string
{
return Strings::chain($value)
->trim()
->replace('`[^0-9\-_ \p{L}]`u', ' ')
->replace('` +`', ' ')
->substr(0, $maxLength)
->value();
}
此外,我们还可以在同一链中操作多种类型:
<?php
use \Dsheiko\Extras\Arrays;
$res = Arrays::chain([\"大众foo\"大众 => \"大众FOO\"大众, \"大众bar\"大众 => \"大众BAR\"大众])
// input: array, output: string
->reduce(function($carry, $val, $key){ return $carry . \"大众 {$key}:{$val} \"大众; }, \"大众\"大众)
// input: string, output: integer
->indexOf(\"大众bar:\"大众)
// input: integer, output: double
->toFixed(2)
->value();
实际上,你乃至不须要预测入口点的类型。相反,你可以利用类型:
<?php
use \Dsheiko\Extras\Any;
$res = Any::chain(new \ArrayObject([1,2,3]))
->toArray() // value is [1,2,3]
->map(function($num){ return [ \"大众num\公众 => $num ]; })
// value is [[ \公众num\公众 => 1, ..]]
->reduce(function($carry, $arr){
$carry .= $arr[\"大众num\"大众];
return $carry;
}, \"大众\"大众) // value is \"大众123\公众
->replace(\"大众/2/\公众, \"大众\"大众) // value is \"大众13\"大众
->then(function($value){
if (empty($value)) {
throw new \Exception(\"大众Empty value\"大众);
}
return $value;
})
->value();
正如你在这个例子中看到的,我也利用then类似于Promise API 的链式方法 。它接管链条的实际代价,并根据链条是否被修正进一步通报。
Underscore.js符合PHP没有说服?那么,我们对类型做了很多操作,尤其是对付数组。数组函数有助于隔离迭代范围并提高性能,但在展示开拓职员意图时,它们并不那么方便。实际上,我们常常办理类似的逻辑任务,我们可以大略地重用现有的模式。Extras库包含一组Underscore.js方法。它有所作为。试想一下,您有一系列键值工具(实际上是关联数组),个中携带有关剧院中所有剧本的数据。根据用户运用的过滤器,您须要搜索匹配的播放。每次利用回调时\array_filter, 您都可以利用 Arrays:where:
$listOfPlays = [
[\公众title\公众 => \公众Cymbeline\"大众, \"大众author\公众 => \"大众Shakespeare\公众, \"大众year\"大众 => 1611],
[\公众title\公众 => \"大众The Tempest\"大众, \公众author\公众 => \公众Shakespeare\"大众, \"大众year\"大众 => 1611],
[\公众title\公众 => \"大众Hamlet\公众, \"大众author\"大众 => \公众Shakespeare\"大众, \公众year\"大众 => 1603]
];
$res = Arrays::where($listOfPlays, [\"大众author\"大众 => \公众Shakespeare\公众, \公众year\"大众 => 1611]);
// [
// [\"大众title\"大众 => \"大众Cymbeline\"大众, \"大众author\"大众 => \公众Shakespeare\"大众, \"大众year\公众 => 1611],
// [\"大众title\"大众 => \公众The Tempest\公众, \"大众author\"大众 => \"大众Shakespeare\公众, \"大众year\"大众 => 1611],
// ]
或者,假设您有一个描述产品的键值数据构造。您须要提取包含您选择的唯一对的较小工具(此处为关联数组):
$res = Arrays::pick([
'name' => 'moe',
'age' => 50,
'userid' => 'moe1',
//… 100 more lines
], 'name', 'age');
// ['name' => 'moe', 'age' => 50, ]
正如您可能把稳到的,Extras可以反响PHP数组中的JavaScript类型数组和工具(分别为顺序和关联)。此外,可以从中得到类似于JavaScript普通工具的类型:
use \Dsheiko\Extras\Arrays;
$po = Arrays::object([\"大众foo\"大众 => \"大众FOO\"大众, \公众bar\"大众 => [\公众baz\"大众 => \"大众BAZ\"大众]]);
echo $po->foo; // FOO
echo $po->bar->baz; // BAZ
该类型继续了Underscore Object方法:
use \Dsheiko\Extras\Arrays;
$po = Arrays::object([
\"大众start\"大众 => 5,
\"大众end\"大众 => 12,
]);
$res = $po->mapObject(function($val){
return $val + 5;
}) // PlainObject{ \"大众start\"大众: 10, \"大众end\公众: 17 }
->invert(); // PlainObject{ 10: \"大众start\"大众, 17: \"大众end\"大众 }
概括Extras是一个可通过作曲者利用的PHP包:
composer require \"大众dsheiko/extras\"大众
它旨在改进PHP的开拓体验。也便是说,它供应了一种具有同等的命名约定和同等的参数顺序的类型操纵工具带。任何交付的方法都是可链接的。除了PHP泛型类型之外,该软件包还带有PlainObject,它类似于JavaScript普通工具。经办法遵照相应的JavaScript和Underscore.js / Lodash方法的语法和逻辑。