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

Path Util Laravel Package

webmozart/path-util

Lightweight PHP utility for safe, cross-platform path handling. Normalize, join, resolve and compare filesystem paths, with helpers for absolute/relative paths and canonicalization. Useful for file operations and libraries needing consistent path logic.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require webmozart/path-util
    

    Add to composer.json if not using autoloading:

    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Webmozart\\PathUtil\\": "vendor/webmozart/path-util/src/"
        }
    }
    

    Run composer dump-autoload.

  2. First Use Case Normalize a path in a Laravel controller or service:

    use Webmozart\PathUtil\PathUtil;
    
    $path = PathUtil::normalize('/var//www//example.com/../');
    // Returns: '/var/www/example.com'
    
  3. Key Classes to Know

    • PathUtil: Core utility for path manipulation.
    • PathUtil::normalize(): Resolves ., .., and duplicate slashes.
    • PathUtil::canonicalize(): Resolves symlinks (if supported by the OS).
    • PathUtil::isAbsolute(): Checks if a path is absolute.
    • PathUtil::join(): Safely joins paths (avoids DIRECTORY_SEPARATOR issues).

Implementation Patterns

Common Workflows

1. Path Normalization in File Uploads

use Webmozart\PathUtil\PathUtil;
use Illuminate\Http\Request;

public function handleUpload(Request $request) {
    $filePath = $request->file('file')->getRealPath();
    $normalizedPath = PathUtil::normalize($filePath);

    // Store or process $normalizedPath
}

2. Cross-Platform Path Handling

Ensure paths work on Linux/Windows in Laravel config:

use Webmozart\PathUtil\PathUtil;

$configPath = PathUtil::join(
    storage_path('config'),
    'custom_' . PathUtil::normalize('some/../path')
);

3. Path Comparison in Validation

use Webmozart\PathUtil\PathUtil;

public function validatePath($path) {
    $normalized = PathUtil::normalize($path);
    return PathUtil::isAbsolute($normalized) &&
           str_starts_with($normalized, storage_path());
}

4. Dynamic Path Construction

Build paths dynamically in Laravel views or Blade:

@php
    $dynamicPath = PathUtil::join(
        public_path('uploads'),
        PathUtil::normalize('user_' . auth()->id() . '/file.txt')
    );
@endphp

5. Symlink Resolution (Advanced)

Resolve symlinks in Laravel's filesystem (e.g., for shared storage):

use Webmozart\PathUtil\PathUtil;

$realPath = PathUtil::canonicalize('/path/with/symlinks');
if (!str_starts_with($realPath, storage_path())) {
    abort(403, 'Path outside allowed directory');
}

Integration Tips

  1. Laravel Service Provider Bind PathUtil as a singleton for dependency injection:

    public function register() {
        $this->app->singleton('pathUtil', function () {
            return new \Webmozart\PathUtil\PathUtil();
        });
    }
    
  2. Custom Helper Add to app/Helpers/path.php:

    if (!function_exists('normalize_path')) {
        function normalize_path($path) {
            return \Webmozart\PathUtil\PathUtil::normalize($path);
        }
    }
    
  3. Filesystem Events Use in filesystem events (e.g., creating, deleting) to sanitize paths:

    use Webmozart\PathUtil\PathUtil;
    
    Storage::extend('custom', function ($app) {
        return new CustomFilesystem(
            $app['files'],
            PathUtil::normalize(storage_path('custom'))
        );
    });
    
  4. Testing Path Logic Mock PathUtil in PHPUnit:

    $this->partialMock(PathUtil::class, ['normalize'])
         ->shouldReceive('normalize')
         ->with('/test/../path')
         ->andReturn('/test/path');
    

Gotchas and Tips

Pitfalls

  1. Symlink Resolution Limitations

    • canonicalize() may fail on Windows or restricted systems.
    • Workaround: Use normalize() for most cases; handle symlinks manually if needed.
  2. Case Sensitivity

    • Paths are case-sensitive on Linux but not on Windows.
    • Tip: Normalize paths before comparison:
      if (PathUtil::normalize('/Path/To/File') === PathUtil::normalize('/path/to/file')) {
          // Compare logic
      }
      
  3. Trailing Slashes

    • normalize() removes trailing slashes, but join() adds them.
    • Tip: Use rtrim() if you need to preserve trailing slashes:
      $path = rtrim(PathUtil::normalize('/path/'), '/');
      
  4. Windows-Specific Issues

    • Backslashes (\) may cause issues in URLs or logs.
    • Tip: Convert to forward slashes for consistency:
      $safePath = str_replace('\\', '/', PathUtil::normalize($path));
      
  5. Performance

    • Avoid overusing canonicalize() in loops (it’s slower due to symlink resolution).
    • Tip: Cache resolved paths if used repeatedly.

Debugging Tips

  1. Log Normalized Paths

    \Log::debug('Normalized path:', ['path' => PathUtil::normalize($rawPath)]);
    
  2. Compare Paths Visually

    dd([
        'Original' => $rawPath,
        'Normalized' => PathUtil::normalize($rawPath),
        'Canonical' => PathUtil::canonicalize($rawPath),
    ]);
    
  3. Check for Hidden Characters Use trim() or preg_replace() to clean paths before normalization:

    $cleanPath = trim($path, "\0..\x1F");
    $normalized = PathUtil::normalize($cleanPath);
    

Extension Points

  1. Custom Path Validator Extend PathUtil for Laravel validation rules:

    use Webmozart\PathUtil\PathUtil;
    
    Validator::extend('valid_path', function ($attribute, $value, $parameters) {
        $normalized = PathUtil::normalize($value);
        return PathUtil::isAbsolute($normalized) &&
               str_starts_with($normalized, $parameters[0] ?? storage_path());
    });
    
  2. Path Utility Trait Create a reusable trait for models or services:

    trait PathUtilTrait {
        protected function normalizePath($path) {
            return PathUtil::normalize($path);
        }
    
        protected function isStoragePath($path) {
            return str_starts_with(
                PathUtil::normalize($path),
                storage_path()
            );
        }
    }
    
  3. Override PathUtil Methods For testing or custom logic, extend the class:

    class CustomPathUtil extends \Webmozart\PathUtil\PathUtil {
        public function normalize($path) {
            $normalized = parent::normalize($path);
            return str_replace('\\', '/', $normalized);
        }
    }
    
  4. Integration with Laravel Filesystem Create a custom filesystem adapter:

    use Webmozart\PathUtil\PathUtil;
    use Illuminate\Filesystem\Filesystem;
    
    class SanitizedFilesystem extends Filesystem {
        public function __construct() {
            parent::__construct();
            $this->basePath = PathUtil::normalize(storage_path());
        }
    }
    

Configuration Quirks

  1. DIRECTORY_SEPARATOR Handling

    • The package uses DIRECTORY_SEPARATOR internally, so paths work cross-platform.
    • Tip: Avoid hardcoding / or \ in your code.
  2. Relative Paths

    • normalize() converts relative paths to absolute if combined with getcwd().
    • Tip: Use join() for relative paths:
      $relative = PathUtil::join('subdir', 'file.txt');
      $absolute = PathUtil::join(__DIR__, $relative);
      
  3. URL vs. Filesystem Paths

    • Normalized paths may not be URL-safe (e.g., spaces, special chars).
    • Tip: Use urlencode() or Str::slug() for URLs:
      $urlSafe = urlencode(PathUtil::normalize('/path with spaces/file.txt'));
      
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
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