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

File Laravel Package

php-standard-library/file

Typed file handles for safe reading and writing in PHP, with explicit write modes and advisory file locking. Part of PHP Standard Library, designed to make filesystem IO clearer and less error-prone.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require php-standard-library/file:^6.1
    

    Add to composer.json under require or require-dev based on your needs.

  2. Basic Usage:

    use PhpStandardLibrary\File\FileHandler;
    
    // Initialize with a file path
    $fileHandler = new FileHandler('/path/to/file.txt');
    
    // Read file content
    $content = $fileHandler->read();
    
  3. First Use Case: Validate a file’s signature (e.g., checksum) before processing:

    $isValid = FileHandler::validateFileSignature(
        '/path/to/uploaded-file.zip',
        'sha256:expected_hash_here'
    );
    

Where to Look First

  • README.md: Focus on the Documentation link for API reference.
  • Core Classes: FileHandler (main class) and FileLock (for advisory locking).
  • Examples: Check the GitHub repository for usage snippets in tests or examples.

Implementation Patterns

Usage Patterns

  1. Typed File Handles: Use explicit modes for read/write operations to avoid accidental overwrites:

    // Read-only handle
    $readHandle = new FileHandler('/path/to/file.txt', 'r');
    
    // Write handle with append mode
    $writeHandle = new FileHandler('/path/to/file.txt', 'a');
    
  2. Atomic Writes: Ensure critical files (e.g., configs, cache) are written atomically:

    FileHandler::atomicWrite(
        '/path/to/config.json',
        json_encode(['key' => 'value'])
    );
    
  3. Advisory Locking: Coordinate concurrent access in CLI jobs or queues:

    $lock = new FileLock('/path/to/locked-file.tmp');
    $lock->acquire();
    try {
        // Critical section
    } finally {
        $lock->release();
    }
    
  4. Streaming Large Files: Process files without loading them entirely into memory:

    $fileHandler = new FileHandler('/path/to/large-video.mp4', 'r');
    while (!$fileHandler->eof()) {
        $chunk = $fileHandler->readChunk(4096);
        // Process chunk
    }
    

Workflows

  1. File Validation Workflow:

    $filePath = storage_path('uploads/plugin.zip');
    $expectedSignature = 'sha256:abc123...';
    
    if (!FileHandler::validateFileSignature($filePath, $expectedSignature)) {
        throw new \RuntimeException('Invalid plugin file!');
    }
    
  2. Secure File Upload Handling:

    $uploadedFile = $request->file('plugin');
    $tempPath = $uploadedFile->getRealPath();
    $signature = 'sha256:'.hash_file('sha256', $tempPath);
    
    // Store signature in DB for later validation
    $plugin->signature = $signature;
    $plugin->save();
    
    // Move to permanent location
    $fileHandler = new FileHandler(storage_path("plugins/{$plugin->id}.zip"), 'w');
    $fileHandler->write($uploadedFile->get());
    
  3. Concurrent File Processing:

    $lockFile = storage_path('processing.lock');
    $lock = new FileLock($lockFile);
    
    if ($lock->acquire()) {
        try {
            // Process file (e.g., generate a report)
            $report = generateReport();
            FileHandler::atomicWrite(
                storage_path('reports/latest.json'),
                $report
            );
        } finally {
            $lock->release();
        }
    } else {
        // Another process is running; retry or notify
    }
    

Integration Tips

  • Laravel Service Container: Bind the FileHandler to Laravel’s IoC container for dependency injection:

    $this->app->singleton(FileHandler::class, function () {
        return new \PhpStandardLibrary\File\FileHandler();
    });
    
  • Facade for Convenience: Create a facade to simplify usage in Blade or controllers:

    // app/Facades/FileHandlerFacade.php
    namespace App\Facades;
    
    use Illuminate\Support\Facades\Facade;
    
    class FileHandlerFacade extends Facade
    {
        protected static function getFacadeAccessor()
        {
            return 'file.handler';
        }
    }
    
  • Custom Validation Rules: Extend Laravel’s validation rules for file signatures:

    use PhpStandardLibrary\File\FileHandler;
    
    class ValidateFileSignature extends FormRequest
    {
        public function rules()
        {
            return [
                'file' => [
                    'required',
                    function ($attribute, $value, $fail) {
                        $path = $value->getRealPath();
                        $signature = $this->getExpectedSignature();
                        if (!FileHandler::validateFileSignature($path, $signature)) {
                            $fail('The file signature is invalid.');
                        }
                    },
                ],
            ];
        }
    }
    
  • Event Listeners for File Operations: Trigger events before/after file operations for logging or side effects:

    use PhpStandardLibrary\File\FileHandler;
    
    FileHandler::addListener('beforeWrite', function ($path, $mode) {
        \Log::info("Writing to file: {$path} in mode: {$mode}");
    });
    
    FileHandler::addListener('afterRead', function ($path, $content) {
        \Log::debug("Read from file: {$path}");
    });
    

Gotchas and Tips

Pitfalls

  1. File Locking Limitations:

    • Advisory locks (e.g., FileLock) are not enforced by the OS. Processes must cooperate to release locks.
    • Tip: Always use try-finally or try-catch-finally to ensure locks are released, even if an exception occurs.
  2. Path Normalization:

    • The package normalizes paths (e.g., converts \ to /), but ensure paths are absolute for cross-platform compatibility.
    • Tip: Use Laravel’s storage_path(), public_path(), or base_path() to generate absolute paths.
  3. Permission Issues:

    • Writing to files may fail silently or throw exceptions if permissions are insufficient.
    • Tip: Check file permissions before operations:
      if (!is_writable(dirname($path))) {
          throw new \RuntimeException("Directory is not writable: " . dirname($path));
      }
      
  4. Memory Usage with Large Files:

    • Reading entire files into memory (e.g., read()) can cause issues with large files.
    • Tip: Use readChunk() for streaming:
      $fileHandler = new FileHandler('/path/to/large-file.log', 'r');
      while (!$fileHandler->eof()) {
          $chunk = $fileHandler->readChunk(8192); // Read 8KB at a time
          // Process chunk
      }
      
  5. Signature Validation Edge Cases:

    • validateFileSignature() may fail for:
      • Corrupted files (e.g., partial downloads).
      • Files with unexpected line endings (e.g., \r\n vs. \n).
    • Tip: Handle exceptions gracefully:
      try {
          if (!FileHandler::validateFileSignature($path, $signature)) {
              throw new \RuntimeException('Invalid file signature.');
          }
      } catch (\PhpStandardLibrary\File\InvalidSignatureException $e) {
          \Log::error("File validation failed: " . $e->getMessage());
          // Handle error (e.g., notify admin, reject upload)
      }
      

Debugging

  1. Check File Handles:

    • Ensure file handles are properly closed after use to avoid resource leaks:
      $fileHandler = new FileHandler('/path/to/file.txt', 'r');
      try {
          $content = $fileHandler->read();
      } finally {
          $fileHandler->close(); // Explicitly close
      }
      
    • Tip: Use finally blocks or context managers (e.g., try-with-resources in PHP 8.1+).
  2. Locking Issues:

    • If locks appear stuck, check for:
      • Processes that crashed without releasing locks.
      • Permission issues preventing lock file creation/deletion.
    • Tip: Implement a lock timeout and cleanup mechanism:
      $lock = new FileLock('/path/to/lock.tmp');
      if (!$lock->acquire(5)) { // Timeout after 5 seconds
          throw new \RuntimeException('Could not acquire lock.');
      }
      
  3. Path Resolution:

    • Use realpath() to debug path issues:
      $path = realpath('/path/to/file.txt');
      if ($path === false) {
          throw new \RuntimeException("Path does not exist or is invalid.");
      }
      

Config Quirks

  1. Default Modes:
    • The package uses PHP
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.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
ecotone/kafka
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata