Most *nix-based sustems support syslog storage for different types of system logs. On Mac OS it’s also present and we can use it.

Monolog

Syslog implementation exists as part of Syslog Handler

To use it let’c create Monolog object and configure handler:

    $monolog = new Monolog('default');
    $monolog->pushHandler(
        new SyslogHandler('My log')
    );

Console

Once you configure this handler, open Console application and filter by:

  • library: php

You will see something like this:

Console

** Note

If you do not see debug messages, go to Action -> Enable Debug Messages

During implementation of CI infrastructure having PHP, you may face with different errors and strange behaviours.

Permission denied error

/home/travis/build.sh: line 45: ./some_script.sh: Permission denied
The command "./some_script.sh" failed and exited with 126 during .

This error happens if you do not have executable bit on your script

chmod +x some_script.sh should fix this error

Environment variables

To be able to use environment variables in your scripts, you need to click More options -> Settings in Travis interface and add it.

Here is my list of recommended articles to read in free time. It collects php, javascript, design patterns and different architecture approaches. Some articles are for high level developers, and some for beginners. I put a comments to recognize them.

Backend

Frontend

Other

Any developer is able to write validator. For date, time, URL, no matter. But what’s a correct way to implement it?

Let’s imagine next interface:

<?php

interface ValidatorInterface {

    public function isValid($value);
}

What’s obvious implementation here?

<?php

class TestValidator implements ValidatorInterface {

    public function isValid($value) {
        if (false === $value) {
            return false
        }

        return true;
    }
}

Ok, that’s make sense. We can either return true or false. But, let’s add one more thing:

<?php

class TestValidator implements ValidatorInterface {

    public function isValid($value) {
        if (fasle === $value) {
            return false
        }

        if (0 === $value) {
            return false
        }

        return true;
    }
}

Here we face with some kind of problem: we can not determine why our value is not valid. Let’s check how big guys do this:

https://github.com/zendframework/zend-validator/blob/master/src/ValidatorInterface.php

<?php

namespace Zend\Validator;

interface ValidatorInterface
{
    /**
     * Returns true if and only if $value meets the validation requirements
     *
     * If $value fails validation, then this method returns false, and
     * getMessages() will return an array of messages that explain why the
     * validation failed.
     *
     * @param  mixed $value
     * @return bool
     * @throws Exception\RuntimeException If validation of $value is impossible
     */
    public function isValid($value);

    /**
     * Returns an array of messages that explain why the most recent isValid()
     * call returned false. The array keys are validation failure message identifiers,
     * and the array values are the corresponding human-readable message strings.
     *
     * If isValid() was never called or if the most recent isValid() call
     * returned true, then this method returns an empty array.
     *
     * @return array
     */
    public function getMessages();
}

Ok, that’s make sense. We collect all occurred errors into array and call getMessages() afterwards.

Stateless

What is stateless? It’s possibility ob object to not have any state. Stateless gives us ability to use Dependency Injections of our validators. Zend Validator is not stateless, because any time when validator is called - it will collect errors or other metadata. So is it possible to write stateless validator with possibility to determine an error?

Yes

<?php

class TestValidator implements ValidatorInterface {

    public function isValid($value) {
        if (fasle === $value) {
            throw new \Exception('Value is not false.');
        }

        if (0 === $value) {
            throw new \Exception('Value is not 0.');
        }

        return true;
    }
}

With exceptions we can not store any kind of information, but this also doesn’t allow us to expect for multiple errors. For such cases we can make decomposition of TestValidator into NotFalseValidator and NotZeroValidator. Also we cannot call such methods as isValid, because another developer would rather expect boolean as return parameter. I would call it validate.

Pros

  • Doesn’t contains any state - can be called in DI;
  • Does not require factories.

Cons

  • Can not validate more than 1 error at the same time;
  • isValid is not correct method name. It can be either validate;
  • Requires copy-paste of try-catches in an kind of calls.

About the architecture of applications in PHP it was written more than a dozen items, but on this issue, more than emphasize the designers of Java and C #. Its essence lies in the rigid dependence of the properties on the other.

Let’s imagine the following situation:

<?php

class Page
{
    /**
     * @var string
     */
    private $content;

    /**
     * @param $content
     */
    public function setContent($content)
    {
        $this->content = $content;
    }
}

class PageBuilder
{
    /**
     * @var Page
     */
    private $page;

    /**
     * @param $page
     */
    public function setPage($page)
    {
        $this->page = $page;
    }

    /**
     * @param $content
     * @return $this
     */
    public function setContent($content)
    {
        $this->page->setContent($content);

        return $this;
    }

    /**
     * @return Page
     */
    public function build()
    {
        return $this->page;
    }
}

$pageBuilder = new PageBuilder();
$pageBuilder->setPage(new Page());
$pageBuilder->setContent('Test content');
$pageBuilder->build();

This example shows that the $pageBuilder->build() is potentially dangerous and can result in a fatal error if $pageBuilder->setPage(new Page()) has not been previously called. Another common mistake - using methods init() or initialization()

<?php

class Page
{
    // Class
}

class PageBuilder
{
    /**
     * @var Page
     */
    private $page;

    /**
     * Initialization
     */
    public function init()
    {
        $this->page = new Page();
    }

    /**
     * @param $content
     * @return $this
     */
    public function setContent($content)
    {
        $this->page->setContent($content);

        return $this;
    }

    /**
     * @return Page
     */
    public function build()
    {
        return $this->page;
    }
}

$pageBuilder = new PageBuilder();
$pageBuilder->init();
$pageBuilder->setContent('Test content');
$pageBuilder->build();

If we forget to call the init() method, we are also waiting for trouble. This code is an excellent example of poor application architecture. Methods-initializers are trying to behave as constructors, whether they are not.

To avoid Temporal Coupling must always use rules:

  • instance of the class must be ready for use immediately after creation;
  • constructors should not perform any logic except of initialization of class properties;

Dependency injection via constructor

This solution is optimal and preferred in most cases. We can use Dependency Injection mechanism of Symfony, Laravel or other modern frameworks.

<?php

class Page
{
    // Class
}

class PageBuilder
{
    /**
     * @var Page
     */
    private $page;

    /**
     * PageBuilder constructor.
     * @param Page $page
     */
    public function __construct(Page $page)
    {
        $this->page = $page;
    }

   // Setter methods
}

$pageBuilder = new PageBuilder(new Page());
$pageBuilder->setContent('Test content');
$pageBuilder->build();

Abstract factory

Slightly modify our code, adding an abstract factory:

<?php

class Page
{
    // Class
}

class PageBuilder
{
    /**
     * @var Page
     */
    private $page;

    /**
     * PageBuilder constructor.
     * @param Page $page
     */
    public function __construct(Page $page)
    {
        $this->page = $page;
    }

    /**
     * @param $content
     * @return $this
     */
    public function setContent($content)
    {
        $this->page->setContent($content);

        return $this;
    }

    /**
     * @return Page
     */
    public function build()
    {
        return $this->page;
    }
}

class PageBuilderFactory implements FactoryInterface
{
    /**
     * @param Page|null $page
     * @return PageBuilder
     */
    public function create(Page $page = null)
    {
        if (null === $page) {
            $page = new Page();
        }

        return new PageBuilder($page);
    }
}

$pageBuilderFactory = new PageBuilderFactory();
$pageBuilder = $pageBuilderFactory->create();
$pageBuilder->setContent('Test content');
$pageBuilder->build();

As you can see, the instance Page created without an explicit call and will be available to our Builder.

Conclusion

Temporal Coupling must always be avoided, regardless of the complexity of the application, the effect of code-review or other factors. Also remember that the designers have to perform only the logic associated with the injections. Otherwise, you run the risk of deterioration in performance on the stage of creating instances of the class.