Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Finder Laravel Package

symfony/finder

Symfony Finder provides a fluent API to locate files and directories. Filter by name, path, size, dates, contents, and more; traverse recursively and iterate results easily—ideal for CLI tools, installers, and build scripts.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require symfony/finder
    

    No additional configuration is required—it’s a standalone component.

  2. First Use Case: Locate all PHP files in a directory and its subdirectories:

    use Symfony\Component\Finder\Finder;
    
    $finder = Finder::create()
        ->files()
        ->in(__DIR__ . '/src')
        ->name('*.php');
    
    foreach ($finder as $file) {
        echo $file->getRealPath() . "\n";
    }
    
  3. Where to Look First:


Implementation Patterns

Core Workflows

1. Basic File Discovery

// Find all files in a directory (non-recursive)
$finder = Finder::create()
    ->files()
    ->in('/path/to/dir');

// Recursive search with glob patterns
$finder = Finder::create()
    ->files()
    ->in('/path/to/dir')
    ->name('*.{php,js}');

2. Filtering by Metadata

// Files modified in the last 7 days
$finder = Finder::create()
    ->files()
    ->in('/logs')
    ->date('>1 week ago');

// Files larger than 1MB
$finder = Finder::create()
    ->files()
    ->in('/uploads')
    ->size('>1M');

3. Excluding Directories

// Exclude 'vendor' and 'node_modules'
$finder = Finder::create()
    ->files()
    ->in(__DIR__)
    ->exclude([
        'vendor',
        'node_modules',
        '*.min.js'
    ]);

4. Sorting Results

// Sort by modification time (newest first)
$finder = Finder::create()
    ->files()
    ->in('/assets')
    ->sortByModifiedTime('DESC');

5. Combining with Laravel

// Use with Laravel's Storage facade (for local files)
use Illuminate\Support\Facades\Storage;

$finder = Finder::create()
    ->files()
    ->in(storage_path('app/public'))
    ->name('*.jpg');

foreach ($finder as $file) {
    $url = Storage::url($file->getRelativePathname());
    // Process URL...
}

6. Iterating Efficiently

// Process files in chunks (memory-efficient for large directories)
$finder = Finder::create()->files()->in('/large/dir');
foreach ($finder as $file) {
    // Process $file (e.g., resize images, parse logs)
}

// Get an array of paths (for batch operations)
$paths = iterator_to_array($finder, false);

Integration Tips

Artisan Commands

use Symfony\Component\Finder\Finder;
use Illuminate\Console\Command;

class OptimizeImagesCommand extends Command
{
    protected $signature = 'images:optimize';
    protected $description = 'Optimize all images in the uploads directory';

    public function handle()
    {
        $finder = Finder::create()
            ->files()
            ->in(public_path('uploads'))
            ->name('*.{jpg,png}');

        foreach ($finder as $file) {
            $this->info("Optimizing: {$file->getRelativePathname()}");
            // Use Intervention Image or similar library
        }
    }
}

Service Providers

// Register a custom Finder service
public function register()
{
    $this->app->singleton('finder', function () {
        return Finder::create()
            ->ignoreDotFiles(false) // Include hidden files
            ->ignoreUnreadableDirs(true); // Skip permission-denied dirs
    });
}

Event Listeners

// Trigger actions when files match criteria
$finder = Finder::create()
    ->files()
    ->in(storage_path('logs'))
    ->date('>1 month ago');

foreach ($finder as $file) {
    event(new LogFileFound($file));
}

Testing

// Mock Finder in unit tests
$finder = $this->createMock(Finder::class);
$finder->method('getIterator')->willReturn(new ArrayIterator([
    new SplFileInfo('/fake/path/file1.txt'),
    new SplFileInfo('/fake/path/file2.txt'),
]));

Gotchas and Tips

Pitfalls

  1. Path Separators:

    • Use DIRECTORY_SEPARATOR or realpath() for cross-platform compatibility:
      $finder->in(__DIR__ . DIRECTORY_SEPARATOR . 'src');
      
  2. Hidden Files/Directories:

    • By default, Finder ignores hidden files (prefixed with .). Explicitly include them if needed:
      $finder->ignoreDotFiles(false);
      
  3. Performance with Large Directories:

    • Avoid loading all results into memory at once. Process files iteratively:
      foreach ($finder as $file) { ... } // Better than $finder->getIterator()->toArray()
      
  4. Symlinks:

    • Finder follows symlinks by default. Disable with:
      $finder->followLinks(false);
      
  5. Case Sensitivity:

    • On case-insensitive filesystems (e.g., Windows), glob patterns may behave unexpectedly. Use regex for precise matching:
      $finder->name('/\.php$/i'); // Case-insensitive regex
      
  6. Empty Results:

    • Finder::append() can fail silently if iterators are empty. Validate inputs:
      $finder = Finder::create()->files()->in('/nonexistent');
      if ($finder->count() === 0) {
          $this->error('No files found!');
      }
      

Debugging Tips

  1. Inspect the Iterator:

    • Convert to an array to debug:
      $files = iterator_to_array($finder, false);
      dd($files);
      
  2. Check Paths:

    • Use getRealPath() to verify absolute paths:
      $file->getRealPath(); // Resolves symlinks and relative paths
      
  3. Date Comparisons:

    • Use now() or DateTime for dynamic comparisons:
      $finder->date('>' . now()->subDays(7)->format('Y-m-d'));
      
  4. Size Units:

    • Use B, K, M, G for sizes (e.g., >1M for 1MB). Avoid raw bytes unless necessary.

Extension Points

  1. Custom Comparators:

    • Extend Symfony\Component\Finder\Comparator\ComparatorInterface for custom logic (e.g., MIME-type filtering).
  2. Event Dispatching:

    • Wrap Finder in a class to dispatch events (e.g., FileFound, SearchComplete):
      class EventfulFinder
      {
          public function find()
          {
              $finder = Finder::create()->files()->in($this->path);
              foreach ($finder as $file) {
                  event(new FileFound($file));
              }
          }
      }
      
  3. Laravel Facade:

    • Create a facade for consistency:
      // app/Facades/Finder.php
      namespace App\Facades;
      use Illuminate\Support\Facades\Facade;
      class Finder extends Facade { protected static function getFacadeAccessor() { return 'finder'; } }
      
      Register in AppServiceProvider:
      $this->app->bind('finder', function () {
          return Finder::create()->ignoreDotFiles(false);
      });
      
  4. Caching Results:

    • Cache Finder results for performance-critical paths:
      $files = Cache::remember('finder_results', now()->addHours(1), function () {
          return iterator_to_array(Finder::create()->files()->in('/data'));
      });
      

Config Quirks

  • No Configuration File: Finder is stateless and requires no config. All options are method chained.
  • Default Exclusions: Always check for unintended exclusions (e.g., vendor, .git) in recursive searches.
  • Memory Limits: For directories with millions of files, use ->limit($n) to cap results:
    $finder->limit(1000); // Process only the first 1000 files
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle