Welcome to Abdul Malik Ikhsan's Blog

Zend Framework 2 : Handling Db connection Error

Posted in Tutorial PHP, Zend Framework 2 by samsonasik on June 2, 2013

zf2-zendframework2Db Connection error is not part of dispatch.error, so we should make a tricky way to handle it to make user happy when see the page. We should try the connection, and catch when failed. call ViewModel to set template with our custom error page, then render with ViewRenderer.
This is it :

//filename : module/YourModule/Module.php
namespace YourModule;
use Zend\Mvc\MvcEvent;

class Module
{
    public function onBootstrap(MvcEvent $e)
    {
        $application   = $e->getApplication();
        $sm            = $application->getServiceManager();
        
        //try to connect, and if not connected, then catch...
        try {
            $dbInstance = $application->getServiceManager()
                                      ->get('Zend\Db\Adapter\Adapter');
            $dbInstance->getDriver()->getConnection()->connect();
        } catch (\Exception $ex) {
            $ViewModel = $e->getViewModel();
            $ViewModel->setTemplate('layout/layout');
                
            $content = new \Zend\View\Model\ViewModel();
            $content->setTemplate('error/mydberrorpagecustompage');
            
            //set $this->layout()->"content" variable
            //with error/mydberrorpagecustompage.phtml
            $ViewModel->setVariable('content', $sm->get('ViewRenderer')
                                                  ->render($content));
            
            exit($sm->get('ViewRenderer')->render($ViewModel));
        }
    }
    
    public function getConfig() { /* common code here */ }
    public function getAutoloaderConfig(){ /*common code here */   }
}

Still want to using EventManager? use at Wildcard attachment to make $callback available in all events (we can’t rely on dispatch.error, render.error, or other), like the following :

//filename : module/YourModule/Module.php
namespace YourModule;
use Zend\Mvc\MvcEvent;

class Module
{
    public function onBootstrap(MvcEvent $e)
    {
        $application   = $e->getApplication();
        $eventManager  = $application->getEventManager();
        
        //using '*' to make $callback available in all events. 
        $eventManager->attach('*', array($this, 'dbInstanceError' ), 1000); 
    }

    public function dbInstanceError(MvcEvent $e)
    {
        $application   = $e->getTarget();
        $sm            = $application->getServiceManager();
        
        //try to connect, and if not connected, then catch...
        try {
            $dbInstance = $application->getServiceManager()
                                      ->get('Zend\Db\Adapter\Adapter');
            $dbInstance->getDriver()->getConnection()->connect();
        } catch (\Exception $ex) {
            $ViewModel = $e->getViewModel();
            $ViewModel->setTemplate('layout/layout');
                
            $content = new \Zend\View\Model\ViewModel();
            $content->setTemplate('error/mydberrorpagecustompage');
            
            //set $this->layout()->"content" variable
            //with error/mydberrorpagecustompage.phtml
            $ViewModel->setVariable('content', $sm->get('ViewRenderer')
                                                  ->render($content));
            
            echo $sm->get('ViewRenderer')->render($ViewModel);
            $e->stopPropagation();
        }
    } 
    
    public function getConfig() { /* common code here */ }
    public function getAutoloaderConfig(){ /*common code here */   }
}

If we are using EventManager, we can use :

$e->stopPropagation();

to stop further event.