PHP code example of jschreuder / middle

1. Go to this page and download the library: Download jschreuder/middle library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

jschreuder / middle example snippets


// Security-critical components are external and replaceable
$app = $app->withMiddleware(
    new RoutingMiddleware(
        new SymfonyRouter($baseUrl),          // Symfony's battle-tested routing
        $fallbackController
    )
);

$app = $app->withMiddleware(
    new SessionMiddleware(
        new LaminasSessionProcessor()         // Laminas's proven session handling
    )
);

// Your domain interface - exactly what your application needs
interface UserRepositoryInterface 
{
    public function findByEmail(string $email): ?User;
    public function save(User $user): void;
    public function findActiveUsers(): array;
}

// Adapter that wraps Doctrine behind your interface
class DoctrineUserRepository implements UserRepositoryInterface 
{
    public function __construct(private EntityManagerInterface $em) {}
    
    public function findByEmail(string $email): ?User 
    {
        return $this->em->getRepository(User::class)->findOneBy(['email' => $email]);
    }
    
    public function save(User $user): void 
    {
        $this->em->persist($user);
        $this->em->flush();
    }
    
    public function findActiveUsers(): array 
    {
        return $this->em->createQuery('SELECT u FROM User u WHERE u.active = true')
                         ->getResult();
    }
}

// Your controllers depend on YOUR interface, not Doctrine's
class UserController implements ControllerInterface 
{
    public function __construct(private UserRepositoryInterface $repository) {}
    
    public function execute(ServerRequestInterface $request): ResponseInterface 
    {
        // Clean, domain-focused code
        $users = $this->repository->findActiveUsers();
        // ...
    }
}

$app = new ApplicationStack(
    new ControllerRunner()              // Executes the matched controller
);

$app = $app->withMiddleware(
    new RoutingMiddleware($router, $fallback)  // Matches routes, adds controller to request
);

$app = $app->withMiddleware(
    new SessionMiddleware($sessionProcessor)   // Adds session to request
);

$app = $app->withMiddleware(
    new ErrorHandlerMiddleware($logger, $errorHandler)  // Catches exceptions
);


use jschreuder\Middle;

// Create a router with fallback for unmatched routes
$router = new Middle\Router\SymfonyRouter('http://localhost');
$fallbackController = Middle\Controller\CallableController::fromCallable(
    function () {
        return new Laminas\Diactoros\Response\JsonResponse(['error' => 'Not found'], 404);
    }
);

// Build the application stack
$app = new Middle\ApplicationStack(
    new Middle\Controller\ControllerRunner(),
    new Middle\ServerMiddleware\RoutingMiddleware($router, $fallbackController)
);

// Add a route
$router->get('home', '/', 
    Middle\Controller\CallableController::factoryFromCallable(function () {
        return new Laminas\Diactoros\Response\JsonResponse([
            'message' => 'Welcome to Middle Framework'
        ]);
    })
);

// Process requests
$request = Laminas\Diactoros\ServerRequestFactory::fromGlobals();
$response = $app->process($request);
(new Laminas\Diactoros\Response\SapiEmitter())->emit($response);


// Create PSR-7 request from globals ($_GET, $_POST, $_SERVER, etc.)
$request = Laminas\Diactoros\ServerRequestFactory::fromGlobals();

// Process the request through your middleware stack
$response = $app->process($request);

// Send the response to the browser
(new Laminas\Diactoros\Response\SapiEmitter())->emit($response);

// Simple routes with closures
$router->get('home', '/', 
    Middle\Controller\CallableController::factoryFromCallable(function () {
        return new Laminas\Diactoros\Response\JsonResponse(['message' => 'Hello World']);
    })
);

// Routes with parameters and }),
    [], // defaults
    ['id' => '\d+'] // 

$app = $app->withMiddleware(
    new Middle\ServerMiddleware\SessionMiddleware(
        new Middle\Session\LaminasSessionProcessor()
    )
);

$errorController = Middle\Controller\CallableController::fromCallable(function ($request) {
    $error = $request->getAttribute('error');
    return new Laminas\Diactoros\Response\JsonResponse([
        'error' => 'Something went wrong'
    ], 500);
});

$app = $app->withMiddleware(
    new Middle\ServerMiddleware\ErrorHandlerMiddleware($logger, $errorController)
);

class CreateUserController implements ControllerInterface, RequestFilterInterface, RequestValidatorInterface 
{
    public function filterRequest(ServerRequestInterface $request): ServerRequestInterface 
    {
        $data = $request->getParsedBody();
        if (is_array($data)) {
            $data['textfield'] = strip_tags(trim(data['textfield']));
            $request = $request->withParsedBody($data);
        }
        
        return $request;
    }
    
    public function validateRequest(ServerRequestInterface $request): void 
    {
        $data = $request->getParsedBody();
        if (empty($data['email'])) {
            throw new ValidationFailedException(['email' => 'Email is 

// Setup Twig renderer
$renderer = new Middle\View\TwigRenderer($twig, $responseFactory);

// For redirects, decorate with redirect capability
$renderer = new Middle\View\RedirectRendererMiddleware($renderer, $responseFactory);

// Controllers return View objects
$router->get('profile', '/profile/{id}',
    Middle\Controller\CallableController::factoryFromCallable(
        function ($request) use ($renderer) {
            $userId = $request->getAttribute('id');
            return $renderer->render($request, new Middle\View\View('profile.twig', [
                'user' => $userRepository->find($userId)
            ]));
        }
    )
);

// Redirects are views too - RedirectRendererMiddleware handles status codes 300-399
return $renderer->render($request, new Middle\View\RedirectView('/dashboard', 302));

throw new Middle\Exception\NotFoundException('User not found');        // 404
throw new Middle\Exception\AuthenticationException('Login ors);         // 400

// Use Laminas Session (default)
$sessionProcessor = new Middle\Session\LaminasSessionProcessor();

// Or implement your own (Redis, database, etc.)
class RedisSessionProcessor implements SessionProcessorInterface {
    public function processRequest(ServerRequestInterface $request): ServerRequestInterface {
        // Add session to request attributes
    }
    
    public function processResponse(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface {
        // Handle session persistence, cookies, etc.
    }
}

function someController(ServerRequestInterface $request): ResponseInterface {
    $session = $request->getAttribute('session');
    $session->set('user_id', 123);
    $session->setFlash('message', 'Welcome back!');
    // ...
}

$router = new Middle\Router\SymfonyRouter('http://localhost');

// The router supports all HTTP methods
$router->get('home', '/', $controllerFactory);
$router->post('api.users', '/api/users', $controllerFactory);
$router->put('api.user', '/api/users/{id}', $controllerFactory, [], ['id' => '\d+']);
$router->delete('api.user.delete', '/api/users/{id}', $controllerFactory);

// Generate URLs in your application
$urlGenerator = $router->getGenerator();
$userUrl = $urlGenerator->generatePath('api.user', ['id' => 123]); // '/api/users/123'
$fullUrl = $urlGenerator->generateUrl('home', []); // 'http://localhost/'

class ApiRoutingProvider implements RoutingProviderInterface {
    public function registerRoutes(RouterInterface $router): void {
        $router->get('api.status', '/api/status', $this->statusControllerFactory());
        $router->post('api.users', '/api/users', $this->createUserControllerFactory());
        // ... more routes
    }
}

$router->registerRoutes(new ApiRoutingProvider());

// Parse JSON request bodies automatically
$app = $app->withMiddleware(
    new Middle\ServerMiddleware\JsonRequestParserMiddleware()
);

// Automatically validate requests if controller implements RequestValidatorInterface
$app = $app->withMiddleware(
    new Middle\ServerMiddleware\RequestValidatorMiddleware($validationErrorHandler)
);

// Automatically filter requests if controller implements RequestFilterInterface  
$app = $app->withMiddleware(
    new Middle\ServerMiddleware\RequestFilterMiddleware()
);

$container = new Pimple\Container();

$container['app'] = function ($c) {
    return new Middle\ApplicationStack(
        new Middle\Controller\ControllerRunner()
    );
};

// Add middleware through container extension
$container->extend('app', function ($app, $c) {
    return $app->withMiddleware(
        new Middle\ServerMiddleware\RoutingMiddleware(
            $c['router'], $c['fallbackController']
        )
    );
});