Type Juggling & Casting
Reviewed & published by Brayan K
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