处理DOM解析结果
QueryList返回的集合数据均为Collection
集合对象而非普通数组,目的就是为了方便处理DOM解析结果数据。
QueryList引入了Laravel中Collection
集合对象,它提供了一个更具可读性的、更便于处理数组数据的封装。下面通过几个例子来说明它的用法,更多用法可以去查看Laravel文档。
Collection文档:https://d.laravel-china.org/docs/5.4/collections
例子
DOM解析所有图片链接,DOM解析目标:
$html =<<<STR
<div class="xx">
<img data-src="/path/to/1.jpg" alt="">
</div>
<div class="xx">
<img data-src="/path/to/2.jpg" alt="">
</div>
<div class="xx">
<img data-src="/path/to/3.jpg" alt="">
</div>
STR;
$html =<<<STR
<div class="xx">
<img data-src="/path/to/1.jpg" alt="">
</div>
<div class="xx">
<img data-src="/path/to/2.jpg" alt="">
</div>
<div class="xx">
<img data-src="/path/to/3.jpg" alt="">
</div>
STR;
$data = QueryList::html($html)->rules([
'image' => ['img','data-src']
])->range('.xx')->query()->getData(function($item){
return $item;
});
print_r($data->all());
$data = QueryList::html($html)->rules([
'image' => ['img','data-src']
])->range('.xx')->query()->getData(function($item){
return $item;
});
print_r($data->all());
Array
(
[0] => Array
(
[image] => /path/to/1.jpg
)
[1] => Array
(
[image] => /path/to/2.jpg
)
[2] => Array
(
[image] => /path/to/3.jpg
)
)
Array
(
[0] => Array
(
[image] => /path/to/1.jpg
)
[1] => Array
(
[image] => /path/to/2.jpg
)
[2] => Array
(
[image] => /path/to/3.jpg
)
)
简化数据
如果我们想要的结果是一位数组,而非二位数组,那该怎么做呢?
可以使用flatten()
方法将多维集合转为一维的,对上面的DOM解析结果data
进行处理:
$rt = $data->flatten()->all();
print_r($rt);
$rt = $data->flatten()->all();
print_r($rt);
输出结果:
Array
(
[0] => /path/to/1.jpg
[1] => /path/to/2.jpg
[2] => /path/to/3.jpg
)
Array
(
[0] => /path/to/1.jpg
[1] => /path/to/2.jpg
[2] => /path/to/3.jpg
)
截取数据
如果我们只想要前2条数据,其它数据都是多余的,那该怎么做呢?
take()
方法返回给定数量项目的新集合,对最初的DOM解析结果data
进行处理:
$rt = $data->take(2)->all();
print_r($rt);
$rt = $data->take(2)->all();
print_r($rt);
输出结果:
Array
(
[0] => Array
(
[image] => /path/to/1.jpg
)
[1] => Array
(
[image] => /path/to/2.jpg
)
)
Array
(
[0] => Array
(
[image] => /path/to/1.jpg
)
[1] => Array
(
[image] => /path/to/2.jpg
)
)
你也可以传入负整数从集合末尾开始获取指定数量的项目,下面获取data
数据中最后2条数据:
$rt = $data->take(-2)->all();
print_r($rt);
$rt = $data->take(-2)->all();
print_r($rt);
输出结果:
Array
(
[1] => Array
(
[image] => /path/to/2.jpg
)
[2] => Array
(
[image] => /path/to/3.jpg
)
)
Array
(
[1] => Array
(
[image] => /path/to/2.jpg
)
[2] => Array
(
[image] => /path/to/3.jpg
)
)
翻转数据顺序
某些情况下我们需要翻转数据顺序,比如:DOM解析论坛的帖子列表,帖子默认是按照发布日期由新到旧排序的,但我们把这些数据存入数据库的时候,想要按照发布日期由旧到新存入。
reverse()
方法用来倒转集合中项目的顺序:
$rt = $data->reverse()->all();
print_r($rt);
$rt = $data->reverse()->all();
print_r($rt);
输出结果:
Array
(
[2] => Array
(
[image] => /path/to/3.jpg
)
[1] => Array
(
[image] => /path/to/2.jpg
)
[0] => Array
(
[image] => /path/to/1.jpg
)
)
Array
(
[2] => Array
(
[image] => /path/to/3.jpg
)
[1] => Array
(
[image] => /path/to/2.jpg
)
[0] => Array
(
[image] => /path/to/1.jpg
)
)
过滤数据
filter()
方法用于按条件过滤数据,只保留满足条件的数据。
下面例子过滤掉图片路径为/path/to/2.jpg
的值。
$rt = $data->filter(function($item){
return $item['image'] != '/path/to/2.jpg';
})->all();
print_r($rt);
$rt = $data->filter(function($item){
return $item['image'] != '/path/to/2.jpg';
})->all();
print_r($rt);
Array
(
[0] => Array
(
[image] => /path/to/1.jpg
)
[2] => Array
(
[image] => /path/to/3.jpg
)
)
Array
(
[0] => Array
(
[image] => /path/to/1.jpg
)
[2] => Array
(
[image] => /path/to/3.jpg
)
)
遍历数据,依次处理每一项数据
map()
方法遍历集合并将每一个值传入给定的回调。该回调可以任意修改项目并返回,从而形成新的被修改过项目的集合。下面遍历data
并补全图片链接地址:
$rt = $data->map(function($item){
$item['image'] = 'http://xxx.com'.$item['image'];
return $item;
})->all();
print_r($rt);
$rt = $data->map(function($item){
$item['image'] = 'http://xxx.com'.$item['image'];
return $item;
})->all();
print_r($rt);
输出结果:
Array
(
[0] => Array
(
[image] => http://xxx.com/path/to/1.jpg
)
[1] => Array
(
[image] => http://xxx.com/path/to/2.jpg
)
[2] => Array
(
[image] => http://xxx.com/path/to/3.jpg
)
)
Array
(
[0] => Array
(
[image] => http://xxx.com/path/to/1.jpg
)
[1] => Array
(
[image] => http://xxx.com/path/to/2.jpg
)
[2] => Array
(
[image] => http://xxx.com/path/to/3.jpg
)
)
连贯操作
Collection
对象的所有方法都是可以连贯操作的,比如下面操作,先翻转数数据顺序,然后补全图片链接,最后截取前2条数据:
$rt = $data->reverse()->map(function($item){
$item['image'] = 'http://xxx.com'.$item['image'];
return $item;
})->take(2)->all();
print_r($rt);
$rt = $data->reverse()->map(function($item){
$item['image'] = 'http://xxx.com'.$item['image'];
return $item;
})->take(2)->all();
print_r($rt);
输出结果:
Array
(
[2] => Array
(
[image] => http://xxx.com/path/to/3.jpg
)
[1] => Array
(
[image] => http://xxx.com/path/to/2.jpg
)
)
Array
(
[2] => Array
(
[image] => http://xxx.com/path/to/3.jpg
)
[1] => Array
(
[image] => http://xxx.com/path/to/2.jpg
)
)
{primary} 大家可以举一反三,更多用法查看Collection文档。