EasyТеория6 min

Типы данных PHP

Скалярные, составные, специальные типы, type juggling, strict_types

Классификация типов

PHP поддерживает 10 примитивных типов данных:

Категория Типы
Скалярные bool, int, float, string
Составные array, object, callable, iterable
Специальные resource, null

Начиная с PHP 8.0+, появились дополнительные типы:

  • mixed (PHP 8.0) — любой тип
  • never (PHP 8.1) — функция не возвращает значение (exit/throw)
  • void — функция ничего не возвращает
  • true, false, null (PHP 8.2) — как отдельные типы

Скалярные типы

bool

<?php
declare(strict_types=1);

$active = true;
$deleted = false;

// Values that evaluate to FALSE:
var_dump((bool) false);     // false
var_dump((bool) 0);         // false
var_dump((bool) 0.0);       // false
var_dump((bool) -0.0);      // false
var_dump((bool) '');         // false
var_dump((bool) '0');        // false — ATTENTION!
var_dump((bool) []);         // false
var_dump((bool) null);       // false

// Everything else is TRUE:
var_dump((bool) 1);          // true
var_dump((bool) -1);         // true
var_dump((bool) 'false');    // true — string 'false' is truthy!
var_dump((bool) '0.0');      // true — only '0' is falsy!
var_dump((bool) [0]);        // true — non-empty array
var_dump((bool) new stdClass()); // true

Ловушка экзамена: Строка '0' является false при приведении к bool. Но строка 'false', 'null', '0.0', ' ' (пробел) — все являются true! Это один из самых частых вопросов на сертификации.

int

<?php
declare(strict_types=1);

// Integer literals
$decimal     = 42;          // Decimal
$negative    = -42;         // Negative
$octal       = 0755;        // Octal (starts with 0)
$hex         = 0xFF;        // Hexadecimal (starts with 0x)
$binary      = 0b10101;     // Binary (starts with 0b)
$underscore  = 1_000_000;   // Underscores for readability (PHP 7.4+)
$octalNew    = 0o755;       // Explicit octal (PHP 8.1+)

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

// Integer overflow => becomes float!
$big = PHP_INT_MAX;
$overflow = $big + 1;
var_dump($overflow);  // float(9.2233720368548E+18)

Ловушка экзамена: При переполнении целого числа PHP автоматически конвертирует в float без предупреждения! PHP_INT_MAX + 1 станет float. Также 0123 — это ВОСЬМЕРИЧНОЕ число (83 в десятичной), а не 123!

float

<?php
declare(strict_types=1);

$pi = 3.14159;
$scientific = 1.2e3;     // 1200.0
$negative = -1.5E-2;     // -0.015

// Special float values
$inf = INF;              // Infinity
$ninf = -INF;            // Negative infinity
$nan = NAN;              // Not a Number

// Checking special values
var_dump(is_infinite($inf));  // true
var_dump(is_nan($nan));       // true
var_dump(is_finite(3.14));    // true

// NEVER compare floats directly!
var_dump(0.1 + 0.2 == 0.3);     // false!
var_dump(0.1 + 0.2);             // 0.30000000000000004

// Correct float comparison
$epsilon = 0.00001;
$result = abs((0.1 + 0.2) - 0.3) < $epsilon;
var_dump($result);  // true

// Or use bcmath for precision
echo bcadd('0.1', '0.2', 1);  // '0.3'

Ловушка экзамена: 0.1 + 0.2 == 0.3 возвращает false из-за погрешности чисел с плавающей точкой (IEEE 754). NAN != NAN — NaN не равен ничему, даже самому себе! Используйте is_nan() для проверки.

string

<?php
declare(strict_types=1);

// Single quotes — no interpolation, no escape sequences (except \\ and \')
$name = 'World';
echo 'Hello $name';     // Hello $name (literal)
echo 'It\'s a test';    // It's a test
echo 'Path: C:\\';      // Path: C:\

// Double quotes — interpolation and escape sequences
echo "Hello $name";             // Hello World
echo "Hello {$name}";           // Hello World
echo "Tab\there\nnewline";     // Tab	here\nnewline
echo "Unicode: \u{1F600}";     // Unicode emoji (PHP 7.0+)

// Heredoc (like double quotes)
$text = <<<EOT
Hello $name!
This is multi-line.
EOT;

// Nowdoc (like single quotes)
$text = <<<'EOT'
Hello $name!
This is literal.
EOT;

// PHP 7.3+: Flexible heredoc/nowdoc (closing marker can be indented)
$html = <<<HTML
    <div>
        <p>Hello $name</p>
    </div>
    HTML;

Составные типы

array

<?php
declare(strict_types=1);

// Indexed array
$fruits = ['apple', 'banana', 'cherry'];

// Associative array
$user = [
    'name' => 'Alice',
    'age' => 25,
    'active' => true,
];

// Mixed keys
$mixed = [
    0 => 'zero',
    'key' => 'value',
    1 => 'one',
];

// Array type coercion for keys
$arr = [
    1     => 'int 1',
    '1'   => 'string 1',     // Overwrites int 1!
    1.7   => 'float 1.7',    // Key becomes 1, overwrites again!
    true  => 'bool true',    // Key becomes 1, overwrites again!
    null  => 'null',          // Key becomes ''
    false => 'bool false',   // Key becomes 0
];
// Result: [0 => 'bool false', 1 => 'bool true', '' => 'null']

Ловушка экзамена: Ключи массива приводятся к int или string. Строка '1' и число 1 — один и тот же ключ! true = 1, false = 0, null = ''. Это очень частый вопрос экзамена.

object

<?php
declare(strict_types=1);

// Creating objects
$obj = new stdClass();
$obj->name = 'Alice';
$obj->age = 25;

// Cast array to object
$arr = ['name' => 'Bob', 'age' => 30];
$obj = (object) $arr;
echo $obj->name;  // 'Bob'

// Cast object to array
$arr = (array) $obj;
echo $arr['name'];  // 'Bob'

callable

<?php
declare(strict_types=1);

// Various callable formats
$func = 'strlen';                       // Function name string
$closure = function(int $x): int { return $x * 2; };  // Closure
$arrow = fn(int $x): int => $x * 2;    // Arrow function

// Callable with class methods
class Math
{
    public static function square(int $n): int { return $n ** 2; }
    public function cube(int $n): int { return $n ** 3; }
}

$static = [Math::class, 'square'];      // Static method
$static2 = 'Math::square';              // Also valid
$instance = [new Math(), 'cube'];       // Instance method

// First-class callable syntax (PHP 8.1+)
$fn = strlen(...);                      // Creates Closure from function
$fn2 = Math::square(...);              // Creates Closure from static method

Специальные типы

null

<?php
declare(strict_types=1);

$value = null;

// Checking for null
var_dump(is_null($value));    // true
var_dump($value === null);    // true (preferred)
var_dump(isset($value));      // false

// Unset makes variable undefined (not null)
$x = 42;
unset($x);
// echo $x;  // Warning: Undefined variable

// Null type in type hints (PHP 8.0+)
function find(int $id): ?string  // Nullable
{
    return $id > 0 ? 'Found' : null;
}

resource

<?php
declare(strict_types=1);

// Resources are being removed in favor of objects
$file = fopen('/tmp/test.txt', 'r');  // resource in PHP 7, still resource
var_dump(is_resource($file));

// In PHP 8.0+, many resources became objects:
// - CurlHandle (was curl resource)
// - GdImage (was gd resource)
// - Socket (was socket resource)
// - OpenSSLCertificate, etc.

fclose($file);

Type Juggling (жонглирование типами)

<?php
declare(strict_types=1);

// Without strict_types, PHP auto-converts types
// (This section shows behavior WITHOUT strict_types)

// String to int
var_dump('42abc' + 0);    // int(42) — takes leading numeric part
var_dump('abc' + 0);      // int(0) + E_WARNING in PHP 8.0+

// Comparison table of conversions
var_dump(null + 1);       // int(1)
var_dump(true + true);    // int(2) — true=1, false=0
var_dump('3' + '4.5');    // float(7.5)
var_dump('0x10' + 0);     // int(0) — hex strings NOT auto-converted!
var_dump(intval('0x10', 16)); // int(16) — explicit conversion works

Порядок приведения типов

При сравнении с == PHP следует этим правилам:

null == false     => true
null|false == int => compare as int
string == string  => compare as strings (unless both numeric)
numeric string == numeric => compare as numbers

Ловушка экзамена: Строка '0x1A' НЕ конвертируется в число при арифметике с PHP 7.0+. '0x1A' + 0 даёт 0 (с предупреждением). Для явной конвертации hex-строк используйте intval('0x1A', 16) или hexdec('1A').

Функции проверки типов

<?php
declare(strict_types=1);

$val = 42;

// is_* functions
var_dump(is_int($val));       // true
var_dump(is_integer($val));   // true (alias)
var_dump(is_long($val));      // true (alias)

var_dump(is_float(3.14));     // true
var_dump(is_double(3.14));    // true (alias)

var_dump(is_string('hello')); // true
var_dump(is_bool(true));      // true
var_dump(is_null(null));      // true
var_dump(is_array([]));       // true
var_dump(is_object(new stdClass())); // true

// is_numeric — checks if value is numeric or numeric string
var_dump(is_numeric(42));        // true
var_dump(is_numeric('42'));      // true
var_dump(is_numeric('42.5'));    // true
var_dump(is_numeric('0x1A'));    // false (since PHP 7.0)
var_dump(is_numeric('1e5'));     // true (scientific notation)
var_dump(is_numeric(''));        // false

// gettype() — returns type as string
echo gettype(42);        // 'integer' (not 'int'!)
echo gettype(3.14);      // 'double' (not 'float'!)
echo gettype(true);      // 'boolean' (not 'bool'!)
echo gettype(null);      // 'NULL'

// get_debug_type() — PHP 8.0+, returns correct type names
echo get_debug_type(42);       // 'int'
echo get_debug_type(3.14);     // 'float'
echo get_debug_type(true);     // 'bool'
echo get_debug_type(null);     // 'null'
echo get_debug_type([]);       // 'array'

Запомни: gettype() возвращает устаревшие имена: 'integer', 'double', 'boolean', 'NULL'. Новая функция get_debug_type() (PHP 8.0+) возвращает корректные имена: 'int', 'float', 'bool', 'null'. На экзамене часто спрашивают именно gettype().

Type Declarations (подсказки типов)

<?php
declare(strict_types=1);

// Scalar type hints (PHP 7.0+)
function multiply(int $a, float $b): float
{
    return $a * $b;
}

// Nullable types (PHP 7.1+)
function findUser(int $id): ?string
{
    return $id > 0 ? 'Alice' : null;
}

// Union types (PHP 8.0+)
function process(int|string $input): void
{
    echo $input;
}

// Intersection types (PHP 8.1+)
function handle(Countable&Iterator $collection): void
{
    // Must implement BOTH interfaces
}

// DNF types — Disjunctive Normal Form (PHP 8.2+)
function complex((Countable&Iterator)|null $data): void
{
    // Intersection in parentheses combined with union
}

// true, false, null as standalone types (PHP 8.2+)
function alwaysTrue(): true
{
    return true;
}

// never type (PHP 8.1+)
function throwError(): never
{
    throw new RuntimeException('Fatal');
    // Function MUST never return (throw or exit)
}

Вопросы с экзамена ZCE

Проверь себя

5 из 12

Какой тип данных не может быть напрямую изменён клиентом?

Что вернёт `is_numeric('1e5')`?

Что выведет этот код? ```php echo strcmp(12345, '12345'); ```

Какой из следующих языков НЕ является строго типизированным?

Что вернёт `gettype(3.14)`?