PHP关于SPL学习经历
2019-08-18 13:18 loserQiu 阅读(187) 评论(0) 编辑 收藏 举报<?php namespace App\Http\Controllers; class WelcomeController extends Controller { use \App\Traiter\TraitTest;// 使用traitpublic function show() { $iterator = new \NoRewindIterator($this->yieldTest());//生成一个Iterator foreach ($iterator as $key => $value) { var_dump($value); } $this->myTest(); $fileIterator = new \NoRewindIterator($this->splFileObject()); foreach ($fileIterator as $key => $value) { var_dump($value); } $path = "../"; $this->splFileObjec($path);// $this->recDirectoryIterator($path); $recArrayIterator = $this->recArrIterator(); $this->recIterIterator($recArrayIterator); $this->recTreeIterator($recArrayIterator); } public function yieldTest() { $array = [ 'a', 'b', 'c', 'd', 'e' ]; $iterator = new \ArrayIterator($array); foreach ($iterator as $key => $value) { yield $value; } } public function splFileObject() { $flieObject = new \SplFileObject(__FILE__, 'r'); while (!$flieObject->eof()) { yield $flieObject->fgets(); } } public function dirIterator($path) { $dirIterator = new \DirectoryIterator($path); foreach ($dirIterator as $fileInfo) { if ($fileInfo->isDir()) { var_dump($fileInfo->getFilename()); } } } public function recDirectoryIterator($path) { $recDirectoryIterator = new \RecursiveDirectoryIterator($path); $recIteratorIterator = new \RecursiveIteratorIterator($recDirectoryIterator, \RecursiveIteratorIterator::SELF_FIRST); foreach ($recIteratorIterator as $name => $object) { // if ($object->isDir()) { // var_dump($object->getPath()); // } if (in_array($object->getFileName(), [".", ".."])) { continue; } var_dump($name); } } public function recArrIterator() { $fruits = array("a" => "lemon" , "b" => ["orange", "taozi"], "c" => array("d" => "apple", "p" => "pear", "sub" => ["ch1", "ch2", "ch3"])); var_dump($fruits); $iterator = new \RecursiveArrayIterator($fruits); while ($iterator->valid()) { if ($iterator->hasChildren()) { foreach ($iterator->getChildren() as $key => $value) { var_dump($value); } } else {
var_dump($value);
}
$iterator->next(); } return $iterator; } public function recIterIterator(\RecursiveArrayIterator $recArrayIterator) { $iterator = new \RecursiveIteratorIterator($recArrayIterator); foreach ($iterator as $key => $value) { $depth = $iterator->getDepth(); var_dump("depth: $depth, key: $key, value: $value"); } } public function recTreeIterator(\RecursiveArrayIterator $recArrayIterator) { $iterator = new \RecursiveTreeIterator($recArrayIterator, null, null, \RecursiveIteratorIterator::LEAVES_ONLY); foreach ($iterator as $key => $value) { var_dump($value); } } } ?>
这里有几个点说明一下
一、yield关键字
1、yield是可以让一个函数重复返回。把函数加载到迭代器Iterator里,然后foreach逐个读取返回值。
2、游历大文件时,通常的办法是一次性加载到数组里,这样的话有可能php内存溢出。用yield结合SplFileObject()类解决这个问题,原理是通过该类的fgets()每读一行就处理一行。工作中经常遇到批量导入数据到数据,该方法可以使用
二、RecursiveArrayIterator()类
1、通常我们处理一个多维数组,想要获取最底层的数组比较困难,需要反复判断Is_array(),然后再次循环,而且不知道会有多少层,这是蛋都隐隐作痛了。比如一家公司下有多个部门,每个部门构成的元素有人和部门,一层层下去,我们需要查找每个部门的人时,就很头大了。通过RecursiveArrayIterator($array)就可以轻松解决了。