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.
🧩 Reorder Challenge
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 .
🧠 Quick Recall
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 .
Common Errors (and the fix)
- (int) "abc" silently became 0 — a blind cast hides bad input. Validate with filter_var(..., FILTER_VALIDATE_INT) first.
- Two different strings compare equal — they're numeric strings under == (e.g. "1" == "01" ). Use === .
- TypeError when calling a typed function — with strict_types=1 you must pass the exact type. Cast deliberately before the call.
- "A non-numeric value encountered" / TypeError on + — PHP 8 won't add a non-numeric string. Clean and validate the value before arithmetic.
Pro Tips
- 💡 Put declare(strict_types=1); at the top of every new file. It turns silent type bugs into loud, early errors.
- 💡 Cast on purpose, compare with === . Explicit beats implicit every time.
- 💡 Treat all input as untrusted strings. Validate with filter_var before you cast or calculate.
📋 Quick Reference — Juggling & Casting
Expression
Result
Why
"5" + 3
8
Juggled to numbers
5 . 3
"53"
Juggled to strings
(int) "42.9"
42
Truncates, no rounding
(bool) "0"
false
"0" is the only falsy string
0 == "abc"
PHP 8 fixed this trap
"10" == "1e1"
true
Numeric strings compared as numbers
strict_types=1
TypeError
No auto-juggling of args
Frequently Asked Questions
Mini-Challenge: Validate Form Fields
Write it yourself, run it on onecompiler.com/php or your own machine, then check against the expected output in the comments.
🎉 Lesson Complete!
- ✅ Juggling is implicit; casting with (type) is explicit and controlled
- ✅ (int) truncates and stops at the first non-digit
- ✅ == juggles; === avoids every surprise
- ✅ declare(strict_types=1) turns type bugs into early errors
- ✅ Validate input with filter_var before casting
- ✅ Next lesson: Constants — values that never change
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.
Continue this course
- Previous: Numbers & Math
- Next: Constants