Strongly Typed PHP - Revisited

May 22, 2016 by PHP  

Almost a decade ago I wrote a post about strongly typed PHP, in which I proposed a very crude workaround, essentially faking strong typing using magic methods. The post was met with a lot of mixed reactions, but received quite a lot of visitors over the years (definitely some interest in the subject).

PHP won't ever (dare I say) become a strongly typed language, but I do believe that in the near future it will become a gradually typed language (like TypeScript).

Which basically means we can statically declare all member types if we want to, but we're not forced to (type declaration is optional).

Now recently (with the great coming of PHP 7.x), developers introduced scalar type declaration, thereby making it possible to type hint (declare) the four scalar types (bool, int, float, string) on function arguments as well (type hints used to be limited to objects, arrays and callables), additionally return type declarations were also introduced.

class Person
{
	private $age;
	public function __construct(int $age) {
		$this->age = $age;
	}
	public function getAge() : int {
		return $this->age;
	}
}

Good stuff, but. there are however a few caveats to be aware of.

Observe the following instances.

$a = new Person(33);
$b = new Person(33.4);
$c = new Person(33.6); 
$d = new Person("33");
$e = new Person("33a"); Warning displayed - A non well formed numeric value encountered
$f = new Person("a"); throws TypeError - must be of the type integer

Keeping with the extremely relaxed weakly typed system in PHP, the first five instances will accept and convert the arguments passed to the constructor. $b and $c will floor the passed float arguments, while $d simply converts the passed string to an integer.

Instance $e, will warn that the passed value is "non well formed", but will convert it regardless to 33, also consistent with what we've learned to expect from PHP.

It is however possible to apply a more strict set of rules to the passed arguments by adding the following code to your script.

declare(strict_types=1);

The script will fail when it reaches instance $b, by throwing a TypeError - must be of the type integer, float given, which is more consistent with what we expect in languages like C# for example.

  • The switch will affect return type declarations as well.
  • The switch doesn't affect included code, but needs to be added to the external files that require strict_levels as well.
Personally (as you might expect by now), I am a strongly typed kind of guy, I am however a little bit concerned about how this switch might affect the portability of scripts (almost like magic quotes all over again), but that said, I didn't run into any weird unexpected behavior yet.

PHP RFC Council


The only part still missing from this equation (making PHP gradually typed) is the ability to declare property types, this has however been proposed in a recent draft document.

class Person
{
	public int $Age; // Not possible yet
}


Like you might have noticed, I finally got around to playing around with the latest version of PHP (7.0.6 at the time of writing this post). I am planning to do  did a little write-up of some of the new features just to get everybody (and myself for that matter) up to speed.


Leave a Comment