sohophp/sofinder-symfony
Symfony bundle for SOfinder that adds container-managed search and filtering to Symfony applications. Configure reusable search definitions, wire services through dependency injection, and keep complex query logic organized and maintainable for database-backed projects.
Install with Composer: composer require sohophp/sofinder. Laravel's package auto-discovery registers the service provider and facade, so no manual wiring is needed on Laravel 9+.
If you're on a non-standard Laravel skeleton, register Sohophp\SoFinder\SoFinderServiceProvider::class and alias the facade in config/app.php.
Publish the config only if you need to override defaults (root directories, ignore patterns, hidden-file handling):
php artisan vendor:publish --tag=sofinder-config
First use case: enumerate files in a project directory with a fluent, Symfony-Finder-style chain:
use Sohophp\SoFinder\Facades\SoFinder;
$phpFiles = SoFinder::in(base_path('app'))
->name('*.php')
->files();
foreach ($phpFiles as $file) {
dump($file->getRealPath());
}
Read first: the README's fluent API table (it's the fastest reference for in(), name(), notName(), path(), depth(), files()/directories()) and the published config/sofinder.php. Most day-to-day questions are answered by those two.
The core workflow mirrors Symfony Finder. Build chains incrementally — start with in(), narrow with name()/path()/size(), then terminate with files(), directories(), or an iterator. Chains are immutable enough that you can store a base "finder" and clone/extend it per use case.
SoFinder facade for quick scripts, Artisan commands, and tinker.Wrap finder queries in Artisan commands for common ops (e.g., "list stale cache files", "audit media directory"). Because the finder is IteratorAggregate, you can stream large trees with foreach instead of loading everything into memory.
For large trees, prefer iterating the finder directly or with your own chunk helper rather than calling ->files()->toArray(). Pair with lazy()/generators to keep memory flat on logs or storage folders.
Storage) only when you actually need a disk abstraction; SoFinder operates on real paths, so use Storage::path() to bridge.config('sofinder.roots') and feed each into a chain — this makes multi-tenant or per-disk scans trivial.artisan schedule:run for periodic cleanup jobs (log rotation, orphaned uploads)..env, .htaccess), explicitly enable them — otherwise the finder silently skips them.name('*.php') is a glob; use path() with a regex or Symfony's notName/name regex helpers when matching substrings. Mixing the two is a frequent source of empty results.current/ dirs, enable symlink following or resolve real paths first.vendor, node_modules, and storage/framework on app-wide scans — otherwise traversal cost explodes. Put these in config/sofinder.php so it's a one-time fix.in(base_path()) or in('app'). Normalize before comparing or storing paths.in() and files(), confirm it finds anything, then re-add name/path/depth to find the culprit.v1.0.0-rc.1 with no documented breaking changes relative to the RC, so RC adopters should upgrade cleanly. Pin to ^1.0 and watch for a 1.1 with API additions.How can I help you explore Laravel packages today?