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.
}
}