Загрузка...

Полифиллы в WordPress-плагине: как не уронить сайт из-за PHP

Разбираем, зачем WordPress-плагину полифиллы, почему старый PHP может устроить Fatal error и как аккуратно сохранить совместимость без костылей по всему коду.
wordpress

При разработке WordPress-плагина важно помнить: плагин будет работать не только у тебя локально, но и на самых разных хостингах.

Где-то свежий PHP, нормальные расширения и всё красиво.
А где-то сервер из серии: “главное — не трогать, а то упадёт”.

В такой ситуации код может внезапно сломаться на функции, которая есть в новой версии PHP, но отсутствует на старой.

Именно так можно поймать ошибку:

Fatal error: Uncaught Error: Call to undefined function mb_rtrim()

В чём проблема

Функции:

  • mb_trim()
  • mb_ltrim()
  • mb_rtrim()

появились только в PHP 8.4.

Если WordPress-плагин запускается на PHP ниже 8.4, вызов mb_rtrim() приведёт к фатальной ошибке.

Для пользователя это выглядит просто: “плагин сломал сайт”.
Объяснение про версии PHP его, скорее всего, не утешит.

Что такое полифилл

Полифилл — это запасная реализация функции.

Логика простая:

  • если функция уже есть в PHP — используем нативную;
  • если функции нет — подключаем свою;
  • сайт не падает;
  • разработчик спит чуть спокойнее.

Для WordPress-плагинов это нормальная практика, потому что окружения у пользователей могут сильно отличаться.

Почему не заменить на rtrim()

Можно было бы быстро заменить mb_rtrim() на обычный rtrim().

Но rtrim() работает с байтами, а не с UTF-8 символами.

В WordPress-плагине это рискованно, потому что в данных могут быть:

  • русские названия товаров;
  • адреса;
  • комментарии;
  • строки из WooCommerce;
  • ответы внешних API;
  • emoji и прочие сюрпризы.

То есть rtrim() подойдёт для простых строк, но для нормальной работы с UTF-8 лучше использовать mb_*-вариант.

Решение

Добавляем отдельный файл с полифиллами, например:

includes/polyfills.php

Подключаем его при загрузке плагина:

require_once __DIR__ . '/includes/polyfills.php';

Внутри объявляем функции только если их ещё нет:

<?php

if (! function_exists('mb_trim')) {
    function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string
    {
        return mb_ltrim(
            mb_rtrim($string, $characters, $encoding),
            $characters,
            $encoding
        );
    }
}

if (! function_exists('mb_ltrim')) {
    function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string
    {
        $characters = $characters ?? " fnrtv�";

        return preg_replace(
            '/^[' . preg_quote($characters, '/') . ']+/u',
            '',
            $string
        ) ?? $string;
    }
}

if (! function_exists('mb_rtrim')) {
    function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string
    {
        $characters = $characters ?? " fnrtv�";

        return preg_replace(
            '/[' . preg_quote($characters, '/') . ']+$/u',
            '',
            $string
        ) ?? $string;
    }
}

Ключевой момент — function_exists().

На PHP 8.4 и выше будут использоваться родные функции.
На старых версиях PHP подключится наша реализация.

Почему это удобнее

Полифилл лучше, чем точечные замены по коду.

Плохой вариант:

$value = rtrim($value);

Или ещё хуже:

if (function_exists('mb_rtrim')) {
    $value = mb_rtrim($value);
} else {
    $value = rtrim($value);
}

Такой код быстро расползается по проекту и превращается в маленький филиал ада.

Лучше один раз добавить полифилл и дальше спокойно писать:

$value = mb_rtrim($value);

Основной код остаётся чистым, а совместимость живёт в одном месте.

Важный нюанс

Если на сервере вообще нет расширения mbstring, это уже отдельная проблема.

В таком случае лучше явно указать системные требования плагина: нужна поддержка mbstring.

Пытаться поддерживать вообще любое окружение — путь в боль. Особенно в WordPress, где у каждого второго хостинга своя атмосфера.

Итог

Полифилл для mb_trim(), mb_ltrim() и mb_rtrim() нужен, чтобы WordPress-плагин не падал на PHP ниже 8.4.

Он даёт сразу несколько плюсов:

  • сохраняет совместимость со старыми окружениями;
  • не ломает работу на новых версиях PHP;
  • позволяет нормально работать с UTF-8;
  • не засоряет основной код проверками;
  • держит всю совместимость в одном файле.

Это не “костыль ради костыля”, а нормальная инженерная страховка.

В WordPress-разработке такая страховка часто экономит часы отладки и немного нервных клеток.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *