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()
.
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.
Here you can see that PDO is only 1% faster than mysqli.
PDO (PHP Data Objects) Earlier versions of PHP used the MySQL extension. However, this extension was deprecated in 2012.
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.
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With