responsive-sk / slim4-paths
Enhanced secure path management for PHP applications with 30+ predefined paths, security validation, and Orbit CMS support
Requires
- php: ^8.1
Requires (Dev)
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^10.0
- squizlabs/php_codesniffer: ^3.7
This package is not auto-updated.
Last update: 2025-06-27 16:03:55 UTC
README
A comprehensive, secure path management package for PHP applications with advanced features for modern web development.
Features
- Secure Path Joining - Prevents path traversal attacks
- 30+ Predefined Paths - Complete coverage for web applications
- Cross-Platform Compatibility - Works on Windows, Linux, macOS
- Auto-Directory Creation - Automatic directory structure setup
- Security Validation - Input validation and path sanitization
- Framework Agnostic - Works with any PHP framework
- Orbit CMS Support - Built-in support for content management
- Module System Integration - Advanced module path resolution
Installation
composer require responsive-sk/slim4-paths
Basic Usage
use ResponsiveSk\Slim4Paths\Paths; // Initialize with base path and configuration $paths = new Paths('/path/to/project', [ 'templates' => '/path/to/project/templates', 'content' => '/path/to/project/content', // ... more paths ]); // Basic path access $templatePath = $paths->templates(); $configPath = $paths->config(); $publicPath = $paths->public();
Convenience Methods
Paths::fromHere(__DIR__, $levelsUp = 3)
Convenience method to create a Paths
instance from the current file location. Useful in modular systems.
use ResponsiveSk\Slim4Paths\Paths; // From a file at src/Modules/Core/SomeClass.php, go up 3 levels to project root $paths = Paths::fromHere(__DIR__, 3); // From a file at src/Services/SomeService.php, go up 2 levels to project root $paths = Paths::fromHere(__DIR__, 2); // Use resolved paths $dbPath = $paths->storage('database.db'); $logPath = $paths->logs('app.log');
Benefits:
- ✅ More expressive than manual path construction
- ✅ Less error-prone than counting
../
manually - ✅ Works in tests, CLI, without DI containers
- ✅ Automatic path validation with clear error messages
Paths::fromEnv($envVar = 'APP_BASE_PATH')
Create a Paths
instance from an environment variable. Useful for applications that need environment-based configuration.
// Set environment variable putenv('APP_BASE_PATH=/path/to/project'); // Create Paths instance from environment $paths = Paths::fromEnv(); // Or use custom environment variable putenv('BASE_PATH=/custom/path'); $paths = Paths::fromEnv('BASE_PATH');
Environment-based Usage
Combine environment-based initialization with existing path methods:
// Environment-based initialization $paths = Paths::fromEnv(); // or Paths::fromHere(__DIR__, 3) // Use existing path methods $paths->base(); // Project root: /path/to/project $paths->public(); // Public directory: /path/to/project/public $paths->config(); // Config directory: /path/to/project/config $paths->src(); // Source directory: /path/to/project/src // Configured paths work as expected $paths->storage('database.db'); // /path/to/project/var/storage/database.db $paths->logs('app.log'); // /path/to/project/var/logs/app.log
Core Path Methods
Basic Directories
$paths->base() // Project root directory $paths->config() // Configuration directory $paths->src() // Source code directory $paths->public() // Public web directory $paths->var() // Variable/runtime directory $paths->vendor() // Vendor directory
Template System
$paths->templates() // Main templates directory $paths->views() // Views directory $paths->layouts('main.php') // Layout templates $paths->partials('header.php') // Partial templates
Content Management (Orbit CMS)
$paths->content() // Content root directory $paths->articles('post.md') // Article files $paths->orbit() // Orbit database directory $paths->orbitDatabase('app') // Orbit database file (app.db)
Module System
$paths->moduleConfig('Core/Storage') // Module config file $paths->moduleRoutes('Core/Template') // Module routes file $paths->moduleTemplates('Optional/Blog') // Module templates directory
Asset Management
$paths->css('app.css') // CSS files $paths->js('main.js') // JavaScript files $paths->images('logo.png') // Image files $paths->fonts('roboto.woff2') // Font files $paths->media('video.mp4') // Media files
Development Tools
$paths->docs('api.md') // Documentation files $paths->scripts('deploy.sh') // Script files $paths->bin('console') // Executable files $paths->tests('UserTest.php') // Test files
Security & Storage
$paths->keys('private.key') // Security keys $paths->exports('data.json') // Export files $paths->imports('import.csv') // Import files $paths->logs('app.log') // Log files $paths->cache('views') // Cache files $paths->storage('uploads') // Storage files
Localization
$paths->lang('en', 'messages.php') // Language files $paths->translations('app.po') // Translation files $paths->locales() // Locales directory
Secure Path Joining
The getPath()
method provides secure path joining with built-in protection against path traversal attacks:
// Secure path joining $safePath = $paths->getPath($baseDir, $relativePath); // Automatic validation try { $maliciousPath = $paths->getPath('/safe/dir', '../../../etc/passwd'); } catch (InvalidArgumentException $e) { // Path traversal detected and blocked echo $e->getMessage(); // "Path traversal detected in: ../../../etc/passwd" }
Security Features
- Path Traversal Protection - Detects and blocks
..
sequences - Home Directory Protection - Blocks
~
access - Input Validation - Validates all path components
- Cross-Platform Safety - Handles different directory separators
Configuration
Basic Configuration
$config = [ 'base_path' => '/path/to/project', 'paths' => [ 'templates' => '/path/to/project/templates', 'content' => '/path/to/project/content', 'public' => '/path/to/project/public', // ... more paths ] ]; $paths = new Paths($config['base_path'], $config['paths']);
Framework Integration
Slim Framework
use ResponsiveSk\Slim4Paths\Paths; use Slim\Factory\AppFactory; $app = AppFactory::create(); // Add Paths to container $container = $app->getContainer(); $container->set(Paths::class, function() { $config = require 'config/paths.php'; return new Paths($config['base_path'], $config['paths']); }); // Use in routes $app->get('/template/{name}', function ($request, $response, $args) { $paths = $this->get(Paths::class); $templatePath = $paths->templates($args['name'] . '.php'); if (!file_exists($templatePath)) { throw new \Slim\Exception\HttpNotFoundException($request); } // Render template... });
Orbit CMS Integration
This package includes built-in support for Orbit-style content management:
// Article management $articlePath = $paths->articles('getting-started.md'); $articlesDir = $paths->articles(); // Database management $appDb = $paths->orbitDatabase('app'); // var/orbit/app.db $markDb = $paths->orbitDatabase('mark'); // var/orbit/mark.db $cacheDb = $paths->orbitDatabase('cache'); // var/orbit/cache.db // Content organization $contentRoot = $paths->content(); // content/ $docsContent = $paths->content('docs'); // content/docs/
Module System Support
Advanced module path resolution for modular applications:
// Module configuration $storageConfig = $paths->moduleConfig('Core/Storage'); // Result: src/Modules/Core/Storage/config.php // Module routes $templateRoutes = $paths->moduleRoutes('Core/Template'); // Result: src/Modules/Core/Template/routes.php // Module templates $blogTemplates = $paths->moduleTemplates('Optional/Blog'); // Result: src/Modules/Optional/Blog/templates/ $blogArticleTemplate = $paths->moduleTemplates('Optional/Blog', 'article.php'); // Result: src/Modules/Optional/Blog/templates/article.php
Security Best Practices
Always Use Secure Path Joining
// Good - secure path joining $filePath = $paths->getPath($baseDir, $userInput); // Bad - vulnerable to path traversal $filePath = $baseDir . '/' . $userInput;
Validate User Input
function loadUserFile(Paths $paths, string $filename) { // Validate filename if (!preg_match('/^[a-zA-Z0-9_-]+\.txt$/', $filename)) { throw new InvalidArgumentException('Invalid filename'); } // Use secure path joining $filePath = $paths->getPath($paths->uploads(), $filename); return file_get_contents($filePath); }
Directory Traversal Protection
The package automatically protects against common attacks:
// These will throw InvalidArgumentException $paths->getPath('/safe/dir', '../../../etc/passwd'); $paths->getPath('/safe/dir', '~/sensitive/file'); $paths->getPath('/safe/dir', 'file/../../../etc/passwd');
Testing
use PHPUnit\Framework\TestCase; use ResponsiveSk\Slim4Paths\Paths; class PathsTest extends TestCase { public function testSecurePathJoining() { $paths = new Paths('/project', ['uploads' => '/project/uploads']); // Valid path $validPath = $paths->getPath($paths->uploads(), 'file.txt'); $this->assertEquals('/project/uploads/file.txt', $validPath); // Invalid path should throw exception $this->expectException(InvalidArgumentException::class); $paths->getPath($paths->uploads(), '../../../etc/passwd'); } }
Requirements
- PHP 8.1 or higher
- No additional dependencies
License
MIT License
Contributing
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
Changelog
Version 2.0.0
- Added 30+ predefined path methods
- Enhanced security with path traversal protection
- Added Orbit CMS support
- Added module system integration
- Added comprehensive test coverage
- Breaking changes from 1.x (see migration guide)
Version 1.0.0
- Initial release
- Basic path management functionality