Nullable типы

Тренажер по PHP для пользователей с начальным уровнем подготовки.

Тренажер PHP

В этом модуле мы изучаем nullable типы в PHP функциях. Nullable типы позволяют параметрам и возвращаемым значениям функций быть либо определенного типа, либо null. Это дает большую гибкость при работе с опциональными данными. Вы научитесь правильно объявлять nullable параметры с помощью символа ?, обрабатывать null значения, использовать значения по умолчанию и понимать разницу между nullable и обычными типами. Также рассмотрим особенности работы с nullable типами в PHP 7.1+ и альтернативный синтаксис union типов в PHP 8.0. Задания расположены от базового синтаксиса до продвинутых случаев использования.

Список тем

Базовый синтаксис nullable типа

id: 38994_task1

Объявите функцию с nullable параметром типа string. Функция должна принимать имя пользователя или null.

Заполните пропуски
<?php
function greetUser(input1S $name) {
    if ($name === null) {
        return "Hello, Guest!";
    }
    return "Hello, " . $name . "!";
}

// Использование функции
echo greetUser("Alice");  // Hello, Alice!
echo greetUser(input2S);   // Hello, Guest!
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

Исправьте ошибки в nullable объявлениях

id: 38994_task2

В коде есть ошибки в синтаксисе nullable типов. Найдите и исправьте их.

Найдите ошибку и исправьте
<?php
function processData(string? $data): ?array {
    if ($data === null) {
        return null;
    }
    return explode(',', $data);
}
 
function getValue(): int? {
    return rand(0, 1) ? 42 : null;
}
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

Результат функции с nullable параметром

id: 38994_task3

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

Выберите правильный вариант ответа
<?php
function calculatePrice(?float $amount, ?float $tax = 0.1) {
    if ($amount === null) {
        return "No amount";
    }
    if ($tax === null) {
        return $amount;
    }
    return $amount + ($amount * $tax);
}

echo calculatePrice(100, 0.2) . PHP_EOL;
echo calculatePrice(100, null) . PHP_EOL;
echo calculatePrice(null, 0.5);
Сообщения
Проверить
Показать подсказку

Соберите функцию с nullable типами

id: 38994_task4

Соберите функцию findUser, которая ищет пользователя по ID и возвращает массив данных или null.

Перетяните в правильном порядке строки из одного блока в другой
function findUser(?int $id): ?array {
    if ($id === null) {
        return null;
    }
    $users = [
        1 => ['name' => 'Alice', 'age' => 25],
        2 => ['name' => 'Bob', 'age' => 30]
    ];
    return $users[$id] ?? null;
}
function findUser($id) {
    return isset($users[$id]);
    $users = null;
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

Заполните пропуски nullable типами

id: 38994_task5

Используя элементы из банка, создайте функцию с правильными nullable типами для работы с опциональными данными.

Нужно правильно расставить в пропуски предложенные варианты
<?php
function createEvent(
    string $title,
    input1S $description = null,
    input2S $date = null
): array {
    $event = ['title' => $title];
    
    if ($description !== input3S) {
        $event['description'] = $description;
    }
    
    if ($date !== null) {
        $event['date'] = $date->format('Y-m-d');
    }
    
    return $event;
}
?string
?DateTime
null
string
DateTime
false
?array
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

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

id: 38994_task6

Проанализируйте код с цепочкой nullable проверок и укажите финальный результат.

Что должно получиться?
<?php
function processOrder(?array $items, ?float $discount = 0.0): ?float {
    if ($items === null || empty($items)) {
        return null;
    }
    
    $total = array_sum($items);
    
    if ($discount === null) {
        return $total;
    }
    
    return $total - ($total * $discount);
}

$order = [10.5, 20.0, 15.5];
$result = processOrder($order, 0.1);
echo $result;
Сообщения
Проверить
Показать подсказку

Типы и их nullable версии

id: 38994_task7

Сопоставьте описания с правильными nullable объявлениями типов.

Сопоставьте строки в правой части с соответствующими строками в левой по порядковому номеру
Параметр может быть целым числом или null
Возвращает массив, никогда не null
Параметр строка или null, по умолчанию null
Union тип: строка или null (PHP 8+)
Параметр обязательно объект класса User
array
?int
User
?string $text = null
string|null
Сообщения
Проверить
Показать подсказку

Проблемы совместимости типов

id: 38994_task8

В коде есть ошибки несовместимости nullable и строгих типов. Исправьте их для корректной работы.

Найдите ошибку и исправьте
<?php
declare(strict_types=1);
 
function processName(string $name): string {
    return strtoupper($name);
}
 
function handleUser(?string $username) {
    // Ошибка: передаем nullable в non-nullable
    $result = processName($username);
    return $result;
}
 
// Вызов с null вызовет ошибку
echo handleUser(null);
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

Nullable в классах и методах

id: 38994_task9

Дополните класс с nullable свойствами и методами для корректной работы с опциональными данными.

Заполните пропуски
<?php
class Product {
    private string $name;
    private input1S $description;
    private ?float $discount;
    
    public function __construct(
        string $name, 
        ?string $description = input2S,
        ?float $discount = null
    ) {
        $this->name = $name;
        $this->description = $description;
        $this->discount = $discount;
    }
    
    public function getDescription(): input3S {
        return $this->description;
    }
    
    public function hasDiscount(): bool {
        return $this->discount !== input4S;
    }
}
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

Nullable и тернарный оператор

id: 38994_task11

Определите результат работы кода с nullable типами и тернарными операторами.

Выберите правильный вариант ответа
<?php
function getValue(?int $input): string {
    // ?? проверяет именно на null
    $value1 = $input ?? 0;
    
    // ?: проверяет на истинность
    $value2 = $input ?: 0;
    
    return "v1=$value1, v2=$value2";
}

echo getValue(5) . PHP_EOL;
echo getValue(0) . PHP_EOL;
echo getValue(null);
Сообщения
Проверить
Показать подсказку

Nullable с массивами и объектами

id: 38994_task12

Проанализируйте работу функции с nullable массивами и определите финальный вывод.

Что должно получиться?
<?php
function mergeData(?array $primary, ?array $secondary = null): array {
    if ($primary === null && $secondary === null) {
        return [];
    }
    
    if ($primary === null) {
        return $secondary;
    }
    
    if ($secondary === null) {
        return $primary;
    }
    
    return array_merge($primary, $secondary);
}

$result = mergeData(['a' => 1], ['b' => 2, 'a' => 3]);
echo json_encode($result);
Сообщения
Проверить
Показать подсказку

Nullable в интерфейсах и наследовании

id: 38994_task13

Исправьте ошибки совместимости типов при реализации интерфейса с nullable типами.

Найдите ошибку и исправьте
<?php
interface DataProcessor {
    public function process(?string $data): ?array;
}
 
class JsonProcessor implements DataProcessor {
    // Ошибка: несовместимая сигнатура
    public function process(string $data): array {
        return json_decode($data, true);
    }
}
 
class XmlProcessor implements DataProcessor {
    // Ошибка: неправильный возвращаемый тип
    public function process(?string $data): array {
        if ($data === null) return [];
        return ['xml' => $data];
    }
}
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

Union типы vs Nullable (PHP 8)

id: 38994_task14

Заполните пропуски, используя современный синтаксис union типов PHP 8 как альтернативу nullable типам.

Заполните пропуски
<?php
// PHP 7.1+ nullable синтаксис
function oldWay(?string $value): ?int {
    return $value !== null ? strlen($value) : null;
}

// PHP 8.0+ union type синтаксис
function newWay(input1S $value): input2S {
    return $value !== null ? strlen($value) : null;
}

// Расширенный union тип
function processValue(input3S $data): string {
    if (is_string($data)) {
        return $data;
    }
    if (is_int($data)) {
        return (string) $data;
    }
    return 'null';
}

// Mixed с null (избыточно, так как mixed уже включает null)
function acceptAnything(input4S $anything): void {
    var_dump($anything);
}
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

Комплексный пример с nullable

id: 38994_task15

Заполните пропуски в классе сервиса, используя правильные nullable типы из банка для создания гибкой системы конфигурации.

Нужно правильно расставить в пропуски предложенные варианты
<?php
class ConfigService {
    private array $config;
    private input1S $cache = null;
    
    public function __construct(array $config, input2S $cacheDriver = null) {
        $this->config = $config;
        $this->cache = $cacheDriver;
    }
    
    public function get(string $key, mixed $default = null): mixed {
        // Сначала проверяем кэш
        if ($this->cache !== input3S) {
            $cached = $this->cache->get($key);
            if ($cached !== null) {
                return $cached;
            }
        }
        
        // Затем конфиг
        return $this->config[$key] ?? $default;
    }
    
    public function getCache(): input4S {
        return $this->cache;
    }
}

interface CacheDriver {
    public function get(string $key): input5S;
    public function set(string $key, mixed $value): void;
}
?CacheDriver
null
?mixed
CacheDriver
?array
mixed
false
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку
НайтиКурс.Ру