Типы данных в PHP

  • PHP
  • 12 июля 2022
  • 36

Введение

PHP, это язык с динамической типизацией, а значит, что тип данных переменной выводится во время выполнения, и если сравнивать другие языки с PHP, то в языке PHP нет необходимости указывать тип данных перед переменной.

Краткое описание типов данных

PHP поддерживает 10 простых типов данных.

Четыре скалярных типа
  • bool - логический тип
  • int - целые числа
  • float - число с плавающей точкой, также известное как double
  • string - строки
Четыре смешанных типа
И, наконец, два специальных типа:

Теперь подробней

Булев (bool)

Это простейший тип. bool выражает истинность значения. Он может быть либо true, либо false.

Синтаксис

Для указания bool, используйте константы true или false. Они обе регистронезависимы.

$foo = True; // присвоить $foo значение TRUE

Обычно, некоторый оператор возвращает значение типа bool, которое потом передаётся управляющей конструкции.

// == это оператор, который проверяет
// эквивалентность и возвращает boolean
if ($action == "show_version") {
    echo "Версия 1.23";
}
// это необязательно...
if ($show_separators == TRUE) {
    echo "test 1 \n";
}

// ... потому что следующее имеет тот же самый смысл:
if ($show_separators) {
    echo "test 2 \n";
}

Преобразование в булев тип

Для явного преобразования в bool, используйте (bool) или (boolean). Однако, в большинстве случаев приведение типа необязательно, так как значение будет автоматически преобразовано, если оператор, функция или управляющая конструкция требует аргумент типа bool.

При преобразовании в bool, следующие значения рассматриваются как false:

  • само значение boolean false
  • integer 0 (ноль)
  • float 0.0 (ноль) и -0.0 (минус ноль)
  • пустая строка, и строка "0"
  • массив без элементов
  • особый тип NULL (включая неустановленные переменные)
  • объекты SimpleXML, созданные из пустых элементов без атрибутов, то есть элементов, не имеющих ни дочерних элементов, ни атрибутов.

Все остальные значения рассматриваются как true (включая любой resource и NAN).

Внимание! -1 рассматривается как true, как и любое другое ненулевое (отрицательное или положительное) число!

var_dump((bool) "");        // bool(false)
var_dump((bool) "0");       // bool(false)
var_dump((bool) 1);         // bool(true)
var_dump((bool) -2);        // bool(true)
var_dump((bool) "foo");     // bool(true)
var_dump((bool) 2.3e5);     // bool(true)
var_dump((bool) array(12)); // bool(true)
var_dump((bool) array());   // bool(false)
var_dump((bool) "false");   // bool(true)

Целые числа (int)

int - это число из множества ℤ = {..., -2, -1, 0, 1, 2, ...}.

Синтаксис

Целые числа (int) могут быть указаны в десятичной (основание 10), шестнадцатеричной (основание 16), восьмеричной (основание 8) или двоичной (основание 2) системе счисления. Для задания отрицательных целых (int) используется оператор отрицания.

Для записи в восьмеричной системе счисления, необходимо поставить перед числом 0 (ноль). Начиная с PHP 8.1.0, восьмеричной нотации также может предшествовать 0o или 0O. Для записи в шестнадцатеричной системе счисления, необходимо поставить перед числом 0x. Для записи в двоичной системе счисления, необходимо поставить перед числом 0b.

Начиная с PHP 7.4.0, целочисленные литералы могут содержать подчёркивания (_) между цифрами для лучшей читаемости литералов. Эти подчёркивания удаляются сканером PHP.

Пример
$a = 1234; // десятичное число
$a = 0123; // восьмеричное число (эквивалентно 83 в десятичной системе)
$a = 0o123; // восьмеричное число (начиная с PHP 8.1.0)
$a = 0x1A; // шестнадцатеричное число (эквивалентно 26 в десятичной системе)
$a = 0b11111111; // двоичное число (эквивалентно 255 в десятичной системе)
$a = 1_234_567; // десятичное число (с PHP 7.4.0)

Числа с плавающей точкой (float)

Числа с плавающей точкой или числа с плавающей запятой (также известные как "float", "double" или "real") могут быть определены следующими синтаксисами:

$a = 1.234;
$b = 1.2e3;
$c = 7E-10;
$d = 1_234.567; // начиная с PHP 7.4.0

Формально, начиная с PHP 7.4.0 (ранее подчёркивание не разрешалось):

LNUM [0-9]+(_[0-9]+)*
DNUM ([0-9]*(_[0-9]+)*[\.]{LNUM}) | ({LNUM}[\.][0-9]*(_[0-9]+)*)
EXPONENT_DNUM (({LNUM} | {DNUM}) [eE][+-]? {LNUM})

Размер числа с плавающей точкой зависит от платформы, хотя максимум, как правило, составляет 1.8e308 с точностью около 14 десятичных цифр (64-битный формат IEEE).

Строки (string)

Строка (тип string) - это набор символов, где символ - это то же самое, что и байт. Это значит, что PHP поддерживает ровно 256 различных символов, а также то, что в PHP нет встроенной поддержки Unicode.

Замечание: В 32-битных системах и в более ранних версиях PHP, строки (string) не могут быть более 2 ГБ (2147483647 байт).

Синтаксис

Строка может быть определена четырьмя различными способами:

  • одинарными кавычками
  • двойными кавычками
  • heredoc-синтаксисом
  • nowdoc-синтаксисом
Пример
echo 'это простая строка'; // это строка с одинарными кавычками

echo 'это простая строка'; // это строка с двойными кавычками

// Базовый пример использования Heredoc
echo <<< END
     a
    b
   c
\n
END;

// Пример использования nowdoc
echo <<<'EOD'
Пример текста,
занимающего несколько строк,
с помощью синтаксиса nowdoc. Обратные слеши всегда обрабатываются буквально,
например, \\ и \'.
EOD;

Массивы

На самом деле массив в PHP - это упорядоченное отображение, которое устанавливает соответствие между значением и ключом. Этот тип оптимизирован в нескольких направлениях, поэтому вы можете использовать его как собственно массив, список (вектор), хеш-таблицу (являющуюся реализацией карты), словарь, коллекцию, стек, очередь и, возможно, что-то ещё. Так как значением массива может быть другой массив PHP, можно также создавать деревья и многомерные массивы.

Объяснение этих структур данных выходит за рамки данного справочного руководства, но вы найдёте как минимум один пример по каждой из них. За дополнительной информацией вы можете обратиться к соответствующей литературе по этой обширной теме.

Синтаксис
Определение при помощи array()

Массив (тип array) может быть создан языковой конструкцией array(). В качестве параметров она принимает любое количество разделённых запятыми пар key => value (ключ => значение).

array(
  key => value,
  key2 => value2,
  key3 => value3,
  ...
)

Запятая после последнего элемента массива необязательна и может быть опущена. Обычно это делается для однострочных массивов, то есть array(1, 2) предпочтительней array(1, 2, ). Для многострочных массивов с другой стороны обычно используется завершающая запятая, так как позволяет легче добавлять новые элементы в конец массива.

$array = array(
    "foo" => "bar",
    "bar" => "foo",
);

// Использование синтаксиса короткого массива
$array = [
    "foo" => "bar",
    "bar" => "foo",
];

key может быть либо типа int, либо типа string. value может быть любого типа.

Дополнительно с ключом key будут сделаны следующие преобразования:

  • Строки (string), содержащие целое число (int) (исключая случаи, когда число предваряется знаком +) будут преобразованы к типу int. Например, ключ со значением "8" будет в действительности сохранён со значением 8. С другой стороны, значение "08" не будет преобразовано, так как оно не является корректным десятичным целым.
  • Числа с плавающей точкой (float) также будут преобразованы к типу int, то есть дробная часть будет отброшена. Например, ключ со значением 8.7 будет в действительности сохранён со значением 8.
  • Тип bool также преобразовываются к типу int. Например, ключ со значением true будет сохранён со значением 1 и ключ со значением false будет сохранён со значением 0.
  • Тип null будет преобразован к пустой строке. Например, ключ со значением null будет в действительности сохранён со значением "".
  • Массивы (array) и объекты (object) не могут использоваться в качестве ключей. При подобном использовании будет генерироваться предупреждение: Недопустимый тип смещения (Illegal offset type).

Если несколько элементов в объявлении массива используют одинаковый ключ, то только последний будет использоваться, а все другие будут перезаписаны.

Объекты (object)

Инициализация объекта

Для создания нового объекта, используйте выражение new, создающее в переменной экземпляр класса:

class foo
{
    function do_foo()
    {
        echo "Код foo.";
    }
}

$bar = new foo;
$bar->do_foo();

Преобразование в объект

Если object преобразуется в object, объект не изменится. Если значение другого типа преобразуется в object, создаётся новый экземпляр встроенного класса stdClass. Если значение было null, новый экземпляр будет пустым. Массивы преобразуются в object с именами полей, названными согласно ключам массива и соответствующими им значениям. Обратите внимание, что в этом случае до PHP 7.2.0 числовые ключи не будут доступны, пока не проитерировать объект.

$obj = (object) array('1' => 'foo');
var_dump(isset($obj->{'1'})); // выводит 'bool(true)', начиная с PHP 7.2.0; 'bool(false)' ранее
var_dump(key($obj)); // выводит 'string(1) "1"', начиная с PHP 7.2.0; 'int(1)' ранее

При преобразовании любого другого значения, оно будет помещено в поле с именем scalar соответствующему типу.

$obj = (object) 'привет';
echo $obj->scalar;  // выведет 'привет'

Функции обратного вызова (callback-функции)

Callback-функции могут быть обозначены объявлением типа callable.

Некоторые функции, такие как call_user_func() или usort(), принимают определённые пользователем callback-функции в качестве параметра. Callback-функции могут быть как простыми функциями, так и методами объектов, включая статические методы классов.

Передача

В PHP функции передаются по имени в виде строки. Можно использовать любые встроенные, либо созданные пользователем функции, за исключением конструкций языка, таких как: array(), echo, empty(), eval(), exit(), isset(), list(), print или unset().

Метод созданного объекта (object) передаётся как массив, содержащий объект по индексу 0 и имя метода по индексу 1. Доступ к закрытым и защищённым методам разрешён изнутри класса.

Статические методы класса также могут быть вызваны без создания экземпляра объекта класса путём передачи имени класса вместо объекта в элементе массива с индексом 0 или выполнения 'ClassName::methodName'.

Помимо обычных пользовательских функций, в качестве callback-функции можно передавать анонимные функции и стрелочные функции.

Как правило, любой объект, реализующий __invoke(), также может быть передан в параметр callback.

Пример #1 Пример callback-функции
// Пример callback-функции
function my_callback_function() {
    echo 'Привет, мир!';
}

// Пример callback-метода
class MyClass {
    static function myCallbackMethod() {
        echo 'Привет, мир!';
    }
}

// Тип 1: Простой callback
call_user_func('my_callback_function');

// Тип 2: Вызов статического метода класса
call_user_func(array('MyClass', 'myCallbackMethod'));

// Тип 3: Вызов метода класса
$obj = new MyClass();
call_user_func(array($obj, 'myCallbackMethod'));

// Тип 4: Вызов статического метода класса
call_user_func('MyClass::myCallbackMethod');

// Тип 5: Вызов относительного статического метода
class A {
    public static function who() {
        echo "A\n";
    }
}

class B extends A {
    public static function who() {
        echo "B\n";
    }
}

call_user_func(array('B', 'parent::who')); // A

// Тип 6: Объекты, реализующие __invoke, могут быть использованы как callback
class C {
    public function __invoke($name) {
        echo 'Привет ', $name, "\n";
    }
}

$c = new C();
call_user_func($c, 'PHP!');

Пример #2 Пример callback-функции с использованием замыкания
// Наше замыкание
$double = function($a) {
    return $a * 2;
};

// Диапазон чисел
$numbers = range(1, 5);

// Использование замыкания в качестве callback-функции
// для удвоения каждого элемента в нашем диапазоне
$new_numbers = array_map($double, $numbers);

print implode(' ', $new_numbers);

Результат выполнения данного примера: 2 4 6 8 10

Итерируемые (iterable)

Iterable - псевдотип, введённый в PHP 7.1. Он принимает любой массив (array) или объект, реализующий интерфейс Traversable. Оба этих типа итерируются с помощью foreach и могут быть использованы с yield from в генераторах.

Использование Iterable

Тип iterable может использоваться как тип параметра для указания, что функция принимает набор значений, но ей не важна форма этого набора, пока он будет использоваться с foreach. Если значение не является массивом или объектом, реализующим Traversable, будет выброшено исключение TypeError.

Пример #1 Пример использования iterable в качестве параметра
function foo(iterable $iterable) {
    foreach ($iterable as $value) {
        // ...
    }
}

Параметры, объявленные как iterable, могут использовать null или массив в качестве значения по умолчанию.

Пример #2 Пример установки значения по умолчанию для iterable
function foo(iterable $iterable = []) {
    // ...
}

Iterable также может использоваться как возвращаемый тип для указания, что функция вернёт итерируемое значение. Если возвращаемое значение не является массивом или объектом, реализующим Traversable, будет выброшено исключение TypeError.

Пример #3 Пример использования iterable в качестве возвращаемого типа
function bar(): iterable {
    return [1, 2, 3];
}

Функции, объявляющие iterable как возвращаемый тип, также могут быть генераторами.

Пример #4 Пример использования iterable в качестве возвращаемого значения генератора
function gen(): iterable {
    yield 1;
    yield 2;
    yield 3;
}

Ресурс (resource)

Resource - это специальная переменная, содержащая ссылку на внешний ресурс. Ресурсы создаются и используются специальными функциями.

Преобразование в ресурс

Поскольку тип resource содержит специальные указатели на открытые файлы, соединения с базой данных, области изображения и тому подобное, преобразование в этот тип не имеет смысла.

Освобождение ресурсов

Благодаря системе подсчёта ссылок, введённой в Zend Engine, определение отсутствия ссылок на ресурс происходит автоматически, после чего он освобождается сборщиком мусора. Поэтому очень редко требуется освобождать память вручную.

NULL

Специальное значение null представляет собой переменную без значения. null - это единственно возможное значение типа null.

Переменная считается null, если:

  • ей была присвоена константа null.
  • ей ещё не было присвоено никакого значения.
  • она была удалена с помощью unset().
Синтаксис

Существует только одно значение типа null - регистронезависимая константа null.

$var = NULL;