Typed PHP, Stronger Types for Cleaner Code (2014)
Design
How To Structure The Types
We’ve already decided to use namespaced functions as the basis, so we need to decide how to use these from within classes.
Resolving Types
We’ll often need to resolve types, within the type methods. Any arguments could potentially be the wrong type. It makes sense for the type resolution/conversion functions to be in their own namespace:
· Type\isString
· Type\isStringObject
· Type\isExpression
· …
· Type\toStringObject
· Type\toExpression
· …
We should proxy to the creation methods:
1 class StringObject extends SPLString
2 {
3 public function trim($mask = "\t\n\r\0\x0B")
4 {
5 $isString = Type\isString($mask);
6 $isStringObject = Type\isStringObject($mask);
7
8 if ($isString or $isStringObject) {
9 if (Type\isExpression($mask)) {
10 $raw = Type\String\trimWithExpression(
11 $this,
12 $mask
13 );
14 } else {
15 $raw = Type\String\trimWithString(
16 $this,
17 $mask
18 );
19 }
20
21 return Type\toStringObject($raw);
22 }
23
24 throw new LogicException("mask is not a string");
25 }
26 }
Chaining
One of the benefits of the object-oriented approach we’re taking is that we can chain calls on the types. You may have noticed how this is implemented (from the previous example), but in-case you didn’t:
1 return Type\toStringObject($raw);
The manipulation methods should return plain PHP types - because we want people to be able to use the types interchangeably. So it falls to the classes (proxies) to wrap plain PHP types within the SPL Types.
Combining Number Types
I’ve already alluded to my desire of a single number type, and that’s exactly what I want to achieve here. For that reason, we’ll completely ignore the SPLNumber class in favour of SPLFloat.
The reason is simple - numbers should be able to handle decimal points, without a separate set of methods or additional mental overhead. This will lead to additional casting in numeric operations, but that’s not the end of the world.