php
53 lines · 7 steps
Recursively finding files with SPL iterators in PHP
A FileFinder walks a directory tree and returns paths matching an extension and minimum size.
Explained by
highlit
1<?php
2
3namespace App\Support;
4
5use FilesystemIterator;
6use RecursiveDirectoryIterator;
7use RecursiveIteratorIterator;
8use SplFileInfo;
9
10final class FileFinder
11{
12 public function __construct(
13 private readonly string $extension = 'php',
14 private readonly int $minBytes = 0,
15 ) {
16 }
17
18 public function find(string $rootPath): array
19 {
20 if (!is_dir($rootPath)) {
21 throw new \InvalidArgumentException("Not a directory: {$rootPath}");
22 }
23
24 $directory = new RecursiveDirectoryIterator(
25 $rootPath,
26 FilesystemIterator::SKIP_DOTS | FilesystemIterator::FOLLOW_SYMLINKS,
27 );
28
29 $iterator = new RecursiveIteratorIterator(
30 $directory,
31 RecursiveIteratorIterator::LEAVES_ONLY,
32 );
33
34 $matches = [];
35
36 foreach ($iterator as $file) {
37 /** @var SplFileInfo $file */
38 if (!$file->isFile() || $file->getExtension() !== $this->extension) {
39 continue;
40 }
41
42 if ($file->getSize() < $this->minBytes) {
43 continue;
44 }
45
46 $matches[] = $file->getRealPath();
47 }
48
49 sort($matches);
50
51 return $matches;
52 }
53}
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1PHP's recursive iterators let you flatten a whole directory tree into a single foreach loop.
- 2Readonly constructor-promoted properties turn a class into a tidy, immutable configuration object.
- 3Filtering with early continue statements keeps a scanning loop flat and easy to read.
Related explainers
php
<?php namespace App\Http\Requests;
A validated date-range value object in PHP
value-object
validation
immutability
Intermediate
7 steps
python
from pathlib import Path from collections import defaultdict from PIL import Image
Finding near-duplicate images by perceptual hash
perceptual-hashing
clustering
hamming-distance
Intermediate
9 steps
php
<?php namespace App\Http\Controllers\Api;
Building a cursor-paginated feed in Laravel
cursor-pagination
eager-loading
validation
Intermediate
8 steps
rust
use axum::{ extract::FromRequestParts, http::{request::Parts, StatusCode, header::ACCEPT_LANGUAGE}, };
A locale extractor for Axum handlers
content-negotiation
http-headers
custom-extractor
Intermediate
7 steps
php
<?php namespace App\Services;
Caching per-tenant settings in Laravel
caching
multi-tenancy
dependency-injection
Intermediate
7 steps
ruby
require "phonelib" class PhoneNumber class InvalidNumber < StandardError; end
Wrapping phone parsing in a Ruby value object
value-object
memoization
validation
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/recursively-finding-files-with-spl-iterators-in-php-explained-php-cff3/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.