php
35 lines · 7 steps
Streaming file lines with a PHP generator
A generator reads a file line by line so you can scan huge files without loading them into memory.
Explained by
highlit
1<?php
2
3declare(strict_types=1);
4
5function readLines(string $path): \Generator
6{
7 $handle = fopen($path, 'rb');
8
9 if ($handle === false) {
10 throw new \RuntimeException("Unable to open file: {$path}");
11 }
12
13 try {
14 $lineNumber = 0;
15
16 while (($line = fgets($handle)) !== false) {
17 yield ++$lineNumber => rtrim($line, "\r\n");
18 }
19 } finally {
20 fclose($handle);
21 }
22}
23
24function countMatchingLines(string $path, string $needle): int
25{
26 $matches = 0;
27
28 foreach (readLines($path) as $number => $line) {
29 if (str_contains($line, $needle)) {
30 $matches++;
31 }
32 }
33
34 return $matches;
35}
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Generators let you process arbitrarily large files with constant memory by yielding one item at a time.
- 2A finally block guarantees resources are released even when the consumer stops iterating early or an error occurs.
- 3Yielding keys alongside values lets a generator carry context like line numbers to its consumer for free.
Related explainers
php
<?php class NameParser {
Parsing a full name into components in PHP
string-parsing
arrays
normalization
Intermediate
8 steps
php
<?php namespace App\Services\Checkout;
Validating coupons with Laravel's Pipeline
pipeline
chain of responsibility
transactions
Intermediate
7 steps
php
<?php namespace App\Services;
How a password strength validator works in PHP
validation
regular-expressions
data-driven
Intermediate
8 steps
python
import random from typing import Iterator, List
How reservoir sampling picks k items
reservoir-sampling
streaming
randomness
Intermediate
5 steps
php
<?php namespace App\Services;
Building a cached daily leaderboard in Laravel
caching
aggregation
eager-loading
Intermediate
9 steps
rust
use chrono::{Duration, NaiveDate}; #[derive(Debug)] pub struct DateRange {
Parsing and iterating date ranges in Rust
error-handling
iterators
parsing
Intermediate
7 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/streaming-file-lines-with-a-php-generator-explained-php-06bf/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.