PHP and Variable Types

We’ve all heard that PHP is “weak” or “loosely” typed, meaning that it doesn’t require you to explicitly specify the type of a variable. This makes programming easier/quicker but it can bite back.

We’ve all heard that PHP is “weak” or “loosely” typed, meaning that it doesn’t require you to explicitly specify the type of a variable.

Consider the following code:

<?php
declare(strict_types=1);

$a = 10;
echo '$a == ' . $a . " and it is a type of " . gettype($a) . "\n";

$a += 1.5;
echo '$a == ' . $a . " and it is a type of " . gettype($a) . "\n";

$a = "test";
echo '$a == ' . $a . " and it is a type of " . gettype($a) . "\n";

$a = 10;
echo '$a == ' . $a . " and it is a type of " . gettype($a) . "\n";

The output of this is:

kenn@alpha:~/source/test$ php test.php
$a == 10 and it is a type of integer
$a == 11.5 and it is a type of double
$a == test and it is a type of string
$a == 10 and it is a type of integer

The variable $a starts as an integer because it is assigned an integer value. When I add a non-integer to it, it becomes a double. I immediately assign text to the “double” and it accepts the value and morphs into a string. Finally, I assign an integer value to the “string” and it’s back to being an integer.

This makes programming easier/quicker but it can bite back. Imagine a larger program that multiple people work on regularly. If, say, I pull the code and don’t notice that the program is already using $a, I might use it myself. PHP will not only let me re-declare it but will let me retype it. No errors are thrown until the code blows up somewhere else – at runtime – when a$ doesn’t have what the previous programmer was expecting.

Problems such as this can be mitigated by avoiding global variables and keeping functions short, but I can see why developers might find this objectionable.

Meanwhile in GoLand

Go will also let you declare variables on the fly. Take the following example:

package main

import "fmt"

func add(x int, y int) int {
    return x + y
}

func main() {
    a := 10
    b := 20

    c := add(a, b)
    fmt.Println(c)
}

The variables a and b are assigned integer values and therefore they become integers. c accepts the integer return value from the add() function and it becomes an integer too.

Subsequent attempts to use variables as types inconsistent with how they were instantiated refuse to compile:

Note also that, in Go syntax, var := "value" is the notation used for defining variables on the fly. Thus when I wanted to change the value of c, I used c = 45. Had I thought that c was new and tried to define it as such, that too would have given an error at compile time:

It was in being reminded of these things that led me to compare with PHP.

But does it really matter?

Actually, yes, I think it does. Thinking back on past projects that I’ve written in Go, I recall – many times – trying to declare a variable on the fly (i.e., using :=) and being told by GoLand that it was already declared. And I remember the opposite happening more than once as well.

What that means is, that I personally made mistakes many times that PHP would have let slide. PHP would have let me use a variable name that I thought was new, overwriting whatever was there before. Which begs the question… how many times have I done that in PHP?

Go is hard(er)

Mind you, I’m not anti-PHP, not by any stretch. A lot of times with Go, I get a little frustrated… and almost every time it’s related to types. Go (or many other languages) forces us to play by rules that most of the web (PHP/JavaScript) folks are used to.

I’m sharing this because I’ve had one of those moments where I’ve shifted from knowing that PHP is loosely-typed to having a real sense of the impact. As PHP moves further toward the adoption of strong typing, I think we should all make an effort to adopt them voluntarily. Yes, it’ll make PHP seem harder, but it’ll make our code – and us – better.

Leave a Reply

Your email address will not be published.

Join our Mailing list!

Get all latest news, exclusive deals and service updates.