PHP Data Types

PHP has 10 built-in types organized into scalar, compound, and special. Learn each one, when to use it, how to check it, and how PHP juggles types under the hood.

Beginner 10 min read 12 examples

Type System Overview

PHP types fall into three families:

FamilyTypes
Scalarint, float, string, bool
Compoundarray, object, callable, iterable
Specialnull, resource (deprecated in PHP 8.x)

Integer (int)

Whole numbers, positive or negative, without a decimal point.

PHP
<?php
$a = 42;          // decimal
$b = -17;         // negative
$c = 0x1A;        // hexadecimal (26)
$d = 0b1010;      // binary (10)
$e = 0755;        // octal (493)
$f = 0o755;       // explicit octal PHP 8.1+ (493)
$g = 1_000_000;   // numeric separator PHP 7.4+ (readability only)

echo PHP_INT_MAX; // 9223372036854775807 on 64-bit
echo PHP_INT_MIN; // -9223372036854775808
echo PHP_INT_SIZE;// 8 (bytes per int)

Float (float)

Floating-point numbers, also called double or real:

PHP
<?php
$price = 19.99;
$pi    = 3.14159;
$big   = 1.5e3;      // 1500
$tiny  = 7E-10;      // 0.0000000007

// Comparison is dangerous due to binary representation
var_dump(0.1 + 0.2 === 0.3);   // bool(false) - surprising!

// Use round() or PHP_FLOAT_EPSILON
var_dump(abs((0.1 + 0.2) - 0.3) < PHP_FLOAT_EPSILON);  // bool(true)
Never store money as float

Use integer cents (1999 for $19.99) or the bcmath extension. Floats cause rounding errors that compound across transactions.

String

A sequence of characters. PHP strings are binary-safe and can hold any byte value.

PHP
<?php
$single = 'Hello $name';       // literal $name, no interpolation
$double = "Hello $name";         // $name expanded
$escape = "Tab:\t Newline:\n";   // escape sequences in double quotes

// Heredoc - like double quotes, multi-line
$html = <<<HTML
<h1>Hello $name</h1>
<p>Welcome!</p>
HTML;

// Nowdoc - like single quotes, multi-line
$raw = <<<'EOT'
$variables are literal here
EOT;

echo strlen($single);     // 13
echo $single[0];          // H
echo $single[-1];         // ! (negative index, PHP 7.1+)

Boolean (bool)

Just true or false. Case-insensitive but conventionally lowercase.

PHP
<?php
$active = true;
$banned = false;

// Falsy values - all of these become false when cast
var_dump((bool) "");        // false
var_dump((bool) "0");       // false  <-- surprising!
var_dump((bool) 0);         // false
var_dump((bool) 0.0);       // false
var_dump((bool) null);      // false
var_dump((bool) []);        // false

// Everything else is truthy - including "false"!
var_dump((bool) "false");   // true
var_dump((bool) "0.0");     // true
var_dump((bool) -1);        // true

Array

An ordered map - PHP arrays are simultaneously lists, dictionaries, and stacks.

PHP
<?php
// Indexed array
$fruits = ["apple", "banana", "cherry"];
echo $fruits[0];          // apple

// Associative array
$user = [
    "name"  => "Ruban",
    "email" => "ruban@example.com",
    "age"   => 30,
];
echo $user["name"];       // Ruban

// Multi-dimensional
$matrix = [
    [1, 2, 3],
    [4, 5, 6],
];
echo $matrix[1][2];       // 6

// Count
echo count($fruits);      // 3

Object

An instance of a class. Built using the new keyword.

PHP
<?php
class User {
    public function __construct(
        public string $name,
        public int $age,
    ) {}
}

$user = new User("Ruban", 30);
echo $user->name;         // Ruban
echo $user->age;          // 30

// Anonymous object via stdClass
$config = (object) [
    "host" => "localhost",
    "port" => 3306,
];
echo $config->host;

Null

A special value meaning "no value". Only one possible value: null.

PHP
<?php
$x = null;

var_dump(is_null($x));     // true
var_dump($x === null);     // true (preferred)
var_dump(isset($x));       // false - null is not "set"

// Nullable types in function signatures (PHP 7.1+)
function findUser(int $id): ?User {
    return $id > 0 ? new User("Found", 1) : null;
}

// Null coalescing operator
$name = $user["name"] ?? "Guest";

Type Checking

PHP
<?php
$x = 42;

// Helper functions
var_dump(is_int($x));         // true
var_dump(is_string($x));      // false
var_dump(is_array($x));       // false
var_dump(is_null($x));        // false
var_dump(is_numeric($x));     // true (also true for numeric strings)
var_dump(is_callable("strlen")); // true

// Get type as string
echo gettype($x);             // integer

// instanceof for objects
var_dump($user instanceof User); // true

Type Casting & Juggling

PHP automatically converts types in many contexts (juggling). You can also force conversions (casting):

PHP
<?php
// Explicit casting
$n   = (int) "42abc";       // 42
$s   = (string) 3.14;       // "3.14"
$a   = (array) "hello";     // ["hello"]
$b   = (bool) 1;            // true

// Helper functions
$n2  = intval("42abc");     // 42
$f2  = floatval("3.14xx");  // 3.14
$s2  = strval(true);        // "1"

// Implicit juggling - avoid!
echo "5" + 3;               // 8 (string -> int)
echo "5" . 3;               // "53" (int -> string)
var_dump("5" == 5);         // true (loose comparison)
var_dump("5" === 5);        // false (strict - preferred)
Enforce strict types

Add declare(strict_types=1); as the first line of every PHP file. Then PHP refuses to silently convert types in function calls - bugs surface as errors instead of weird behavior.

Next Steps

Frequently Asked Questions

Use gettype($x) for a string name, or type-specific functions: is_int(), is_string(), is_array(), is_bool(), is_null(), is_object(). These are faster and clearer than comparing strings.

The string "0" is falsy - one of PHP's most surprising quirks. The strings "", "0", the integer 0, null, false, and an empty array are all falsy. Everything else (including the string "false"!) is truthy.

(int) is faster and works only on PHP values. intval($x, $base) accepts a base parameter (for hex/binary parsing) and handles trailing characters more gracefully. Both convert non-numeric strings to 0.

Yes - add declare(strict_types=1); as the first line of every PHP file. It enforces exact type matches on function parameters and return values, catching bugs at runtime instead of letting them silently corrupt data.

Floats use IEEE 754 binary representation, which can't exactly represent some decimals (like 0.1). Use round() for comparison or the bcmath extension for exact decimal arithmetic when money is involved.