Blog

Simple PHP formatter for bytes

Usage:

$this->formatSize = new FormatSize();

$bytes = 4398046511104;
$decimals = 2;
$formatted = $this->formatSize->formatBytes($bytes, $decimals);
$this->assertEquals('4.00 TB', $formatted); 

View on GitHub
Ubuntu 16.04 Xenial
Serve PHP7 using PHP7-fpm and Apache 2.4

By default, in Ubuntu 16.04 Xenial, installing the packages for PHP, PHP-fpm, and Apache does not result in a working php website. 

The extra configuration required follows:

Install Apache2
> sudo apt-get -y install apache2

Install php, with some common packages
> sudo apt-get -y install php php-cli php-mbstring php-gd php-mcrypt php-pgsql php-mysql php-xml php-curl php-intl

Create your own apache vhost config
> vi /etc/apache2/sites-available/vhosts
<VirtualHost *:80>
    ServerName tutorial.localhost   
DocumentRoot /path/to/tutorial/web   
SetEnv APP_ENV "dev"   
<Directory /path/to/tutorial/web>       
AllowOverride All       
Require all granted #<-- 2.4 New configuration   
</Directory>
</VirtualHost>

Enable your vhost config
> sudo a2ensite vhosts

Disable the defualt config
> sudo a2dissite 000-default

And the missing parts of conflagration:

Enable php7-fpm
> sudo a2enconf php7.0-fpm

Enable rewrite so frameworks such as Symfony, Zend, Larvel, etc work with 'pretty' urls
enable proxy so apache can send php requests to php7-fpm
> sudo a2enmod rewrite proxy proxy_fcgi

And restart apache
> sudo systemctl restart apache2

PHP should be working now

> vi /path/to/webroot/phpinfo.php
<?php
phpinfo();

End of document. Thanks for reading.
If you are developing Symfony, Zend, Laravel, or any web framework requiring .htaccess,
and you upgrade Apache from 2.2 to 2.4, or your dev Vagrant vm is updated to a newer OS, your web site may start showing the ambiguous error message
“Forbidden You don't have permission to access / on this server”

There are a multitude of possible causes for this error, but assuming you web site was working, and you just upgraded Apache, check the Apache virtual host configuration as the Authorization configuration has changed between Apache 2.2 and 2.4

Ubuntu
> sudo vi /etc/apache2/sites-enabled/[your vhost site].conf

Centos
> sudo vi /etc/httpd/conf.d/[your vhost site].conf

Prior Configuration
<VirtualHost *:80>
    ServerName tutorial.localhost   
DocumentRoot /path/to/tutorial/web   
SetEnv APP_ENV "dev"   
<Directory /path/to/tutorial/web>       
AllowOverride All       
Order allow,deny    #<-- 2.2 config       
Allow from all      #<-- 2.2 config   
</Directory>
</VirtualHost>

Updated Configuration
<VirtualHost *:80>
    ServerName tutorial.localhost   
DocumentRoot /path/to/tutorial/web   
SetEnv APP_ENV "dev"   
<Directory /path/to/tutorial/web>       
AllowOverride All       
Require all granted   #<-- 2.4 New configuration   
</Directory>
</VirtualHost>

Ah the simple things

Restart apache

Ubuntu
> sudo systemctl restart apache2

Centos
> sudo service httpd restart

References:
http://httpd.apache.org/docs/2.4/upgrading.html#run-time
https://stackoverflow.com/a/24665604/3893727


Related info:
You can also make sure apache has permission to your web root

> ls -l /path/to/tutorial/web

Ubuntu
www-data should have access

Centos
apache should have access

Or find whatever process name Apache is running as
> ps -aef | grep apacheor
> ps -aef | grep httpd

If your web root is a personal directory, you can add your user to the Apache group

Ubuntu
> sudo usermod -a -G www-data vagrant

Centos
> sudo usermod -a -G apache vagrant

End of document. Thanks for reading.
For Symfony2, when your database is down, the default server error 500 message is shown.
To instead show a more appropriate 503 service unavailable message, you need to create custom exception listener.  While the custom exception listener will listen to all exceptions, you can specify exception type checks inside it.

In your services.yml you need to specify the listener:
> src\Acme\AppBundle\Resources\config\services.yml
services:
kernel.listener.your_pdo_listener:
class: Acme\AppBundle\EventListener\YourExceptionListener
tags:
- { name: kernel.event_listener, event: kernel.exception, method: onKernelException }

Now you need to create the listener class:
> src\Acme\AppBundle\EventListener\AcmeAppBundleListener.php
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;

use PropelException;
// use DoctrineException;

class YourExceptionListener implements EventSubscriberInterface
{
$env = $this->container->getParameter('kernel.environment');
if ($env == 'dev' || $env == 'test') {
// show default exception
return;
}

$exception = $event->getException();

// only customize propel or doctrine ie database exceptions
// if (!$exception instanceof DoctrineException) {
if (!$exception instanceof PropelException) {
// show default exception
return;
}

$path = $event->getRequest()->getPathInfo();

$response = new Response();

// set status text
$exception_msg = $exception->getMessage();
if (stripos($exception_msg, 'Unable to open PDO connection') !== false) {
$response->setStatusCode(Response::HTTP_SERVICE_UNAVAILABLE);
$status_text = $this->container->getParameter("message.error.unable_to_connect");
} else {
// show default exception
return;
}

// add exception code, if set
$exception_code = $exception->getCode();
if ($exception_code > 0) {
$status_text .= " [".$exception_code."]";
}

$response->setContent(
$this->templating->render(
'AcmeAppBundle:Exception:exception.html.twig',
[
'status_code' => $response->getStatusCode(),
'status_text' => $status_text
]
)
);

$event->setResponse($response);
}

Add the message configuration:
> src\Acme\AppBundle\Resources\config\messages.yml
parameters:
message.error.unable_to_connect: "Unable to connect to service at the moment"

Create the exception template:
> src\Acme\AppBundle\Resources\views\Exception\exception.html.twig
<!DOCTYPE html>
<html><head>   
<meta charset="{{ _charset }}" />   
<title>An Error Occurred: {{ status_text }}</title>
</head>
<body>
<h1>Zork! An Error Occurred</h1>
<h2>The server returned a "{{ status_code }} {{ status_text }}".</h2>

<div>This should be temporary, but if not, please let us know what you were doing when this error occurred. We will fix it as soon as possible. Sorry for any inconvenience caused.</div>

</body>
</html>

Stop your database or in your code throw DoctrineException or PropelException and you should see the new exception page.

Reference
https://stackoverflow.com/questions/29732630/catching-database-exceptions-in-symfony2

End of document. Thanks for reading.