Типизация данных
В отличие от ряда языков программирования в PHP при определении переменных или параметров функций можно не указывать тип данных. Однако в принципе PHP в ряде ситуаций - при определении свойств классов, параметров или возвращаемого значения функций - позволяет указать тип данных. Установка типа данных позволит избежать ситуаций, когда в программу будут переданы данные не тех типов, которые ожидалась разработчиком:
<?
function isPositive($number)
{
return $number > 0;
}
$result = isPositive("-Youdontknowwhoiam");
if($result) echo "положительное";
else echo "отрицательное или равно нулю";
В данном случае функция isPositive()
очевидно ожидает, что в качестве параметра будет передано
число,
чтобы установить, больше оно нуля или нет.
Тем не менее при вызове функции мы можем передать в нее произвольное значение. Чтобы оградиться от подобным
ситуаций
необходимо явным образом
указать, что функция может принимать только число, то есть типизировать параметр функции.
Определение типа
Какие определения типов могут использоваться при типизации:
-
bool
допустимые значенияtrue
иfalse
-
float
значение должно число с плавающей точкой -
int
значение должно представлять целое число -
string
значение должно представлять строку -
mixed
любое значение -
callable
значение должно представлять функцию -
array
значение должно представлять массив -
iterable
значение должно представлять массив или класс, который реализует интерфейсTraversable
. Применяется при переборе в циклеforeach
-
Имя класса
объект должен представлять данный класс или его производные классы -
Имя интерфейса
объект должен представлять класс, который реализует данный интерфейс -
Self
объект должен представлять тот же класс или его производный класс. Может использоваться только внутри класса -
parent
объект должен представлять родительский класс данного класса. Может использоваться только внутри класса
Типизация параметров функции
При типизации параметров тип указывается перед названием параметра:
<?
function isPositive(int $number)
{
return $number > 0;
}
$result1 = isPositive(25); // норм - 25 число
$result2 = isPositive("25"); // норм - PHP может преобразовать значение в число
$result3 = isPositive("-Youdontknowwhoiam"); // ошибка TypeError
В данном случае параметр $number
должен представлять тип int
, то есть целое
число.
Поэтому при вызове функции мы должны передать в функцию целочисленное значение. Если будет передано значение
другого
типа,
то PHP попытается преобразовать значение. В некоторых случаях такое преобразование можно завершится успешно:
$result2 = isPositive("25");
В других случаях прееобразование может завершится неудачно, и программа завершит выполнение с ошибкой TypeError:
$result3 = isPositive("-Youdontknowwhoiam");
Другой пример:
<?
function sum(array $numbers, callable $condition)
{
$result = 0;
foreach($numbers as $number) {
if($condition($number)) {
$result += $number;
}
}
return $result;
}
$isPositive = function($n) {
return $n > 0;
};
$myNumbers = [-2, -1, 0, 1, 2, 3, 4, 5];
$positiveSum = sum($myNumbers, $isPositive);
echo $positiveSum; // 15
В данном случае параметры функции должный представлять массив и другую функцию (тип callable
). В
качестве функции можно передать анонимную функцию.
Типизация возвращаемого значения
Для установки типа возвращаемого из функции значения после списка параметров указывается двоеточие :
и
после него тип данных:
<?
function isPositive (int $number) : bool
{
return $number > 0;
}
$result = isPositive(34);
В данном случае функция isPositive
должна возвращать значение типа bool
, то есть
true
или false
.
Другой пример - возвращение функции:
<?
function select($n): callable
{
switch($n) {
case 1: return function($a, $b) {return $a + $b;};
case 2: return function($a, $b) {return $a - $b;};
case 3: return function($a, $b) {return $a * $b;};
default: return function($a, $b) {return $a . " " . $b;};
}
}
$selection = select(2);
echo $selection(4,5); // -1
Особо стоит отметить ключевое слово static
, добавленное в PHP 8, которое применяется, если надо
возвратить из метода класса объект этого же класса:
<?
class Node {
function generate() : static
{
return new Node();
}
}
$node1 = new Node();
$node2 = $node1->generate();
Типизация свойств
В качестве типа свойств может применяться любой тип кроме callable
:
<?
class Person {
public $name;
public int $age;
}
$tom = new Person();
$tom->name = "Tom";
$tom->age = 36; // корректное значение
echo $tom->age; // 36
$tom->age = "36"; // корректное значение, так как PHP может преобразовать в число
echo $tom->age; // 36
$tom->age = "thirty-eight"; // некорректное значение, возникнет ошибка TypeError
echo $tom->age;
В данном случае явным образом определено, что свойство $age
представляет именно тип int
, то
есть целое число. Соответственно этому свойству мы сможем присвоить только целое число.
Стоит учитывать, что свойство, для которого не указан тип данных, по умолчанию имеет значение null
.
Тогда как свойство, для которого указан тип, неинициализировано, то есть не имеет никакого конкретного значения.
<?
class Person {
public $name; // равно null
public int $age; // неинициализировано
}
Соответственно если нетипизированное свойство мы сможем использовать, то при попытке обратиться к типизированному, но неинициализиованному свойству программа завершит выполнение ошибкой:
$tom = new Person();
echo $tom->name; // норм - null
echo $tom->age; // ошибка - свойство неинициализировано
Тип Union
В PHP 8 был добавлен тип union
или объединение, который по сути представляет объединение
типов, разделенных вертикальной чертой |
.
Например, мы хотим написать функцию сложения чисел, и чтобы в функцию можно было передавать только числа. Однако
числа в PHP предствлены двумя
типами - int
и float
. Чтобы не создавать по функции для каждого типа, применим
объединения:
<?
function sum(int|float $n1, int|float $n2,): int|float
{
return $n1 + $n2;
}
echo sum(4, 5); // 9
echo "<br>";
echo sum(2.5, 3.7); // 6.2