Embracing coercion in PHP

Coercion is implicit typecasting for scalar types (integer, float, boolean and string). In this article we look at how we can use coercion as an elegant alternative to explicit typecasting.

Coercing to integer

We can coerce any expression to integer by suffixng |0 – bitwise or operator followed by zero. Bitwise operators only work on integers so PHP coerces both operands to integer before performing the operation. Performing bitwise or with a value of zero has no effect on the numeric value so we just benefit from the integer coercion.

Integer coercion is equivalent to (int)floor($x), intval($x) or typecasting with (int)$x or (integer)$x. In some languages this can also be achieved by prefixing ~~ – two not operators.

Examples

Expression Evaluation
true|0 1
false|0 0
1.6|0 1
'1a'|0 1
'a1'|0 0

Coercing to float

We can coerce any expression to float by suffixing +0. or +.0. Floating-point numbers can be specified without the exponent or significand (but not both), in which case the unspecified part is presumed to be zero; that is, 0. and .0 are the same as writing 0.0.

Float coercion is equivalent to floatval($x) or doubleval($x) or typecasting with (float)$x, (double)$x or (real)$x.

Examples

Expression Evaluation
true+0. 1.0
false+0. 0.0
'1'+0. 1.0

Coercing to numeric

We can coerce any expression to numeric; that is, an integer or float, by prefixing + or -. Although typically used for addition and subtraction as arithmetic operators, when applied to only one operand we call them unary plus and minus because they only operate on one operand. Unary plus converts its operand to either int or float depending on which is most appropriate; unary minus does the same but also flips the sign.

Numeric coercion cannot be achieved with any other built-in PHP function or syntax.

Examples

Expression Evaluation
+true 1
-true -1
-false 0
-'-1.6a' 1.6
+('1'.'6') 16
+'0x10' 16
+'010' 10
+'0b10' 0

Coercing to boolean

We can coerce any expression to boolean by prefixing at least one ! – logical not operator. Logical operators always return a boolean value. We use the not operator because it offers the most concise syntax as the only unary logical operator. The not operator also inverts the meaning of the expression but prefixing a pair (!!) preserves the meaning.

Boolean coercion is equivalent to boolval($x) or typecasting with (bool)$x or (boolean)$x.

Examples

Expression Evaluation
!!true true
!0 true
!!1 true
!!'a' true
!!'0' false

For more conversions see the true/false columns of the loose comparisons truth table.

Coercing to string

We can coerce any scalar or objects implementing __toString() to string by enclosing them in double quotes.

String coercion is equivalent to strval($x) or typecasting with (string)$x.

Example

Exception implements __toString() providing a string representation of the exception.

$e = new Exception('foo');
"$e";

exception 'Exception' with message 'foo' in -:2
Stack trace:
#0 {main}

Practical applications

Some people have tried to agument the language to provide strong typing for scalars but by working with the grain of the language and embracing coercion we can ensure variables are the types we expect much more easily.

Mutator example

Coercion is useful when writing getters and setters. In the following example we want to ensure only integer values are stored in our class when its setInteger method is called.

class Bar {
	private $integer;

	public function setInteger($integer) {
    	$this->integer = $integer|0;
    }
}

ToString example.

We want to implement __toString in our class and it is paramount that our implementation actually returns a string to avoid PHP throwing a fatal error. We could use typecasting but coercion solves the problem elegantly.

class Foo {
	public $value;
    
    public function __toString() {
    	return "$this->value";
    }
}

$foo = new Foo;
$foo->value = 123;
"$foo"

'123'

Summary

Type Coercion
Integer $x|0
Float $x+0. or $x+.0
Numeric +$x or -$x
Boolean !!$x or !$x
String "$x"

Conclusion

We explored coercion as a terse alternative to typecasting that works with PHP's concept of type juggling to modify the type of an expression by manupulating its context. Although these examples apply to PHP the concept of coercion can be applied to many scripting languages to modify the types of expressions.