首页 > 解决方案 > 使用带有由 ORM 形成或从数据库中水合的模型实体的生成器

问题描述

使用 PHP 生成器可以更有效地使用内存。所有教程都使用示例,其中数字递增并yield从 foreach() 循环中获取。

但是我如何以下面描述的更复杂的方式使用生成器。

class Book {
}

class Library 
{
    /**
     * @var Books[]
     */
    private $books;

    public function loadBooks()
    {
        // We load individual Books from database and form our "Book" objects
        // and push them into $this->books;
    }    

    public function getBooks()
    {
        foreach ($this->books as $book) {
            yield $book;
        }
    }
}

$library = new Library();
$library->loadBooks();

问题

使用yieldthere 对所需的内存量有何影响?我们不是已经花费了存储每本书所需的内存$this->books吗?

当您处理由来自数据库/ORM 的另一个对象组成的对象时,生成器在这种情况下有用吗?

标签: phpgenerator

解决方案


虽然您的示例没有从中受益yield,但您的问题的答案是:这取决于。

假设您在对象内部保留了结果的句柄,则如果不是将所有记录加载到属性中,您可能会获得收益。

还有一些 ORM 确实会动态收集关系数据,因此在表之间定义了关系的同时,它们从表 1 中检索完整结果,然后在需要时为表 2 的详细信息构建单独的选择。在这种情况下,您应该从产量中获益,尤其是当您尝试显示足够大的集合以使用所有进程内存时。这是可能的,因为数据库有它们的内部“游标”来来回读取数据,所以如果您使用这些游标而不是将所有内容加载到内存中,那么您可以处理比内存更多的数据。而yield恰好比这很有帮助。

尽管如此,yield 对于 ORM 并没有多大用处,因为大多数流行的 ORM 也是为了非常优化的资源使用而制作的。在您的情况下,我宁愿专注于正确使用您的 ORM,而不是使用花哨的技术。


推荐阅读