MBrownieBytes

A blog for software engineers, sys admins, devops, and the technically inclined.
How to guides, Tutorials, Tips and Tricks

  1. You are here:  
  2. Home

Blog

Ubuntu 16.04 Xenial serve PHP7 using PHP7-fpm and Apache 2.4

Details
Published: 02 April 2018
  • ubuntu
  • php
  • apache
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.

Authorization configuration has changed between Apache 2.2 and 2.4

Details
Published: 26 March 2018
  • php
  • apache
  • vagrant
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.

Symfony custom database exception

Details
Published: 19 March 2018
  • php
  • symfony
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.

PHPUnit exceeds memory limit

Details
Published: 12 March 2018
  • php
  • phpunit
If you happen to be stuck running PHPUnit 4.8 or such,
you many run into memory limits when you run a large number of tests.
With PHPUnit 4.8, you can add some extra code to clear out the variables you created during each test, thus saving some memory.


class YourTestCase extends WebTestCase
{
protected function tearDown()
{
echo 'pre reduce memory usage: '.sprintf('%.2fM', memory_get_usage(true)/1024/1024);
// reduce memory usage

// get all properties of self
$refl = new \ReflectionObject($this);
foreach ($refl->getProperties() as $prop) {
// if not phpunit related or static
if (!$prop->isStatic() && 0 !== strpos($prop->getDeclaringClass()->getName(), 'PHPUnit_')) {
// make accessible and set value to to free memory
$prop->setAccessible(true);
$prop->setValue($this, null);
}
}
echo 'post reduce memory usage: '.sprintf('%.2fM', memory_get_usage(true)/1024/1024);

parent::tearDown();
}

Reference
https://stackoverflow.com/questions/13537545/clear-memory-being-used-by-php    

Note:
Using unset($this) or unset($var) does not immediately free the variable from memory.  However, setting $this = null or $var = null immediately assigns the value null, which uses less memory than the object, string, or other value that was set.  You could also use the value of 0 or "" or anything really, just null is short and sweet and infers the intent of the value being unset.

Related extra
You can also increase the allowed memory usage in your test.

class YourTestCase extends WebTestCase
{   
public function setUp()   
{       
ini_set('memory_limit', '512M');   

parent::setUp();
}
}

End of document. Thanks for reading.
  1. fix composer "The lock file is not up to date with the latest changes in composer.json"
  2. Adding camera api to react native

Page 17 of 21

  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

Search

Tags

php 21 git 10 windows 10 aws 9 nodejs 7 security 6 virtualbox 6 android 5 portable 4 redhat 4 ubuntu 4 react native 3 reactjs 3 docker 3 devops 3 nginx 3 bash 3 symfony 3 apache 3 ide 2

Most Read Posts

  • Handle HTTP 302 response from proxy in Angular
  • PHPUnit exceeds memory limit
  • Adding camera api to react native
  • Portable Java
  • Clear out old MSMQ messages

Older Posts

  • HDMI and Display Port versions
  • Useful Linux Commands
  • DevOps SysAdmin Tips for researching a slow or unresponsive app or system
  • DDEV for local development in containers
  • Valid local self signed certs
  • Bash script to delete merged local git branches
My Blog