Two problems in PHP projects

Artem Zakirullin
3 min readJul 20, 2020

--

Array in PHP is akin to the Swiss Army Knife, it has a lot to offer: a queue, stack, list, hash table.
The latter is rather unwanted — spread all over the system, it can bring a pain in the ass.

Type casting is also a trouble — it’s not as obvious as we want it to be. Have you learned all those tricky (bool)'on' => true or (string)false => ''? I bet you haven’t. And there’s no need to.

That being said, let’s get to the point.

Associative arrays

Arrays. Arrays are everywhere. And nobody looks after their invariants.
Once you let your associative arrays (with string keys) travel through the code, you’re in trouble. They don’t have contracts — in fact, they are just raw data with no interface whatsoever. Client-side would always have to guess what’s inside.

To get rid of all that mess, we should come up (and we hopefully do!) with a ValueObject (which is the invariants guarantee).
No matter where an array comes from (request/response/config/options), we would like to build a ValueObject (DTO might also be an option).

Let’s imagine we’re getting some information about a book from some 3rd party API.
We would end up with a ValueObject like this:

Way too verbose. It is preferable to use predicate-like statements (and asserts).
For that purpose, there’s a small naive package called TypedAccessor:

A few exceptions can be thrown during the building process, that can be properly handled in one place.
No need to let the raw data (which is what associative array is) travel all around the system.

Still, sometimes we would like to use plain arrays, e.g. for maps or lists. There are getListOfInt() and getListOfString() methods for that.

The problem is solved! Without further ado, let’s dive into the second one.

Type casting

Let’s imagine we’re building a library that’s configured this way:

Our library initialization:

For now, it seems to be all good. But it’s not.
Let’s look at some client-side code:

No matter if that’s a misuse or the result of breaking changes — bad things tend to happen, from time to time.
The worst thing about the code above is, our library continues to work. Though not in a way it was supposed to work, from the client-side perspective.

PHP tries to do its best to make it work, at least somehow.

TypedAccessor on the other hand, has a rather stupid type casting system:

'\d+' => int // OK
'buzz12' => int // UncastableValueException
bool => int // UncastableValueException
array => int // UncastableValueException
object => int // UncastableValueException
resource => int // UncastableValueException

We want type casting to be simple and predictable (with no “cast at least somehow” mantra).

So now we have the solution for the second issue as well.
Two problems solved, one tiny package created. Grab it here and make your code more stable and safe.

PRs are welcome 🚀!

--

--