Fork me on GitHub

PHP(yield)生成器

 yield手册

       yield生成器是php5.5之后出现的,官方文档这样解释:yield提供了一种更容易的方法来实现简单的迭代对象,相比较定义类实现 Iterator 接口的方式,性能开销和复杂性大大降低。

生成器的核心是一个yield关键字,一个生成器函数看起来像一个普通的函数,不同的是:普通函数返回一个值,而一个生成器可以yield生成许多它所需要的值。生成器函数被调用时,返回的是一个可以被遍历的对象。

yield和return有点类似,不过不同的是,return会返回值并且终止代码的执行,而yield会返回一个值给循环调用此生成器的代码并且只是暂停执行生成器函数。

yield作用

1.yield 生成器主要解决占用大内存数据,内存溢出,例如常见错误 超出php最大运行内存(php的运行内存是有极限,默认128M)。

2,生成器允许你在 foreach 代码块中写代码来迭代一组数据而不需要在内存中创建一个数组,那会使你的内存达到上限,或者会占据可观的处理时间。相反,你可以写一个生成器函数,就像一个普通的自定义函数一样, 和普通函数只返回一次不同的是, 生成器可以根据需要 yield 多次,以便生成需要迭代的值。

yield利弊

读取大数量数据,例如csv,excel,以及各种日志文件等。

代码示例

<?php
//###使用yield测试用例
set_time_limit(0);
header("Content-type=text/HTML,charset=gbk");
function Read_file()
	{
    $path=__DIR__."/"."userinfo.txt";
    if(!file_exists($path)||!is_file($path)){
    return false;
    }
    $handle=fopen($path,"rb");
	
    while(!feof($handle)){ 
	      yield fgets($handle);
		
	}
    fclose($handle);
   }
   $data=Read_file();

   foreach($data as $value)
	{
	  //echo $data->rewind();
      //echo $data->key().PHP_EOL;
	  //echo $data->next().PHP_EOL;
	  //echo $data->valid().PHP_EOL;
	  //echo $data->current();
      echo "this is the ".$value;
   }
  //利用Iterator实现yield
  class interor implements Iterator {
    
       protected $path=__DIR__."/"."userinfo.txt";
	   protected $line;
	   protected $content;
	   protected $key=0;
       public function __Construct(){   
		$this->content=fopen($this->path,"rb");
        
	   }
	   public function __Destruct(){}
	   public function rewind(){
         //行数据
          $this->line=fgets($this->content);
	   }
	   public function current(){
		   //当前数据值
           return explode('=',$this->line)[0];
	   }
	   public function key(){
           return $this->key;
	   }
	   public function next(){
          $this->key++;
		  //给定结束标识符
	   if(feof($this->content)) {
            $this->line = fgets($this->content);
            fclose($this->content);
        }else{
            $this->line = fgets($this->content);
        }
	   }
	   public function valid(){
		   return !empty($this->line);
	   }
	  
  }
  echo PHP_EOL."QW";

  $res=new interor();

  foreach($res as $key=>$value){

	  echo $key.'=>'.$value;
  }
?>
  






<?php//###使用yield测试用例set_time_limit(0);header("Content-type=text/HTML,charset=gbk");function Read_file(){    $path=__DIR__."/"."userinfo.txt";    if(!file_exists($path)||!is_file($path)){    return false;    }    $handle=fopen($path,"rb");    while(!feof($handle)){       yield fgets($handle);}    fclose($handle);   }   $data=Read_file();
   foreach($data as $value){  //echo $data->rewind();      //echo $data->key().PHP_EOL;  //echo $data->next().PHP_EOL;  //echo $data->valid().PHP_EOL;  //echo $data->current();      echo "this is the ".$value;   }    class interor implements Iterator {           protected $path=__DIR__."/"."userinfo.txt";   protected $line;   protected $content;   protected $key=0;       public function __Construct(){   $this->content=fopen($this->path,"rb");           }   public function __Destruct(){}   public function rewind(){         //行数据          $this->line=fgets($this->content);   }   public function current(){   //当前数据值           return explode('=',$this->line)[0];   }   public function key(){           return $this->key;   }   public function next(){          $this->key++;  //给定结束标识符   if(feof($this->content)) {            $this->line = fgets($this->content);            fclose($this->content);        }else{            $this->line = fgets($this->content);        }   }   public function valid(){   return !empty($this->line);   }    }  echo PHP_EOL."QW";
  $res=new interor();
  foreach($res as $key=>$value){
  echo $key.'=>'.$value;  }?>  
posted @ 2022-09-10 12:51  v_nice  阅读(76)  评论(0)    收藏  举报
1