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

Io Laravel Package

php-standard-library/io

Handle-based I/O abstractions for PHP: composable, testable streams and readers/writers designed to be async-ready. Part of PHP Standard Library, with docs and contribution links available via php-standard-library.dev.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require php-standard-library/io
    

    For Laravel projects, ensure compatibility with your PHP version (8.1+) and Laravel version (10+ for async features).

  2. First Use Case: Async File Processing

    use PhpStandardLibrary\IO\FileHandle;
    use PhpStandardLibrary\IO\FileReader;
    use PhpStandardLibrary\IO\Async\AsyncReader;
    
    // Sync read
    $handle = new FileHandle(storage_path('app/example.txt'));
    $reader = new FileReader($handle);
    $content = $reader->read();
    
    // Async read (requires async PHP environment like Swoole)
    $asyncHandle = new AsyncHandle($handle);
    $asyncReader = new AsyncReader($asyncHandle);
    $content = yield $asyncReader->read();
    
  3. Where to Look First

    • Documentation: PHP Standard Library IO Docs for core concepts.
    • Laravel Integration: Focus on PhpStandardLibrary\IO\HandleInterface and PhpStandardLibrary\IO\ResourceInterface for Laravel service binding.
    • Async Examples: Check tests/ for async workflows (e.g., AsyncReaderTest).

Implementation Patterns

Laravel-Specific Workflows

  1. Service Container Binding Register handles as Laravel services in AppServiceProvider:

    use PhpStandardLibrary\IO\FileHandle;
    use Illuminate\Support\ServiceProvider;
    
    public function register()
    {
        $this->app->bind(
            \PhpStandardLibrary\IO\HandleInterface::class,
            function () {
                return new FileHandle(storage_path('app'));
            }
        );
    }
    
  2. Async Job Integration Use IO handles in queued jobs for non-blocking file/network operations:

    use PhpStandardLibrary\IO\Async\AsyncWriter;
    use Illuminate\Bus\Queueable;
    use Illuminate\Queue\SerializesModels;
    
    class ProcessLargeFile implements ShouldQueue
    {
        use Queueable, SerializesModels;
    
        public function handle()
        {
            $handle = new AsyncHandle(new FileHandle(storage_path('large_file.csv')));
            $writer = new AsyncWriter($handle);
            yield $writer->write('data...'); // Async write
        }
    }
    
  3. Composable Middleware for HTTP Chain IO readers/writers with Laravel’s HTTP middleware:

    use PhpStandardLibrary\IO\HttpClient;
    use PhpStandardLibrary\IO\Reader;
    
    $client = new HttpClient();
    $response = $client->request('GET', 'https://api.example.com/data');
    $reader = new Reader($response->getBody());
    $data = $reader->read();
    
  4. Testing with Mock Handles Replace Laravel’s Storage mocks with IO handles in tests:

    use PhpStandardLibrary\IO\HandleInterface;
    use PhpStandardLibrary\IO\MockHandle;
    
    public function testFileUpload()
    {
        $mockHandle = new MockHandle();
        $mockHandle->expects('write')->with('test');
    
        $this->app->instance(HandleInterface::class, $mockHandle);
        // Test your upload logic here
    }
    

Integration Tips

  • Laravel Filesystem Adapter Create a bridge between IO and Laravel’s Storage facade:

    use PhpStandardLibrary\IO\HandleInterface;
    use Illuminate\Contracts\Filesystem\Filesystem;
    
    class LaravelIOAdapter implements HandleInterface
    {
        public function __construct(private Filesystem $filesystem) {}
    
        public function write(string $path, string $contents): void
        {
            $this->filesystem->put($path, $contents);
        }
    
        // Implement other HandleInterface methods...
    }
    
  • Event-Driven I/O Use IO handles with Laravel events for reactive workflows:

    use PhpStandardLibrary\IO\EventedHandle;
    use Illuminate\Support\Facades\Event;
    
    $handle = new EventedHandle(new FileHandle('log.txt'));
    $handle->on('open', fn() => Event::dispatch('file.opened'));
    $handle->open();
    
  • Dependency Injection Prefer constructor injection for IO handles in Laravel services:

    use PhpStandardLibrary\IO\HandleInterface;
    
    class FileProcessor
    {
        public function __construct(private HandleInterface $handle) {}
    
        public function process()
        {
            $this->handle->write('processed data');
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Async Environment Requirements

    • Async features (e.g., AsyncReader, AsyncWriter) require PHP extensions like Swoole or RoadRunner.
    • Fix: Ensure your Laravel server supports async PHP (e.g., swoole in php.ini or RoadRunner as a process manager).
  2. Resource Leaks

    • Forgetting to close handles can lead to memory leaks in long-running Laravel processes (e.g., queues).
    • Fix: Use context managers or Laravel’s illuminate/support traits:
      use PhpStandardLibrary\IO\HandleInterface;
      use Illuminate\Support\Traits\Macroable;
      
      class FileService
      {
          public function __construct(private HandleInterface $handle) {}
      
          public function __destruct()
          {
              $this->handle->close();
          }
      }
      
  3. Blocking Calls in Async Code

    • Mixing sync and async IO operations can cause deadlocks.
    • Fix: Clearly separate async and sync paths in your codebase.
  4. Laravel Facade Conflicts

    • Overusing IO handles alongside Laravel’s Storage facade may lead to confusion.
    • Fix: Stick to one abstraction per module (e.g., use IO for async-heavy services, Storage for simple file ops).
  5. Testing Async Code

    • Async IO operations require special test setups (e.g., Swoole test environments).
    • Fix: Use phpunit/swoole-extension or mock async handles:
      $mockAsyncHandle = new MockAsyncHandle();
      $mockAsyncHandle->expects('read')->willReturn('mocked data');
      

Debugging Tips

  1. Handle State Inspection Use var_dump($handle->getMetadata()) to debug handle states (e.g., open/closed, position).

  2. Async Debugging Enable Swoole’s debug mode for async operations:

    swoole_set_process_name('laravel:async-io');
    
  3. Laravel Log Integration Wrap IO operations in Laravel’s logging:

    use Illuminate\Support\Facades\Log;
    
    try {
        $handle->write($data);
    } catch (\Exception $e) {
        Log::error('IO Error', ['exception' => $e]);
        throw $e;
    }
    

Extension Points

  1. Custom Handle Types Extend HandleInterface for domain-specific handles (e.g., DatabaseHandle):

    use PhpStandardLibrary\IO\HandleInterface;
    
    class DatabaseHandle implements HandleInterface
    {
        public function write(string $query): void
        {
            DB::table('logs')->insert(['query' => $query]);
        }
        // Implement other methods...
    }
    
  2. Laravel-Specific Extensions Add Laravel-specific methods to IO classes via traits:

    use Illuminate\Support\Facades\Cache;
    
    trait LaravelCacheHandle
    {
        public function cache(string $key, mixed $data): void
        {
            Cache::put($key, $data);
        }
    }
    
  3. Async Event Dispatch Integrate IO events with Laravel’s event system:

    use PhpStandardLibrary\IO\EventedHandle;
    use Illuminate\Support\Facades\Event;
    
    $handle = new EventedHandle(new FileHandle('app.log'));
    $handle->on('write', fn($data) => Event::dispatch('log.written', $data));
    

Configuration Quirks

  1. Handle Timeouts Configure default timeouts for async handles in config/app.php:

    'io' => [
        'async_timeout' => 30, // seconds
    ],
    

    Then apply in your handle:

    $handle = new AsyncHandle($fileHandle, config('app.io.async_timeout'));
    
  2. Laravel Cache Integration Use Laravel’s cache for IO metadata (e.g., file hashes):

    use Illuminate\Support\Facades\Cache;
    
    $handle = new FileHandle('app.log');
    $hash = Cache::remember("io.handle.{$handle->getPath()}.hash", 60, fn() => md5($handle->read()));
    
  3. Service Provider Bootstrapping Ensure IO handles are bound before Laravel’s bootstrapping:

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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope