PHP 7: Type-safe Arrays of Objects

With PHP 7 you can choose to write much more type-safe code than before, thanks to scalar type hints and return types.

function repeat(string $text, int $times) : string;

But what about arrays? There’s still only the generic “array” type hint, you cannot specify what’s in the array. For the IDE, you can add PhpDoc comments:

/**
 * @return User[]
 */
function allUsers() : array;

Now IDEs like PhpStorm can help with code completion for items in the returned array. But we cannot benefit from any checks at runtime, like with real type hints.

For arguments, there is a partial workaround, using variadic arguments. Take the following function

/**
 * @param User[] $users
 */
function deleteUsers(array $users);

With variadic arguments we can rewrite it to

function deleteUsers(User ...$users);

Usage also changes, to deleteUsers(...$users); In this call, the argument $users will be “unpacked” into single variables, and in the method itself “packed” back into an array $users. Each item is validated to be of type User. $users can also be an iterator, it will be converted to an array.

Unfortunately there is no similar workaround for return types, and it only works for the last argument.

See also: Type hinting in PHP 7 – array of objects

I’ve used this technique a lot in PHP 7 code, but I’ve found another one that’s even better and does not come with the mentioned flaws:
Continue reading “PHP 7: Type-safe Arrays of Objects”

Collection Pipelines in PHP

If you read the book “Refactoring to Collections” or saw screencasts and talks by Adam Wathan about collection pipelines, but do not work with Laravel, you might have asked yourself how to apply these techniques to other PHP applications, for example Magento.

If you did not, let me explain collection pipelines first. Better, I’ll let Martin Fowler give the definition:

A collection pipeline lays out a sequence of operations that pass a collection of items between them. Each operation takes a collection as an input and emits another collection (except the last operation, which may be a terminal that emits a single value). The individual operations are simple, but you can create complex behavior by stringing together the various operations, much as you might plug pipes together in the physical world, hence the pipeline metaphor.

Continue reading “Collection Pipelines in PHP”

Memoize Method Calls in PHP with Cache Decorators

A “memoized” function is a function that only calculates the return value for each combination of arguments once and returns the previously calculated value if the function is called a second time with the same arguments.

In PHP, I often see this implemented with code like this:

class ProductRepository implements ProductRepositoryInterface
{
    private $products = [];
    public function product($id)
    {
        if (! isset($this->products[$id])) {
            $this->products[$id] = $this->load($id);
        }
        return $this->products[$id];
    }

    private function load($id) { ... }
}

Continue reading “Memoize Method Calls in PHP with Cache Decorators”

The week on StackExchange #12 / 2016

Here’s the next update, this time only with new, hopefully interesting answers on Magento StackExchange.

Magento 2

Magento 1

Design Patterns for Framework Agnostic Extensions/Plugins – Autoloading

Part 5 of my blog series on integer-net.com about framework independent code is out: Using Advanced Autoloading. This one is only relevant for the integration of legacy applications that do not use composer autoloading yet (Magento 1).

Previous Parts

  1. Introduction: Shared Code For Magento 1 and Magento 2 Extensions
  2. Accessing Configuration Data
  3. Using Dependency Injection
  4. Building Bridges
  5. Preparing Data For Output

The week on StackExchange #9 / 2016

I’ll try a new weekly format on the blog with a summary of recent questions and answers from StackExchange, all around PHP and Magento. Let’s see how it works out and start right away:

New Answers

Open questions

In the next week there is more to come on the topic of Magento 2, since I am just starting to get deeper into it.