Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP yield vs PDO fetch?

Yesterday, I've learned that PHP has a yield() method. I was unure about its usefulness in PHP.

A colleague said it could help for SQL statements returning many rows causing potential memory issues. I believe he was refering to fetchAll(). But, instead of using fetchAll(), one can also use fetch() and process rows one-by-one. So, yield() is not key to solving the issue he is referring to.

Am I missing something about yield() vs fetch() here? Are there more benefits to using yield() and generators?

P.S.: It's true that it's easier to write clean, readable and maitainable code in large applications with yield() than with with fetch().

like image 931
Jérôme Verstrynge Avatar asked Jun 15 '16 07:06

Jérôme Verstrynge


People also ask

Is PDO faster than MySQLi?

Performance. While both PDO and MySQLi are quite fast, MySQLi performs insignificantly faster in benchmarks - ~2.5% for non-prepared statements, and ~6.5% for prepared ones. Still, the native MySQL extension is even faster than both of these.

Is PDO slower than MySQLi?

Here you can see that PDO is only 1% faster than mysqli.

Is PDO deprecated?

PDO (PHP Data Objects) Earlier versions of PHP used the MySQL extension. However, this extension was deprecated in 2012.

Why should I use PDO PHP?

PDO—PHP Data Objects—are a database access layer providing a uniform method of access to multiple databases. It doesn't account for database-specific syntax, but can allow for the process of switching databases and platforms to be fairly painless, simply by switching the connection string in many instances.


1 Answers

So, yield() is not key to solving the issue he is referring to.

Exactly.

But it can let you to disguise while()/fetch() sequence as a foreach() call if you prefer to, without memory overhead as well.

However, PDO is not a very good example, because PDOStatement already implements a traversable interface and thus can be iterated over using foreach():

$stmt = $pdo->query('SELECT name FROM users');
foreach ($stmt as $row)
{
    var_export($row);
}

So let's take mysqli for the example API that can only stream results one by one.
Edit. Actually, since 5.4.0 mysqli supports Traversable as well, so there is no point in using yield with mysqli_result either. But meh, let's keep it for the demonstration purpose.

Let's create a generator like this

function mysqli_gen (mysqli_result $res)
{
    while($row = mysqli_fetch_assoc($res))
    {
        yield $row;
    }
}

and now you can get rows using foreach without an overhead:

$res = $mysqli->query("SELECT * FROM users");
foreach (mysqli_gen($res) as $row)
{
    var_export($row);
}
like image 105
Your Common Sense Avatar answered Oct 13 '22 00:10

Your Common Sense