Weave 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 Helper Laravel Package

jackiedo/path-helper

PHP helper for working with local filesystem paths. Normalize directory separators, restyle paths for Unix/Windows/current OS, build absolute/relative paths, check if paths are absolute/relative, and test ancestor/descendant relationships. Composer install.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require jackiedo/path-helper
    

    Add to composer.json under require if using a monorepo or constrained environment.

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

    use Jackiedo\PathHelper\Path;
    
    $normalizedPath = Path::normalize(storage_path('app/logs/../backups'));
    // Returns: storage_path('app/backups') with OS-specific separators
    
  3. Where to Look First:

    • Core Methods: Focus on normalize(), absolute(), relative(), and isAbsolute() for 80% of use cases.
    • OS-Specific Styling: Use unixStyle() or winStyle() when generating paths for cross-platform APIs (e.g., CLI tools or shared storage).
    • Path Relationships: Leverage isAncestor()/isDescendant() for security checks (e.g., ensuring uploaded files stay within storage/app/uploads/).

Implementation Patterns

Usage Patterns

1. Path Normalization in File Operations

  • Pattern: Normalize paths before passing to Laravel’s filesystem methods (Storage::put(), File::move()).
$userUploadPath = Path::normalize(public_path('uploads/' . $request->file('avatar')->hashName()));
Storage::put($userUploadPath, $request->file('avatar')->get());

2. Cross-Platform CLI Tools

  • Pattern: Use osStyle() to generate paths for commands or logs, ensuring consistency across dev/staging/prod.
$logPath = Path::osStyle(storage_path('logs/laravel-' . date('Y-m-d') . '.log'));
Artisan::call('log:clear', ['--path' => $logPath]);

3. Path Validation in APIs

  • Pattern: Validate file paths in API requests using isAbsolute() and isDescendant() to prevent directory traversal.
if (!Path::isAbsolute($request->path) || !Path::isDescendant($request->path, storage_path('app/safe-zone'))) {
    abort(403, 'Invalid path');
}

4. Dynamic Path Generation

  • Pattern: Combine absolute() and relative() for dynamic path resolution (e.g., generating URLs or symlinks).
$basePath = Path::absolute('config/');
$relativeConfig = Path::relative($basePath, 'config/production.php');
// Output: '../production.php' (relative to basePath)

5. Service Provider Integration

  • Pattern: Bind the helper to Laravel’s container for global access.
// app/Providers/AppServiceProvider.php
public function register()
{
    $this->app->singleton('pathHelper', function () {
        return new \Jackiedo\PathHelper\Path();
    });
}

Usage:

$helper = app('pathHelper');
$normalized = $helper->normalize($path);

Workflows

File Upload Handling

  1. Normalize the upload path:
    $uploadPath = Path::normalize(storage_path('uploads/' . $userId));
    
  2. Validate the path is within allowed directories:
    if (!Path::isDescendant($uploadPath, storage_path('uploads'))) {
        throw new \Exception('Upload path outside allowed directory');
    }
    
  3. Use Laravel’s filesystem with the normalized path.

Cross-Environment Asset Links

  1. Generate OS-agnostic paths for asset URLs:
    $assetPath = Path::unixStyle(public_path('assets/images/logo.png'));
    $url = asset(Path::relative(public_path(), $assetPath));
    
  2. Use in Blade templates or API responses.

Debugging Path Issues

  1. Log normalized paths for debugging:
    \Log::debug('Normalized path:', [
        'input'  => $rawPath,
        'output' => Path::normalize($rawPath),
    ]);
    

Integration Tips

Laravel Filesystem

  • Use Path::normalize() before passing paths to Storage::disk()->put() or File::copy() to avoid OS-specific issues.
  • Example:
    $normalizedPath = Path::normalize(storage_path('app/backups/' . $filename));
    Storage::disk('local')->put($normalizedPath, $content);
    

Artisan Commands

  • Normalize paths in command arguments or outputs:
    protected $signature = 'backup:create {--path= : Backup path}';
    public function handle()
    {
        $path = Path::normalize($this->option('path') ?? storage_path('backups'));
        // Proceed with backup logic
    }
    

Testing

  • Mock Path helper in tests to isolate filesystem logic:
    $this->partialMock(Jackiedo\PathHelper\Path::class, function ($mock) {
        $mock->shouldReceive('normalize')->andReturn('mocked/path');
    });
    

Configuration

  • Store normalized paths in config files (e.g., config/filesystems.php) to avoid hardcoding:
    'disks' => [
        'local' => [
            'root' => Path::normalize(env('STORAGE_PATH', storage_path('app'))),
        ],
    ],
    

Gotchas and Tips

Pitfalls

  1. Path Existence Assumption:

    • Path::absolute() does not check if the path exists (unlike realpath()). Always validate existence separately:
      $absolutePath = Path::absolute($relativePath);
      if (!file_exists($absolutePath)) {
          // Handle non-existent path
      }
      
  2. Windows Drive Letters:

    • Paths like C:\Users\file.txt are treated as absolute, but Path::isAbsolute() may behave unexpectedly on Unix-like systems. Normalize first:
      $path = Path::normalize('C:\Users\file.txt');
      
  3. Trailing Slashes:

    • Methods like isDescendant() may fail if paths have inconsistent trailing slashes. Normalize both paths:
      $path1 = Path::normalize('/base/path/');
      $path2 = Path::normalize('/base/path');
      Path::isDescendant($path1, $path2); // true
      
  4. Built-in Functions Conflict:

    • Avoid using the global functions (e.g., absolute_path()) in Laravel projects to prevent naming collisions with other packages or custom helpers.
  5. PHP 5.4+ Limitation:

    • The package lacks support for newer PHP features (e.g., typed properties, attributes). If using PHP 8+, consider alternatives like Spatie\Path.

Debugging

  1. Unexpected Path Normalization:

    • Use Path::normalize($path, '|') to visualize path segments:
      $debugPath = Path::normalize($path, '|');
      // Output: base|folder|..|file.txt
      
  2. Absolute Path Issues:

    • Compare Path::absolute($path) with realpath($path) to debug discrepancies:
      $absolute = Path::absolute($path);
      $realpath = realpath($path);
      \Log::debug('Absolute vs Realpath', [$absolute, $realpath]);
      
  3. Ancestor/Descendant Logic:

    • Test edge cases like:
      Path::isAncestor('/base', '/base/../parent'); // false (avoids traversal)
      Path::isDescendant('/base/sub', '/base');     // true
      

Tips

  1. Consistent Separators:

    • Use Path::unixStyle() for API responses or logs to ensure consistency:
      $logPath = Path::unixStyle(storage_path('logs/error.log'));
      
  2. Path Joining:

    • Combine with DIRECTORY_SEPARATOR for explicit control:
      $joined = Path::normalize($path1 . DIRECTORY_SEPARATOR . $path2);
      
  3. Laravel Helper Integration:

    • Extend Laravel’s Str or File helpers by adding static methods:
      if (!class_exists('Str')) {
          class_alias('Jackiedo\PathHelper\Path', 'Str');
      }
      
      (Use cautiously to avoid conflicts.)
  4. Performance:

    • Cache normalized paths in config or environment variables if paths are static:
      $normalizedCachePath = Path::normalize(config('cache.path'));
      
  5. Alternative for PHP 8+:

    • Use Spatie\Path for modern PHP features:
      composer require spatie/path
      
      Example:
      use Spatie\Path\Path as SpatiePath;
      $path = SpatiePath::make($path)->normalize();
      
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.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
adachsoft/php-code-style