Reading large files in PHP: fread, fgets, and generators
Processing a 3 GB CSV import. file() and file_get_contents() exhaust memory immediately. Sharing two approaches that keep memory flat.
fgets line by line (simplest):
Generator (reusable, composable):
Memory usage stays constant regardless of file size.
The generator approach is the most reusable. You can compose it with other generators: filter, transform, batch. None of those steps load the full file.
fread with explicit buffer size is faster than fgets for binary files or when you control the chunk size. fgets stops at newline so it is not useful for fixed-width binary records.
SplFileObject also does line-by-line reading and has a CSV mode built in: set SplFileObject::READ_CSV flag and iterate. A bit slower than fgets but cleaner API.
quick question - is 8192 for fread just some magic number or does it actually matter? saw it in like 5 different tutorials
8192 matches the typical filesystem block size but 65536 is often faster on modern hardware with large reads. Benchmark your specific case. The optimal size depends on the filesystem, storage type, and CPU cache size.
For network streams (HTTP responses, sockets) smaller buffers reduce latency. For local files larger buffers reduce syscall overhead. Different defaults for different use cases.
stream_get_contents with a length argument also works for chunked reads and plays nicely with stream filters. You can attach a base64 decode filter and read encoded data without a separate decode step.