Вопрос или проблема
Я хотел бы очистить поле ввода типа целое число в WordPress. Вот так..
<input type="number" name="amount" />
Что мне теперь делать?
Странно, что WordPress до сих пор не предоставляет функции для очистки чисел. Распространенная проблема заключается в том, что (int)
и т. д. просто усечают ввод, и они не работают, если ввод содержит разделители. Принуждение к типу на ввод, например 4,000
, дает 4
, а не 4000
, и разделители различаются в зависимости от локали.
Существует NumberFormatter::parse()
, который довольно строг:
$nf = new NumberFormatter('en_CA', NumberFormatter::DECIMAL);
var_dump($nf->parse('4 500,9', NumberFormatter::TYPE_INT64));
var_dump($nf->parse('4 5002,9', NumberFormatter::TYPE_INT64));
Вывод:
int(4500)
bool(false)
Он также усечает числа и не работает, если ввод не имеет точно правильный формат.
В качестве альтернативы, ввод может быть разобран, предполагя, что все, что не является арабской цифрой (0-9) или десятичной точкой для данной локали, не имеет значения:
# получить ожидаемый символ десятичной точки для текущей локали
$radix = nl_langinfo(DECIMAL_POINT);
# вернуться к "." если функция локали завершилась неудачей, и экранировать его для использования в PCRE
$radix = preg_quote($radix === false ? '.' : $radix, "https://wordpress.stackexchange.com/");
# удалить все, что не является цифрой или десятичной точкой
$parsed = preg_replace("/[^\d$radix]+/", '', $input);
# получить части числа и терпеть повторяющиеся десятичные точки
$parsed = preg_split("/$radix+/", $parsed);
# либо усечь дробную часть...
$parsed_truncated = (int) $parsed[0];
# либо округлить его
$parsed_rounded = (int) round($parsed[0] . '.' . ($parsed[1] ?? '0'), 0);
Округленный вывод будет 1010
от ввода вроде 10,0 9. 7
. Он не обрабатывает отрицательные числа, но их можно обнаружить, сначала проверяя ввод на наличие символа, возвращаемого nl_langinfo(NEGATIVE_SIGN)
.
Ответ или решение
Чтобы обеспечить безопасную обработку целочисленных значений в WordPress, необходимо учитывать, что просто преобразование через (int)
не всегда является надежным решением, особенно если пользователь вводит числа в нестандартном формате, например, с разделителями или пробелами. Вот пошаговое руководство по безопасной обработке целочисленного ввода:
Шаг 1: Получение значения из поля ввода
Предположим, у вас есть следующее поле ввода на вашем сайте:
<input type="number" name="amount" />
Шаг 2: Получение и очистка входных данных
В вашем обработчике формы вы можете использовать следующий код для получения и очистки значения:
// Получение входных данных из запроса
$input = isset($_POST['amount']) ? sanitize_text_field($_POST['amount']) : '';
// Получаем символ десятичной точки для текущей локали
$radix = nl_langinfo(DECIMAL_POINT);
$radix = preg_quote($radix === false ? '.' : $radix, '/');
// Удаляем все символы, кроме цифр и десятичной точки
$parsed = preg_replace("/[^\d$radix]+/", '', $input);
// Разделяем число на целую и дробную части
$parsed_parts = preg_split("/$radix+/", $parsed);
// Обрабатываем целую часть, округляя или преобразуя в целое число
if (isset($parsed_parts[0])) {
// Округление
$parsed_rounded = (int) round($parsed_parts[0] . '.' . ($parsed_parts[1] ?? '0'), 0);
} else {
$parsed_rounded = 0; // Если нет введенных значений
}
// Результат
echo "Значение: " . $parsed_rounded;
Шаг 3: Дополнительные проверки
Если вы хотите добавить поддержку отрицательных чисел, вы можете проверить наличие знака минус в вводимых данных:
// Проверка на наличие знака минус
$is_negative = strpos($input, nl_langinfo(NEGATIVE_SIGN)) !== false;
if ($is_negative) {
$parsed_rounded *= -1; // Меняем знак результата
}
Шаг 4: Использование функции
Этот код может быть инкапсулирован в функцию, чтобы облегчить его повторное использование:
function sanitize_integer_input($input) {
$radix = nl_langinfo(DECIMAL_POINT);
$radix = preg_quote($radix === false ? '.' : $radix, '/');
$parsed = preg_replace("/[^\d$radix]+/", '', $input);
$parsed_parts = preg_split("/$radix+/", $parsed);
if (isset($parsed_parts[0])) {
$parsed_rounded = (int) round($parsed_parts[0] . '.' . ($parsed_parts[1] ?? '0'), 0);
} else {
$parsed_rounded = 0;
}
$is_negative = strpos($input, nl_langinfo(NEGATIVE_SIGN)) !== false;
if ($is_negative) {
$parsed_rounded *= -1;
}
return $parsed_rounded;
}
// Пример использования
$sanitized_amount = sanitize_integer_input($_POST['amount']);
Заключение
С помощью этого метода вы сможете корректно обрабатывать целочисленные значения, учитывая различные форматы ввода. Этот подход не только очищает данные, но и преобразует их в ожидаемый формат, что снижает риск возникновения ошибок в дальнейшей обработке.