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 is a fluent API for locating files and directories. Filter by name, size, date, depth, permissions, and content; include/exclude paths; sort results; and iterate efficiently across local filesystems.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require symfony/finder
    

    No configuration required—ready to use immediately.

  2. First Use Case: Find 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->getPathname() . "\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(public_path('uploads'));

// Find all directories
$finder = Finder::create()
    ->directories()
    ->in(storage_path('logs'));

2. Filtering Files

Use chained methods to narrow results:

$finder = Finder::create()
    ->files()
    ->in(app_path())
    ->name('*.php')          // Match extension
    ->notName('*.test.php')  // Exclude test files
    ->size('>10M')           // Larger than 10MB
    ->date('modified', '>1 year ago') // Modified in last year
    ->mimeType('text/plain'); // Only text files

3. Sorting Results

$finder = Finder::create()
    ->files()
    ->sortByModifiedTime() // Newest first
    ->sortByName()         // Alphabetical
    ->sortByType();        // Directories first

4. Excluding Directories

$finder = Finder::create()
    ->files()
    ->in(base_path())
    ->exclude([
        'vendor',
        'node_modules',
        'storage/framework/cache',
    ]);

5. Appending Searches

Combine multiple search criteria:

$finder = Finder::create()
    ->files()
    ->in([storage_path('app'), storage_path('framework')]);

$finder->append(
    Finder::create()
        ->files()
        ->name('*.log')
        ->in(log_path())
);

6. Lazy Loading with Iterators

Process files without loading all into memory:

$iterator = Finder::create()
    ->files()
    ->in(public_path('assets'))
    ->getIterator();

foreach ($iterator as $file) {
    // Process one file at a time
}

Laravel-Specific Patterns

1. Integration with Laravel’s Storage Facade

Use Finder with Laravel’s Storage for cloud-based file systems:

use Illuminate\Support\Facades\Storage;
use Symfony\Component\Finder\Finder;

$finder = Finder::create()
    ->files()
    ->in(Storage::disk('s3')->path('uploads'));

foreach ($finder as $file) {
    $url = Storage::disk('s3')->url($file->getRelativePathname());
}

2. Artisan Commands

Build CLI tools for file operations:

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

class OptimizeImages extends Command
{
    protected $signature = 'images:optimize';
    protected $description = 'Optimize large images';

    public function handle()
    {
        $finder = Finder::create()
            ->files()
            ->in(public_path('images'))
            ->size('>5MB');

        foreach ($finder as $file) {
            $this->info("Optimizing: {$file->getRelativePathname()}");
            // Add optimization logic
        }
    }
}

3. Event Listeners for File Changes

Trigger actions when files match criteria:

use Illuminate\Filesystem\Events\FileCreated;
use Symfony\Component\Finder\Finder;

public function handle(FileCreated $event)
{
    $finder = Finder::create()
        ->files()
        ->in($event->path)
        ->name('*.log');

    if ($finder->count() > 10) {
        // Log rotation or cleanup
    }
}

4. Dynamic Asset Publishing

Publish only changed files during php artisan vendor:publish:

$finder = Finder::create()
    ->files()
    ->in(resource_path('views'))
    ->notPath('vendor/*')
    ->ignoreDotFiles(true);

foreach ($finder as $file) {
    $this->files->put(
        public_path($file->getRelativePathname()),
        $file->getContents()
    );
}

5. Testing File-Based Features

Mock file systems in tests:

use Symfony\Component\Finder\Finder;

public function testFileDiscovery()
{
    $finder = Finder::create()
        ->files()
        ->in(__DIR__ . '/tests/files');

    $this->assertCount(3, $finder);
}

Performance Tips

  1. Avoid Loading All Files at Once: Use iterators or limit() for large directories:

    $finder = Finder::create()
        ->files()
        ->in(storage_path('app'))
        ->limit(100); // Process only 100 files
    
  2. Combine Filters Early: Apply restrictive filters (e.g., name(), extension()) before broader ones (e.g., size()) to reduce the search space.

  3. Use ignore() for Common Exclusions:

    $finder = Finder::create()
        ->files()
        ->in(base_path())
        ->ignore([
            'vendor',
            '.git',
            'node_modules',
        ]);
    
  4. Cache Results for Repeated Use: Store Finder instances or results in memory/cache if reused frequently:

    $cacheKey = 'recent_files';
    $finder = cache()->remember($cacheKey, now()->addHour(), function () {
        return Finder::create()
            ->files()
            ->in(storage_path('logs'))
            ->date('modified', '>1 day ago');
    });
    

Gotchas and Tips

Pitfalls

  1. Path Handling Across OSes:

    • Issue: Finder uses forward slashes (/) internally, but paths passed to in() or ignore() must match the OS’s format.
    • Fix: Use Laravel’s str() helpers or realpath() to normalize paths:
      $finder = Finder::create()
          ->files()
          ->in(str_replace('\\', '/', base_path('src')));
      
  2. Case Sensitivity in Filenames:

    • Issue: On case-insensitive filesystems (e.g., Windows), name('*.php') may miss *.PHP files.
    • Fix: Use name('*.php') with Finder::create()->ignoreCase(true) or normalize case:
      $finder = Finder::create()
          ->files()
          ->in(__DIR__)
          ->name('*.php')
          ->ignoreCase(true);
      
  3. Symlink Traversal:

    • Issue: Finder follows symlinks by default, which may cause infinite loops or unintended directory traversal.
    • Fix: Disable symlink following:
      $finder = Finder::create()
          ->files()
          ->in(__DIR__)
          ->followLinks(false);
      
  4. Empty Results from append():

    • Issue: Appending an empty Finder instance can break iteration (fixed in v8.0.4+).
    • Fix: Ensure appended Finder instances are non-empty or use hasResults() to check:
      $finder = Finder::create()->files()->in('nonexistent');
      if ($finder->hasResults()) {
          $mainFinder->append($finder);
      }
      
  5. Glob Pattern Quirks:

    • Issue: Unanchored glob patterns (e.g., *test*.php) may not work as expected due to regex conversion.
    • Fix: Use anchored patterns or escape special characters:
      $finder = Finder::create()
          ->files()
          ->name('/^test.*\.php$/'); // Regex mode
      
  6. Memory Leaks with Large Directories:

    • Issue: Loading thousands of files into memory can cause high memory usage.
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui