PHPackages                             hdaklue/larapath - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [File &amp; Storage](/categories/file-storage)
4. /
5. hdaklue/larapath

ActiveLibrary[File &amp; Storage](/categories/file-storage)

hdaklue/larapath
================

A secure, fluent path builder for PHP with sanitization strategies and Laravel 11-12 integration

2.2.4(7mo ago)831.7k2MITPHPPHP ^8.2CI passing

Since Aug 27Pushed 7mo agoCompare

[ Source](https://github.com/hdaklue/LaraPath)[ Packagist](https://packagist.org/packages/hdaklue/larapath)[ Docs](https://github.com/hdaklue/LaraPath)[ RSS](/packages/hdaklue-larapath/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (9)Dependencies (6)Versions (11)Used By (0)

LaraPath
========

[](#larapath)

[![Tests](https://github.com/hdaklue/LaraPath/workflows/Tests/badge.svg)](https://github.com/hdaklue/LaraPath/actions)[![Latest Stable Version](https://camo.githubusercontent.com/7e6918c5d23acc15fae64183e1d8ba13fde2f22e92e1fb941cb0ae2289b15137/68747470733a2f2f706f7365722e707567782e6f72672f6864616b6c75652f6c617261706174682f762f737461626c65)](https://packagist.org/packages/hdaklue/larapath)[![License](https://camo.githubusercontent.com/56198e62e9df4722e6dc90273c504b1bff69e7159ce4f1a56777e8427f826cd9/68747470733a2f2f706f7365722e707567782e6f72672f6864616b6c75652f6c617261706174682f6c6963656e7365)](https://packagist.org/packages/hdaklue/larapath)

[![Lara Path](artwork.svg)](artwork.svg)A secure, fluent path builder for PHP with sanitization strategies and Laravel 11-12 integration.

Features
--------

[](#features)

- 🔒 **Security First**: Built-in protection against directory traversal attacks with comprehensive validation
- 🎯 **Fluent API**: Clean, readable path building with method chaining
- 🔧 **Sanitization Strategies**: Multiple strategies for different use cases (hash, slug, snake\_case, timestamp)
- 📁 **Extension Preservation**: Automatic file extension preservation during sanitization
- 🚀 **Immutable Operations**: Thread-safe path building with no side effects
- 🏗️ **Strategy Pattern**: Extensible sanitization system with automatic validation
- 🎨 **Type Safety**: Full type hints and IDE autocompletion
- 📦 **Laravel Integration**: Optional Laravel Storage facade integration
- ⚡ **Error Handling**: Comprehensive exception handling with specific error types

Installation
------------

[](#installation)

```
composer require hdaklue/larapath
```

Quick Start
-----------

[](#quick-start)

```
use Hdaklue\PathBuilder\PathBuilder;
use Hdaklue\PathBuilder\Enums\SanitizationStrategy;
// Or use the facade in Laravel
use LaraPath;

// Basic usage (static)
$path = PathBuilder::base('uploads')
    ->add('images')
    ->add('avatar.jpg')
    ->toString(); // "uploads/images/avatar.jpg"

// Laravel facade usage (auto-registered)
$path = LaraPath::base('uploads')
    ->add('images')
    ->add('avatar.jpg')
    ->toString();

// With sanitization strategies
$path = PathBuilder::base('uploads')
    ->add('user-123', SanitizationStrategy::HASHED)
    ->add('My File.jpg', SanitizationStrategy::SLUG)
    ->validate()
    ->toString(); // "uploads/a665a45920422f9d417e4867efdc4fb8/my-file.jpg"
```

Real-World Use Cases
--------------------

[](#real-world-use-cases)

For detailed examples of how LaraPath solves critical problems in multi-tenant Laravel applications, see [Real World Problems](real-world-problems.md).

The guide covers 5 essential scenarios:

- Multi-tenant storage organization with privacy protection
- Database-friendly storage strategies across multiple disks
- File naming conflicts and data loss prevention
- Cross-platform filename sanitization and migration
- Team-wide consistency and standardization

Perfect for understanding LaraPath's value in complex Laravel applications.

Usage Examples
--------------

[](#usage-examples)

### Sanitization Strategies

[](#sanitization-strategies)

LaraPath automatically preserves file extensions during sanitization, ensuring your files maintain their proper types.

```
// Hash sensitive data (preserves extensions)
$path = PathBuilder::base('storage')
    ->addFile('user@email.com', SanitizationStrategy::HASHED)
    ->toString(); // "storage/d549c81aa88e6e76e1f4c141aaae4c6e.com"

// Create URL-friendly names (preserves extensions)
$path = PathBuilder::base('uploads')
    ->addFile('My Amazing File!.pdf', SanitizationStrategy::SLUG)
    ->toString(); // "uploads/my-amazing-file.pdf"

// Convert to snake_case (preserves extensions)
$path = PathBuilder::base('files')
    ->addFile('CamelCase Name.docx', SanitizationStrategy::SNAKE)
    ->toString(); // "files/camel_case_name.docx"

// Add timestamps for uniqueness (preserves extensions)
$path = PathBuilder::base('temp')
    ->addFile('session.log', SanitizationStrategy::TIMESTAMP)
    ->toString(); // "temp/session_1640995200.log"

// Directory names (no extensions to preserve)
$path = PathBuilder::base('uploads')
    ->add('User Documents', SanitizationStrategy::SLUG)
    ->toString(); // "uploads/user-documents"
```

### File Extension Preservation

[](#file-extension-preservation)

All sanitization strategies automatically detect and preserve file extensions:

```
// Complex filename with special characters
$path = PathBuilder::base('documents')
    ->addFile('My Complex File Name!@#.pdf', SanitizationStrategy::SLUG)
    ->toString(); // "documents/my-complex-file-name.pdf"

// Multiple dots in filename - preserves only the last extension
$path = PathBuilder::base('archives')
    ->addFile('backup.2023.tar.gz', SanitizationStrategy::SLUG)
    ->toString(); // "archives/backup-2023-tar.gz"

// Files without extensions work normally
$path = PathBuilder::base('configs')
    ->addFile('README', SanitizationStrategy::SLUG)
    ->toString(); // "configs/readme"

// Hidden files (starting with dot)
$path = PathBuilder::base('configs')
    ->addFile('.env.example', SanitizationStrategy::SLUG)
    ->toString(); // "configs/env.example"
```

### Path Operations

[](#path-operations)

```
$builder = PathBuilder::base('files/video.mp4');

// Extract path components
$extension = $builder->getExtension(); // "mp4"
$filename = $builder->getFilename(); // "video.mp4"
$filenameWithoutExt = $builder->getFilenameWithoutExtension(); // "video"
$directory = $builder->getDirectoryPath(); // "files"

// Modify paths
$newPath = $builder->replaceExtension('webm')->toString(); // "files/video.webm"
```

### Laravel Integration

[](#laravel-integration)

LaraPath is automatically registered in Laravel applications with facade support and container binding.

```
// Using the facade (recommended for Laravel)
use LaraPath;

$exists = LaraPath::base('uploads')
    ->add('avatar.jpg')
    ->exists('public'); // Uses Storage::disk('public')->exists()

// Using container binding
$builder = app('larapath');
$size = $builder->base('files')
    ->add('document.pdf')
    ->size(); // Uses Storage::size()

// Using static methods (framework-agnostic)
use Hdaklue\PathBuilder\PathBuilder;

$url = PathBuilder::base('images')
    ->add('logo.png')
    ->url('public'); // Uses Storage::disk('public')->url()

// Delete file
$deleted = LaraPath::base('temp')
    ->add('cache.tmp')
    ->delete(); // Uses Storage::delete()

// Get file size in different formats
$path = LaraPath::base('uploads')->add('document.pdf');

$size = $path->size(); // Raw bytes: 1048576
$formatted = $path->getSizeFormatted(); // Human readable: "1 MB"
$sizeInKB = $path->getSizeInKB(); // Binary KB: 1024.0
$sizeInMB = $path->getSizeInMB(); // Binary MB: 1.0
$sizeInKBDecimal = $path->getSizeInKBDecimal(); // Decimal KB: 1048.576
```

### Validation and Security

[](#validation-and-security)

LaraPath provides comprehensive security and validation features:

```
// Automatic path validation
$path = PathBuilder::base('uploads')
    ->add('../../../etc/passwd') // Dangerous path
    ->validate() // Throws UnsafePathException
    ->toString();

// Manual safety check
$isSafe = PathBuilder::isSafe('uploads/../dangerous/path'); // false
$isSafe = PathBuilder::isSafe('uploads/safe/file.txt'); // true

// File existence validation
$path = PathBuilder::base('uploads')
    ->addFile('document.pdf')
    ->mustExist('public') // Throws PathNotFoundException if file doesn't exist
    ->toString();

$path = PathBuilder::base('uploads')
    ->addFile('new-file.pdf')
    ->mustNotExist('public') // Throws PathAlreadyExistsException if file exists
    ->toString();
```

### Error Handling

[](#error-handling)

LaraPath throws specific exceptions for different error conditions:

```
use Hdaklue\PathBuilder\Exceptions\UnsafePathException;
use Hdaklue\PathBuilder\Exceptions\PathNotFoundException;
use Hdaklue\PathBuilder\Exceptions\PathAlreadyExistsException;
use Hdaklue\PathBuilder\Exceptions\InvalidSanitizationStrategyException;

try {
    $path = PathBuilder::base('../dangerous')
        ->addFile('file.txt')
        ->validate();
} catch (UnsafePathException $e) {
    // Handle directory traversal attempt
    echo "Unsafe path detected: " . $e->getMessage();
}

try {
    $path = PathBuilder::base('uploads')
        ->addFile('missing.txt')
        ->mustExist('local');
} catch (PathNotFoundException $e) {
    // Handle missing file
    echo "File not found: " . $e->getMessage();
}

try {
    $path = PathBuilder::base('uploads')
        ->add('input', 'InvalidStrategy');
} catch (InvalidSanitizationStrategyException $e) {
    // Handle invalid sanitization strategy
    echo "Invalid strategy: " . $e->getMessage();
}
```

### Custom Strategies

[](#custom-strategies)

Create custom sanitization strategies by implementing the `SanitizationStrategyContract`:

```
use Hdaklue\PathBuilder\Contracts\SanitizationStrategyContract;

class UuidStrategy implements SanitizationStrategyContract
{
    public static function apply(string $input): string
    {
        return \Str::uuid()->toString();
    }
}

// Use custom strategy
$path = PathBuilder::base('files')
    ->add('temp-file', UuidStrategy::class)
    ->toString(); // "files/550e8400-e29b-41d4-a716-446655440000"
```

### Strategy Validation

[](#strategy-validation)

LaraPath automatically validates that custom strategies implement the required contract:

```
// ✅ Valid strategy - implements SanitizationStrategyContract
$path = PathBuilder::base('files')
    ->add('input', MyCustomStrategy::class)
    ->toString();

// ❌ Invalid strategy - throws InvalidSanitizationStrategyException
$path = PathBuilder::base('files')
    ->add('input', 'NonExistentStrategy')
    ->toString(); // Exception: Strategy class NonExistentStrategy not found

// ❌ Invalid strategy - missing contract implementation
$path = PathBuilder::base('files')
    ->add('input', \stdClass::class)
    ->toString(); // Exception: Strategy class stdClass must implement SanitizationStrategyContract interface
```

API Reference
-------------

[](#api-reference)

### PathBuilder Methods

[](#pathbuilder-methods)

- `PathBuilder::base(string $path, ?SanitizationStrategy $strategy = null): self`
- `add(string $name, ?SanitizationStrategy $strategy = null): self`
- `addFile(string $filename, ?SanitizationStrategy $strategy = null): self`
- `addTimestampedDir(): self`
- `addHashedDir(string $input, string $algorithm = 'md5'): self`
- `replaceExtension(string $newExt): self`
- `getExtension(): string`
- `getFilename(): string`
- `getFilenameWithoutExtension(): string`
- `getDirectoryPath(): string`
- `ensureTrailing(): self`
- `removeTrailing(): self`
- `validate(): self`
- `toString(): string`

### Laravel Integration Methods

[](#laravel-integration-methods)

- `mustExist(string $disk = 'local'): self`
- `mustNotExist(string $disk = 'local'): self`
- `exists(string $disk = 'local'): bool`
- `size(string $disk = 'local'): int`
- `getSizeFormatted(string $disk = 'local', int $precision = 3): string`
- `getSizeInKB(string $disk = 'local'): float`
- `getSizeInMB(string $disk = 'local'): float`
- `getSizeInGB(string $disk = 'local'): float`
- `getSizeInKBDecimal(string $disk = 'local'): float`
- `getSizeInMBDecimal(string $disk = 'local'): float`
- `getSizeInGBDecimal(string $disk = 'local'): float`
- `url(string $disk = 'local'): string`
- `delete(string $disk = 'local'): bool`

### Static Utility Methods

[](#static-utility-methods)

- `PathBuilder::build(array $segments): string`
- `PathBuilder::join(string ...$segments): string`
- `PathBuilder::normalize(string $path): string`
- `PathBuilder::isSafe(string $path): bool`
- `PathBuilder::buildRelativePath(string $absolutePath, string $basePath): string`

Available Strategies
--------------------

[](#available-strategies)

All strategies automatically preserve file extensions when present:

- `SanitizationStrategy::HASHED` - MD5 hash of input (preserves extensions: `user.txt` → `hash.txt`)
- `SanitizationStrategy::SLUG` - URL-friendly slug (preserves extensions: `My File!.pdf` → `my-file.pdf`)
- `SanitizationStrategy::SNAKE` - snake\_case conversion (preserves extensions: `CamelCase.docx` → `camel_case.docx`)
- `SanitizationStrategy::TIMESTAMP` - Appends Unix timestamp (preserves extensions: `file.log` → `file_1640995200.log`)

Requirements
------------

[](#requirements)

- PHP ^8.2
- illuminate/support ^11.0|^12.0 (for Laravel integration)

Testing
-------

[](#testing)

```
composer test
```

License
-------

[](#license)

MIT License. See [LICENSE](LICENSE) for details.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.

Security
--------

[](#security)

If you discover any security related issues, please email  instead of using the issue tracker.

###  Health Score

43

—

FairBetter than 91% of packages

Maintenance64

Regular maintenance activity

Popularity31

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~4 days

Total

10

Last Release

221d ago

Major Versions

v1.1.0 → v2.0.02025-08-27

### Community

Maintainers

![](https://www.gravatar.com/avatar/537e93066b76a4e68c5aa480f60fb00dfc3c17a031c317984add79898f2eb8e8?d=identicon)[hdaklue](/maintainers/hdaklue)

---

Top Contributors

[![hdaklue](https://avatars.githubusercontent.com/u/107682410?v=4)](https://github.com/hdaklue "hdaklue (35 commits)")

---

Tags

composer-packagelaravelpath-builderphpsecurityfilesystemlaravelsecuritypathbuilderfluentimmutablesanitization

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/hdaklue-larapath/health.svg)

```
[![Health](https://phpackages.com/badges/hdaklue-larapath/health.svg)](https://phpackages.com/packages/hdaklue-larapath)
```

###  Alternatives

[yoelpc4/laravel-cloudinary

Laravel Cloudinary filesystem cloud driver.

3343.0k](/packages/yoelpc4-laravel-cloudinary)[zing/laravel-flysystem-obs

Flysystem Adapter for OBS

1211.2k](/packages/zing-laravel-flysystem-obs)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
