Type Juggling & Casting
PHP is loosely typed, which means it will quietly convert types behind your back. This lesson shows exactly when juggling happens, how to take control with explicit casts, how PHP 8 made comparisons safer, and how strict_types protects your functions.
Learn Type Juggling & Casting in our free PHP course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick recall.
Part of the free Php course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn in This Lesson
1️⃣ Implicit Juggling
Juggling happens automatically whenever an operator meets the "wrong" type. Arithmetic operators juggle towards numbers; the . operator juggles towards strings; boolean contexts juggle towards true / false . PHP 8 tightened the rules: adding a string that doesn't start as a number now throws a TypeError rather than guessing.
2️⃣ Explicit Casting
When you want a conversion you control, put the target type in parentheses in front of the value: (int) , (float) , (string) , (bool) , (array) . Note that (int) truncates (it never rounds) and stops at the first non-digit.
3️⃣ Loose vs Strict Comparison
The loose == operator juggles both sides to a common type before comparing — the source of PHP's most infamous surprises. PHP 8 fixed the worst of them ( 0 == "abc" is now false ), but numeric strings still compare numerically, so "10" == "1e1" is true . The strict === sidesteps all of it.
4️⃣ Turning Off Juggling: strict_types
Add declare(strict_types=1); as the first line of a file and PHP stops auto-juggling the arguments and return values of typed functions. Pass the wrong type and you get an immediate TypeError — a bug caught now rather than three layers deep later. (An int is still accepted where a float is wanted, because that widening loses nothing.)
5️⃣ Converting User Input Safely
Everything from a form or URL arrives as a string , so converting it is a daily task — and the place where a careless (int) bites. The robust pattern is validate, then cast : filter_var() returns the clean value or false , making "invalid" unmistakable.
Now you try. Fill the ___ blanks with the right cast keyword.
These scrambled lines should validate a string and print a result. Put them in the order that prints Valid: 50 .
You must define $raw , then trim it, then validate it into $clean before you can test and print it. The === false check is essential because filter_var returns false for invalid input but could legitimately return 0 for the string "0". Output: Valid: 50 .
Predict the output before revealing each answer.
The first prints 8 (arithmetic juggles "5" to the int 5); the second prints 53 (the . operator juggles both to strings and concatenates).
Prints int(42) . Casting to int truncates the fractional part — it does not round to 43.
Prints bool(true) . Both are numeric strings, so PHP compares them numerically: 10 equals 10 (1e1 is scientific notation for 10). With === it would be false .
📋 Quick Reference — Juggling & Casting
Write it yourself, run it on onecompiler.com/php or your own machine, then check against the expected output in the comments.
Practice quiz
What does echo "5" + 3; print?
- 53
- "5"3
- 8
- A TypeError
Answer: 8. The + operator juggles the numeric string "5" to the int 5, giving 8.
What does echo 5 . 3; print?
- 53
- 8
- 15
- 5.3
Answer: 53. The . concatenation operator juggles both numbers to strings and joins them: "53".
What does var_dump((int) "42.9"); output?
- int(43)
- float(42.9)
- int(0)
- int(42)
Answer: int(42). Casting to int truncates the fractional part — it does not round — so it is 42.
What does var_dump("10" == "1e1"); output?
- bool(false)
- bool(true)
- int(10)
- An error
Answer: bool(true). Both are numeric strings, so PHP compares them numerically; 1e1 is 10, so they are equal.
In PHP 8, what does var_dump(0 == "abc"); output?
- bool(false)
- bool(true)
- int(0)
- An error
Answer: bool(false). PHP 8 fixed this trap: a non-numeric string is no longer treated as 0, so the result is false.
What does var_dump(0 === "0"); output?
- bool(true)
- int(0)
- bool(false)
- string(1)
Answer: bool(false). === compares value AND type; an int and a string differ in type, so the result is false.
What does var_dump((int) "abc123"); output?
- int(123)
- int(0)
- int(456)
- string(6)
Answer: int(0). (int) reads leading digits only; "abc123" has no leading digits, so it casts to 0.
What does var_dump((bool) "0"); output?
- bool(true)
- int(0)
- string(1)
- bool(false)
Answer: bool(false). "0" is the one string that casts to false; any other non-empty string is true.
What is the difference between juggling and casting?
- They are the same thing
- Juggling is implicit; casting is explicit with (int), (float), etc.
- Casting is automatic; juggling is manual
- Juggling only works on integers
Answer: Juggling is implicit; casting is explicit with (int), (float), etc.. PHP juggles types automatically during operations; casting is a deliberate (type) conversion you control.
What does filter_var("nope", FILTER_VALIDATE_INT) return?
- 0
- null
- false
- "nope"
Answer: false. filter_var returns false for invalid input, which is far clearer than a blind (int) cast turning it into 0.