responsive-sk / slim4-root
Root path management with auto-discovery for Slim 4 applications
Requires
- php: ^7.4 || ^8.0
- psr/container: ^1.0 || ^2.0
- slim/slim: ^4.0
Requires (Dev)
- php-di/php-di: ^6.0
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^9.6
- slim/psr7: ^1.0
- squizlabs/php_codesniffer: ^3.12
This package is not auto-updated.
Last update: 2025-04-25 13:48:48 UTC
README
Root path management with auto-discovery for Slim 4 applications. Say goodbye to relative paths like __DIR__ . '/../../../config'
and hello to clean, consistent path access.
New in 2.0
- Automatic root path discovery for common directory structures
- Built-in path validation with detailed error messages
- Cross-platform path normalization for Windows and Unix
- Dedicated exception handling for path-related errors
- Enhanced developer experience with more intuitive API
- No more relative paths with
../
- everything is relative to the root
Features
- Centralized path management for Slim 4 applications
- Auto-discovery of common directory structures
- Support for custom directory structures
- Path validation and normalization
- Middleware for accessing paths in route handlers
- PSR-11 container integration
- No dependencies (except Slim 4 and PSR Container)
- Fully tested
- Ready for PHP 7.4 and 8.0+
Requirements
- PHP 7.4+ or 8.0+
- Slim 4
Installation
composer require responsive-sk/slim4-root
Usage
Basic Usage
use Slim4\Root\Paths; // Create a new Paths instance with auto-discovery enabled $paths = new Paths(__DIR__); // Get paths relative to the root $configPath = $paths->getConfigPath(); $viewsPath = $paths->getViewsPath(); $logsPath = $paths->getLogsPath(); // Get all paths at once $allPaths = $paths->getPaths(); // No more ../../../ paths! // Instead of: // require_once __DIR__ . '/../../../vendor/autoload.php'; // Use: // require_once $paths->path('vendor/autoload.php');
With Custom Paths
use Slim4\Root\Paths; // Create a new Paths instance with custom paths $paths = new Paths( __DIR__, [ 'config' => __DIR__ . '/app/config', 'views' => __DIR__ . '/app/views', 'logs' => __DIR__ . '/app/logs', ], true, // Enable auto-discovery (default: true) false // Disable path validation (default: false) ); // Get paths $configPath = $paths->getConfigPath(); // Returns __DIR__ . '/app/config' $viewsPath = $paths->getViewsPath(); // Returns __DIR__ . '/app/views' $logsPath = $paths->getLogsPath(); // Returns __DIR__ . '/app/logs'
Path Auto-Discovery
use Slim4\Root\PathsDiscoverer; // Create a new PathsDiscoverer instance $discoverer = new PathsDiscoverer(); // Discover paths $discoveredPaths = $discoverer->discover(__DIR__); // Use discovered paths var_dump($discoveredPaths);
Path Validation
use Slim4\Root\PathsValidator; use Slim4\Root\Exception\InvalidPathException; // Create a new PathsValidator instance $validator = new PathsValidator(); // Validate paths try { $validator->validate([ 'config' => __DIR__ . '/config', 'views' => __DIR__ . '/views', ], true); // Strict validation (throws exception if path doesn't exist) } catch (InvalidPathException $e) { echo $e->getMessage(); }
Path Normalization
use Slim4\Root\PathsNormalizer; // Create a new PathsNormalizer instance $normalizer = new PathsNormalizer(); // Normalize paths $normalizedPath = $normalizer->normalize('C:\\path\\to\\project\\'); // Returns: 'C:/path/to/project'
With DI Container
use Slim4\Root\PathsProvider; use DI\ContainerBuilder; // Create container $containerBuilder = new ContainerBuilder(); // Register paths services $rootPath = dirname(__DIR__); PathsProvider::register( $containerBuilder->build(), $rootPath, [], // Custom paths true, // Enable auto-discovery false // Disable path validation ); // Get paths from the container $paths = $container->get(Slim4\Root\PathsInterface::class);
With Middleware
use Slim4\Root\PathsMiddleware; use Slim\Factory\AppFactory; // Create app $app = AppFactory::createFromContainer($container); // Add the middleware to the app $app->add($container->get(PathsMiddleware::class)); // Access paths in a route handler $app->get('/', function ($request, $response) { $paths = $request->getAttribute('paths'); $configPath = $paths->getConfigPath(); // ... return $response; });
Integration with Twig
use Slim\Views\Twig; use Slim4\Root\PathsInterface; // Register Twig with the container $container->set(Twig::class, function (ContainerInterface $container) { $paths = $container->get(PathsInterface::class); $twig = Twig::create($paths->getViewsPath(), [ 'cache' => $paths->getCachePath() . '/twig', 'debug' => true, 'auto_reload' => true, ]); return $twig; });
Integration with Monolog
use Monolog\Logger; use Monolog\Handler\StreamHandler; use Psr\Log\LoggerInterface; use Slim4\Root\PathsInterface; // Register Logger with the container $container->set(LoggerInterface::class, function (ContainerInterface $container) { $paths = $container->get(PathsInterface::class); $logger = new Logger('app'); $logger->pushHandler(new StreamHandler($paths->getLogsPath() . '/app.log', Logger::DEBUG)); return $logger; });
Available Methods
PathsInterface
getRootPath()
- Get the root path of the projectgetConfigPath()
- Get the config pathgetResourcesPath()
- Get the resources pathgetViewsPath()
- Get the views pathgetAssetsPath()
- Get the assets pathgetCachePath()
- Get the cache pathgetLogsPath()
- Get the logs pathgetPublicPath()
- Get the public pathgetDatabasePath()
- Get the database pathgetMigrationsPath()
- Get the migrations pathgetStoragePath()
- Get the storage pathgetTestsPath()
- Get the tests pathpath(string $path)
- Get a path relative to the root pathgetPaths()
- Get all paths as an associative array
PathsDiscoverer
discover(string $rootPath)
- Discover paths in the given root path
PathsValidator
validate(array $paths, bool $strict)
- Validate paths
PathsNormalizer
normalize(string $path)
- Normalize path
Customizing Paths
You can customize the paths by passing an array of custom paths to the constructor:
$paths = new Paths( __DIR__, [ 'config' => __DIR__ . '/app/config', 'views' => __DIR__ . '/app/views', 'logs' => __DIR__ . '/app/logs', 'cache' => __DIR__ . '/app/cache', 'public' => __DIR__ . '/public', 'database' => __DIR__ . '/app/database', 'migrations' => __DIR__ . '/app/database/migrations', 'storage' => __DIR__ . '/app/storage', 'tests' => __DIR__ . '/tests', ], true, // Enable auto-discovery false // Disable path validation );
Feature Comparison
Feature | v1.x | v2.x |
---|---|---|
Auto-discovery | ❌ No | ✅ Yes |
Path validation | ❌ Basic | ✅ Comprehensive |
Path normalization | ❌ No | ✅ Yes |
Error handling | ❌ Generic exceptions | ✅ Dedicated exceptions |
Relative paths | ❌ Manual ../ |
✅ Everything relative to root |
Test coverage | ✅ Good | ✅ Excellent |
Flexibility | ✅ Good | ✅ Excellent |
Auto-Discovery
The Paths
class can automatically discover common directory structures in your project. This is enabled by default, but you can disable it by passing false
as the third parameter to the constructor.
// With auto-discovery (default) $paths = new Paths(__DIR__); // Without auto-discovery $paths = new Paths(__DIR__, [], false);
The auto-discovery process looks for the following directories:
config
- Looks forconfig
,app/config
,etc
resources
- Looks forresources
,app/resources
,res
views
- Looks forresources/views
,templates
,views
,app/views
assets
- Looks forresources/assets
,assets
,public/assets
cache
- Looks forvar/cache
,cache
,tmp/cache
,storage/cache
logs
- Looks forvar/logs
,logs
,log
,storage/logs
public
- Looks forpublic
,web
,www
,htdocs
database
- Looks fordatabase
,db
,storage/database
migrations
- Looks fordatabase/migrations
,migrations
,db/migrations
storage
- Looks forstorage
,var
,data
tests
- Looks fortests
,test
Path Validation
The Paths
class can validate that all paths exist. This is disabled by default, but you can enable it by passing true
as the fourth parameter to the constructor.
// Without validation (default) $paths = new Paths(__DIR__); // With validation $paths = new Paths(__DIR__, [], true, true);
If validation is enabled and a path doesn't exist, an InvalidPathException
will be thrown:
try { $paths = new Paths(__DIR__, [], true, true); } catch (\Slim4\Path\Exception\InvalidPathException $e) { echo $e->getMessage(); // "Configured path for 'views' is not a valid directory: /path/to/views" }
Testing
composer test
Documentation
For detailed documentation, see:
Examples
- Simple Example - Basic usage in a typical Slim 4 project
- Template Engines Integration - Integration with popular PHP template engines
- Advanced Use Cases - Detailed use cases for various scenarios and architectures
License
The MIT License (MIT). Please see License File for more information.
Credits
About Responsive.sk
Responsive.sk is a web development company specializing in creating modern, responsive web applications using the latest technologies and best practices.
Roadmap
We're planning to expand this package with integrations for other frameworks and libraries. Check out our TODO list for upcoming features and ways to contribute.
Community
We're looking to collaborate with Laminas and Cycle ORM communities to create integrations for these frameworks. If you're interested in contributing, please check out our TODO list and get in touch!