Please wait

Type Juggling

In this lesson, learn how PHP can automatically type case your variables and the problems that can arise from this behavior.

What is type juggling?

Type juggling refers to the automatic conversion of values from one data type to another, depending on the context in which the values are used. It's not uncommon to accidentally compare two values with completely different data types. If that's the case, PHP won't throw an error. Instead, it'll attempt to typecast one of the values into the same data type as another value.

Let's say you're trying to add a string to a number. PHP will "juggle" the types around to make sense of this operation. It will convert the string to a number and then perform the addition.

Here's an example:

$num = 10;         // $num is an integer
$str = "20";       // $str is a string
 
$result = $num + $str; // The string $str is converted to an integer for the operation
echo $result; // This will output 30

In the example above, PHP has automatically "juggled" the types to make the addition operation possible. The string "20" was converted to the integer 20 before the addition operation took place. The result is the integer 30.

Alternative name

From time to time, you may hear this feature referred to as type coercion. It means the same thing.

Type juggling can be convenient, but it can also lead to unexpected results if you're not careful. Let's look at how type juggling works with different operators.

Arithmetic Operators

In PHP, arithmetic operators are designed to operate on numerical data types, namely integers and floating-point numbers.

Using Booleans

When you use a boolean value in a mathematical operation, PHP will automatically convert true to 1 and false to 0. This behavior is an instance of PHP's type juggling, specifically its automatic conversion of boolean values to numbers in the context of a mathematical operation.

Here are some examples:

ExampleAfter Type JugglingResultExplanation
1 + true1 + 1int(2)Boolean true is type juggled to an integer 1.
1 + false1 + 0int(1)Boolean false is type juggled to the integer 0.

Using Strings

When a string is used in a arithmetic operation in PHP, the resulting behavior largely depends on the contents of the string. This leads to the categorization of strings into three types when they are used in numeric contexts:

  • Numeric strings: These are strings that contain only valid integers or floating-point numbers, like '123' or '12.3'. When used in arithmetic operations, they are treated as their numeric counterparts.
  • Leading numeric strings: These are strings that start with a valid integer or floating-point number followed by non-numeric characters, like '123apples' or '12.3oranges'. In arithmetic operations, PHP uses the initial numeric portion and disregards the rest of the string.
  • Non-numeric strings: These are strings that do not start with a valid number, like 'one' or 'one444'. If you attempt to use such strings in a mathematical operation, PHP will throw a TypeError Exception, preventing unexpected behaviors.

Here are some examples:

ExampleAfter Type JugglingResultExplanation
10 + '10'10 + 10int(20)The string '10' is type juggled into an integer 10.
41 + '7.7'41 + 7.7float(48.7)The string '7.7' is typed juggled into a float 7.7.
1 + '1.5e+5'1 + 150000float(150001)The string '1.5e+5'holds a float using an exponent. It is type juggled into a float 150000.
5 + '5bananas'5 + 5int(10) Warning: A non-numeric value encounteredThe string '5bananas' holds an integer followed by other characters. The number is treated as an integer. Everything after is ignored.
2 + '2.5apples'2 + 2.5float(4.5) Warning: A non-numeric value encounteredThe string '2.5apples' holds a float followed by other characters. The number is treated as a float. Everything after is ignored.
1 + 'adfasdfas'1 + 0Fatal error: Uncaught TypeError: Unsupported operand types: int + stringError thrown. String does not contain an integer or float. Value is type juggled into 0.

Comparison Operators

When you use the == operator (equal to), PHP will attempt to convert the types to make a comparison if the two variables or values are not of the same type. This is often referred to as a "loose" comparison.

Here's a classic example that often trips people up:

$test = "123" == 123;
 
var_dump($test);

In this example, we're using the var_dump() function. It's similar to the echo keyword as it'll output the value, but it'll also output the data type.

This will output bool(true) because PHP converts the string "123" to an integer 123 to perform the comparison, and those two are indeed equal. Here's a table with how PHP compares values of different data types:

Loose comparisons with ==
==truefalse10-1"1""0""-1"null[]"php"""
truetruefalsetruefalsetruetruefalsetruefalsefalsetruefalse
falsefalsetruefalsetruefalsefalsetruefalsetruetruefalsetrue
1truefalsetruefalsefalsetruefalsefalsefalsefalsefalsefalse
0falsetruefalsetruefalsefalsetruefalsetruefalsefalsefalse
-1truefalsefalsefalsetruefalsefalsetruefalsefalsefalsefalse
"1"truefalsetruefalsefalsetruefalsefalsefalsefalsefalsefalse
"0"falsetruefalsetruefalsefalsetruefalsefalsefalsefalsefalse
"-1"truefalsefalsefalsetruefalsefalsetruefalsefalsefalsefalse
nullfalsetruefalsetruefalsefalsefalsefalsetruetruefalsetrue
[]falsetruefalsefalsefalsefalsefalsefalsetruetruefalsefalse
"php"truefalsefalsefalsefalsefalsefalsefalsefalsefalsetruefalse
""falsetruefalsefalsefalsefalsefalsefalsetruefalsefalsetrue

Strict Comparison

These examples illustrate why loose comparisons can be tricky in PHP. To avoid this kind of unexpected behavior, you can use a "strict" comparison with the === operator (identical to), which checks both the value and the type. With strict comparisons, "123" is not equal to 123, "0" is not equal to 0, and "abc" is definitely not equal to 0.

Here's a table with how PHP compares values of different data types using strict comparison:

Strict comparisons with ===
===truefalse10-1"1""0""-1"null[]"php"""
truetruefalsefalsefalsefalsefalsefalsefalsefalsefalsefalsefalse
falsefalsetruefalsefalsefalsefalsefalsefalsefalsefalsefalsefalse
1falsefalsetruefalsefalsefalsefalsefalsefalsefalsefalsefalse
0falsefalsefalsetruefalsefalsefalsefalsefalsefalsefalsefalse
-1falsefalsefalsefalsetruefalsefalsefalsefalsefalsefalsefalse
"1"falsefalsefalsefalsefalsetruefalsefalsefalsefalsefalsefalse
"0"falsefalsefalsefalsefalsefalsetruefalsefalsefalsefalsefalse
"-1"falsefalsefalsefalsefalsefalsefalsetruefalsefalsefalsefalse
nullfalsefalsefalsefalsefalsefalsefalsefalsetruefalsefalsefalse
[]falsefalsefalsefalsefalsefalsefalsefalsefalsetruefalsefalse
"php"falsefalsefalsefalsefalsefalsefalsefalsefalsefalsetruefalse
""falsefalsefalsefalsefalsefalsefalsefalsefalsefalsefalsetrue

Always be explicit

In some cases, you may want to purposely compare two values with completely different data types. In those cases, you can perform type casting, such as (int) $someValue. It's better to be explicit with your type casting, so that you know exactly where a value changes.

Key takeaways

  • Type juggling is a behavior in PHP where values are automatically type cast into the same data type before performing any operation.
  • This behavior cannot be disabled.
  • To avoid this behavior, it's recommended to always use strict comparison operators and to explicitly typecast your own values.

Comments

Please read this before commenting