PHP has eight types you use every day: int, float, string, bool, array, object, null, plus callable for functions you pass around. A variable has no fixed type; its current value does. var_dump($x) shows both the type and the value, and gettype($x) returns the type as a string.
The first column is gettype(), the second get_debug_type(). Replace a value with your own and run it again. They disagree on a few names: gettype says integer, double and boolean for historical reasons, while get_debug_type uses the names from type declarations (int, float, bool) and gives the class name for an object.
The PHP types at a glance
| Type | Example | Notes |
|---|---|---|
int | 42, -7, 0x1A, 1_000_000 | whole numbers, 64-bit on modern systems |
float | 3.14, 1.5e3 | decimals, inexact like in every language |
string | "hi", 'hi' | a sequence of bytes, not characters |
bool | true, false | case-insensitive (TRUE works too) |
array | [1, 2], ["a" => 1] | ordered map: list and dictionary in one |
object | new User(), new stdClass() | an instance of a class |
null | null | the only value of type null; also "no value set" |
callable | 'strlen', fn($x) => $x * 2 | anything you can call |
iterable | an array or a Traversable object | what foreach accepts |
resource | the result of fopen() | a handle to something outside PHP |
Inspect values with var_dump
var_dump is the tool for seeing what you really have. It prints the type, the value, and for strings the length in bytes:
echo would print 10 for the first three and hide the difference. The length in string(5) "café" counts bytes, which is why strlen and mb_strlen differ for non-ASCII text.
Integers and floats
An integer is a whole number. Literals can use underscores for readability, and hex, octal and binary notation. A float is any number with a decimal point or exponent, and like in every language it stores most decimals approximately:
Never compare floats with ==; compare the difference against a small tolerance, or round both sides first. For money, store whole cents as integers.
Booleans and which values are false
A bool is true or false. Where PHP expects a condition (if, while, !), any value is converted to bool, and a short list of values counts as false: false, 0, 0.0, "", "0", [] and null. Everything else is true. The table shows each value with its type, its bool conversion and whether it is numeric:
| $x | gettype | bool | is_numeric |
|---|---|---|---|
| 0 | |||
| 1 | |||
| -1 | |||
| 0.0 | |||
| 1.5 | |||
| "0" | |||
| "" | |||
| " " | |||
| "0.0" | |||
| "10" | |||
| "1e1" | |||
| "abc" | |||
| "null" | |||
| true | |||
| false | |||
| null | |||
| [] | |||
| [0] |
The surprises are "0.0", " " and "null": all three are non-empty strings other than "0", so they are true, and if ($value) runs its body for them.
Arrays, objects and null
An array holds any mix of values under integer or string keys. An object is an instance of a class; stdClass is PHP's empty class for quick objects, and (object) turns an array into one. null means "no value":
Check a type with is_* functions
Each type has a test function that returns true or false. is_numeric is different from is_int: it accepts numeric strings too, which is what you want when checking form input.
Others: is_bool, is_array, is_object, is_null, is_callable, is_iterable, and $x instanceof ClassName for a specific class.
Type juggling and strict types
PHP converts types automatically when an operator needs a different one. A numeric string used in arithmetic becomes a number, and . turns numbers into strings. A string that is not numeric at all cannot be added, and PHP 8 throws a TypeError:
Typed parameters convert too, unless the file starts with declare(strict_types=1);. Then a call with the wrong scalar type fails instead of being converted:
To convert on purpose, cast: (int) "42", (float) "3.5", (string) 10, (bool) "0". The type casting page covers every cast and its edge cases.
Common mistake: comparing different types with ==
Because == converts before comparing, two values of different types can be "equal" in ways that cause bugs, such as "1e1" == "10" (both are the number 10) or null == false. Use ===, which also requires the same type, unless you want the conversion:
PHP 8 fixed the worst case: "abc" == 0 used to be true and is now false, because a non-numeric string is compared as a string. The full tables are on the comparison operators page.
Frequently Asked Questions
How do I check the type of a variable in PHP?
var_dump($x) prints the type and value, for example int(5). gettype($x) returns the type name as a string ("integer"), and get_debug_type($x) returns the modern name ("int", or the class name for objects). To test for one type, use is_int, is_string, is_array and the other is_* functions.
Why does gettype return "double" for a float?
For historical reasons gettype() reports floats as "double" and integers as "integer". get_debug_type(), added in PHP 8, returns "float" and "int", the same names you write in type declarations.
What values are false in PHP?
Converted to bool, these are false: false, 0, 0.0, "", "0", [] and null. Everything else is true, including "0.0", " " and "false".
What is the maximum integer in PHP?
PHP_INT_MAX, which is 9223372036854775807 on 64-bit systems. Adding past it does not wrap around: the result becomes a float and loses precision.
Is PHP strongly or weakly typed?
PHP is dynamically typed and, by default, converts types when it can ("10" + 5 is 15). With declare(strict_types=1); at the top of a file, calls to typed functions in that file reject wrong scalar types with a TypeError instead of converting them.