Skip to content

Instantly share code, notes, and snippets.

@jfcherng
Last active June 25, 2024 18:14
Show Gist options
  • Save jfcherng/2fa6cccd68ad4cc84a31b974066db293 to your computer and use it in GitHub Desktop.
Save jfcherng/2fa6cccd68ad4cc84a31b974066db293 to your computer and use it in GitHub Desktop.
Symfony 5 maintenance mode
MAINTENANCE_MODE=0
<?php
declare(strict_types=1);
namespace App\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Twig\Environment as TwigEnvironment;
class KernelRequestSubscriber implements EventSubscriberInterface
{
private TwigEnvironment $twig;
public function __construct(TwigEnvironment $twig)
{
$this->twig = $twig;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents(): array
{
return [
KernelEvents::REQUEST => [
['onMaintenance', \PHP_INT_MAX - 1000],
],
];
}
public function onMaintenance(RequestEvent $event): void
{
/** @var bool $isMaintenance */
$isMaintenance = \filter_var($_ENV['MAINTENANCE_MODE'] ?? '0', \FILTER_VALIDATE_BOOLEAN);
if ($isMaintenance) {
$event->setResponse(new Response(
$this->twig->render('maintenance.html.twig'),
Response::HTTP_SERVICE_UNAVAILABLE,
));
$event->stopPropagation();
}
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Site temporarily under maintenance</title>
</head>
<body>
<h1>Site temporarily under maintenance</h1>
<p>Sorry for the inconvenience, we will get back soon!</p>
</body>
</html>
@jfcherng
Copy link
Author

jfcherng commented Jun 9, 2020

To enable the maintenance mode, set env variable MAINTENANCE_MODE=1 in the .env.local file.

@MaxiCom
Copy link

MaxiCom commented May 11, 2023

Hello @jfcherng, thanks for the gist!

It seems like i don't need to check if \PHP_SAPI === 'cli', my function seems to only execute when it's a web request anyway, any idea why?
Maybe because of symfony/runtime which separate the two types of requests? I'm not sure!

Bye!

@jfcherng
Copy link
Author

Ah, yes. It's very likely that the KernelEvents::REQUEST hook won't be triggered when executed via CLI. Although I didn't do a real experiment but that sounds reasonable to me.

@sarim
Copy link

sarim commented Nov 27, 2023

for modern symfony you can use this

    public function __construct(
        private TwigEnvironment $twig,
        #[Autowire('%env(bool:MAINTENANCE_MODE)%')]
        private $isMaintenance
    ) {
    }

@kappaj
Copy link

kappaj commented Jun 25, 2024

Completing @sarim 's answer, a full example with with the usage of some newer Symfony and PHP features (Symfony 6.4+, PHP 8.2+) looks like this:

<?php

namespace App\EventListener;

use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Twig\Environment;

readonly class MaintenanceKernelRequestSubscriber
{
    public function __construct(
        #[Autowire('%env(bool:MAINTENANCE_MODE)%')]
        private bool $isMaintenance,
        private Environment $twig,
    ) {
    }

    #[AsEventListener(event: KernelEvents::REQUEST, priority: PHP_INT_MAX - 1000)]
    public function onMaintenance(RequestEvent $event): void
    {
        if (!$this->isMaintenance) {
            return;
        }

        $event->setResponse(new Response(
            $this->twig->render('maintenance.html.twig'),
            Response::HTTP_SERVICE_UNAVAILABLE,
        ));
        $event->stopPropagation();
    }
}

@jfcherng
Copy link
Author

Haha thanks you guys. Though I haven't written any PHP for years.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment