Ошибка PHP 8.5 при передаче null в file_exists() и function_exists(): причины и решение
Краткое описание: В PHP 8.5 ужесточилась проверка типов аргументов для встроенных функций. Передача null в функции, ожидающие строку (например, file_exists() или function_exists()), теперь вызывает предупреждение об устаревшем поведении (deprecation notice). Разбираемся, почему это происходит, и как правильно исправить код, чтобы он работал в PHP 8.5 и будущих версиях.
Ошибка возникает не потому, что file_exists() устарела сама по себе, а потому что в PHP 8.5 строже относятся к типам передаваемых аргументов. Раньше PHP мог автоматически преобразовывать null в пустую строку, но теперь это поведение объявлено устаревшим (deprecated).
В будущих версиях PHP (например, в PHP 9) передача null в такие функции, скорее всего, приведёт к фатальной ошибке. Поэтому код нужно исправить сейчас.
✅ Правильное решение
Проблема не в том, чтобы заменить file_exists() на другую функцию, а в том, чтобы гарантировать, что в неё передаётся строка, а не null.
Самый простой и правильный способ — добавить проверку перед вызовом:
if ($filename !== null && file_exists($filename)) {
// Файл существует
}Или, если у вас есть значение, которое может быть null, можно использовать оператор null coalescing (??), чтобы подставить значение по умолчанию (например, пустую строку):
// Вместо file_exists($filename)
file_exists($filename ?? '')Однако лучше использовать первый вариант с явной проверкой, так как передача пустой строки в file_exists() может привести к ложному результату (она всегда вернёт false для несуществующего файла, но это менее очевидно и может скрыть другие ошибки).
💡 Альтернативные функции
Вы также можете использовать функции is_file() или is_dir() для более точной проверки, но они подвержены той же проблеме с типами аргументов. Поэтому проверку на null нужно делать в любом случае.
📌 Краткий итог
- Не заменяйте
file_exists()на другую функцию. - Всегда проверяйте, что переменная, которую вы передаёте, не равна
null. - Используйте
if ($filename !== null && file_exists($filename))илиfile_exists($filename ?? '')как временное решение.
Это позволит вашему коду работать корректно в PHP 8.5 и быть готовым к будущим версиям.
Да, function_exists() подвержена той же проблеме.
Её сигнатура в документации — function_exists(string $function): bool. Это означает, что она требует строку и не принимает null.
Попытка передать null в function_exists() в PHP 8.5 приведёт к такому же предупреждению (deprecation notice), как и в случае с file_exists().
✅ Единственно правильное решение
Как и в прошлом случае, проблему решает проверка переменной перед передачей:
if ($functionName !== null && function_exists($functionName)) {
// Функция существует
}Или, как временное решение, можно использовать оператор ?? для подстановки значения по умолчанию:
function_exists($functionName ?? '')📌 Итог
- Любая нативная PHP-функция, которая в документации ожидает
string(а неstring|null), вызовет такое же предупреждение при передачеnull. - Универсального «безопасного» заменителя для
function_exists()нет, так как проблема не в самой функции, а в некорректном типе передаваемых данных. - Проверяйте переменную на
nullперед вызовом — это надёжное и совместимое с будущими версиями PHP решение.
Список официальных источников и RFC:
Основной RFC, который ввёл deprecation в PHP 8.1
Deprecate passing null to non-nullable arguments of internal functions
- Ссылка: https://wiki.php.net/rfc/deprecate_null_to_scalar_internal_arg
- Суть: Этот RFC сделал передачу
nullв не-nullable аргументы внутренних функций устаревшей, чтобы синхронизировать поведение внутренних и пользовательских функций. Именно с этого начались deprecation-уведомления, о которых идёт речь.
Обсуждение и планы на PHP 8.5
Deprecations for PHP 8.5
- Ссылка: https://wiki.php.net/rfc/deprecations_php_8_5
- Суть: В этом RFC для PHP 8.5 уточняется deprecation для
readdir(),rewinddir()иclosedir()при передачеnull. Это часть общего курса на ужесточение типов.
Контекст и дополнительные источники
- Обсуждение на php.internals: https://externals.io/message/112327 — содержит аргументы о том, почему это изменение создаёт проблемы при обновлении.
- Репозиторий php-src (коммит с реализацией RFC): https://github.com/php/php-src/commit/b10416a.
- NULL Coercion Consistency (проект RFC): https://wiki.php.net/rfc/null_coercion_consistency — обсуждает проблемы обратной совместимости, вызванные этим изменением.