Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Какой из вариантов проверки целого числа лучше?
 
 автор: TetRiska   (13.10.2012 в 01:19)   письмо автору
 
 

Всем привет. Ожидается целое число, кроме ноля. Есть 3 мне известных варианта:

1 - if(is_numeric($id) == false || $id == 0){exit;} // тут приходится проверять число ли это и после чего еще дополнительно проверять не ноль ли это, но по идее пропустит 09, 009 и тд, чего бы не хотелось

2 - if(!preg_match("/^(?:[1-9]\d*)$/", $id)){exit;} //регулярка не пропустит не число, также не даст в начале числового значения поставить ноль (09, 009 и тд) и также сам ноль

3- if(floor($id) == 0){exit;} //вариант хорош, т.к. любое не число сделает нолем после чего я тут же проверю на ноль и если это так, то выход

  Ответить  
 
 автор: confirm   (13.10.2012 в 06:23)   письмо автору
 
   для: TetRiska   (13.10.2012 в 01:19)
 

if((int)$id) и не надо никаких ==0, а floor, это для несколько иных чисел.

  Ответить  
 
 автор: TetRiska   (13.10.2012 в 09:49)   письмо автору
 
   для: confirm   (13.10.2012 в 06:23)
 

Приведу такую ситуацию, если мне передадут в переменную такое:
- 0
-08
-008
- массив чего либо
- текст

то скрипт должен сразу дать exit, пропускаем лишь:
- от 1 до ....

if((int)$id){exit;} с этим справится? опробовать сейчас нет возможности

  Ответить  
 
 автор: Sfinks   (13.10.2012 в 10:07)   письмо автору
 
   для: TetRiska   (13.10.2012 в 09:49)
 

Использовать напрямую то, что вам передадут - в корне не правильно.
ВСЕГДА нужно переданное обработать, присвоить новой переменной и результат уже использовать!
Следовательно:
<?
  $id 
= (int)$_GET['id']; // тут уберутся ведущие нули
  
if( !$id ) exit; // тут выполнятся остальные условия

  Ответить  
 
 автор: confirm   (13.10.2012 в 10:25)   письмо автору
 
   для: TetRiska   (13.10.2012 в 09:49)
 

Проверять то собственно нечего, достаточно заглянуть в руководство, прочесть о типах и их преобразовании.
Вы в конце концов научитесь формулировать свои вопросы в полном объеме? Сперва вы приводите пример с числами, при чем непонятно чего и с ними пытаетесь сотворить, так как вопрос вроде бы о целых, а почему-то оперируете всем чем угодно, включая и floor. Ну а далее пошли еще добавки: массив, текст...

08, если это из формы, то это строка, и преобразование ее к числу как (int), или (integer), или intval() вернет вам 8. Это приемлемо для вас? Нет, значит надо говорить не преобразовании и проверке, а соответствии шаблону, а это только рег. выражения.

08 представленное как число при преобразовании в integer вернет 0, так как как это запись восьмеричного числа, но за его диапазоном, а диапазон от 01 до 07, это верные восьмеричные числа, и будут возвращать целое.

(int)string вернет ноль. Массив после преобразования будет возвращать 0, если массив пуст, или 1 в противном случае.

Вот собственно и все. Определитесь чего вам надо, и...

  Ответить  
 
 автор: Jackson   (13.10.2012 в 12:17)   письмо автору
 
   для: TetRiska   (13.10.2012 в 09:49)
 

>Приведу такую ситуацию, если мне передадут в переменную такое:
>- 0
>-08
>-008
>- массив чего либо
>- текст
>
>то скрипт должен сразу дать exit, пропускаем лишь:
>- от 1 до ....
>
>if((int)$id){exit;} с этим справится? опробовать сейчас нет возможности

Нет, не справится! при 08 и 008 (int) вернет тебе 0, т.к. с нуля начинаются числа в восмеричном исчислении, и 08 09 для него незначащие позиции (сам когда то на такое попался), а при массиве и строке - вернет 1 и пропустит далее, наплевав на якобы "проверку целочисленности"

  Ответить  
 
 автор: confirm   (13.10.2012 в 12:19)   письмо автору
 
   для: Jackson   (13.10.2012 в 12:17)
 

>а при массиве и строке - вернет 1...

Это кто такое вернет, преобразование в integer? А не ошибаетесь?

  Ответить  
 
 автор: Jackson   (13.10.2012 в 12:21)   письмо автору
 
   для: confirm   (13.10.2012 в 12:19)
 

>>а при массиве и строке - вернет 1...
>
>Это кто такое вернет, преобразование в integer? А не ошибаетесь?

(int) вернет... согласен с замечаниями выше про пустой и заполненный массив - соответственно 0 и 1 будет

  Ответить  
 
 автор: confirm   (13.10.2012 в 12:25)   письмо автору
 
   для: Jackson   (13.10.2012 в 12:21)
 

А строка значит все такие 1 будет возвращать? А не наоборот ли?
А почему массив так возвращает, так это вытекает из того, что это простое преобразование булевого значения (равноценно, как если бы проверяли if($array)) в этом случае - false (0) для пустого массива, и true (1) для имеющего элементы.

  Ответить  
 
 автор: Jackson   (13.10.2012 в 12:30)   письмо автору
 
   для: confirm   (13.10.2012 в 12:25)
 

со всем полностью согласен... про строку погорячился.

а проверить, является ли значение переменной целым типом, можно просто функцией is_int($id);

только что автор будет делать дальше, если ему передадут 08 или 09 - это открытый вопрос

  Ответить  
 
 автор: confirm   (13.10.2012 в 12:35)   письмо автору
 
   для: Jackson   (13.10.2012 в 12:30)
 

А если подумать? Если проверяются данные из формы, а это, даже если и содержащие целые числа, строковые значения. А данная функция может вернуть true только именно для целого ЧИСЛА. Об этом ведь даже в описании ее сказано, копирую специально для вас:

Замечание:

Чтобы проверить, что переменная является числом или строкой, содержащей число (как поле ввода в форме, которое всегда является строкой), используйте is_numeric().

А что он будет делать с 08 и т.п., я не знаю, как и не знаю чего он еще захочет проверять, кроме строк, массивов....

  Ответить  
 
 автор: Jackson   (13.10.2012 в 12:43)   письмо автору
 
   для: confirm   (13.10.2012 в 12:35)
 

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

  Ответить  
 
 автор: Jackson   (13.10.2012 в 12:54)   письмо автору
 
   для: Jackson   (13.10.2012 в 12:43)
 

да, и вовсе не факт, что данные поступают из формы )))

и опять таки, если дать функции is_numeric строку с действительным числом "0.21" будет истина.

  Ответить  
 
 автор: confirm   (13.10.2012 в 13:10)   письмо автору
 
   для: Jackson   (13.10.2012 в 12:54)
 

Я все таки, на 99.999% уверен, что проверяемые данные из формы, просто исхожу из того, что этими нуликами и цифрами автор "наследил" в трех разделах форума.
Ну а почему "0.21" не будет истиной, это ведь число? Данная функция не обязана проверять, что это за число, авторы ее на это не уполномочили.

Я не знаю, чего в конечном итоге хочется автору, но из его изложения могу сказать только одно - число, строка, массив, это разные типы данных, и проверить сразу все на принадлежность к одному, плюс значение, действием "два в одном" не получится. Типы, это типы, а значения, это характеристика типа, так что как бы одно строкой да покрасивее, это из разряда излишних душевных терзаний, не более.

  Ответить  
 
 автор: Jackson   (13.10.2012 в 12:08)   письмо автору
 
   для: confirm   (13.10.2012 в 06:23)
 

>if((int)$id) и не надо никаких ==0, а floor, это для несколько иных чисел.

какая же это проверка на целочисленность?? в условии вы мало того, что принудительно приводите переменную $id к целочисленному типу и теряете все что было кроме целого числа, так еще и просто проверяете существует ли переменная с именем id...

  Ответить  
 
 автор: confirm   (13.10.2012 в 12:11)   письмо автору
 
   для: Jackson   (13.10.2012 в 12:08)
 

А вы внимательно прочли условия автора? И вообще поняли из его дальнейшего, чего он вообще хочет проверить?
Из первого следует, что допускается только целое число, а то что вы назвали "теряете все что было кроме целого числа" вроде бы как и не нужно...
Что касается переменной под именем $id, то она в условии и проверяется.

  Ответить  
 
 автор: Jackson   (13.10.2012 в 12:23)   письмо автору
 
   для: confirm   (13.10.2012 в 12:11)
 

>А вы внимательно прочли условия автора?

ну мне сразу показалось, что автор хочет проверить целое ли ему число дали или какой то иной тип :)

  Ответить  
 
 автор: TetRiska   (13.10.2012 в 23:01)   письмо автору
 
   для: Jackson   (13.10.2012 в 12:23)
 

данные отправляются на сервер не через сабмит формы, а через jquery post

для эксперимента создал массив с такими данными:

$data = array(
    0  => array(5, "test", 12),
    1  => -5,
    2  => "-5",
    3  => 5,
    4  => "5",
    5  => 0,
    6  => "0",
    7  => 3.4,
    8  => "3.4",
    9  => -3.4,
    10 => "-3.4",
    11 => "test",
    12 => 5+"test",
    13 => "5test",
    14 => "test"+5,
    15 => "test5",
    16 => 09,
    17 => "09",
    18 => 0-9,
    19 => false,
    20 => true,
    21 => null,
    22 => ""
);

и начал пробовать смотреть вывод:

$num = 0;
foreach ($data as $value){
    if(gettype($value) == 'integer' && $value > 0){
        echo $num." => ".gettype($value)." => ".$value."<br/>";
    }
    $num++;
}

или

$num = 0;
foreach ($data as $value){
    if(is_int($value) == true && $value > 0){
        echo $num." => ".gettype($value)." => ".$value."<br/>";
    }
    $num++;
}

даст

3  => integer => 5
12 => integer => 5
14 => integer => 5

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

другие примеры не прошли проверку т.к. там проскакивают различные типы данных, хотя в итоге мы получим значение, которые еще придется обработать, но если посудить, зачем пропускать левый тип, который наверняка послан "кем-то"

$num = 0;
foreach ($data as $value){
    if(intval($value) > 0){
        echo $num." => ".gettype($value)." => ".$value."<br/>";
    }
    $num++;
}

или

$num = 0;
foreach ($data as $value){
    if((int)$value > 0){
        echo $num." => ".gettype($value)." => ".$value."<br/>";
    }
    $num++;
}

даст

0  => array => Array
3  => integer => 5
4  => string => 5
7  => double => 3.4
8  => string => 3.4
12 => integer => 5
13 => string => 5test
14 => integer => 5
17 => string => 09
20 => boolean => 1

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования