Familiarity Bias is Holding You Back: It’s Time to Embrace Arrow Functions

I don't think that less lines of code automatically means code is more readable, but I'm a big fan of ES6' arrow functions. In this article Eric Elliott dives deep into them.
I also supect that your team would become significantly more productive if you learned to embrace and favor more of the concise syntax available in ES6. While it’s true that sometimes things are easier to understand if they’re made explicit, it’s also true that as a general rule, less code is better. If less code can accomplish the same thing and communicate more, without sacrificing any meaning, it’s objectively better.
https://medium.com/javascript-scene/familiarity-bias-is-holding-you-back-its-time-to-embrace-arrow-functions-3d37e1a9bb75 Let's hope we'll soon have array functions in PHP too.

Making overloaded functions readable

Sometimes you might allow a function to accept multiple data types. I don't know for certain if it's the correct term but for the remainder of this post I'm going to call such a function overloaded. In this post I'd like to show you a little trick to make overloaded functions more readable. Let's first take a look at a function in Laravel that accepts multiple data types. To store something in a session you can pass a key and value to the session helper:
session($key, $value);
But you can also give it an array:
session(['key' => 'value']);
Now behind the scenes Laravel is calling a put function. It could have been implemented like this:
public function put($key, $value = null)
{
    if (is_array($key)) {
       foreach ($key as $arrayKey => $arrayValue) {
           $this->set($arrayKey, $arrayValue);
       }
    }
    else {
       $this->set($key, $value);
    }
}
In the function above there's a path for doing the work if an array was passed and another path for when (hopefully) a string was passed. The actual implementation is a bit different (and much better):
public function put($key, $value = null)
{
    if (! is_array($key)) {
        $key = [$key => $value];
    }

    foreach ($key as $arrayKey => $arrayValue) {
        $this->set($arrayKey, $arrayValue);
    }
}
The cool thing to note is that what the function first converts the passed arguments to a certain format (in this case an array) and then perform the work on the format. The actual work, the call to $this->set is only coded up once. When reading the source code of Laravel you'll often come across this pattern. Let's take a look at another real life example to make the benefit of this pattern more clear. This next snippet is taken from a recent PR to the laravel-permission package. It aims to a add a query scope to a User model to perform the query only on users that have the given role(s). Roles can be passed through as an array, a string or an instance of Role.
/**
 * Scope the user query to certain roles only.
 *
 * @param string|array|Role|\Illuminate\Support\Collection $roles
 *
 * @return bool
 */
public function scopeRole($query, $roles)
{
    if (is_string($roles)) {
        return $query->whereHas('roles', function ($query) use ($roles) {
            $query->where('name', $roles);
        });
    }

    if ($roles instanceof Role) {
        return $query->whereHas('roles', function ($query) use ($roles) {
            $query->where('id', $roles->id);
        });
    }

    if (is_array($roles)) {
        return $query->whereHas('roles', function ($query) use ($roles) {
            $query->where(function ($query) use ($roles) {
                foreach ($roles as $role) {
                    if (is_string($role)) {
                        $query->orWhere('name', $role);
                    }

                    if ($role instanceof Role) {
                        $query->orWhere('id', $role->id);
                    }
                }
            });
        });
    }

    return $query;
}
The query is being build up in a few different ways depending on the type of the argument being passed through. The readability of this code can vastly be improved by:
  • first converting all arguments to a single format to work with
  • performing the work on that format
public function scopeRole($query, $roles)
{
    if ($roles instanceof Collection) {
        $roles = $roles->toArray();
    }

    if (! is_array($roles)) {
        $roles = [$roles];
    }

    $roles = array_map(function ($role) {
        if ($role instanceof Role) {
            return $role;
        }

        return app(Role::class)->findByName($role);
    }, $roles);

    return $query->whereHas('roles', function ($query) use ($roles) {
        $query->where(function ($query) use ($roles) {
            foreach ($roles as $role) {
                $query->orWhere('id', $role->id);
            }
        });
    });
}
In the snippet above all input, no matter what type is being passed through, is first converted to an array with Role objects. U sing that array the query is only being build up once. I should mention that the author of the PR did provide a good set of tests so it was very easy to refactor the code. Let's do one more example. This one's taken from our laravel-fractal package which aims to make working with Fractal more developer friendly. To return a response with json data you can to this in a Laravel app.
$books = fractal($books, new BookTransformer())->toArray();

return response()->json($books);
In the last version of our package a respond() method was added. Here's the equivalent code using the respond method.
return fractal($books, new BookTransformer())->respond();
You can pass a response code as the first parameter and optionally some headers as the second
return fractal($books, new BookTransformer())->respond(403, [
    'a-header' => 'a value',
    'another-header' => 'another value',
]);
You can also set the status code and the headers using a callback:
use Illuminate\Http\JsonResponse;

return fractal($books, new BookTransformer())->respond(function(JsonResponse $response) {
    $response
        ->setStatusCode(403)
        ->header('a-header', 'a value')
        ->withHeaders([
            'another-header' => 'another value',
            'yet-another-header' => 'yet another value',
        ]);
});
This is original code for the function that was submitted through a PR (slightly redacted):
public function respond($callbackOrStatusCode = 200, $callbackOrHeaders = [])
{
    $response = new JsonResponse();

    $response->setData($this->createData()->toArray());

    if (is_callable($callbackOrStatusCode)) {
        $callbackOrStatusCode($response);
    } else {
        $response->code($callbackOrStatusCode);

        if (is_callable($callbackOrHeaders)) {
            $callbackOrHeaders($response);
        } else {
            $response->withHeaders($callbackOrHeaders);
        }
    }

    return $response;
}
Sure, that code does the job. Unfortunately the real work (in this case: modifying $response) is done all over the place. Let's refactor! In the code below we're going to convert all input to callables first and then use them to modify $response.
public function respond($statusCode = 200, $headers = [])
{
    $response = new JsonResponse();

    $response->setData($this->createData()->toArray());

    if (is_int($statusCode)) {
        $statusCode = function (JsonResponse $response) use ($statusCode) {
            return $response->setStatusCode($statusCode);
        };
    }

    if (is_array($headers)) {
        $headers = function (JsonResponse $response) use ($headers) {
            return $response->withHeaders($headers);
        };
    }

    if (is_callable($statusCode)) {
        $statusCode($response);
    }

    if (is_callable($headers)) {
        $headers($response);
    }

    return $response;
}
Hopefully you can use this neat little trick to improve the readability of your code as well.

When are single-character variable names acceptable?

Generally I don't like to abbreviate variable names. This answer on Quora lists a few situations where an abbreviation is probably ok.
There is a simple (but unsatisfying) answer to all questions of this form: they are acceptable when they would make the code clearer. This can happen in a few ways. The most common, as you noted, is convention: i, j, k for loop variables, x and y for coordinates, e for exceptions, f and g for functions and so on. Another is structure. Often, the broad structure of an expression is more important than its contents. Using shorter variable names makes it easier to read at a glance. I think this is often more important than being easy to read in detail! If a variable has a very small scope—say one or two lines at most—and it's easy to see where it comes from, having a long name is just noise.
https://www.quora.com/When-are-single-character-variable-names-acceptable/answer/Tikhon-Jelvis

Improving readability using array_filter

In this post I'd like to share a quick tip on how you can improve the readability of your code with array_filter. Today I was working on some code that looked something like this:
class Address
{
    ...

    public function toArray()
    {
        $address = [
            'name' => $this->name,
            'street' => $this->street,
            'location' => $this->location,
        ];

        if ($this->line2 != '') {
            $address['line2'] = $this->line2;
        }

        if ($this->busNumber != '') {
            $address['busNumber'] = $this->busNumber;
        }

        if ($this->country != '') {
            $address['country'] = $this->country;
        }


        return $address;
    }
}
Did you know that you can use array_filter to clean this up? I didn't, until today. When that function is called without a second argument it will remove any element that contains a falsy value (so null, or an empty string) Here's the refactored, equivalent code:
class Address
{
    ...

    public function toArray()
    {
        return array_filter([
            'name' => $this->name,
            'street' => $this->street,
            'line2' => $this->line2,
            'busNumber' => $this->busNumber,
            'location' => $this->location,
            'country' => $this->country,
        ]);
    }
}
That's much better! Just be careful when using this with numeric data that you want to keep in the array. 0 is considered as a falsy value too, so it'll be removed as well.

Using collection macros in Laravel

Laravel 5.2 provides some nice additions to the framework. One handy feature that I don't see listed in the release notes is that Collection now is macroable.  Using it's macro function you can easily extend Illuminate\Support\Collection with your own custom functions. Take a look at this piece of code to uppercase every string in a collection.
$uppercaseWords = collect(['code', 'ferengi'])->map(function($word)  {
   return strtoupper($word);
});
That's good code, but image you need to uppercase a lot of collections. Typing the same closure will get very tiresome. Let's improve this with a macro.
use Illuminate\Support\Collection;

Collection::macro('uppercase', function() {

    return collect($this->items)->map(function($word) {
        return strtoupper($word);
    });

});
You could create a service provider to load up these macro's. Now that the macro is defined let's uppercase collections like there's no tomorrow:
$uppercaseWords = collect(['code', 'ferengi'])->uppercase();
$moreUppercaseWords = collect(['love', 'the', 'facade'])->uppercase();
$evenMoreUppercaseWords = collect(['activerecord', 'forever'])->uppercase();
You could be thinking "Why should I use a macro? I can easily to this with a regular function.". Consider this piece of code.
function uppercase($collection) {
...
}

$uppercaseWords = uppercase(collect(['halo','five']));
It works, but you have to encapsulate the collection with your function. The last executed function is put first, which is confusing. With macro's you can still chain functions and greatly improve readability.
//lots of functions
function4(function3(function2(function1(collect(['jack','cheats'])))));

//lots of macros
collect(['i', 'want', 'to', 'live', 'in', 'a', 'desert'])
  ->function1()
  ->function2()
  ->function3()
  ->function4();
Sure, the examples use in this post were a bit contrived, but I hope you see that collection macro's can be very handy. EDIT: it seems that collection macro's were introduced in Laravel 5.1.25 a month ago.

Making call_user_func_array more readable

There's a lot PHP 7 love going around these days, but PHP 5.6 has it's fair share of nice features too. One of those features is the splat operator. It looks like this: .... The splat operator can capture a variable number of arguments.
function logThis(...$messages)
{
    foreach ($messages as $message) {
        echo $message.PHP_EOL;
    }
}

logThis('one', 'two', 'three');
You can still use regular arguments as well:
function logThis($firstMessage, ...$otherMessages)
{
    echo "superimportant: {$firstMessage}".PHP_EOL;

    foreach ($otherMessages as $message) {
        echo $message.PHP_EOL;
    }
}

logThis('one', 'two', 'three');
Another usage for the splat operator is argument unpacking:
$messages[] = "one";
$messages[] = "two";
$messages[] = "three";

logThis(...$messages);
The operator can also help replacing usages of call_user_func_array to something more readable. Consider this contrived example where all calls to a class are forwarded to a dependency.
class ClassA
{
    protected $classB;

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

    public function __call($method, $args)
    {
        call_user_func_array([$this->classB, $method], $args);
    }
}
Using this splat operator this can be rewritten to:
class ClassA
{
    protected $classB;

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

    public function __call($method, $args)
    {
        $this->classB->$method(...$args);
    }
}
Do you know some other cool usage of the operator? Let me know in the comments below.

Making string concatenation readable in PHP

Probably all PHP developers know how to concatenate strings. The most popular method is using the .-operator.  For small concatenations using this operator works fine. When lots of strings or variables need to be combined it can become cumbersome. Here's an example: $logMessage = 'A '.$user->type.' with e-mailaddress '.$user->email.' has performed '.$action.' on '.$subject.'.'; Wow, my fingers hurt... While typing the most time is spent on making sure the quotes are open and closed on the right places. It also isn't very readable. Especially the .'.' at the end make my eyes bleed. A better way to create the string is to use the sprintf-function. This example produces the same string as the code above: $logMessage = sprintf('A %s with email %s has performed %s on %s.', $user->type, $user->email, $action, $subject); That's much better. This is much easier to type and you don't have to pay attention to opening an closing quotes. But my eyes still need to do a lot of work. To find out which string goes in which %s-placeholder you have to switch watching the beginning and end of the line of code. There is another option to concatenate strings. It uses curly braces. Let's take a look: $logMessage = "A {$user->type} with e-mailaddress {$user->email} has performed {$action} on {$subject}." In my mind this is much better. This option has the least amount of characters to type. Your eyes can just read the line of code from left to right to understand what's going on. Keep in mind that this only works when using the curly braces between a double quote. The first character after the opening curly braces should be a dollar-sign. EDIT: The curly braces syntax works well if you only need to concatenate strings. As mentioned in the comments below this post, sprintf might be a better fit when concatenating some other type of variable.