Type juggling (coercion) in PHP
PHP has generally gotten a bad wrap for something known as type juggling. If you attempt to combine multiple different data types together, either on purpose or by accident, the data types are automatically converted to one of the data types, known as juggling.
This provides a sort of fallback mechanism for those new to PHP, but it can get very dangerous if depended upon in larger applications because it can lead to undesired output.
Let’s remove the type casts on both variables so they are instead using the automatic PHP data type assignments.
<?php $title = 'My Blog'; $numPosts = 10; ?> <h1><?= $title ?></h1> <p><?= gettype($title) ?></p> <h2><?= $numPosts ?></h2> <p><?= gettype($numPosts) ?></p>
And when we refresh the page, we are seeing our expected output.
Let’s multiply our number of posts by 10, but lets wrap that 10 within single quotes:
<?php $title = 'My Blog'; $numPosts = 10 * '10'; ?> <h1><?= $title ?></h1> <p><?= gettype($title) ?></p> <h2><?= $numPosts ?></h2> <p><?= gettype($numPosts) ?></p>
If we refresh the page, we’ll see something interesting. You’d probably expect to see an error here, but instead, PHP uses data coercion, or juggling, to come up with a reasonable guess of what the output should be.
When you are creating dependable web applications, you don’t really want to be relying on reasonable guesses. You want to be 100% sure that what you expect to happen, will in fact happen.
Let’s elaborate on this just a bit more, by saying this first number in numPosts
is also a string:
<?php $title = 'My Blog'; $numPosts = '10' * '10'; ?> <h1><?= $title ?></h1> <p><?= gettype($title) ?></p> <h2><?= $numPosts ?></h2> <p><?= gettype($numPosts) ?></p>
Refreshing... we see 100. This is a bit odd to me, because we are multiplying a string and a string. But, PHP assumes since you are using a math operand, that both values should be numbers. Ok.
But let’s go a step further, and add these strings together:
<?php $title = 'My Blog'; $numPosts = '10' + '10'; ?> <h1><?= $title ?></h1> <p><?= gettype($title) ?></p> <h2><?= $numPosts ?></h2> <p><?= gettype($numPosts) ?></p>
And similarly, the output is 20. So, that sort of still holds up. But let’s do something different — let’s use a period instead of a plus sign. We haven’t learned this yet, but this is how you join two strings together.
<?php $title = 'My Blog'; $numPosts = '10' . '10'; ?> <h1><?= $title ?></h1> <p><?= gettype($title) ?></p> <h2><?= $numPosts ?></h2> <p><?= gettype($numPosts) ?></p>
And when we refresh... we don’t get a number. We get a string. And rather than adding these two strings together like we saw previously, both of these values are converted into actual strings, and then concatenated together. I’m sure 1010 is probably not the output you were expecting to see.
Later on when we get to functions, we can actually enable something in PHP called strict mode, which will help prevent situations like this. But, we’ll learn more about that later.