responsive-sk/slim4-root 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

responsive-sk/slim4-root

Composer 安装命令:

composer require --dev responsive-sk/slim4-root

包简介

Root path management with auto-discovery, base path detection and testing utilities for Slim 4 applications

README 文档

README

Root path management with auto-discovery and base path detection for Slim 4 applications. Say goodbye to relative paths like __DIR__ . '/../../../config' and hello to clean, consistent path access.

Latest Version on Packagist Software License Total Downloads

New in 1.4

  • 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
  • Base path detection for applications running in subdirectories
  • Testing utilities for easier test setup and execution
  • Monolog integration for easy logging setup

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
  • Base path detection for applications running in subdirectories
  • Testing utilities for easier test setup and execution
  • Monolog integration for easy logging setup
  • 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 Paths 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;
});

With Base Path Detection

use Slim4\Root\BasePathMiddleware;
use Slim\Factory\AppFactory;

// Create app
$app = AppFactory::createFromContainer($container);

// Add the middleware to detect and set the base path
$app->add(new BasePathMiddleware($app));

// Now all routes will work correctly even if your app is in a subdirectory
$app->get('/', HomeAction::class);

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\Level;
use Slim4\Root\Integration\MonologFactory;
use Slim4\Root\PathsInterface;
use Psr\Log\LoggerInterface;

// Register Logger with the container
$container->set(LoggerInterface::class, function (ContainerInterface $container) {
    $paths = $container->get(PathsInterface::class);
    $factory = new MonologFactory($paths);

    return $factory->createLogger([
        'name' => 'app',
        'path' => 'app.log',
        'level' => Level::Debug,
        'rotating' => true,
        'max_files' => 7,
    ]);
});

Or use the MonologProvider for easier setup:

use Monolog\Level;
use Slim4\Root\Integration\MonologProvider;

// Register a single logger
MonologProvider::register($container, [
    'name' => 'app',
    'path' => 'app.log',
    'level' => Level::Debug,
]);

// Register multiple loggers
MonologProvider::registerMultiple($container, [
    'default' => [
        'path' => 'app.log',
        'level' => Level::Debug,
    ],
    'error' => [
        'path' => 'error.log',
        'level' => Level::Error,
    ],
]);

// Use loggers
$logger = $container->get(LoggerInterface::class); // Default logger
$errorLogger = $container->get('logger.error');

For more details, see Monolog Integration.

Testing Utilities

The package includes a Testing module that provides utilities for easier test setup and execution.

TestContainer

TestContainer is a simple static container for sharing objects between tests without using globals.

use Slim4\Root\Testing\TestContainer;
use Slim4\Root\Paths;

// In your bootstrap file
$paths = new Paths(__DIR__);
TestContainer::set(Paths::class, $paths);

// In your tests
$paths = TestContainer::get(Paths::class);

Bootstrap File

The package includes a bootstrap file that you can use in your PHPUnit configuration:

// tests/bootstrap.php
require_once __DIR__ . '/../vendor/autoload.php';
require_once __DIR__ . '/../vendor/responsive-sk/slim4-root/src/Testing/bootstrap.php';

Or you can create your own bootstrap file:

// tests/bootstrap.php
require_once __DIR__ . '/../vendor/autoload.php';

use Slim4\Root\Paths;
use Slim4\Root\Testing\TestContainer;

// Create Paths object
$rootPath = (string)realpath(__DIR__ . '/..');
$paths = new Paths($rootPath);

// Store in TestContainer
TestContainer::set(Paths::class, $paths);

Available Methods

PathsInterface

  • getRootPath() - Get the root path of the project
  • getConfigPath() - Get the config path
  • getResourcesPath() - Get the resources path
  • getViewsPath() - Get the views path
  • getAssetsPath() - Get the assets path
  • getCachePath() - Get the cache path
  • getLogsPath() - Get the logs path
  • getPublicPath() - Get the public path
  • getDatabasePath() - Get the database path
  • getMigrationsPath() - Get the migrations path
  • getStoragePath() - Get the storage path
  • getTestsPath() - Get the tests path
  • path(string $path) - Get a path relative to the root path
  • getPaths() - Get all paths as an associative array

BasePathMiddleware

  • process(ServerRequestInterface $request, RequestHandlerInterface $handler) - Process the request and set the base path for the Slim application

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

TestContainer

  • set(string $key, mixed $value) - Set an item in the container
  • get(string $key, mixed $default = null) - Get an item from the container
  • has(string $key) - Check if an item exists in the container
  • remove(string $key) - Remove an item from the container
  • clear() - Clear all items from the container

MonologFactory

  • createLogger(array $config = []) - Create a new Monolog logger instance
  • createConsoleLogger(string $name, Level $level) - Create a console logger
  • createFileLogger(string $name, string $path, Level $level) - Create a file logger
  • createRotatingLogger(string $name, string $path, int $maxFiles, Level $level) - Create a rotating file logger

MonologProvider

  • register(ContainerInterface $container, array $config) - Register a logger in the container
  • registerMultiple(ContainerInterface $container, array $loggers) - Register multiple loggers
  • registerConsoleLogger(ContainerInterface $container, string $name, Level $level) - Register a console logger
  • registerFileLogger(ContainerInterface $container, string $name, string $path, Level $level) - Register a file logger
  • registerRotatingLogger(ContainerInterface $container, string $name, string $path, int $maxFiles, Level $level) - Register a rotating file logger

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.1 v1.2 v1.3 v1.4
Auto-discovery ❌ No ✅ Yes ✅ Yes ✅ Yes
Path validation ❌ Basic ✅ Comprehensive ✅ Comprehensive ✅ Comprehensive
Path normalization ❌ No ✅ Yes ✅ Yes ✅ Yes
Error handling ❌ Generic exceptions ✅ Dedicated exceptions ✅ Dedicated exceptions ✅ Dedicated exceptions
Relative paths ❌ Manual ../ ✅ Everything relative to root ✅ Everything relative to root ✅ Everything relative to root
Base path detection ❌ No ✅ Yes ✅ Yes ✅ Yes
Testing utilities ❌ No ❌ No ✅ Basic ✅ Enhanced
Monolog integration ❌ No ❌ No ❌ No ✅ Yes
Test coverage ✅ Good ✅ Excellent ✅ Excellent ✅ Excellent
Flexibility ✅ Good ✅ Excellent ✅ Excellent ✅ 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 for config, app/config, etc
  • resources - Looks for resources, app/resources, res
  • views - Looks for resources/views, templates, views, app/views
  • assets - Looks for resources/assets, assets, public/assets
  • cache - Looks for var/cache, cache, tmp/cache, storage/cache
  • logs - Looks for var/logs, logs, log, storage/logs
  • public - Looks for public, web, www, htdocs
  • database - Looks for database, db, storage/database
  • migrations - Looks for database/migrations, migrations, db/migrations
  • storage - Looks for storage, var, data
  • tests - Looks for tests, 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

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!

responsive-sk/slim4-root 适用场景与选型建议

responsive-sk/slim4-root 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 61 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 04 月 17 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「path」 「filesystem」 「testing」 「phpunit」 「slim」 「root」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 responsive-sk/slim4-root 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 responsive-sk/slim4-root 我们能提供哪些服务?
定制开发 / 二次开发

基于 responsive-sk/slim4-root 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 61
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 28
  • 依赖项目数: 2
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-04-17