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

Php Vfs Laravel Package

php-vfs/php-vfs

Simple virtual filesystem via a PHP stream wrapper for unit tests. Emulates files/dirs in memory so you can test code that reads/writes the filesystem without temporary folders or fixtures. Works with PHPUnit, PHPSpec, and other frameworks.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require --dev php-vfs/php-vfs
    

    Add to composer.json under require-dev:

    "php-vfs/php-vfs": "^1.4"
    
  2. First Use Case: Create a virtual filesystem in a test class:

    use org\bovigo\vfs\vfsStream;
    
    public function testFileOperations()
    {
        $root = vfsStream::setup('root');
        $file = vfsStream::create(['file.txt' => 'Hello, VFS!']);
        $this->assertFileExists($root->url() . '/file.txt');
    }
    
  3. Key Entry Points:

    • vfsStream::setup(): Creates a virtual root directory.
    • vfsStream::create(): Builds a directory structure from an array.
    • $root->url(): Gets the filesystem root URL for use with PHP filesystem functions.

Implementation Patterns

Core Workflows

  1. Isolated File Operations:

    public function testFileReadWrite()
    {
        $root = vfsStream::setup('test');
        $file = vfsStream::create(['data.txt' => 'Test content']);
        $content = file_get_contents($root->url() . '/data.txt');
        $this->assertEquals('Test content', $content);
    }
    
  2. Directory Structure Mocking:

    $structure = [
        'project' => [
            'src' => ['index.php' => '<?php echo "Hello";'],
            'tests' => ['TestCase.php' => '<?php class TestCase {}']
        ]
    ];
    $root = vfsStream::create($structure);
    
  3. Integration with Laravel:

    • Use Storage::fake() (Laravel 8+) for Laravel-specific filesystem testing.
    • For legacy Laravel, manually mock filesystem paths:
      $root = vfsStream::setup('storage');
      Storage::fake('local');
      Storage::disk('local')->put('file.txt', 'Content');
      $this->assertEquals('Content', file_get_contents($root->url() . '/file.txt'));
      
  4. Symlinks and Permissions:

    $root = vfsStream::setup('links');
    vfsStream::create([
        'original.txt' => 'Original',
        'link.txt' => 'link'
    ]);
    $root->addChild(vfsStream::symlink('link.txt', 'original.txt'));
    $this->assertTrue(is_link($root->url() . '/link.txt'));
    
  5. Testing File Uploads:

    public function testUploadHandler()
    {
        $root = vfsStream::setup('uploads');
        $file = vfsStream::create(['photo.jpg' => 'fake binary data']);
        $request = new UploadedFile($root->url() . '/photo.jpg', 'photo.jpg');
        $handler = new FileUploadHandler();
        $this->assertTrue($handler->handle($request));
    }
    

Laravel-Specific Tips

  • Mocking Storage Facade: Use Storage::fake() for Laravel's filesystem, but fall back to VFS for legacy code:

    public function testLegacyStorage()
    {
        $root = vfsStream::setup('legacy');
        Storage::disk('local')->put('file.txt', 'Legacy content');
        $this->assertEquals('Legacy content', file_get_contents($root->url() . '/file.txt'));
    }
    
  • Testing filesystem Config: Override config in tests:

    $this->app->instance('path.storage', $root->url());
    

Gotchas and Tips

Common Pitfalls

  1. Path Resolution:

    • Always use $root->url() to resolve paths, not relative paths.
    • Example of WRONG:
      file_get_contents('data.txt'); // Fails (relative to current dir)
      
    • Example of CORRECT:
      file_get_contents($root->url() . '/data.txt');
      
  2. Glob and Directory Iteration:

    • Avoid glob(); use DirectoryIterator or readdir():
      $iterator = new DirectoryIterator($root->url());
      foreach ($iterator as $file) {
          // Handle file
      }
      
  3. File Permissions:

    • VFS mimics Unix permissions. Use chmod() if needed:
      chmod($root->url() . '/file.txt', 0644);
      
  4. Stream Wrapper Conflicts:

    • Disable other stream wrappers (e.g., zip) if they interfere:
      stream_wrapper_unregister('zip');
      
  5. Laravel Caching:

    • Clear cached configs if testing filesystem changes:
      $this->app->make('config')->set('filesystems.disks.local.root', $root->url());
      

Debugging Tips

  1. Inspect Structure:

    $this->assertTrue($root->hasChild('expected/file.txt'));
    $this->assertEquals('Content', $root->getChild('file.txt')->getContent());
    
  2. Log File Contents:

    $content = file_get_contents($root->url() . '/file.txt');
    $this->log($content); // Use Laravel's logger or var_dump
    
  3. Handle Exceptions:

    • VFS throws RuntimeException for missing files/dirs. Catch explicitly:
      try {
          file_get_contents($root->url() . '/missing.txt');
          $this->fail('Expected exception');
      } catch (RuntimeException $e) {
          $this->assertStringContainsString('No such file', $e->getMessage());
      }
      

Extension Points

  1. Custom Stream Wrappers: Extend vfsStream for domain-specific needs:

    class CustomVfs extends vfsStream {
        public static function createWithPermissions(array $structure, int $permissions = 0755) {
            // Custom logic
        }
    }
    
  2. Mocking File Class: For Laravel, mock Illuminate/Filesystem/File:

    $mock = Mockery::mock('Illuminate/Filesystem/File');
    $mock->shouldReceive('exists')->andReturnTrue();
    $mock->shouldReceive('get')->andReturn('Content');
    
  3. Integration with Flysystem: Use VFS as a Flysystem adapter:

    $adapter = new VfsAdapter(vfsStream::setup('flysystem'));
    $filesystem = new League\Flysystem\Filesystem($adapter);
    

Performance Notes

  • VFS is not a drop-in replacement for real filesystems in performance-critical paths.
  • Use for unit tests only; avoid in integration tests with real I/O.

Laravel-Specific Quirks

  1. Fake Storage: Laravel's Storage::fake() uses a different implementation. Prefer it for Laravel-specific tests:

    public function testLaravelStorage()
    {
        Storage::fake('local');
        Storage::disk('local')->put('file.txt', 'Content');
        $this->assertTrue(Storage::disk('local')->exists('file.txt'));
    }
    
  2. Config Overrides: Override filesystem.disks in phpunit.xml:

    <env name="FILESYSTEM_DISK" value="local"/>
    
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky