За последние 24 часа нас посетили 16508 программистов и 1646 роботов. Сейчас ищут 1617 программистов ...

Объясните несведующему про in_array

Тема в разделе "Вопросы от блондинок", создана пользователем Hight, 7 янв 2011.

  1. Hight

    Hight Старожил
    Команда форума Модератор

    С нами с:
    5 мар 2006
    Сообщения:
    7.153
    Симпатии:
    0
    Адрес:
    из злой параллельной вселенной
    PHP:
    1. <?php header('Content-Type: text/html; charset=utf-8');
    2.  
    3. /* Из мана:
    4.  * range — Создать массив, содержащий диапазон элементов
    5.  * in_array — Проверить, присутствует ли в массиве значение
    6.  */
    7.  
    8. // Массив в диапазоне элементов типа int от 1 до 10
    9. $int_range_arr = range(1, 10);
    10.  
    11. // Посмотрим на содержимое массива
    12. echo'<pre>'; print_r($int_range_arr); echo'</pre>';
    13.  
    14. // Строка
    15. $string = '9 моё любимое число';
    16.  
    17. // Проверим, присутствует ли строка в массиве - ПРИСУТСТВУЕТ!!! Не понимаю!!!
    18. if(in_array($string, $int_range_arr)) echo'Строка "9 моё любимое число" входит в диапазон от 1 до 10<br>';
    19.  
    20. // А теперь проверим в strict mode - НЕ ПРИСУТСТВУЕТ. Понимаю.
    21. if(in_array($string, $int_range_arr, true)) echo'Строка "9 моё любимое число" входит в диапазон от 1 до 10<br>';
    22.  
    23. // Число
    24. $int = 9;
    25.  
    26. // Проверим, присутствует ли число в массиве - ПРИСУТСТВУЕТ. Понимаю.
    27. if(in_array($int, $int_range_arr)) echo'Число "9" входит в диапазон от 1 до 10<br>';
    28.  
    29. // А теперь проверим в strict mode - ПРИСУТСТВУЕТ. Понимаю.
    30. if(in_array($int, $int_range_arr, true)) echo'Число "9" входит в диапазон от 1 до 10<br>';
    31.  
    32. /*
    33.  *
    34.  * Внимание, Вопрос знатокам! Почему в первом случае функция in_array возвращает true?!
    35.  *
    36.  */
    37.  
    38. ?>
     
  2. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    Hight
    Говеный type hinting, как всегда.
     
  3. Hight

    Hight Старожил
    Команда форума Модератор

    С нами с:
    5 мар 2006
    Сообщения:
    7.153
    Симпатии:
    0
    Адрес:
    из злой параллельной вселенной
    Apple
    Как избавиться от такого поведения функции?
     
  4. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    PHP:
    1. <?php
    2. $string = '9 моё любимое число';
    3.  echo (int)$string;
    =)
    а когда true то там типы проверяются
     
  5. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    Дак ты уже избавился - добавил строгую типизацию в последнем аргументе.
     
  6. Hight

    Hight Старожил
    Команда форума Модератор

    С нами с:
    5 мар 2006
    Сообщения:
    7.153
    Симпатии:
    0
    Адрес:
    из злой параллельной вселенной
    Padaboo
    Я в курсе. Только я не считаю поведение функции in_array нормальным. ИМХО это ошибка. Мне насрать, что это функции было передано, она должна проверить наличие из того, что есть, а не заниматься приведением типов.

    Я могу этой функции скормить кучу смешанного говна, пусть проверяет. А если она будет заниматься привидением типов, то это уже не проверка. Мне такая функция нахер не нужна.
     
  7. Hight

    Hight Старожил
    Команда форума Модератор

    С нами с:
    5 мар 2006
    Сообщения:
    7.153
    Симпатии:
    0
    Адрес:
    из злой параллельной вселенной
    Ну да. Только это не выход. =(

    Ведь раньше эта функция правильно работала.
     
  8. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    Hight
    Напиши обертку либо свою функцию.
    РНР очень бажный в приведении типов, да.
     
  9. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    я еше в 3-4 местах такие грабли видел
     
  10. Hight

    Hight Старожил
    Команда форума Модератор

    С нами с:
    5 мар 2006
    Сообщения:
    7.153
    Симпатии:
    0
    Адрес:
    из злой параллельной вселенной
    Apple
    Привидение типов и обрезание строки, это, как минимум, разные вещи. Это даже не баг, это как-то через жопу всё.
     
  11. Hight

    Hight Старожил
    Команда форума Модератор

    С нами с:
    5 мар 2006
    Сообщения:
    7.153
    Симпатии:
    0
    Адрес:
    из злой параллельной вселенной
    блин, дофига придётся переписать. =((( моя в печали.
     
  12. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Нормальное поведение. "9 blala" == 9 не удивляет? Тогда почему inarray который делает == по всем элементам - вдруг удивлять начал?
     
  13. <?=RPG?>

    <?=RPG?> Активный пользователь

    С нами с:
    19 ноя 2010
    Сообщения:
    451
    Симпатии:
    0
    Вполне таки нормальное поведение: не-strict режим тем и отличается, что не производит приведение типов.

    Примерно на те же грабли наступают новички, когда пользуются strpos, не проверяя, какой ноль вернула функция: булев ноль (не найдено) или инт ноль (найдено в нулевой позиции).

    На самом деле все претензии — к невнимательному чтению мануала. Да, с типами данных и очевидностью кода у РНР есть проблемы. Таким уж уродился. Но это плата за простоту и прозрачность типов.

    ЗЫ
    Как умиляет...
     
  14. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Меня как-то удивило и я понял, что все мои проверки $var == (int)$var не являются рабочими =\
    Т.е. получается, чтобы проверить переменную, нужно:
    isset($var) and is_numeric($var) and $var == ($int)$var

    Ктстати, есть ctype_digit - вот она офигенна для проверки входящих чисел. Но я заметил, что она присутствует не на всех серверах =\
     
  15. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Ну можно еще как-то так (string)$var === (string)(int)$var
    Хотя, конечно, ужас :)
     
  16. <?=RPG?>

    <?=RPG?> Активный пользователь

    С нами с:
    19 ноя 2010
    Сообщения:
    451
    Симпатии:
    0
    Не всё так страшно, товарищи. Если вам нужно лишь чтобы в SQL запросе id был интом, достаточно будет преобразования типов.
    Исход $var == (int)$var зависит от того, какой был тип изначально у переменной. Если она получена через гет, следовательно строка — проверка будет вполне рабочей.
     
  17. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    Был случай, когда я видел в скрипте очень жесткую дырку.
    Выглядела примерно слещующим образом:

    PHP:
    1. <?php
    2.  
    3. if(intval($_GET["id"]) > 1) {
    4.  mysql_query(/* ... $id ...*/);
    5. }
    6.  
    7. ?>
    Само собой такая штука обходится очень и очень просто - в проверке-то он даст цифру.
     
  18. alBoo

    alBoo Активный пользователь

    С нами с:
    27 мар 2008
    Сообщения:
    63
    Симпатии:
    0
    не так давно такая дырка в битриксе была, чем я собственно успешно и пользовался :))
     
  19. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Hight
    Вообще это всё документировано и является основой основ PHP. Просто со временем мы об этом забываем, что обычно приводится к числовым типам, а не к строкам. Но вообще да, штука неприятная. Это общий недостаток скриптовых языков. В JS тоже иногда приходится сталкиваться с WTF, а потом переделывать кучу всего. Со временем запоминается.
    http://ru.php.net/manual/en/language.ty ... ggling.php
     
  20. <?=RPG?>

    <?=RPG?> Активный пользователь

    С нами с:
    19 ноя 2010
    Сообщения:
    451
    Симпатии:
    0
    if((int)$id>0) //неправильно
    $id = (int)$id; if($id>0) // правильно

    Прописная истина:)

    is_numeric тоже очень надежно. По хорошему самое главное - отфильтровать сроку так, чтобы там было лишь число. То что там инт число или положительное целое - это уже второстепенна задача.
     
  21. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    На виндовых идет по дефолту, на линуксах должно быть скомпилировано с флагом enabled ctype
     
  22. Hight

    Hight Старожил
    Команда форума Модератор

    С нами с:
    5 мар 2006
    Сообщения:
    7.153
    Симпатии:
    0
    Адрес:
    из злой параллельной вселенной
    Расслабьтесь. Я с недосыпа тормознул. Совсем крыша поехала.