【问题标题】:Generator function not executed PHP生成器函数未执行 PHP
【发布时间】:2018-02-04 08:25:58
【问题描述】:

在以下代码中,我的输出没有得到“处理”。我看到文件句柄是一个资源,文件被打开并调用了 FqReader 的构造函数,我检查了所有这些。但是执行 FqReader::getread() 我看不到输出并且返回的数组是空的。当我放置 while(1) 而不是现在代码中的逻辑测试时,第一个 while 循环也没有被执行。

<?php

class FastqFile {
    function __construct($filename) {
        if (substr($filename, -3, 3) == '.gz') {
            $this->handle = gzopen($filename, 'r');
            return $this->handle;
        }
        else
            $this->handle = fopen($filename, 'r');
            return $this->handle;
    }
}

class FqReader {
    function __construct($file_handle) {
        $this->handle = $file_handle;
    }
    function getread() {
        while ($header = fgets($this->handle) !== false) {
            echo "handled";
            $bases = fgets($this->handle);
            $plus = fgets($this->handle);
            $scores = fgets($this->handle);
            yield array($header, $plus, $scores);
        }
    }
}

$filename = $argv[1];
$file_handle = new FastqFile($filename);
var_dump($file_handle);
$reader = new FqReader($file_handle);
var_dump($reader->getread());

它输出:

object(FastqFile)#1 (1) {
  ["handle"]=>
  resource(5) of type (stream)
}
object(Generator)#3 (0) {
}

【问题讨论】:

  • 当我像 foreach ($reader->getread()) echo $read[0] 这样循环时,我收到一个警告:PHP 警告:fgets() 期望参数 1 是资源,对象在/home/niels/Projects/umi/fastqgz.php 在第 21 行,但它说它是类型(流)的资源,对吗?所以我很困惑
  • $this-&gt;handle 不是资源,它是FastqFile 类型的对象
  • 顺便说一句,从构造函数返回任何东西没有任何意义。

标签: php generator fgets yield


【解决方案1】:

没错,这就像一个魅力:

(使用函数打开文件,而不是类)

function openfq($filename)
{
    if (substr($filename, -3, 3) == '.gz') {
        $handle = gzopen($filename, 'r');
        return $handle;
    }
    else
        $handle = fopen($filename, 'r');
        return $handle;
}

class FqReader {
    function __construct($file_handle) {
        $this->handle = $file_handle;
    }
    function getread() {
        while (($header = fgets($this->handle)) !== false) {
            echo "handled";
            $bases = fgets($this->handle);
            $plus = fgets($this->handle);
            $scores = fgets($this->handle);
            yield array($header, $bases, $scores);
        }
    }
}

$filename = $argv[1];
$file_handle = openfq($filename);
var_dump($file_handle);
$reader = new FqReader($file_handle);
var_dump($reader->getread());
foreach($reader->getread() as $read) {
    var_dump($read);
}

【讨论】:

    【解决方案2】:

    $file_handle 是一个FastqFile实例。然后将该对象传递给fgets(),但您需要将该对象的句柄传递给fgets()。例如:

    class FqReader {
        function __construct($file_handle) {
            $this->handle = $file_handle->handle;
        }
        function getread() {
            while ($header = fgets($this->handle) !== false) {
                echo "handled";
                $bases = fgets($this->handle);
                $plus = fgets($this->handle);
                $scores = fgets($this->handle);
                yield array($header, $plus, $scores);
            }
        }
    }
    

    yield 的用法并未向您显示该错误。

    【讨论】:

    • 另外,在__construct中返回一些东西是没有用的
    • 这是为什么呢?最好在这里只使用一个函数,对吧?
    猜你喜欢
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 2011-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-09
    相关资源
    最近更新 更多