Object of class Generator could not be converted to string

4.4k views Asked by At

I have some code that can return massive amount of data. So instead of saving this into an array I wanted to use generators. However, I'm having quite a few problems with it.

Now, when I'm doing it simple like this

foreach ($this->test(0,10) as $test) {
    print $test;
}

public function test($from, $to) {
    for ($i = $from; $i < $to; $i++) {
        yield $i;
    }
}

Here I'm getting the following output

0123456789

Now, I wanted to to the same with a real life example. Like this

$posts = $this->getPosts();
foreach ($posts as $post) {
    print $post;
}

protected function getPosts()
{
    // Getting the content of the sitemap
    $response = Curl::get('http://wpde.org/sitemap.xml')[0];
    // Loading the string as XML
    $sitemapJson   = simplexml_load_string($response->getContent());
    // This case is true when the sitemap has a link to more sitemaps instead of linking directly to the posts
    if (isset($sitemapJson->sitemap)) {
        foreach ($sitemapJson->sitemap as $post) {
            if (substr($post->loc, -3) === "xml") {
                $this->setUrl((string)$post->loc);
                yield $this->getPosts(); // I also tried it here without the yield, but then I just get an empty output :/
            }
        }
    } 
    // This case is true, when the sitemap has now the direct links to the post
    elseif (isset($sitemapJson->url)) {
        foreach ($sitemapJson->url as $url) {
            yield (string)$url->loc;
        }
    }
}

But here I'm getting the error:

Catchable fatal error: Object of class Generator could not be converted to string

The strange thing is, when I'm printing out the URL

print $this->url . '<br>';

I'm only getting the first URL of the Sitemap. However, if I remove the yield parts I'm getting all links of the Sitemap. It just seems like it's somehow stopping there?

Anyway, I'm just not able to print out the data. How would I do this? Thanks!

And without the yield in the first if case there is simply no content.

1

There are 1 answers

1
ptkoz On BEST ANSWER

Change this line

yield $this->getPosts();

to

foreach($this->getPosts() as $post)
    yield $post;

as only one item, not whole "collection" may be yielled at once.