Search code examples
phpgeneratorfgetsyield

Generator function not executed PHP


In the following code, I don't get 'handled' on my output. I see the filehandle a resource, the file gets opened en the contructor of FqReader is called, I checked all that. But with execution of FqReader::getread() I don't see output and the returned array is empty. The first while loop also does not get exectuted when I put while(1) instead of the logic test as in the code now.

<?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());

It outputs:

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

Solution

  • $file_handle is a FastqFileinstance. Then you pass that object to fgets(), but you need to pass that object's handle to fgets(). For instance:

    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);
            }
        }
    }
    

    The usage of yield was not showing you that error.