Устаревание передачи null в параметры строкового типа PHP

Раздел: Основы программирования на PHP -> Типы данных в PHP

В PHP 8.1 и выше при передаче значения null в параметр, объявленный с типом string, возникает предупреждение об устаревании (deprecation). Это связано с переходом к строгой типизации в будущих версиях (PHP 9). В данной статье рассматриваются способы устранения данного предупреждения без потери функциональности.

Основное решение: использование union типа string|null

Самый прямой способ избежать предупреждения - явно разрешить null в сигнатуре функции, используя объединение типов string|null (или сокращённо ?string). Это сообщает PHP, что функция ожидает либо строку, либо null, и предупреждение исчезает.

function greet(?string $name): void {
    echo "Привет, " . ($name ?? "гость") . "!";
}

greet(null); // Без предупреждения

Php check type (проверка типа переменной в php)

Цель: сохранение возможности передавать null без изменения логики. Используется, когда null является допустимым значением (например, отсутствие данных).

Какие альтернативные подходы существуют для устранения предупреждения?

Вариант 1: Явное приведение типа (string)

Если нужно гарантировать, что в функцию всегда передаётся строка, можно привести переменную к строковому типу перед вызовом. null при этом преобразуется в пустую строку.

function showLength(string $text): void {
    echo strlen($text);
}

$value = null;
showLength((string) $value); // null станет ""

Of type string is deprecated php (предупреждение об устаревании типа string в php)

Проблема: теряется различие между пустой строкой и null. Если логика функции зависит от отсутствия значения, такое преобразование может привести к ошибкам.

Вариант 2: Использование null coalescing оператора (??)

Оператор ?? позволяет задать значение по умолчанию, если переменная равна null.

function formatText(string $input): string {
    return trim($input);
}

$data = null;
echo formatText($data ?? ''); // Передаётся пустая строка

Php mime type (mime-типы в php)

Если переменная не определена (undefined), использовать ?? безопаснее, чем (string), так как не генерируется warning. Однако при работе с массивами и объектами нужно учитывать, что ?? проверяет только null, а не существование ключа.

Вариант 3: Использование ?string с проверкой внутри функции

Если необходимо явно обработать случай null внутри функции, применяется тип ?string вместе с условной логикой.

function process(?string $input): void {
    if (is_null($input)) {
        // особая обработка
        echo "Данные отсутствуют";
    } else {
        echo "Длина: " . strlen($input);
    }
}

process(null);

Php set type (функция settype() в php)

Нужно помнить, что внутри функции переменная $input может быть как строкой, так и null, поэтому все операции с ней должны быть защищены проверками.

Вариант 4: Параметр со значением по умолчанию null

Можно сделать параметр необязательным, задав ему значение по умолчанию null. При этом тип должен быть объявлен как ?string.

function logMessage(?string $message = null): void {
    echo date('Y-m-d H:i:s') . ' ' . ($message ?? 'пусто') . PHP_EOL;
}

logMessage(); // Без предупреждения, параметр пропущен

Php number type (числовые типы в php)

Вариант 5: Использование с встроенными функциями (strlen, trim и др.)

Встроенные функции, ожидающие строку, также выдают предупреждение при передаче null. Решение аналогично: либо приводить тип, либо использовать ??, либо оборачивать вызов в пользовательскую функцию с ?string.

$name = null;
// Предупреждение: strlen(null) deprecated
// Исправление:
echo strlen($name ?? '');
Некоторые функции, такие как strpos, могут возвращать false или 0, поэтому при комбинировании с ?? нужно учитывать тип возвращаемого значения.
- Php 7 types (типы данных в php 7)
- Php return types (типы возвращаемых значений в php)

Расширенные примеры с пошаговыми пояснениями

Пример 1: Пользовательская функция с передачей null

Рассмотрим функцию, которая преобразует строку в верхний регистр. При передаче null в PHP 8.1 появится deprecation warning.

Пример
// Код с предупреждением:
function upper(string $text): string {
    return strtoupper($text);
}

echo upper(null);
// Deprecated: Passing null to parameter #1 ($text) of type string is deprecated
Deprecated: strtoupper(): Passing null to parameter #1 ($string) of type string is deprecated в ... на строке ...

Исправление с union type:

Пример
function upper(?string $text): string {
    return strtoupper($text ?? '');
}

echo upper(null); // вывод: пустая строка

Теперь предупреждение не выводится. Если нужно сохранить исходное значение null, можно вернуть null при входном null.

Пример 2: Использование null в массиве с filter_var

Функция filter_var с флагом FILTER_SANITIZE_STRING ожидает строку. Передача null вызывает deprecation.

Пример
$value = null;
$result = filter_var($value, FILTER_SANITIZE_STRING);
// Deprecated
Deprecated: filter_var(): Passing null to parameter #1 ($value) of type string is deprecated

Исправление через ??:

Пример
$result = filter_var($value ?? '', FILTER_SANITIZE_STRING);
// Без предупреждения

Пример 3: Работа с PDO и значением null

При подготовке запроса с параметром, который может быть null, необходимо явно указать тип PDO::PARAM_NULL или использовать ?string в объявлении.

Пример
$pdo = new PDO('sqlite::memory:');
$pdo->exec('CREATE TABLE test (name TEXT)');

$name = null;
$stmt = $pdo->prepare('INSERT INTO test (name) VALUES (:name)');
$stmt->bindValue(':name', $name, PDO::PARAM_STR); // Deprecated в PHP 8.1
$stmt->execute();
Deprecated: PDOStatement::bindValue(): Passing null to parameter #2 ($value) of type string is deprecated

Исправление – передавать null как PDO::PARAM_NULL:

Пример
$stmt->bindValue(':name', $name, is_null($name) ? PDO::PARAM_NULL : PDO::PARAM_STR);

Более элегантный способ – использовать явный тип в методе bindValue с передачей null как отдельного параметра (начиная с PHP 8.3 есть опция).

Пример 4: Класс с типизированным свойством и сеттером

Типизированные свойства класса (string $name) тоже вызывают предупреждение при присвоении null.

Пример
class User {
    public string $name;
}

$user = new User();
$user->name = null; // Deprecated
Deprecated: Typed property User::$name must not be accessed before initialization (or assigned null)

Исправление – изменить тип свойства на ?string:

Пример
class User {
    public ?string $name;
}

$user = new User();
$user->name = null; // Работает без предупреждения

Пример 5: Комбинирование с функциями, возвращающими null

Функция array_search может вернуть false или int, но не null. Однако если результат передать в строковую функцию, нужно обработать false.

Пример
$fruits = ['apple', 'banana'];
$index = array_search('orange', $fruits); // false
// При передаче false в strlen будет warning, но не deprecated.
// Но если приведение к строке: 
echo strlen($index); 
// Stringable object?
// В данном контексте не относится к нашей теме.

Важно различать ситуации, когда возвращается null (например, из функции fun_get_arg при отсутствии аргумента). В таких случаях применяются те же методы.

Предупреждение об устаревании типа string в PHP - comments

En
Of type string is deprecated php (php)