Chain pattern


require "vendor/autoload.php";

use Chain\HomeStatus;
use Chain\Lock;
use Chain\Lights;
use Chain\Alarm;


$lock = new Lock();
$lights = new Lights();
$alarm = new Alarm();

$lock->setSuccessor($lights);
$lights->setSuccessor($alarm);

$homeStatus = new HomeStatus();
$lock->check($homeStatus);
echo PHP_EOL;


Strategy pattern


namespace Stra;

use Stra\Logger;
use Stra\DatabaseLogger;
use Stra\FileLogger;

class Strategy
{
    public function log($msg, Logger $logger = null)
    {
        if(is_null($logger)) {
            $logger = new DatabaseLogger();
        }

        $logger->log($msg);
    }
}

Test Drive


require 'vendor/autoload.php';

use Stra\Strategy;
use Stra\FileLogger;
use Stra\DatabaseLogger;

$app = new Strategy();
$app->log('Some action happened.', new FileLogger());

Factory pattern

Code


namespace Patterns;


/**
 * Design pattern - Factory
 *
 * @author: Hazrat Ali
 * @mail: iloveyii@yahoo.com
 * Date: 2016-07-30
 */
class ShapeFactory
{
    private static $types = ['Rectangle', 'Square'];

    public static function create($type)
    {
        if( ! in_array($type, self::$types)) {
            die('Invalid type ' . $type . ', valid types are ' . implode(',', self::$types) . EOL);
        }

        if($type == 'Rectangle') {
            return new Rectangle(50, 15);
        }

        if($type == 'Square') {
            return new Square(20);
        }
    }
}


SingletonX

Git repo


namespace Patterns;


/**
 * Design pattern - Singleton extended
 * The extended version contains an array of instances
 *
 * @author: Hazrat Ali
 * @mail: iloveyii@yahoo.com
 * Date: 2016-07-30
 */
class SingletonX
{
    private static $instances = [];
    private $dir = 'tr';
    private $language;
    private $translations;

    public function __construct($language)
    {
        $this->language = $language;
        $this->readTranslationFile('string.json');

        echo 'Object initiated with language ' , $language . EOL;
    }

    public static function getInstance($language)
    {
        if( ! isset(self::$instances[$language])) {
            self::$instances[$language] = new self($language);
        }

        return self::$instances[$language];
    }

    public function translate($text)
    {
        return isset($this->translations[$text]) ? $this->translations[$text] : false;
    }

    private function readTranslationFile($fileName)
    {
        $filePath = $this->getPathAbs($fileName);

        if(file_exists($filePath)) {
            $contents = file_get_contents($filePath);
        } else {
            $svContents = json_encode([
                'language'=>'språk',
                'code'=>$this->language,
                'country'=>'land',
                'city'=>'stad'
            ]);
            $frContents = json_encode([
                'language'=>'la langue',
                'code'=>$this->language,
                'country'=>'pays',
                'city'=>'ville'
            ]);

            if($this->language == 'sv') {
                file_put_contents($filePath, $svContents);
                $contents = $svContents;
            }

            if($this->language == 'fr') {
                file_put_contents($filePath, $frContents);
                $contents = $frContents;
            }
        }

        $this->translations = json_decode($contents, JSON_FORCE_OBJECT);
    }

    private function getPathAbs($fileName)
    {
        $path = sprintf("%s/%s/%s/%s", dirname(__FILE__), $this->dir, $this->language, $fileName);

        if( ! file_exists(dirname($path))) {
            mkdir(dirname($path), 0777, true);
        }

        return $path;
    }
}

Singleton pattern

Code

The singleton pattern is used to restrict the creation of only object of a class. This is useful when it is expensive (in terms of resources) to initiate new objects every time the same object is needed. This pattern specifically put this logic of maintaining only one instance inside the class itself.

This pattern can be used in situations like database connectivity, reading and writing to disk, sending emails.

In the example below we use a simple translation class which read a json file with translations. Only one instance is needed since reading file operations are slower. Therefore we can easily use this object as many times as needed for multiple words translation. Since it is a singleton so it will keep only one instance each time we use it in the code.

namespace Patterns;


/**
 * Design pattern - Singleton
 * @author: Hazrat Ali
 * @mail: iloveyii@yahoo.com
 * Date: 2016-07-30
 */
class Singleton
{
    private static $instance;
    private $dir = 'tr';
    private $language;
    private $translations;

    public function __construct($language)
    {
        $this->language = $language;
        $this->readTanslationFile('string.json');
    }

    public static function getInstance($language)
    {
        if( ! isset(self::$instance)) {
            self::$instance = new self($language);
        }

        return self::$instance;
    }

    public function translate($text)
    {
        return isset($this->translations[$text]) ? $this->translations[$text] : false;
    }

    private function readTanslationFile($fileName)
    {
        $filePath = $this->getPathAbs($fileName);

        if(file_exists($filePath)) {
            $contents = file_get_contents($filePath);
        } else {
            $contents = json_encode([
                'language'=>'språk',
                'code'=>$this->language,
                'country'=>'land',
                'city'=>'stad'
            ]);

            file_put_contents($filePath, $contents);
        }

        $this->translations = json_decode($contents, JSON_FORCE_OBJECT);
    }

    private function getPathAbs($fileName)
    {
        $path = sprintf("%s/%s/%s/%s", dirname(__FILE__), $this->dir, $this->language, $fileName);

        if( ! file_exists(dirname($path))) {
            mkdir(dirname($path), 0777, true);
        }

        return $path;
    }
}

Ubuntu install PHP mail function

It is not installed by default so you have to install it and then a little configuration is required.

sudo apt install sendmail

The run the following command and choose Y for all the options.

sudo sendmailconfig

Now edit the host file:

sudo nano /etc/hosts

And add or edit as:

127.0.0.1    localhost localhost.localdomain your_machine_name

To get your_machine_name run:

hostname

Ubuntu 16.04 – PhpStorm – configure xdebug with PHP 7.0

Today I spent a couple of hours to figure out that ONLY the following configuration works. It is not covered in any video/tutorial.

This is the settings that MUST be added to all the files:

[xDebug] zend_extension=/usr/lib/php/20160303/xdebug.so
xdebug.default_enable=1
xdebug.idekey=PHPSTORM
xdebug.remote_port=9000
xdebug.remote_enable=1
xdebug.remote_handler=dbgp
xdebug.remote_autostart = on
xdebug.remote_start = on
xdebug.profiler_enable=1
xdebug.profiler_output_dir=/dev/null
xdebug.remote_host=localhost

 

 

The files are :

/etc/php/7.0/apache2/php.ini
/etc/php/7.0/phpdbg/php.ini
/etc/php/7.0/cli/php.ini