Intereting Posts
Как вы устанавливаете переключатель CodeIgniter, прежде чем он находится в $ _POST? memory_limit = 1024M, все еще, Невозможно выделить память: не удалось создать дочерний процесс: / opt / suphp / sbin / suphp Колонка не найдена: 1054 Unknown column laravel php class html-dom dosen't возвращает весь html Ошибка ZendFatal: класс 'Zend \ Ldap \ Ldap' не найден Всплывающее диалоговое окно подключения к Facebook PHP DOM: Как получить дочерние элементы по имени тега элегантным способом? PHP: fopen () Разрешение отклонено Функция «Редактировать» для сообщений на форуме и т. Д. jQuery datepicker не работает с динамическим HTML PHP Специальная функция SMTP-почты Возврат ERROR fputs send bytes failed errno = 32 Разбитая труба Как получить список общих друзей на Facebook с помощью их API? Возврат ключей, если 3 соседних значения соответствуют кодирование / декодирование данных между php / java для android Самый простой способ удалить все пробелы из файла кода?

Надежное целочисленное типирование

Я работаю над пакетом валидатора данных для PHP (в основном как упражнение в некоторых новых дополнениях в 5.3, таких как пространства имен). Я планирую иметь основной класс валидатора, который использует классы плагинов для фактической проверки.

Первый плагин проверки, который я строю, просто для целых чисел. Источник ниже:

namespace validator\validatorplugins; class Integer implements ValidatorPlugin { private $field = NULL; public function cast () { return ($this -> field = (int) ($this -> field * 1)); } public function isValid () { if (!$isValid = is_int ($this -> field * 1)) { $this -> field = NULL; } return ($isValid); } public function __construct ($field) { $this -> field = $field; } public function __toString() { return ((string) $this -> field); } } 

Я использую следующие тесты вышеуказанного класса:

 $a = new Integer (0xDEADBEEF); var_dump ($a -> isValid ()); var_dump ($a -> cast ()); echo ($a . "\n\n"); $b = new Integer ('0xDEADBEEF'); var_dump ($b -> isValid ()); var_dump ($b -> cast ()); echo ($b . "\n\n"); $c = new Integer (0777); var_dump ($c -> isValid ()); var_dump ($c -> cast ()); echo ($c . "\n\n"); $d = new Integer ('0777'); var_dump ($d -> isValid ()); var_dump ($d -> cast ()); echo ($d . "\n\n"); 

Из приведенных выше тестовых примеров я получаю следующие результаты:

bool (true) int (3735928559) 3735928559

bool (true) int (3735928559) 3735928559

bool (true) int (511) 511

bool (true) int (777) 777

Как вы можете видеть, я столкнулся с проблемой со строкой, которая кодирует восьмеричное число. Он должен оцениваться до 511 (0777 в базе 10), но я фактически получаю 777 вместо этого.

Поскольку однажды я могу использовать этот класс для проверки форм, и поскольку формы всегда рассматриваются как массивы строк PHP, вы можете видеть, что обработка восьмеричных чисел, которые являются строками с этим плагином, является проблематичной.

Я пробовал различные подходы к целочисленной проверке (с помощью is_int всегда возвращает false для строк, умножая на 1, а is_numeric не будет захватывать float, typecasting и intval – создает нежелательный результат при работе с восьмеричными числами). Есть ли другой подход, который я мог бы использовать, который будет работать для базы 10 (десятичный), базы 16 (шестнадцатеричный) и базы 8 (восьмеричный)?

Solutions Collecting From Web of "Надежное целочисленное типирование"

intval имеет необязательный аргумент $base :

 intval('0777', 8); // 511 intval('0777', 10); // 777 intval('0777'); // 777 intval(0777); // 511 

Поэтому вы можете сделать что-то вроде этого:

 $i = '0777'; $base = 10; if (strtolower(substr($i, 0, 2)) === '0x') $base = 16; else if (substr($i, 0, 1) === '0') $base = 8; intval($i, $base); 

Сначала вам нужно определить, как восьмеричное число представлено в строке. Потому что некоторые люди склонны говорить, что строка типа "0777" является десятичным значением 777 .

Итак, как ваш класс должен знать, что думал пользователь при выполнении ввода, который вы хотели бы проверить (или более правильно преобразовать в целочисленное значение).

Насколько вам интересно, чтобы имитировать то, как сам PHP решает значение «как PHP», вы можете имитировать с помощью eval ( Demo ):

 <?php $value = '0777'; $value = eval("return $value;"); var_dump($value); 

Однако это не решает основной проблемы дизайна. У вас должен быть DecimalInteger или HexadecimalInteger или OctalInteger для вашей линейки ваших классов песочницы.