<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title><![CDATA[Nikola Poša - Blog]]></title>
    <link href="https://www.nikolaposa.in.rs/blog/feed" rel="self"/>
    <link href="https://www.nikolaposa.in.rs/"/>
    <updated>2020-08-17T16:08:36+02:00</updated>
    <id>https://www.nikolaposa.in.rs/</id>
        <generator uri="http://sculpin.io/">Sculpin</generator>
            <entry>
            <title type="html"><![CDATA[Self-validating Domain Model]]></title>
            <link href="https://www.nikolaposa.in.rs/blog/2020/08/17/self-validating-domain-model/"/>
            <updated>2020-08-17T00:00:00+02:00</updated>
            <id>https://www.nikolaposa.in.rs/blog/2020/08/17/self-validating-domain-model/</id>
            <content type="html"><![CDATA[<p>If you have ever had a dilemma "where" to put validation logic, "when" to validate, "what" should be validated, the tips and practical experiences I will share can help you establish a viable validation strategy for a system of any scale.</p>

<p>This post primarily deals with the validation of business rules that target individual values, such as for example: "Username must be between 3-20 characters long". Common term for this type of pure, stateless validation is input validation. Another type of business rules are those that define whether the value is acceptable in the broader context in which it is used. "Username must be unique" is an example of such a business rule, but their validation is not the focus of this post.</p>

<h3 id="client-side-or-server-side-validation%3F">Client-side or server-side validation?</h3>

<p>You have probably encountered this question many times, but the choice should not even be questioned. You should do both. These two types of validation are by no means in conflict or exclusive, they are complementary.</p>

<p>It is understood that validation in server code is mandatory, because we should never trust UI. Attackers can easily bypass JavaScript or the entire UI and submit malicious data to the server.</p>

<p>But the client-side validation is equally important and useful. Not only is it a great convenience for users because it saves them time by giving instant feedback for the data entered, client-side validation avoids unnecessary round trips to the server by preventing users from sending invalid data at all.</p>

<h3 id="form-validation-is-ui-validation">Form validation is UI validation</h3>

<p>Many proponents of the idea of server side–only validation use DRY (Don't Repeat Yourself principle) as the main argument. That may be good reasoning, but only if some important considerations are kept in mind.</p>

<p><strong>The browser is just one of the interfaces or ports through which your system can be used. In terms of validating input, the same rules must apply and exist in those cases as well</strong>. For example, the registration form on the website can be one of the ways to create users, in addition to API, or a command-line and other types of tools for creating and importing users.</p>

<p>In the web context, form validation is often considered to be the ultimate validation, on both ends. But form is a UI concern, therefore form validation should not be regarded as server-side validation at all. Also, forms are a feature of the CRUD–style user interface, while modern web and mobile UIs have been trending towards the direction of being task based, allowing user to perform certain action, for example "Mark Todo as Done", "Set a Reminder", "Approve Friend Request", and similar. Forms are not really as common interface elements as they seem.</p>

<p>Most importantly, domain models are typically much more complex and rather different than view models so trying to bind a form directly to the domain model seems irrational.</p>

<p>Some people will find this difficult to hear, but unless you are building traditional server side rendered application, components such as Symfony or Laminas (previously Zend) Form have no place on the back-end, especially not for validation purposes.</p>

<p>So how do we validate input on the server side?</p>

<h3 id="validation-at-the-domain-model-level">Validation at the domain model level</h3>

<p>The systems we build can have complex business logic, hence we usually resort to domain modeling in order to abstract and organize that complexity by creating a web of interconnected objects where each object represents some meaningful unit. But along the way, we somehow forget to appropriately model simple values that have special meaning, such as email address, username, money, address, and similar. Consequently, logic for validating these values is typically scattered and duplicated throughout the code base, wherever such value is dealt with.</p>

<p>This phenomenon has inspired some critics to characterize it as a code smell called <a href="https://refactoring.guru/smells/primitive-obsession">Primitive Obsession</a>. Although I justify this criticism, I think the formulation itself is too harsh. We are not obsessed with primitives, we simply neglect the use of objects by taking shortcuts that are available.</p>

<p>Just because we can represent a certain concept as a primitive type, does not mean that we always should. Email address is not a string. Its textual representation is stringy and can be casted to a string, but it is a well-defined structure made up of a mailbox name, an @ symbol and a case-insensitive domain. Username is not a string neither, it isn't <em>any</em> text, but is usually defined by business rules for length and allowed characters. All these concepts have some new, special meaning, therefore they should be modeled accordingly.</p>

<p><strong>Instead of representing some piece of domain knowledge as primitive type, make it a custom type, or in Domain-Driven Design (DDD) terminology, turn it into a self-validating Value Object that encapsulates all the business rules in a single place</strong>.</p>

<p>Here's how the definition of a <code>Username</code> value object might look like:</p>

<pre><code>final class Username
{
    private string $username;

    private function __construct(string $username)
    {
        if (!preg_match('/^[a-z0-9_-]{3,20}$/', $username)) {
            throw new \InvalidArgumentException('Username must be alphanumeric string that may include "_" and "–", having a length of 3 to 20 characters');
        }

        $this-&gt;username = $username;
    }

    public static function fromString(string $username): self
    {
        return new self($username);
    }

    public function toString(): string
    {
        return $this-&gt;username;
    }
}
</code></pre>

<p>Validation happens at the construction time through the use of <strong>guard clauses</strong> that immediately raise an exception if the passed value is not valid according to one or more criteria. This was in a way an answer to the question of where validation should live.</p>

<p><strong>Self-validation, but also another important characteristic of value objects – immutability, are a guarantee that a value object is valid for the entire time of its existence. We no longer have to worry about whether we need to validate a parameter or it has already been validated, and if not, what is the best place to validate without causing duplication.</strong></p>

<p>In terms of effort and time required, creating value objects for all primitive types may seem like over-engineering. But don't forget that with a primitive string, you still need to write validation logic and apply it consistently to all necessary places in the code.</p>

<h3 id="assertions">Assertions</h3>

<p>When they hear the word "assert" or "assertion", most developers think of testing, specifically the operation represented in xUnit testing frameworks such as PHPUnit. However, the same term exists in the context of validation, where assertions are a more convenient way to implement guard clauses for input validation, by writing expressive statements instead of <code>if/throw</code> structures.</p>

<p>The PHP ecosystem is known for having multiple libraries to solve the same problem. This is also the case with assertions as there are two libraries for which I know:</p>

<ol>
<li><a href="https://github.com/beberlei/assert">beberlei/assert</a></li>
<li><a href="https://github.com/webmozart/assert">webmozart/assert</a></li>
</ol>

<p>The second one seems to have been born in response to some shortcomings of the original library, but I personally favor Beberlei's Assert and I think it's quite solid.</p>

<p>Here is a refined version of the <code>Username</code> constructor:</p>

<pre><code>final class Username
{
    private function __construct(string $username)
    {
        Assertion::regex($username, '/^[a-z0-9_-]{3,20}$/', 'Username must be alphanumeric string that may include "_" and "–", having a length of 3 to 20 characters');

        $this-&gt;username = $username;
    }
}
</code></pre>

<p>The example of the Username value object validation may not be demonstrative enough because it only has one guard clause, yet it is obvious that <strong>the main benefit of using assertions is that they significantly reduce the amount of code needed for implementing input validation in your models</strong>. Also, the list of built-in assertions is huge, and it is possible to extend it as well.</p>

<h4 id="custom-assertion-class">Custom Assertion class</h4>

<p>Although assertions are pure, stateless, general-purpose functions, I prefer to create my own Assertion class for these reasons:</p>

<ol>
<li>have more control over the exception type that gets raised,</li>
<li>keep the domain "pure" by avoiding direct coupling with the library,</li>
<li>ability to write domain-specific assertions,</li>
<li>shield from potential BC breaks in the library.</li>
</ol>

<p>Beberlei's Assert gives me that ability, where I can also override the thrown exception:</p>

<pre><code>namespace App\User;

use Assert\Assertion;
use App\User\Exception\InvalidUserInput;

class UserAssertion extends Assertion
{
    protected static $exceptionClass = InvalidUserInput::class;
}
</code></pre>

<p>Custom exception type:</p>

<pre><code>namespace App\User\Exception;

use Assert\InvalidArgumentException;

final class InvalidUserInput extends InvalidArgumentException implements UserException
{
}
</code></pre>

<p>The decision whether to create a generic custom Assertion class or one per domain concept is always context-dependent and influenced by the amount of customizations you are making and the granularity of exception types you want to have.</p>

<h3 id="value-objects-obsession">Value Objects Obsession</h3>

<p>In order to fully switch to this new approach of representing simple domain concepts, the key is to strictly adhere to the use of value objects for properties, constructor parameters, method parameters, etc. Entities are typically comprised of value objects, they are a great example of fully embracing type safety:</p>

<pre><code>class User
{
    protected UserId $id;
    protected Username $username;
    protected EmailAddress $emailAddress;
    protected DateTimeImmutable $createdAt;

    final protected function __construct(UserId $id, Username $username, EmailAddress $emailAddress, DateTimeImmutable $createdAt)
    {
        $this-&gt;id = $id;
        $this-&gt;username = $username;
        $this-&gt;emailAddress = $emailAddress;
        $this-&gt;createdAt = $createdAt;
    }

    public static function new(Username $username, EmailAddress $emailAddress)
    {
        return new static(UserId::generate(), $username, $emailAddress, new DateTimeImmutable());
    }
}
</code></pre>

<p>Just like in case of value objects, this design ensures that the entity will always be created in a valid state, regardless of the context and part of the system where it is used.</p>

<h4 id="gluing-all-the-pieces">Gluing all the pieces</h4>

<p>Despite this complete obsession with value objects, there must be a part of the code in which primitive values from the raw data submitted to the server are converted into value objects.</p>

<p>Commands are an ideal mechanism for abstracting use cases and the place to put the conversion logic:</p>

<pre><code>class RegisterUser
{
    protected Username $username;
    protected EmailAddress $email;

    public function __construct(array $payload)
    {
        UserAssertion::keysExists($payload, [
            'username',
            'email',
        ]);
        $this-&gt;username = Username::fromString($payload['username']);
        $this-&gt;email = EmailAddress::fromString($payload['email']);
    }

    public function username(): Username
    {
        return $this-&gt;username;
    }

    public function email(): EmailAddress
    {
        return $this-&gt;email;
    }
}
</code></pre>

<p>You can handle this command directly in some action controller, or better yet, capture this procedure in a dedicated command handler which may also perform some additional business rule validation:</p>

<pre><code>class RegisterUserHandler
{
    private UserRepository $userRepository;
    private UniqueUsernameChecker $uniqueUsernameChecker;

    public function __construct(UserRepository $userRepository, UniqueUserEmailChecker $uniqueUsernameChecker)
    {
        $this-&gt;userRepository = $userRepository;
        $this-&gt;uniqueUsernameChecker = $uniqueUsernameChecker;
    }

    public function handle(RegisterUser $command): void
    {
        if ($this-&gt;uniqueUsernameChecker-&gt;exists($command-&gt;username()) {
            throw UsernameTaken::for($command-&gt;username());
        }

        $user = User::new($command-&gt;username(), $command-&gt;email());

        $this-&gt;userRepository-&gt;save($user);
    }
}
</code></pre>

<p>Command Handler can then be used different contexts, such as Web action:</p>

<pre><code>class RegisterAction implements RequestHandlerInterface
{
    public function handle(ServerRequestInterface $request): ResponseInterface
    {
        $payload = $request-&gt;getParsedBody();

        $this-&gt;registerUserHandler-&gt;handle(new RegisterUser($payload));

        return new JsonResponse(['success' =&gt; true]);
    }
}
</code></pre>

<h3 id="user-friendly-validation-messages">User-friendly validation messages</h3>

<p>You are probably wondering how this domain model–level validation approach reflects on the user experience, in the case of a web application for example. Here's the twist – the end user should not even come into contact with input validation assertions, and therefore not see the assertion messages. The way to ensure this is having rich UI validation optimized for better user experience. That's why client-side validation is crucial.</p>

<p>If you are concerned about DRY, consider that in this case code reuse might result in coupling between back-end and front-end, which is a much greater concern than to strictly adhere to the DRY principle.</p>

<p>At the beginning, I pointed out that domain and view models are different, the same goes for their validation. The two may seem similar, but they have a different purpose and will change for different reasons, so it's completely fine to keep them separate.</p>

<h3 id="final-thoughts">Final thoughts</h3>

<p><strong>Shift in mindset in terms of consistently modeling simple concepts using value objects has a positive impact on all layers of the system</strong>. Code becomes more concise, clear, without noisy <code>if</code> checks in places where we do not expect them. Input validation is centralized within value objects, making it easier to find and change.</p>

<p>Guard clauses in value objects prevent invalid data from penetrating the domain layer. If someone tries to create an entity or aggregate composed of value objects anywhere in the application, type-safe contract guarantees that the resulting object will be valid. <strong>Not only are value objects self-validating, they spread this characteristic to the entire domain layer</strong>.</p>

<p>Validation at the domain model level is the ultimate solution for server-side validation, it has no alternative. In addition, decent UI validation is the first line of defense, so your system should include both.</p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[Stop using DateTime]]></title>
            <link href="https://www.nikolaposa.in.rs/blog/2019/07/01/stop-using-datetime/"/>
            <updated>2019-07-01T00:00:00+02:00</updated>
            <id>https://www.nikolaposa.in.rs/blog/2019/07/01/stop-using-datetime/</id>
            <content type="html"><![CDATA[<p>Working with date &amp; time in PHP can sometimes be annoying, leading to unexpected bugs in the code:</p>

<pre><code>$startedAt = new DateTime('2019-06-30 10:00:00');

$finishedAt = $startedAt-&gt;add(new DateInterval('PT3M')); 

var_dump($startedAt-&gt;format('Y-m-d H:i:s')); //2019-06-30 10:03:00 ❌
var_dump($finishedAt-&gt;format('Y-m-d H:i:s')); //2019-06-30 10:03:00 ✅
</code></pre>

<p>Both <code>$startedAt</code> and <code>$finishedAt</code> are 3 minutes forward in time, because methods such as <code>add()</code>, <code>sub()</code> or <code>modify()</code> also <strong>change</strong> <code>DateTime</code> object they were called on before returning it. In the above example, this certainly isn't the desired behaviour.</p>

<p>We can fix this by copying reference object before acting on it, like so:</p>

<pre><code>$startedAt = new DateTime('2019-06-30 10:00:00');

$finishedAt = clone $startedAt;
$finishedAt-&gt;add(new DateInterval('PT3M'));
</code></pre>

<p>Every time I encounter <code>clone</code> in PHP code things start to smell as it is usually about someone hacking someone else's bad code design. In this particular case it was used to avoid mutating behavior, but it makes the code ugly and introduces unnecessary noise.</p>

<p>Alternatively, this could be solved by converting original <code>DateTime</code> instance to <code>DateTimeImmutable</code>:</p>

<pre><code>$startedAt = new DateTime('2019-06-30 10:00:00');

$finishedAt = DateTimeImmutable::createFromMutable($startedAt)-&gt;add(new DateInterval('PT3M'));
</code></pre>

<p>But why not using <code>DateTimeImmutable</code> from the beginning?</p>

<h3 id="uncompromising-use-of-datetimeimmutable">Uncompromising use of DateTimeImmutable</h3>

<p><strong>Instead of manually applying defensive techniques in order to prevent unexpected mutation when passing around date/time objects, use <code>DateTimeImmutable</code> that encapsulates those techniques, making your code more reliable.</strong></p>

<pre><code>$startedAt = new DateTimeImmutable('2019-06-30 10:00:00');

$finishedAt = $startedAt-&gt;add(new DateInterval('PT3M'));

var_dump($startedAt-&gt;format('Y-m-d H:i:s')); //2019-06-30 10:00:00 ✅
var_dump($finishedAt-&gt;format('Y-m-d H:i:s')); //2019-06-30 10:03:00 ✅
</code></pre>

<p>In most contexts, concept of a date is treated as a value, we compare dates by their values, and when we modify a date it becomes a different date. All this perfectly matches the definition of a <a href="https://www.martinfowler.com/bliki/ValueObject.html">Value Object</a>, and one important characteristic of value objects is that they are <strong>immutable</strong>.</p>

<h3 id="verbose-coding-style">Verbose coding style</h3>

<p>Immutability forces you to explicitly reassign a <code>DateTimeImmutable</code> object every time you act on it, because it never modifies itself but a new copy is returned. After years of working with mutable <code>DateTime</code>, and due to the fact that mutability is the default in imperative programming languages, it is hard to get rid of bad mutating habits and conform to the new coding style that enforces reassignment:</p>

<pre><code>$this-&gt;expiresAt = $this-&gt;expiresAt-&gt;modify('+1 week');
</code></pre>

<p>Static analysis tools such as PHPStan and <a href="https://github.com/Slamdunk/phpstan-extensions#rules">one of its extensions</a> can warn us if we misuse <code>DateTimeImmutable</code> by omitting assignment.</p>

<p>Yet this cognitive bias towards mutability is suppressed when we perform arithmetic operations on primitive values, for example: <code>$a + 3;</code>. On its own, this gets perceived as an pointless statement that is clearly missing reassignment: <code>$a = $a + 3;</code> or <code>$a += 3;</code>. Would not it be lovely if we could use something similar in the case of value objects?</p>

<p>Some programming languages features a syntactic sugar called <a href="https://en.wikipedia.org/wiki/Operator_overloading">operator overloading</a> that allows for implementing operators in user-defined types and classes, so that they behave much like the primitive data types. I would not mind if PHP steals this trick from another programming language that would allow us to write our code this way:</p>

<pre><code>$this-&gt;expiresAt += '1 week';
</code></pre>

<h3 id="one-off-calculations">One-off calculations</h3>

<p>Some people argue that performance-wise, it is better to use <code>DateTime</code> when calculations are done within a single scope of execution. That is a valid point, but unless you are doing hundreds of operations, and given that references to the old <code>DateTimeImmutable</code> object will be garbage collected, in most practical scenarios memory consumption should not be a concern.</p>

<h3 id="date%2Ftime-libraries">Date/time libraries</h3>

<p><a href="https://carbon.nesbot.com/">Carbon</a> is a super popular library that extends PHP's date/time API with a rich set of functionality. To be more accurate, it extends API of a mutable <code>DateTime</code> class, which conflicts with the aim of this blog post.</p>

<p>So if you like working with Carbon, but you favor immutability, I suggest you consider <a href="http://book.cakephp.org/chronos">Chronos</a>. It is a standalone library that was originally based on Carbon, focusing on providing immutable date/time objects by default, but it also ships with mutable variants in case you need them.</p>

<p>Edit (05/07/2019): It turns out that Carbon <em>does</em> have an immutable date/time variant, which is a big plus on its account. Yet, the reason I gave Chronos advantage is that unlike Carbon, it encourages and promotes immutability by default, both in code and documentation, and that is a crucial factor with regard to the message of this post.</p>

<h3 id="final-thoughts">Final thoughts</h3>

<p><code>DateTimeImmutable</code> was first introduced back in the ancient PHP 5.5, and to my surprise many developers are discovering it only now. Use <code>DateTimeImmutable</code> by default whenever possible, also bearing in mind some of the tradeoffs I've described, which I consider to be more a matter of habit and shift in mindset.</p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[Better naming convention]]></title>
            <link href="https://www.nikolaposa.in.rs/blog/2019/01/06/better-naming-convention/"/>
            <updated>2019-01-06T00:00:00+01:00</updated>
            <id>https://www.nikolaposa.in.rs/blog/2019/01/06/better-naming-convention/</id>
            <content type="html"><![CDATA[<p>In the last couple of months, I spent a lot of time studying <a href="https://github.com/prooph/proophessor-do">Proophessor Do</a> demo project that showcases features of <a href="http://getprooph.org/">Prooph</a> components, all with the aim of mastering CQRS/Event Sourcing concepts. Along the way, something else turned my attention away from the main topic - <strong>unconventional</strong>, but <strong>clean and concise</strong> naming convention for class and method names.</p>

<p>This was a true eye-opener for me, I immediately liked the idea and after adapting it a bit I started practicing it at work. Excited and full of enthusiasm, I shared my findings and opinions with the rest of the world:</p>

<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">Inspired by naming style promoted by Prooph (<a href="https://t.co/XRb4boWTJQ">https://t.co/XRb4boWTJQ</a>), I decided to adopt similar style for my code. In short:<br>- no `get` prefix for getters in entities and value objects<br>- no `Exception` suffix<br>- no `Interface` suffix<br><br>Result: tidy, less verbose, concise code. 👌🏻 <a href="https://t.co/812cCkmMOr">pic.twitter.com/812cCkmMOr</a></p>&mdash; Nikola Poša (@nikolaposa) <a href="https://twitter.com/nikolaposa/status/1077327810627358721?ref_src=twsrc%5Etfw">December 24, 2018</a></blockquote>

<p>Later I found out that <a href="https://github.com/doctrine/coding-standard">Doctrine Coding Standard</a> project is also enforcing many of these conventions which gave me confidence that I'm going in the right direction because parts of the community have already adopted such naming style.</p>

<p>I feel like I only scratched the surface with my tweet that opened many questions, without detailed explanation and reasoning behind the ideas presented. This post aims to fix that.</p>

<p>In order to understand what is good about this approach, we first need to understand what is wrong with the conventional one. Following are several naming conventions which I formulated as <strong>naming anti-patterns</strong> for reason. They are the motivation for designing a new, better naming convention.</p>

<h3 id="anti-pattern-1%3A-prefixes%2Fsuffixes-convention-for-interfaces">Anti-pattern 1: Prefixes/suffixes convention for Interfaces</h3>

<p>Let's start with the one for which there should be the least controversy. To give you better a sense of the problem, I'll make an analogy with one feature of human language - <strong>tautology</strong>:</p>

<blockquote class="quote-side">
    <p>In literary criticism and rhetoric, a tautology is a statement which repeats the same idea, using near-synonymous morphemes, words, or phrases, that is, "saying the same thing twice"</p>
    <p><cite><a href="https://en.wikipedia.org/wiki/Tautology_(language)">Wikipedia</a></cite></p>
</blockquote>

<p>Tautologies are common in everyday language, and when unintentional, they are often considered a fault of style. Think of terms such as "round circle", "dry desert", "new innovation". Sometimes even acronyms are not spared of this: "ATM machine", "GPS system", "ISBN number".</p>

<p>Now consider this piece of code and read aloud the entire definition of this interface:</p>

<pre><code class="php">interface TodoRepositoryInterface
{
}
</code></pre>

<p>Exactly, tautology is present in programming, too. Until recently, I did not pay attention to that, I did not think about this at all. Now I realize that this imposed naming convention is as silly as using <code>TodoClass</code> instead of <code>Todo</code> for the name of the entity class. Here's why I believe so:</p>

<ol>
<li>Interfaces already have the keyword <code>interface</code> in their definition, and therefore using <code>I</code> as a prefix or <code>Interface</code> as a suffix is a tautology that does not provide any additional value, but only <strong>blurs the actual purpose</strong>.</li>
<li>Each of these meaningless prefix/suffix naming conventions violates the <a href="https://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a> software development principle as well.</li>
<li>UML class diagrams provide mechanisms to represent and distinguish classes, interfaces («interface» preceding the name) and abstract classes (italicized):
<img src="/assets/img/posts/better-naming-convention/todo_uml.png" alt="" class="img-responsive aligncenter" style="margin-top: 10px;"></li>
<li>Modern IDEs are doing a similar thing by visualizing files:
<img src="/assets/img/posts/better-naming-convention/modern_ide.png" alt="" class="img-responsive aligncenter" style="margin-top: 10px;"></li>
</ol>

<p>The same arguments apply to abstract classes and traits, and respective <code>Abstract</code> and <code>Trait</code> prefixes/suffixes. However, since abstract classes should never be part of any <strong>public facing interface</strong> (consumers will deal with interfaces, value objects, entities), I think that <code>Abstract</code> prefix is somewhat acceptable exception to the rule. Of course, you could still come up with a better name by using alternative prefix such as <code>Base</code>. Yet, this should be used as a last resort, because I assure you that you can get the right name if you precisely describe purpose and scope of the abstract class. For example, <code>PdoRepository</code> could be an abstract class with logic common for PDO-based repositories, while <code>MySqlTodoRepository</code> could be a concrete implementation.</p>

<p>Something that is not so common in PHP, and I hope it never will be, is practice of using <code>Impl</code> as a suffix for concrete implementations. That is even more noise, more tautology, because anything that isn't an interface is basically an implementation, so putting <code>Impl</code> suffix on every name of every class is absurd to say the least.</p>

<p>It is quite clear that language construct prefixes and suffixes do not bring any value, and they add nothing but more stuff to type to your code.</p>

<h3 id="anti-pattern-2%3A-archetype-suffix-convention-for-domain-classes">Anti-pattern 2: Archetype suffix convention for domain classes</h3>

<p>What I'm focusing on here are classes that make up the domain, core business logic of the application - Entities, Value Objects, Exceptions, Events, and similar. Entities and Value Object are the least controversial, because we are all more or less used to choose a good name for them: <code>User</code>, <code>EmailAddress</code>, <code>Todo</code>, <code>TodoText</code>. But let's examine following Exception class that represents an exceptional condition in our domain:</p>

<pre><code class="php">namespace My\Todo\Exception;

final class CannotReopenTodoException extends \Exception
{
}
</code></pre>

<p>Reading it, <code>Exception</code> suffix is not nearly as striking as in the case of <code>Interface</code> suffix. Things start to change when you look into FQCN: <code>\My\Todo\Exception\CannotReopenTodoException</code> because <code>Exception</code> is already a namespace. But even if we ignore the repetition within the FQCN, <code>CannotReopenTodoException</code> it is still a form of tautology, because <strong>wording</strong> and the <strong>context</strong> in which it is used (<code>throw</code>, <code>catch</code>, <code>$ex</code> variable name) unambiguously indicate that we are dealing with an Exception:</p>

<pre><code class="php">try {
    throw CannotReopenTodoException::notDone($todo);
} catch (CannotReopenTodoException $ex) {
}
</code></pre>

<p>It should now be clear that the suffix here is superfluous.</p>

<p>Event is another concept that is an indispensable part of event-driven and event-sourced architectures, and the same principle applies for them and most of the other domain elements that resides in their own namespace. The importance of the wording is even more pronounced in their case. <code>FooEvent</code> does require suffix for clarification, but accurate description told in the past tense such as <code>TodoWasMarkedAsDone</code> is self-evident.</p>

<p>Suffix removal is possible only if the class names are <strong>descriptive</strong> enough. Bad name is usually the result of a <strong>design</strong> flaw, and the inability to rename a class to something meaningful suggests that it has a poor cohesion.</p>

<h3 id="anti-pattern-3%3A-%22get%22-prefix-convention-for-property-accessors">Anti-pattern 3: "get" prefix convention for property accessors</h3>

<p>Enough with tautologies. The claim that <code>get</code> prefix is excessive is a bold statement, and it seems to be the one that is very hard to swallow for a lot of people who have read and discussed my tweet.</p>

<p>Getters and setters are the main forms of interaction with the properties of an object through its public interface. But given that Value objects are immutable, and Entities foster encapsulation, there should be no classical setter methods in any of them. In such circumstances, the getters take on the role of simple <strong>property accessors</strong>:</p>

<pre><code class="php">final class Todo
{
    public function getId(): TodoId
    {
    }

    public function getDescription(): string
    {
    }

    public function getStatus(): Status
    {
    }
}
</code></pre>

<p>It becomes obvious that the <code>get</code> prefix becomes excessive and provides no value to the consumer other than grouping all the property accessors with a common prefix.</p>

<p>I believe that the alternative "strip naked" naming convention for property accessor methods is a step closer to what will soon be a standard way of writing entities and value objects. Since the <a href="https://wiki.php.net/rfc/typed_properties_v2">Typed Properties RFC</a> has been accepted and feature will be available in PHP 7.4, and hopefully <a href="https://wiki.php.net/rfc/readonly_properties">Read-only Properties RFC</a> will go equally well, in the near future we will be able write our classes as follows:</p>

<pre><code class="php">final class Todo
{
    public TodoId readonly $id;

    public string readonly $description;

    public Status readonly $status;
}
</code></pre>

<h3 id="final-thoughts">Final thoughts</h3>

<p>I regret that it took me a long time to start thinking pragmatically about naming, because now most of my projects, both private and open source, still suffer from this tautology syndrome and the majority will never be healed. But going forward, every new work and new backward incompatible versions of my libraries shall be in accordance with the naming style elaborated in this article.</p>

<h3 id="tl%3Bdr">TL;DR</h3>

<p><a href="/assets/img/posts/better-naming-convention/bad_vs_good.png">
    <img src="/assets/img/posts/better-naming-convention/bad_vs_good.png" alt="" class="img-responsive">
</a></p>

<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[Community-driven PHP 8 Wish List]]></title>
            <link href="https://www.nikolaposa.in.rs/blog/2018/09/23/community-driven-php8-wish-list/"/>
            <updated>2018-09-23T00:00:00+02:00</updated>
            <id>https://www.nikolaposa.in.rs/blog/2018/09/23/community-driven-php8-wish-list/</id>
            <content type="html"><![CDATA[<p>It's been over two months since I started a research on Twitter about the things that developers would like to be added or improved in the next major PHP release:</p>

<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">Fellow <a href="https://twitter.com/hashtag/PHP?src=hash&amp;ref_src=twsrc%5Etfw">#PHP</a> developers, what are the features you would like to be added, changed or removed in 8.0?</p>&mdash; Nikola Poša (@nikolaposa) <a href="https://twitter.com/nikolaposa/status/1018966511388647429?ref_src=twsrc%5Etfw">July 16, 2018</a></blockquote>

<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<p>It had a surprisingly long reach, inspiring developers, prominent experts, community representatives to express their opinion through more than a hundred responses.</p>

<p>It would be a waste to leave such a valuable data in the form of a raw and fuzzy Twitter thread, so I finally found some time to turn it into something more useful. I created a spreadsheet containing a list of proposals and their number of votes:</p>

<iframe src="https://docs.google.com/spreadsheets/d/e/2PACX-1vSzPZJIynPV-Hj99F5WqUlticSzwuzNJ-G8NcuKCRJf9ZHmaFI7LsOt9SGxobH8OJEKI6qRCDuSnPK8/pubhtml?widget=true&amp;headers=false" style="width: 100%; height: 300px; padding: 0px; border: medium none; max-width: 100%; min-width: 500px; margin-top: 10px; margin-bottom: 10px;"></iframe>

<p><a href="https://docs.google.com/spreadsheets/d/e/2PACX-1vSzPZJIynPV-Hj99F5WqUlticSzwuzNJ-G8NcuKCRJf9ZHmaFI7LsOt9SGxobH8OJEKI6qRCDuSnPK8/pubhtml"><strong>Click here for a full, more transparent spreadsheet / chart</strong></a></p>

<p>The list was processed as follows:</p>

<ul>
<li>duplicate proposals have been merged into one so that the final list is unique (identifying duplicates was not an easy task, so some suggestions may be unintentionally omitted),</li>
<li>features that are already implemented or will be implemented in some of the upcoming PHP 7.x releases have been omitted,</li>
<li>the proposals relating to PHP extensions have been omitted,</li>
<li>some unrealistic and jokey proposals, such as removing <code>-&gt;</code> notation, have been omitted,</li>
<li>the total number of votes for each proposal is the sum of the number of likes for the proposal and the number of responses in which the proposal was found.</li>
</ul>

<p>The results clearly shout that PHP developers are eager for stronger object-oriented interface, multi-threading and asynchronous processing, strict typing, as well as some syntactic sugar additions following the example of other languages.</p>

<p>I would like to thank everyone who contributed in making this list, either by sending their own proposal or voting for the existing one. Let your PHP 8 wishes come true!</p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[Lazy loading services using Zend Service Manager]]></title>
            <link href="https://www.nikolaposa.in.rs/blog/2018/07/14/lazy-loading-services-using-zf-service-manager/"/>
            <updated>2018-07-14T00:00:00+02:00</updated>
            <id>https://www.nikolaposa.in.rs/blog/2018/07/14/lazy-loading-services-using-zf-service-manager/</id>
            <content type="html"><![CDATA[<p>Any more complex application includes a big dependency injection tree of services, some of which can have a more complicated creation logic. If the service is injected as a dependency, but not necessarily used at every execution, you may want to lazily initialize that service until it is really needed.</p>

<p>In those situations, you may be tempted to inject the entire Dependency Injection Container instead, and lazy-load that resource-hungry service. I find that to be an anti-pattern, and I explained my views in a <a href="/blog/2017/09/03/using-dic-the-right-way">blog post</a> written some time ago.</p>

<p>To come up with a better solution, ask yourself a tricky question: how would you solve this puzzle without the help of a DI container, in a situation where you would have to manually assemble application services? Such a challenge evokes creativity, forces us to approach a problem from a different angle, and eventually leads us to think about design patterns.</p>

<p><strong>Proxy</strong> design pattern makes it possible to avoid coupling to the DI container so that you keep dependencies explicit, while achieving the same goal of lazy-loading an object that is expensive to instantiate. Here is an example for a proxy implemented using an anonymous class:</p>

<pre><code class="php">$notifier = new class implements NotiferInterface {
    private $realNotifier;

    public function notify(RecipientsCollection $recipients, Notification $notification) : void
    {
        $this-&gt;getRealNotifier()-&gt;notify($recipients, $notification);
    }

    private function getRealNotifier() : NotiferInterface
    {
        if (null === $this-&gt;realNotifier) {
            $this-&gt;realNotifier = new MultiChannelNotifier(
                'email' =&gt; new NativeMailer(),
                'sms' =&gt; new TwilioSMS('token', new HttpClient()),
                'push' =&gt; Pushover('token', new HttpClient()),
            );
        }

        return $this-&gt;realNotifier;
    }
};
</code></pre>

<p>You can inject this efficient object in any one that depends on <code>NotiferInterface</code>, while complex logic for creating actual (real) notifier will be executed only when a notification is sent:</p>

<pre><code class="php">final class ArticleService
{
    public function comment(string $articleId, array $commentPayload)
    {
        $article = $this-&gt;articleRepo-&gt;get($articleId);
        $comment = Comment::fromInput($commentPayload);

        $article-&gt;add($comment);

        $this-&gt;articleRepo-&gt;save($article);

        //service is instantiated only here!
        $this-&gt;notifier-&gt;notify(
            new RecipientsCollection([
                $article-&gt;getAuthor(),
            ]), 
            new NewCommentNotification($comment)
        );
    }
}
</code></pre>

<p>Some DI container solutions, such as <a href="https://docs.zendframework.com/zend-servicemanager/">Zend Service Manager</a>, go a step further with features that facilitate the use of different creational patterns. The one that is relevant to our story is <code>LazyServiceFactory</code>, which completely eliminates the effort and hides the complexity of proxying application services. Internally, it uses <a href="https://github.com/Ocramius/ProxyManager">ProxyManager</a> - library that provides abstraction for generating proxy classes, so you will need to install that package before using this feature.</p>

<p><strong>NotifierFactory.php</strong></p>

<pre><code class="php">final class NotiferFactory 
{
    public function __invoke(ContainerInterface $container) : NotiferInterface
    {
        return new MultiChannelNotifier(
           'email' =&gt; new NativeMailer(),
           'sms' =&gt; new TwilioSMS('token', new HttpClient()),
           'push' =&gt; Pushover('token', new HttpClient()),
       );
    }
};
</code></pre>

<p><strong>ArticleServiceFactory.php</strong></p>

<pre><code class="php">final class ArticleServiceFactory 
{
    public function __invoke(ContainerInterface $container) : ArticleService
    {
        return new ArticleService(
           $container-&gt;get(ArticleRepositoryInterface::class),
           $container-&gt;get(NotifierInterface::class),
       );
    }
};
</code></pre>

<p><strong>services.php</strong></p>

<pre><code class="php">use MyApp\NotifierFactory;
use MyApp\NotifierInterface;
use Zend\ServiceManager\Factory\InvokableFactory;
use Zend\ServiceManager\Proxy\LazyServiceFactory;
use Zend\ServiceManager\ServiceManager;

$serviceManager = new ServiceManager([
    'factories' =&gt; [
        ArticleService::class =&gt; ArticleServiceFactory::class,
        NotifierInterface::class =&gt; NotifierFactory::class,
    ],
    'delegators' =&gt; [
        NotifierInterface::class =&gt; [
            LazyServiceFactory::class,
        ],
    ],
    'lazy_services' =&gt; [
         'class_map' =&gt; [
             NotifierInterface::class =&gt; NotifierInterface::class,
         ],
    ],
]);

return $serviceManager;
</code></pre>

<p>With just a few lines of configuration code, <code>LazyServiceFactory</code> does all the heavy lifting, and an efficient <code>Notifier</code> object gets returned behind the scenes whenever you require it from a DI Container.</p>

<p>Performance is a crucial feature of the applications we develop today, every millisecond and each memory byte counts, so optimizing the assembly part of our application can save valuable resources. Thereby, do not stuck with the easiest solution, think twice every time you are tempted to leak DI Container into the code. Breaking the Dependency Rule is not a valid compromise, because for every problem there is a proper solution. Tools such as Zend Service Manager facilitate the work needed even more.</p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[Testing web API clients using Guzzle Mock Handler]]></title>
            <link href="https://www.nikolaposa.in.rs/blog/2018/04/07/testing-web-api-clients-using-guzzle-mock-handler/"/>
            <updated>2018-04-07T00:00:00+02:00</updated>
            <id>https://www.nikolaposa.in.rs/blog/2018/04/07/testing-web-api-clients-using-guzzle-mock-handler/</id>
            <content type="html"><![CDATA[<p>Whether you're writing a client for your own web API to offer it to users or you're simply implementing integration for a 3rd-party API in your system, it is important to test it to make sure your client is capable of handling actual API responses correctly.</p>

<p>Testing web API clients is mostly about checking how they deal with responses received after sending requests to API endpoints, and for your unit tests, you introduce test doubles to simulate API calls instead of executing real HTTP requests.</p>

<h3 id="remark">Remark</h3>

<p>When faced with such and similar challenges, PHP developers usually resort to mocking, facilitated either by PHPUnit or some alternative framework, and methods such as <code>expects()</code>, <code>with()</code>, <code>willReturn()</code> and similar. But this persistent and excessive use of mocking seems very unnatural to me as if there are no alternatives, especially in the case where it is needed to simulate web service requests.</p>

<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">Sadly, mocking has become the predominant term in testing as if there are no other patterns for replacing production object for testing purposes. Almost as googling, like there&#39;s no other way to search content on the Internet.</p>&mdash; Nikola Poša (@nikolaposa) <a href="https://twitter.com/nikolaposa/status/980372315216207872?ref_src=twsrc%5Etfw">April 1, 2018</a></blockquote>

<p><strong>Ideally, test code should resemble usage examples from a README file, instead of being overwhelmed with impractical directives that make sense only in the testing context.</strong></p>

<h3 id="http-layer-stub">HTTP layer stub</h3>

<p>Web API clients (or SDKs) are typically built on top of some HTTP client implementation that facilitates communication with the API, which can be reduced to a direct usage of cURL functions or some more sophisticated and robust solution. <a href="http://docs.guzzlephp.org/en/stable/">Guzzle</a> is probably the most popular HTTP client for PHP providing a simple and convenient object-oriented interface for executing HTTP requests.</p>

<p>For sending HTTP requests, Guzzle features handlers system, and amongst default handlers there is one called <a href="http://docs.guzzlephp.org/en/stable/testing.html#mock-handler">Mock Handler</a>, designed just for the purpose of simulating different successful and error response scenarios without hitting an actual web API. With the help of it, instead of messing with mocking Guzzle and its methods that your API client is invoking during execution, you elegantly setup a response that should be returned when the Guzzle object is used by your API client:</p>

<pre><code class="php">use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\Psr7\Response;
use My\ApiClient;
use PHPUnit\Framework\TestCase;

class ApiClientTest extends TestCase
{
    protected $apiClient;

    protected $mockHandler;

    protected function setUp()
    {
        $this-&gt;mockHandler = new MockHandler();

        $httpClient = new Client([
            'handler' =&gt; $this-&gt;mockHandler,
        ]);

        $this-&gt;apiClient = new ApiClient($httpClient);
    }

    /**
     * @test
     */
    public function it_retrieves_students_collection()
    {
        $this-&gt;mockHandler-&gt;append(new Response(200, [], file_get_contents(__DIR__ . '/fixtures/products.json')));

        $products = $this-&gt;apiClient-&gt;getStudents();

        $this-&gt;assertCount(5, $products);
    }
}
</code></pre>

<p>Can you imagine the overhead of using mocking methods for achieving the same goal in some more complex scenario?</p>

<p>The irony, of course, is that the author formulated this handy test double as <code>MockHandler</code>, instead of <code>StubHandler</code>, so I'm tempted to create a pull request to fix this inaccurate name because <a href="https://martinfowler.com/articles/mocksArentStubs.html">mocks are not stubs</a>.</p>

<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[Factory as a Service]]></title>
            <link href="https://www.nikolaposa.in.rs/blog/2018/02/16/factory-as-a-service/"/>
            <updated>2018-02-16T00:00:00+01:00</updated>
            <id>https://www.nikolaposa.in.rs/blog/2018/02/16/factory-as-a-service/</id>
            <content type="html"><![CDATA[<p>Dependency Injection Containers are a great invention - when <a href="/blog/2017/09/03/using-dic-the-right-way">used the right way</a>, they allow us to keep our factories and assembly logic of services outside the core business logic of our application.</p>

<p>By default, a service created is shared, meaning that exactly the same instance will be returned whenever service is retrieved from a container. This is a desired behaviour in most of the cases. For example, application typically use a single database, so database connection service should be instantiated only once for the entire request lifecycle.</p>

<p><strong>config.php</strong></p>

<pre><code class="php">return [
    'db' =&gt; [
        'host' =&gt; 'localhost',
        'user' =&gt; 'root',
        'password' =&gt; 'secret',
        'dbname' =&gt; 'app',
    ],
];
</code></pre>

<p><strong>services.php</strong></p>

<pre><code class="php">return [
    DbConnectionInterface::class =&gt; function(ContainerInterface $container) {
        $config = $container-&gt;get('Config');
        return new DbConnection($config['db']);
    }
];
</code></pre>

<p>Yet certain use cases may require services to be created conditionally during runtime, such as for example based on the value of a parameter resolved from the current request.</p>

<p>Imagine that your application stores data in multiple databases, and the database itself is selected based on certain criteria in your application logic. This implies that database connection service cannot be shared anymore because <code>dbname</code> becomes a dynamic parameter for multiple connections that can exist during the request lifecycle.</p>

<p>This of course is not a difficult problem to solve, but things can go wrong if not treated properly.</p>

<h3 id="anti-patterns">Anti-patterns</h3>

<p>From my experience, there are several pitfalls I've seen developers fall into in struggle to come up with a solution for such an requirement while still adhering to the usage of a DI container for assembling application services:</p>

<ol>
<li><p>setter method - add a method to the service class that allows changing object's configuration on the fly:</p>

<pre><code class="php">public function __construct(DbConnectionInterface $dbConnection)
{
   $this-&gt;dbConnection = $dbConnection;
   $this-&gt;dbConnection-&gt;selectDatabase('some_database');
}
</code></pre>

<p>For this to work, database connection implementation had to be hacked to allow switching to a different database, and therefore made the class mutable for no good reason. This probably will not even be possible to achieve if you use some 3rd party libraries that were designed in a way that prevents changing object's state after its initial creation.</p>

<p><strong>Don't sacrifice immutability of your services.</strong></p></li>
<li><p>service location - have a DI container as a dependency and use it to build or locate appropriate service instance. Some DI container libraries, such as <a href="https://github.com/zendframework/zend-servicemanager">Zend Service Manager</a> for example, extend PSR-11 interface with methods that allow creating discrete instances of objects, acting as factory methods:</p>

<pre><code class="php">public function __construct(ServiceManager $serviceManager)
{
   $this-&gt;dbConnection = $serviceManager-&gt;build([
       'dbname' =&gt; 'some_database',
   ]);
}
</code></pre>

<p>While this is a handy feature, passing around and having the entire DI container as a dependency causes testing difficulties and leads to a problem of hidden dependencies.</p></li>
<li><p>static factory - give up on using DI container and introduce a static factory for creating service instances in-place:</p>

<pre><code class="php">$dbConnection = DbConnectionFactory::create($dbConfig);
</code></pre>

<p>Not only that this approach results in tight coupling between the consumer code and creation details of its dependency, but also makes it very difficult to test its functionality with fake database connection objects for example.</p></li>
</ol>

<h3 id="solution">Solution</h3>

<p>The way I handle these cases is by introducing a special type of service - one whose responsibility is to create and manage objects. I avoid using the term "factory" here, because this factory class is also a service that should have its own factory (see?) when registered in the DI container. For this particular example, I will formulate service as a Database Connection Pool, which nicely describes its purpose. It encapsulates default database configuration and creates connection objects for the database name passed as an input parameter:</p>

<pre><code class="php">interface DbConnectionPoolInterface
{
    public function get(string $dbName) : DbConnectionInterface;
}

final class DbConnectionPool implements DbConnectionPoolInterface
{
    private $dbConfig; 

    public function __construct(array $dbConfig)
    {
        $this-&gt;dbConfig = $dbConfig;
    }

    public function get(string $dbName) : DbConnectionInterface
    {
        return new DbConnection(array_merge(
            $this-&gt;dbConfig,
            [
                'dbname' =&gt; $dbName,
            ]
        ));
    }
}
</code></pre>

<p>You register it with your favorite DI container the same way you do in case of any other service:</p>

<pre><code class="php">return [
    DbConnectionPoolInterface::class =&gt; function(ContainerInterface $container) {
        $config = $container-&gt;get('Config');
        return new DbConnectionPool($config['db']);
    }
];
</code></pre>

<p>... and inject / use it where needed:</p>

<pre><code class="php">public function __construct(DbConnectionPoolInterface $dbConnections)
{
   $this-&gt;dbConnection = $dbConnections-&gt;get('some_database');
}
</code></pre>

<p>Additionally, you can apply <a href="https://en.wikipedia.org/wiki/Flyweight_pattern">Flyweight</a> design pattern to minimize memory usage:</p>

<pre><code class="php">final class DbConnectionPool implements DbConnectionPoolInterface
{
    private $dbConnections = []; 

    public function get(string $dbName) : DbConnectionInterface
    {
        if (!isset($this-&gt;dbConnections[$dbName]) {
            $this-&gt;dbConnections[$dbName] = new DbConnection(array_merge(
                $this-&gt;dbConfig,
                [
                    'dbname' =&gt; $dbName,
                ]
            ));
        }

        return $this-&gt;dbConnections[$dbName];
    }
}
</code></pre>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[On the wings of audience]]></title>
            <link href="https://www.nikolaposa.in.rs/blog/2017/11/11/on-the-wings-of-audience/"/>
            <updated>2017-11-11T00:00:00+01:00</updated>
            <id>https://www.nikolaposa.in.rs/blog/2017/11/11/on-the-wings-of-audience/</id>
            <content type="html"><![CDATA[<p>A while ago I blogged about <a href="/blog/2016/08/17/exceptional-behavior-best-practices/">Best practices for handling exceptional behaviour</a>, not thinking about the significance this writing could have on my career. It had a pretty good response and attracted a lot of attention, but it was just the beginning of an exciting journey...</p>

<h3 id="talk-at-a-local-user-group-meetup">Talk at a local user group meetup</h3>

<p><a href="http://phpsrbija.rs/">PHP Serbia</a> is a user group I'm a member of, known for organizing big events that bring together people not only from Serbia but also from abroad. We organize meetups on a monthly basis, and finding speakers willing to talk is often a difficult job. Last year in September, fellow member - <a href="https://twitter.com/komita1981">Milan Popović</a> called me on the phone, asking if I would be able to meet the crew responsible for meetups by being a speaker at an upcoming meetup. He liked my post about exceptional behaviour, suggesting that I could turn it into a short talk. After a lot of hesitation, I accepted the challenge, and I quickly compiled a dozen of slides to fit everything into a 30 minutes slot.</p>

<p><img src="/assets/img/posts/first-conference-talk/meetup-talk.jpg" alt="Meetup talk" class="img-responsive"></p>

<p>The talk went smoothly, and was met with a great feedback, especially from Milan, whose immediate reaction was that the quality of my presentation is almost at the level of a conference talk.</p>

<h3 id="cfp-submissions">CFP submissions</h3>

<p>Milan urged me to start submitting my talk to some major PHP conferences. I was unwilling again, but we eventually agreed to submit together, each his own proposals. It seems to me that Milan believed in my submission more than in his own.</p>

<p>Over time, I improved the title and abstract of my talk, and I eventually ended up with the catchy title of: <strong>Journey through "unhappy" path - Dealing with exceptional conditions</strong>.</p>

<p>Nevertheless, my proposals were ending with rejections, but I simply didn't care, because I wasn't optimistic about the acceptance of my proposal by any of the major conferences.</p>

<h3 id="dear-speaker%2C-welcome-to-phpce-conference%21">Dear Speaker, welcome to phpCE Conference!</h3>

<p>Just when I thought that submitting conference talks is a futile job, I received an email with the above subject. I got accepted for a <a href="https://2017.phpce.eu/">PHP Central Europe Conference 2017</a> in Poland! The initial joy and excitement soon morphed into panic, because I needed to significantly improve my presentation and enrich it with content to fill 50 minutes slot. This is going to be my first conference talk ever, and unlike with meetup, the first talk of this kind in a language other than my native Serbian language, so I have to practice it well.</p>

<p>I worked hard for two months until the very conference and took my presentation to a whole new level, which in the end was actually a rewrite rather than an improvement of the initial presentation.</p>

<p>Milan did me a great favor, by organizing trial of my talk in his company's office, in front of a handful of people that gave me very useful feedback after the talk.</p>

<h3 id="trip-to-poland">Trip to Poland</h3>

<p>Conference organizers did their best to be good hosts, and they hosted Opening Day for speakers which included tour around Warsaw. We started from the Palace of Culture and Science and visited all the major attractions of Warsaw using cool old-fashioned bus as a means of transport. I really enjoyed it, it's good to be a speaker!</p>

<p><img src="/assets/img/posts/first-conference-talk/warsaw-tour.jpg" alt="Warsaw tour" class="img-responsive"></p>

<p>After the sunset, we headed to the conference venue - Ossa Congress &amp; Spa hotel, located in the countryside about 50 kilometers away from Warsaw.</p>

<h3 id="d-day">D-Day</h3>

<p>My talk was scheduled just after the lunch, so I had enough time during the break to connect my laptop and setup hands-free microphone. With no more than 50 people in the room few minutes before my talk I though that this is going to be easy, as a spoke in front of a slightly larger auditorium at a local user group meetup.</p>

<p>Suddenly, the crowd began flooding the room and the capacity of about 400 seats has become insufficient in short time. I still don't understand exactly what happened to me right then, but with every next person entering the room, I was more and more self-confident! Zero nervousness, zero jitter. Very - strange - feeling. I never experienced something like that before. Eventually, I think the attendees were more scared of me, and not the other way around.</p>

<p>Slide after slide, my talk went smoothly, fluently, keeping the audience's attention all the time. I was done in about 40 minutes, leaving enough time for questions.</p>

<p>The large audience seemed to have a positive impact on my performance. I'm really looking forward to the video recording of my talk to see who that person really was.</p>

<p><img src="/assets/img/posts/first-conference-talk/conference-talk.jpg" alt="Conference talk" class="img-responsive"></p>

<h3 id="upshot">Upshot</h3>

<p>My first conference talk ever went better than I ever imagined it! In the end I got a round of applause that echoed hall for a few minutes. After the lecture, people came to me from all sides to congratulate me on a great performance. It felt so damn good!</p>

<p>Something that surprised not only me, but fellow speakers, too, was the amount of positive feedback I got at the <a href="https://joind.in/event/php-central-europe-conference/journey-through-unhappy-path---dealing-with-exceptional-conditions">Joind.in page of my talk</a>. At the time of writing this I have 18 reviews, all 5-star rated.</p>

<h3 id="thank-you">Thank You</h3>

<p>Big thanks to PHP CE conference organizers for giving me a chance to speak at such a huge event, next to some of the most prominent experts from the PHP community, in front of a large audience eager to learn. Massive thanks to everyone who attended my talk and gave valuable feedback on it!</p>

<p>And of course, thank you Milan for being an optimist and making me get involved in all of this. Without your support, none of this would have happened. Also thanks to everyone who helped during the talk trial.</p>

<h3 id="tips">Tips</h3>

<p>Even though I just stepped into the conference speaker career, I think I have a couple of useful tips to share:</p>

<ul>
<li><strong>believe in your words</strong> - no matter how controversial your topic is or how many people might have disagreements with your opinion, be 100% confident about what you say,</li>
<li><strong>get to know your slides</strong> - don't rely on speaker notes, learn/remember the matter of your talk and use bullet points on your slides as a reminder in order to look more convincing and natural on the stage,</li>
<li><strong>practice</strong> - in front of a mirror, in front of your friends, at the meetup, just practice, a lot.</li>
</ul>

<p>I will continue to submit proposals persistently, hoping to get a chance to transfer knowledge in some new countries and even continents. Being a conference speaker is a major step forward in the career of every developer and one of the most exciting things to experience, so get out and talk.</p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[Using DIC the right way]]></title>
            <link href="https://www.nikolaposa.in.rs/blog/2017/09/03/using-dic-the-right-way/"/>
            <updated>2017-09-03T00:00:00+02:00</updated>
            <id>https://www.nikolaposa.in.rs/blog/2017/09/03/using-dic-the-right-way/</id>
            <content type="html"><![CDATA[<p>DIC stands for Dependency Injection Container, which is a tool that manages the construction and wiring up of application services. It closely relates to the letter "D" of a SOLID acronym - <a href="https://en.wikipedia.org/wiki/Dependency_inversion_principle">Dependency Inversion Principle</a> and is employed to facilitate adhering to the principle.</p>

<p>By their nature, DI Containers are also <a href="https://en.wikipedia.org/wiki/Service_locator_pattern">Service Locator</a> implementations, design pattern that is the exact opposite to Dependency Injection. Because of that, DI Container is a double-edged sword which can mislead you if not used wisely, and ironically bring your code into a state in which there is no dependency injection at all.</p>

<h3 id="core-vs-assembly-code">Core vs Assembly code</h3>

<p>The easiest way to comprehend what is right and what is not with regard to using DI Containers is by looking at the code we write in the form of two extremely simplified and broad categories.</p>

<p>Most of today's application share similar types of code ingredients. Business logic is made up of entities, repositories, services. Depending on the interfaces application exposes and patterns used for these purposes, we find middleware, action controllers and console commands. Often there is a need for writing customizations and add-ons for lower level components such as database handlers, loggers, and similar. All this belongs to the first, dominant category that I'm gonna formulate as the <strong>core</strong>.</p>

<p>All these classes and components do not function by themselves. At some point you need to create and connect their real instances, and run them. Configuration, factory classes, construction logic, bootstrapping scripts, and application runner itself constitute our second category - a thin layer that assembles the various components of our system and eventually runs it.</p>

<p>The following diagram illustrates this division:</p>

<p><img src="/assets/img/posts/core_vs_assembly.png" alt="Core vs Assembly layer" class="img-responsive aligncenter"></p>

<p>It is understood that DI Container has its place only in the outer layer, but sometimes it still manages to reach the core. This is precisely the problem that I want to point out and raise awareness of.</p>

<h3 id="dic-must-not-leak-into-the-core">DIC must not leak into the core</h3>

<p>Ideally, the only place in the system where you refer the DI Container is that outermost part of your application, consisting of factories, configurations and bootstrapping scripts, meaning that the core stuff must not be aware of the existence of a DI Container. This may sound too idealistic, but it's actually very feasible.</p>

<p>The phenomenon of a DIC's penetration into the core actually leads to the adoption of the aforementioned Service Locator design pattern. Many consider it <a href="http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/">anti-pattern</a> for a reason. I see two major problems with doing service location within core classes, either in case of injecting service locator as a dependency, or worse, randomly pulling dependencies from a global/static service locator:</p>

<p>The two strongest arguments against this pattern that I find important are:</p>

<ul>
<li><strong>hidden dependencies</strong> - unlike a class that requires explicit dependencies via constructor injection, thus clearly shouting how it's supposed to be used, class that has a service locator as a dependency forces consumer to examine the code for calls to the locator.</li>
<li><strong>testing difficulties</strong> - having a DIC at the class entrance not only unnecessarily complicates injecting test doubles for real dependencies, but also causes DIC leakage into test code.</li>
</ul>

<h3 id="establish-the-assembly-layer">Establish the assembly layer</h3>

<p>Keeping the DIC under control is all about creating a clear boundary between the core and assembly layer and strictly adhering to a continuous process of:</p>

<ol>
<li>writing factory classes for core services</li>
<li>registering services and corresponding factories to the DI Container</li>
</ol>

<p>Having a boundary between the core and assembly code is all about separating concerns, they don't have to be separated at the filesystem level at all. That being said, there's nothing wrong with factories sitting right next to the classes for whose creation they are responsible:</p>

<pre><code class="nohighlight">src/
    Framework/
        Db/
            DbConnectionFactory.php
            DbConnectionInterface.php
            DoctrineDbConnection.php
    Post/
        Post.php
        PostRepositoryFactory.php
        PostRepositoryInterface.php
        SqlPostRepository.php
</code></pre>

<p>Typically, factory is a callable or a class implementing <code>__invoke()</code> method that gets container instance as an argument:</p>

<pre><code class="php">class PostRepositoryFactory
{
    public function __invoke(ContainerInterface $container) : PostRepositoryInterface
    {
        return new SqlPostRepository($container-&gt;get(DbConnectionInterface::class));
    }
}
</code></pre>

<p>The vast majority of popular DI Containers for PHP complies with common <a href="http://www.php-fig.org/psr/psr-11/">PSR-11</a> interface, which is a good news from the standpoint of interoperability, as you will be able to easily switch to some alternative DI Container without touching factories.</p>

<p>Depending on the DI Container of your choice, you will either initialize it (fill it with service definitions) programmatically or via configuration. I prefer the latter approach because I find it much more convenient and easier to maintain:</p>

<p><strong>config/services.global.php</strong></p>

<pre><code class="php">return [
    'di' =&gt; [
        'factories' =&gt; [
            MyApp\Framework\Db\DbConnectionInterface::class =&gt; MyApp\Framework\Db\DbConnectionFactory::class,
            MyApp\Post\PostRepositoryInterface::class =&gt; MyApp\Post\PostRepositoryFactory::class,
        ],
    ],
];
</code></pre>

<p>Initializing DI Container means loading/merging configuration and feeding container with the data from a relevant configuration key, which is <code>di</code> in this case. I'm gonna use <a href="https://github.com/zendframework/zend-servicemanager">Zend Service Manager</a> as an example:</p>

<p><strong>src/bootstrap.php</strong>
</p>

<pre><code class="php">$config = [];

$files = glob('config/{{,*.}global,{,*.}local}.php', GLOB_BRACE);

foreach ($files as $file) {
    $config = array_merge($config, include $file);
}

$config = new ArrayObject($config, ArrayObject::ARRAY_AS_PROPS);

$diContainer = new Zend\ServiceManager\ServiceManager($config['di']);
$diContainer-&gt;set('config', $config);

return $diContainer;
</code></pre>

<p></p>

<p>Everything from general purpose services (database adapter, mailer, logger, and similar), over domain services, repositories, and even application runners should be set in a DI container. That way, your application's main entry point will look as simple as:</p>

<p><strong>public/index.php</strong></p>

<pre><code class="php">/** @var \Psr\Container\ContainerInterface $container */
$container = require __DIR__ . '/../src/bootstrap.php';

$container-&gt;get(Application::class)-&gt;run();
</code></pre>

<h4 id="controllers-are-no-exception">Controllers are no exception</h4>

<p>Controllers are probably the most commonly misinterpreted elements of MVC-like PHP applications. With the arrival of new concepts and patterns, such tradition is transferred to action handlers and middleware. The most famous violation is the one for which they get the status of "fat", which is due to putting too much business logic in a class of such high level of abstraction.</p>

<p>With regard to the topic of this article, they are misused by making them DIC-aware. Just like any other service class, controller can have explicit dependencies required through their constructor, so in my mind there's no reason for them to be treated differently. You register them into dependency injection container just like any other service, meaning that depending on the specific DIC you use, you'll either write factories or rely on some "magic" mechanism for automatic injection of dependencies.</p>

<p>If you're worried that this approach might result in too many parameters in controller's constructor, that is a code smell and clear indicator that you should probably split it into few, smaller, cohesive controller classes.</p>

<h4 id="efficient-di-configurations">Efficient DI configurations</h4>

<p>As you define more and more services, especially if you follow my advice on controllers, your DI configuration can grow to the point if being bulky and difficult to maintain. Good practice of splitting big classes into smaller ones is a valid point in this case. Simply divide your single service definitions file into smaller logical units:</p>

<p><strong>config/services.global.php</strong></p>

<pre><code class="php">return [
    'di' =&gt; [
        'factories' =&gt; [
            MyApp\Framework\Db\DbConnectionInterface::class =&gt; MyApp\Framework\Db\DbConnectionFactory::class,
            MyApp\Post\PostRepositoryInterface::class =&gt; MyApp\Post\PostRepositoryFactory::class,
        ],
    ],
];
</code></pre>

<p><strong>config/web.global.php</strong></p>

<pre><code class="php">return [
    'di' =&gt; [
        'factories' =&gt; [
            MyApp\Post\Web\SubmitPostAction::class =&gt; MyApp\Post\Web\SubmitPostActionFactory::class,
            MyApp\Post\Web\ViewPostAction::class =&gt; MyApp\Post\Web\ViewPostActionFactory::class,
        ],
    ],
    'templates' =&gt; [
        'post' =&gt; 'resources/templates/post',
    ],
];
</code></pre>

<p>Doing so, not only that you will be able to organize services configuration more efficiently, but also other configuration option that relate to them.</p>

<h4 id="auto-magic-wiring-of-dependencies">Auto-magic wiring of dependencies</h4>

<p>If you find writing factories and registering services tiring and tedious activity, look for some Dependency Injection tool that reduces that effort, either through more efficient configuration-driven approach or some "magic" mechanism for automatic injection of dependencies based on type-hints. I don't believe in magic, and I prefer to keep things under control by having explicit service definitions. <a href="https://github.com/zendframework/zend-servicemanager">Zend Service Manager</a> is my weapon of choice in this case, which can further simplify DI configuration through its <a href="http://zendframework.github.io/zend-servicemanager/config-abstract-factory/">Config Abstract Factory</a> feature.</p>

<h3 id="final-thoughts">Final thoughts</h3>

<p>Dependency Injection is the crucial concept for building maintainable applications, and DI Containers facilitate this idea. If not used the right way, DIC can run wild and get out of control, so you should know how to tame it.</p>

<p>The key lesson is that DI Container should be used as Dependency Injection system, and not as a Service Locator system. Being consistent with this conviction means a discipline of keeping core services completely ignorant of their factories and the overall assembly/runtime process they are involved in. To me, Service Locator is an anti-pattern if used within the core code context. As we have seen, it is completely valid and inevitable to use it within factories and application runner scripts for example.</p>

<p>Ultimately, Dependency Injection Container is a tool, while Dependency Injection itself is a principle, and software design principles are evergreen. Let the principles dominate your code, and use the tools in an unobtrusive way.</p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[Using Monolog with Zend Service Manager]]></title>
            <link href="https://www.nikolaposa.in.rs/blog/2017/06/12/using-monolog-with-zend-service-manager/"/>
            <updated>2017-06-12T00:00:00+02:00</updated>
            <id>https://www.nikolaposa.in.rs/blog/2017/06/12/using-monolog-with-zend-service-manager/</id>
            <content type="html"><![CDATA[<p>Without any doubt, <a href="https://github.com/Seldaek/monolog">Monolog</a> and <a href="https://zendframework.github.io/zend-servicemanager/">Zend Service Manager</a> are two libraries that are almost always found in the <code>composer.json</code> file <code>require</code> section of my projects. In case you didn't know, Monolog is a <a href="http://www.php-fig.org/psr/psr-3/">PSR-3</a> compliant logging library that allows you to save logs to various storage types and web services, while Zend Service Manager is a <a href="https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-11-container.md">PSR-11</a> compliant dependency injection container and a service locator implementation that facilitates management of application dependencies.</p>

<p>In this post I'm gonna show you how the two can work together.</p>

<h3 id="configuration">Configuration</h3>

<p>Preferred way of configuring Zend Service Manager is using an associative array containing definitions of services. Typically, this configuration lives in a file, along with other configurations of your application.</p>

<p>Monolog is based on a concept of creating <code>Logger</code> instances, whereas each one is identified by a <em>channel</em> (name) and equipped with a stack of handlers. And just like a router, database handler, cache, or any other application dependency of that kind, Logger is a <strong>service</strong> that you register with the DI container and inject it into other application services.</p>

<p>Here's a basic example of a Logger service usage:</p>

<p><strong>config.php</strong></p>

<pre><code class="php">use Interop\Container\ContainerInterface;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\FirePHPHandler;
use Monolog\Logger;

return [
    'dependencies' =&gt; [
        'factories' =&gt; [
            'AppLogger' =&gt; function (ContainerInterface $container) {
                $logger = new Logger('app');

                $logger-&gt;pushHandler(new StreamHandler(__DIR__ . '/../data/log/app.log', Logger::DEBUG));
                $logger-&gt;pushHandler(new FirePHPHandler());

                return $logger;
            },
        ],
    ],
];
</code></pre>

<p><strong>index.php</strong></p>

<pre><code class="php">use Zend\ServiceManager\ServiceManager;

$config = require 'config.php';
$serviceManager = new ServiceManager($config['dependencies']);

$logger = $serviceManager-&gt;get('AppLogger');
$logger-&gt;info('Hello world');
</code></pre>

<h3 id="separate-configuration-and-object-construction-logic">Separate configuration and object construction logic</h3>

<p>While this is all that it takes to glue Monolog and Zend Service Manager together, configuration itself looks bulky and can become hard to maintain as you add more loggers. I prefer my configuration files to be light, plain PHP arrays, and keep object construction logic in separate classes. Besides a callable, Zend Service Manager also supports specifying factories as class names, so let's change our example accordingly:</p>

<p><strong>config.php</strong></p>

<pre><code class="php">return [
    'dependencies' =&gt; [
        'factories' =&gt; [
            'AppLogger' =&gt; My\AppLoggerFactory::class,
        ],
    ],
];
</code></pre>

<p><strong>AppLoggerFactory.php</strong></p>

<pre><code class="php">namespace My;

use Interop\Container\ContainerInterface;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\FirePHPHandler;
use Monolog\Logger;

class AppLoggerFactory
{
    public function __invoke(ContainerInterface $container)
    {
        $logger = new Logger('app');

        $logger-&gt;pushHandler(new StreamHandler(__DIR__ . '/../data/log/app.log', Logger::DEBUG));
        $logger-&gt;pushHandler(new FirePHPHandler());

        return $logger;
    }
}
</code></pre>

<p><strong>index.php</strong></p>

<pre><code class="php">use Zend\ServiceManager\ServiceManager;

$config = require 'config.php';
$serviceManager = new ServiceManager($config['dependencies']);

$logger = $serviceManager-&gt;get('AppLogger');
$logger-&gt;info('Hello world');
</code></pre>

<h3 id="keep-environment-specific-configuration-away-from-code">Keep environment-specific configuration away from code</h3>

<p>By solving one problem, we've introduced another one. Our code now contains something that varies between environments (development, staging, production). In this particular example it is a path to the log file (<code>data/log/app.log</code>), but this includes everything that is specific for the environment on which application is running. Things like database connection parameters, credentials for external services, and as we now know logging configuration, should not be kept in code and put under version control by any cost! Note that configuration file with real values should not be versioned neither, but only as a template, usually named <code>config.php.dist</code> by a convention.</p>

<p>Bearing all this mind, let's apply appropriate changes:</p>

<p><strong>config.php</strong></p>

<pre><code class="php">return [
    'logger' =&gt; [
        'app' =&gt; [
            'file' =&gt; __DIR__ . '/../data/log/app.log',
        ],
    ],
    'dependencies' =&gt; [
        'factories' =&gt; [
            'AppLogger' =&gt; My\AppLoggerFactory::class,
        ],
    ],
];
</code></pre>

<p><strong>AppLoggerFactory.php</strong></p>

<pre><code class="php">namespace My;

use Interop\Container\ContainerInterface;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\FirePHPHandler;
use Monolog\Logger;

class AppLoggerFactory
{
    public function __invoke(ContainerInterface $container)
    {
        $config = $container-&gt;get('Config');

        $logger = new Logger('app');

        $logger-&gt;pushHandler(new StreamHandler($config['logger']['app']['file'], Logger::DEBUG));
        $logger-&gt;pushHandler(new FirePHPHandler());

        return $logger;
    }
}
</code></pre>

<p><strong>index.php</strong></p>

<pre><code class="php">$config = require 'config.php';

$serviceManager = new ServiceManager($config['dependencies']);
$serviceManager-&gt;set('Config', $config);

$logger = $serviceManager-&gt;get('AppLogger');
$logger-&gt;info('Hello world');
</code></pre>

<p>Two things to note here:</p>

<ol>
<li>Additional service was registered with the Service Manager - <code>'Config'</code>, which holds entire configuration array.</li>
<li>Logger factory retrieves configuration from the provided Container (Service Manager) instance to obtain environment-specific logger configuration.</li>
</ol>

<h3 id="generic-logger-factory">Generic logger factory</h3>

<p>As you add more and more loggers, therefore writing more factories, you start thinking about a generic factory that can instantiate loggers based on their array-like configuration, containing handlers, formatter and processors definitions.</p>

<p>Zend Service Manager facilitates such an idea in particular by featuring a concept of <a href="https://zendframework.github.io/zend-servicemanager/configuring-the-service-manager/#mapping-multiple-service-to-the-same-factory">mapping multiple services to the same factory</a>. This was made possible through <code>$requestedName</code> that is passed as the second parameter of a factory.</p>

<p>To give you an idea of how a generic logger factory may look like:</p>

<pre><code class="php">namespace My;

use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Exception\ServiceNotFoundException;
use Zend\ServiceManager\Factory\FactoryInterface;

final class LoggerFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        $config = $container-&gt;get('Config');
        $loggerConfig = $config['logger'];

        if (! array_key_exists($requestedName, $loggerConfig)) {
            throw new ServiceNotFoundException(sprintf(
                'Configuration for "%s" is missing',
                $requestedName
            ));
        }

        return $this-&gt;createLoggerFromConfig($loggerConfig[$requestedName]);
    }

    private function createLoggerFromConfig(array $config)
    {
        // ...
    }
}
</code></pre>

<p>Configuration file becomes a lot more cleaner and readable:</p>

<pre><code class="php">return [
    'logger' =&gt; [
        'AppLogger' =&gt; [
            'name' =&gt; 'app',
            'handlers' =&gt; [
                [
                    'name' =&gt; Monolog\Handler\StreamHandler::class,
                    'options' =&gt; [
                        'stream' =&gt; __DIR__ . '/../data/log/app.log',
                        'level' =&gt; Monolog\Logger::INFO,
                    ],
                ],
                [
                    'name' =&gt; Monolog\Handler\FirePHPHandler::class,
                ],
            ],
        ],
        'NotificationsLogger' =&gt; [
            'name' =&gt; 'notifications',
            [
                'name' =&gt; Monolog\Handler\LogglyHandler::class,
                'options' =&gt; [
                    'token' =&gt; '123',
                ],
            ],
        ],
    ],
    'dependencies' =&gt; [
        'factories' =&gt; [
            'AppLogger' =&gt; My\LoggerFactory::class,
            'NotificationsLogger' =&gt; My\LoggerFactory::class,
        ],
    ],
];
</code></pre>

<h3 id="monolog-factory">Monolog Factory</h3>

<p>After repeating these things through projects, I eventually wrote a generic logger factory whose essence I've omitted in the previous example, with the aim of letting you know at this point that I've made <a href="https://github.com/nikolaposa/monolog-factory">Monolog Factory</a> - library that facilitates creation of Monolog logger objects in both generic and container-interop contexts. It works nicely with Zend Service Manager, but also any other PSR-11 compliant dependency injection container.</p>
]]></content>
        </entry>
    </feed>