Weave Code
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

Laminas Stratigility Laravel Package

laminas/laminas-stratigility

Laminas Stratigility provides PSR-15 HTTP middleware tools, including a middleware pipeline and helpers for composing request handlers. Build reusable, interoperable middleware stacks for PHP applications and frameworks.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require laminas/laminas-stratigility
    

    Ensure your project uses PSR-7 (e.g., laminas/laminas-diactoros for HTTP messages).

  2. First Use Case: Create a middleware pipeline for a simple route handler:

    use Laminas\Stratigility\Middleware\MiddlewareInterface;
    use Psr\Http\Message\ResponseInterface;
    use Psr\Http\Message\ServerRequestInterface;
    use Psr\Http\Server\MiddlewareInterface as PsrMiddlewareInterface;
    
    // Define a middleware
    class MyMiddleware implements PsrMiddlewareInterface {
        public function process(ServerRequestInterface $request, ResponseInterface $response, callable $next): ResponseInterface {
            $response->getBody()->write('Before ');
            $response = $next($request, $response);
            $response->getBody()->write(' After');
            return $response;
        }
    }
    
    // Dispatch the pipeline
    $middleware = new MyMiddleware();
    $pipe = new \Laminas\Stratigility\MiddlewarePipe();
    $pipe->pipe($middleware);
    $response = $pipe($request, $response);
    
  3. Key Files:


Implementation Patterns

Core Workflows

  1. Middleware Composition: Chain middleware in a pipeline using MiddlewarePipe:

    $pipe = new \Laminas\Stratigility\MiddlewarePipe();
    $pipe->pipe(new AuthMiddleware());
    $pipe->pipe(new LoggingMiddleware());
    $pipe->pipe(new RouteMiddleware());
    
  2. Conditional Middleware: Use ConditionalMiddleware to add logic:

    use Laminas\Stratigility\Middleware\ConditionalMiddleware;
    
    $conditional = new ConditionalMiddleware(
        fn($request) => $request->getUri()->getPath() === '/admin',
        new AdminMiddleware()
    );
    $pipe->pipe($conditional);
    
  3. Error Handling: Wrap pipelines in ErrorHandlerMiddleware:

    use Laminas\Stratigility\Middleware\ErrorHandlerMiddleware;
    
    $errorHandler = new ErrorHandlerMiddleware(
        new \Laminas\Stratigility\Error\ErrorResponseGenerator(),
        new \Laminas\Stratigility\Error\WhoopsErrorHandler()
    );
    $pipe->pipe($errorHandler);
    
  4. Route-Based Dispatching: Use RouteMiddleware with a router (e.g., laminas/laminas-router):

    use Laminas\Stratigility\Middleware\RouteMiddleware;
    
    $router = new \Laminas\Router\Http\Segment();
    $routeMiddleware = new RouteMiddleware($router);
    $pipe->pipe($routeMiddleware);
    

Integration Tips

  • Laravel-Specific: Leverage laminas/laminas-stratigility with Laravel’s Http\Kernel by creating a custom middleware group:

    // app/Http/Kernel.php
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Laminas\Stratigility\Middleware\MiddlewarePipe::class, // Custom pipe
        ],
    ];
    
  • PSR-15 Compliance: Ensure all middleware implement Psr\Http\Server\MiddlewareInterface for compatibility.

  • Testing: Mock middleware pipelines in tests:

    $pipe = new \Laminas\Stratigility\MiddlewarePipe();
    $pipe->pipe(new class implements PsrMiddlewareInterface {
        public function process(ServerRequestInterface $request, ResponseInterface $response, callable $next) {
            // Test logic
            return $next($request, $response);
        }
    });
    

Gotchas and Tips

Pitfalls

  1. Middleware Order Matters: Pipelines execute middleware sequentially. Reordering can break functionality (e.g., auth before logging vs. logging before auth).

  2. Error Handling Gaps: Uncaught exceptions in middleware terminate the pipeline. Always wrap critical middleware in ErrorHandlerMiddleware:

    $pipe->pipe(new ErrorHandlerMiddleware(...));
    
  3. PSR-7 Version Conflicts: Ensure your PSR-7 implementation (e.g., laminas-diactoros) matches laminas-stratigility's requirements (PSR-7 v1.1+ for v4.x).

  4. Circular Dependencies: Avoid recursive middleware calls (e.g., middleware A calling middleware B, which calls A again). Use MiddlewarePipe::getMiddlewareQueue() to inspect the pipeline.

Debugging

  • Middleware Inspection: Dump the pipeline queue to debug order:

    foreach ($pipe->getMiddlewareQueue() as $index => $middleware) {
        echo "Middleware #$index: " . get_class($middleware) . "\n";
    }
    
  • Response Logging: Log responses after each middleware for debugging:

    $pipe->pipe(new class implements PsrMiddlewareInterface {
        public function process(ServerRequestInterface $request, ResponseInterface $response, callable $next) {
            $response = $next($request, $response);
            error_log($response->getBody()->getContents());
            return $response;
        }
    });
    

Extension Points

  1. Custom Middleware: Extend AbstractMiddleware for reusable base logic:

    use Laminas\Stratigility\Middleware\AbstractMiddleware;
    
    class BaseMiddleware extends AbstractMiddleware {
        protected function process(ServerRequestInterface $request, ResponseInterface $response, callable $next) {
            // Shared logic
            return $next($request, $response);
        }
    }
    
  2. Middleware Stacks: Dynamically build pipelines from config (e.g., config/middleware.php):

    return [
        'web' => [
            \App\Middleware\Auth::class,
            \App\Middleware\Locale::class,
        ],
        'api' => [
            \App\Middleware\CORS::class,
            \App\Middleware\RateLimit::class,
        ],
    ];
    
  3. PSR-15 Middleware: Convert PSR-15 middleware to laminas-stratigility format:

    $psr15Middleware = new class implements PsrMiddlewareInterface {
        public function process(ServerRequestInterface $request, ResponseInterface $response, callable $next) {
            return $next($request, $response);
        }
    };
    $pipe->pipe($psr15Middleware);
    

Config Quirks

  • PHP 8.5+: Use str_contains() or str_starts_with() for path matching in middleware (PHP 8.5 deprecates strstr() for this purpose).
  • Type Safety: Enable strict types in middleware for better IDE support:
    declare(strict_types=1);
    class MyMiddleware implements PsrMiddlewareInterface { ... }
    
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky