Типизация данных

Последнее обновление: 31.03.2021

В отличие от ряда языков программирования в 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

В данном случае мы говорим, что параметры $n1 и $n2 могут представлять как тип int, так и тип float. Аналогично возвращаемое значение также может представлять либо int, либо float.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850