nette/finder
Nette Finder is a lightweight PHP utility for finding files and directories with an expressive, fluent API. Filter by name, size, date, and type, search recursively, and iterate results easily—ideal for CLI tools, build scripts, and apps.
Installation:
composer require nette/finder
(Note: While archived, the package remains functional for legacy projects.)
Basic Usage:
use Nette\Finder;
$finder = new Finder();
$files = $finder->in(__DIR__)->files();
foreach ($files as $file) {
echo $file->getPathname() . "\n";
}
First Use Case:
.js or .css files in a public/assets directory for bundling..php or .yaml files in config/ to validate or merge them.Filtering Files/Directories:
// Find all PHP files in a directory (recursive)
$finder->in('src')->name('*.php')->files();
// Exclude vendor/ and tests/
$finder->in('src')->exclude(['vendor', 'tests']);
Sorting and Grouping:
// Sort by modification time (newest first)
$finder->sortBy('mtime')->reverse();
// Group by extension
$filesByExt = [];
foreach ($finder->in('public')->files() as $file) {
$filesByExt[$file->getExtension()][] = $file;
}
Integration with Laravel:
public function register()
{
$this->app->singleton('finder', function () {
return new Finder();
});
}
$finder = app('finder');
$views = $finder->in(resource_path('views'))->files();
Dynamic Paths:
storage_path(), public_path(), or base_path() for cross-environment consistency:
$finder->in(public_path('uploads'))->name('*.jpg');
Archived Package:
symfony/finder (used by Laravel under the hood).composer require symfony/finder
Replace Nette\Finder with Symfony\Component\Finder\Finder.Performance:
->depth('> 10')) on large directories (e.g., node_modules). Use ->depth('== 0') for top-level files.$cachedFiles = cache()->remember('finder_files', now()->addHours(1), function () {
return iterator_to_array($finder->in('storage')->files());
});
Path Handling:
->ignoreDotFiles(false) to avoid hidden files (e.g., .gitignore).->name('*.PHP') may miss files. Use ->name('*.php') consistently.Iterator Behavior:
Finder returns a Traversable object. Convert to array with iterator_to_array() or loop directly:
foreach ($finder->files() as $file) { ... } // Correct
$array = $finder->files()->toArray(); // ❌ Error: No toArray() method
Laravel-Specific Shortcuts:
$finder->in(app_path())->name('*.php')->filter(function ($file) {
return str_contains(file_get_contents($file), 'namespace App');
});
Extension Points:
->filter() for logic not covered by built-in methods:
$finder->filter(function ($file) {
return $file->getMTime() > strtotime('-1 month');
});
Events facade):
foreach ($finder->files() as $file) {
event(new FileFound($file));
}
Debugging:
$finder->in('app')->files()->map->getPathname()->dump();
->ignoreDotFiles(true) temporarily.Alternatives:
// Instead of Finder, use:
File::allFiles(app_path());
File::directories(database_path());
```markdown
---
**Note**: Replace `nette/finder` with `symfony/finder` in production code. The patterns above translate directly to Symfony’s Finder API.
How can I help you explore Laravel packages today?