Sarfraz AhmedFrom Bad to Good: DI, DIC and Services (28.8.2016, 09:37 UTC)

In this post, I intend to touch the concepts of:

Even though these terms seems scary at first especially to new-comers but are really easy to understand and help write quality code that is easy to understand and extend. We will take a ^legacy code^ and convert it into object-oriented one by using these principles.

Suppose we have simple application that sends newsletter email to all its subscribers, here is the legacy code:

// file: index.php or could also be considered as Controller file in MVC paradigm

require __DIR__ . 'vendor/autoload.php';

use Demo\Mailer\SmtpMailer;

$dsn = 'sqlite:' . __DIR__ . 'database.sqlite';
$pdo = new PDO($dsn);

$mailer = new SmtpMailer('smtp.example.com', 'user', 'password', '465');

$sql = 'SELECT * from subscribers';

foreach ($pdo->query($sql) as $row) {
    $mailer->sendMessage(
        $row['email'],
        'This is the email body',
        $row['name'],
        'info@example.com'
    );
}

Right now above code smells and has these problems:

  • Logic is mixed up, SQL queries, sending emails database configuration is all in one file

To fix this, first instinct is to convert it into class:

class SubscriberMailer
{
    public function sendEmails()
    {
        $dsn = 'sqlite:' . __DIR__ . 'database.sqlite';
        $pdo = new PDO($dsn);

        $mailer = new SmtpMailer('smtp.example.com', 'user', 'password', '465');

        $sql = 'SELECT * from subscribers';

        foreach ($pdo->query($sql) as $row) {
            $mailer->sendMessage(
                $row['email'],
                'This is the email body',
                $row['name'],
                'info@example.com'
            );
        }
    }
}

This looks good to eye but it has more problems:

  • Logic is still mixed up, SQL queries, sending emails database configuration is all in one file
  • It has hard-coded dependencies (tight-coupling) on PDO and Mailer class, what if we wanted to change Mailer class ?
  • It is hard to unit-test because of tight coupling

Let's try to fix these problems. We can see that this class has dependency on PDO so instead of hard-coding it inside SubscriberMailer class, we can ^pass^ it via its constructor which now makes the class:

class SubscriberMailer
{
    protected $pdo = null;

    public function __construct($pdo)
    {
        $this->pdo = $pdo;
    }

    public function sendEmails()
    {
        $mailer = new SmtpMailer('smtp.example.com', 'user', 'password', '465');

        $sql = 'SELECT * from subscribers';

        foreach ($this->pdo->query($sql) as $row) {
            $mailer->sendMessage(
                $row['email'],
                'This is the email body',
                $row['name'],
                'info@example.com'
            );
        }
    }
}

This is a bit better, the class doesn't care where PDO objects comes from, it just needs one to operate and you can't instantiate the class without providing one so it makes its intention clear. So this is what is called Dependency Injection, no need to fear even though the term sounded scary initially (read my previous article on more ways of injecting dependencies). Here is how we use above class at this point of the time:

require __DIR__ . 'vendor/autoload.php';

use Demo\Mailer\SmtpMailer;
use Demo\Mailer\SubscriberMailer;

$dsn = 'sqlite:' . __DIR__ . 'database.sqlite';
$pdo = new PDO($dsn);

$subscriberMailer = new SubscriberMailer($pdo);
$subscriberMailer->sendEmails();

This is starting to look better compared to first snippet of code. However, we still have a problem in that we have hard-coded smtp config into our class, what if we wanted to change the smtp config without touching the class ? Or what if we had different setup of smtp config for development and production ? Remember a class should be a black-box which simply does its job without editing it again and again, you can only extend it not edit it. So this reasoning hints us that like pdo, we should also pass smtp config via class's constructor and move it from the class itself.

class SubscriberMailer
{
    protected $pdo = null;
    protected $smtpConfig = [];

    public function __construct($pdo, array $smtpConfig)
    {
        $this->pdo = $pdo;
        $this->smtpConfig = $smtpConfig;
    }

    public function sendEmails()
    {
        $mailer = new SmtpMailer(
            $this->smtpConfig['host'],
            $this->smtpConfig['user'],
            $this

Truncated by Planet PHP, read more at the original (another 10978 bytes)

Link
SitePoint PHPLocal Composer for Everyone! A Conference-Friendly Satis Setup (27.8.2016, 16:00 UTC)

While preparing my technical materials for WebSummerCamp, I realized my workshop would rely on a fairly stable internet connection, as we'd have a lot of ground to cover and a lot of packages to install. Rather than rely on the gods of live demos, or pre-installing everything and ruining the experience, I picked another route.

In this post, I'll show you how to set up a local Satis instance and have it host the packages over the network it's currently on, so that everyone who's also connected to it can put the address into composer.json as a custom repository source, and retrieve all packages from your machine locally - no internet connection required!

Composer logo with deal with it sunglasses

Prerequisites

Due to a habit of never installing programming-related software on my main OS (more about that here), I'm using Homestead Improved, as usual. If you have a working PHP installation on your host machine, or prefer Docker or something similar, please feel free to use that. Note, however, that for the sake of cross-platform friendliness and simplicity, this tutorial will be Homestead Improved-specific.

Before booting up the VM, make sure you share an arbitrary port. This can be done by editing the bottom section of Homestead.yaml. I picked 6789, so that my local "packagist" will be hosted on IP:6789 where IP will be the IP address of my host machine.

Satis

Inside the VM, in an arbitrary location of your choice (I picked /home/vagrant/Code/) install a new Satis project with:

composer create-project composer/satis --stability=dev --keep-vcs

This will create the subfolder satis.

Continue reading %Local Composer for Everyone! A Conference-Friendly Satis Setup%

Link
SitePoint PHPHow to Create a Pokemon Spawn Locations Recorder with CouchDB (26.8.2016, 16:00 UTC)

In a previous article, you’ve been introduced to CouchDB. This time, you’re going to create a full-fledged app where you can apply the things you learned. You’re also going to learn how to secure your database at the end of the tutorial. Overview of the Project You’re going to build a Pokemon spawn locations recorder. […]

Continue reading %How to Create a Pokemon Spawn Locations Recorder with CouchDB%

Link
Voices of the ElePHPantInterview with Brian Retterer (26.8.2016, 09:00 UTC) Link
PHP ClassesPHP and JavaScript Innovation Award Report August 2016 Edition - May 2016 nominees (26.8.2016, 06:09 UTC)
By Manuel Lemos
This is the August edition of the Innovation Award podcast hangout recorded by Manuel Lemos and Arturs Sosins to comment on the outstanding features of all the past month nominees and winners PHP and JavaScript packages, the prizes that the authors earned, starting with the nominees from the month of May 2016.

Listen to the podcast, or watch the hangout video to learn why the nominated packages were considered to be innovative, as well the current rankings of the Innovation Award Championship by author and by country.
Link
Anna FilinaMySQL Duplicate Entry, But Not Really (25.8.2016, 21:08 UTC)

I chased an interesting bug today. MySQL was complaining about “Integrity constraint violation: 1062 Duplicate entry”. I had all the necessary safeguards in my code to prevent duplicates in tha column.

I gave up on logic and simply dumped the contents of the problematic column for every record. I found that there was a record with and without an accent on one of the characters. PHP saw each as a unique value, but MySQL did not make a distinction, which is why it complained about a duplicate value. It’s a good thing too, because based on my goal, these should have been treated as duplicates.

My solution was to substitute accented characters before filtering duplicates in the code. This way, similar records were rejected before they were sent to the database.

Happy coding!

[Edit 2016-08-26] As pointed out in the comments, a more robust and versatile solution would be to check the collation on the column. Thanks!

Link
PHP ClassesNotable PHP package: PHP Builder Pattern Generator (25.8.2016, 06:33 UTC)
By Manuel Lemos
The builder design pattern allows to dynamically create objects in a way that the same process of construction can allow multiple representations of the object that can be changed over time according to the needs of a project.

This package implements the builder design pattern with a concrete builder class that generates code for classes dynamically to implement a representation of the object class being built at run time.

Read this article to learn more details about how this notable PHP package works.
Link
Nomad PHPBug Hunting with Git Bisect (24.8.2016, 20:04 UTC)

Speaker: Alessandro Lai @AlessandroLai Bugs are introduced in our code almost everyday, one way or another, even if we do our best to avoid it. Often, we need to identify where a bug originated to fix it, but we have to sift through a long history of commits to do that. Git comes to the …

The post Bug Hunting with Git Bisect appeared first on Nomad PHP.

Link
PHP ClassesFast PHP Error Monitoring and Bug Fixing with Rollbar (24.8.2016, 05:37 UTC)
By Samuel Adeshina
Regardless of how good you are as a developer, you will always ship code to production that will have bugs or does not deal with situations that were unanticipated.

Therefore you always need to have a tool that can monitor the errors on the server side, so you can act promptly and fix issues as quickly as possible.

Read this tutorial to learn how you can use Rollbar to keep track of your PHP Web applications issues.
Link
Anna FilinaConFoo Montreal 2017 Calling for Papers (23.8.2016, 17:16 UTC)

ConFoo | March 8-10, 2017 | Montreal, CanadaWant to get your web development ideas in front of a live audience? The call for papers for the ConFoo Montreal 2017 web developer conference is open! If you have a burning desire to hold forth about PHP, Java, Ruby, Python, or any other web development topics, we want to see your proposals. The window is open only from August 21 to September 20, 2016, so hurry. An added benefit: If your proposal is selected and you live outside of the Montreal area, we will cover your travel and hotel.

You’ll have 45 minutes to wow the crowd, with 35 minutes for your topic and 10 minutes for Q&A. We can’t wait to see your proposals. Knock us out!

ConFoo Montreal will be held on March 8-10, 2017. For those of you who already know about our conference, be aware that this annual tradition will still be running in addition to ConFoo Vancouver. Visit our site to learn more about both events.

Link
LinksRSS 0.92   RDF 1.
Atom Feed   100% Popoon
PHP5 powered   PEAR
ButtonsPlanet PHP   Planet PHP
Planet PHP