За последние 24 часа нас посетили 22392 программиста и 1141 робот. Сейчас ищут 687 программистов ...

Где в PHP логика?

Тема в разделе "PHP для новичков", создана пользователем NerdRage, 15 фев 2017.

  1. NerdRage

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

    С нами с:
    6 июл 2016
    Сообщения:
    439
    Симпатии:
    42
    Я просто охренел с этого.
    PHP:
    1. echo '<pre>'; var_export('deny'==0); echo '</pre>'; // возвращает true
    У меня накрылись отчёты в контролирующий орган и я теперь правонарушитель из-за такого вот кода.
    PHP:
    1. $status = 0;
    2. switch($status) {
    3.     default:
    4.         // первый тип отчёта
    5.     break;
    6.     case 'deny':
    7.         // второй тип отчёта
    8.     break;
    9. }
    Не поверите, но здесь стреляет второй тип отчёта, потому что PHP считает, что 0 == 'deny'. Где логика?

    --- Добавлено ---
    Решение у меня есть, можете не предлагать:
    PHP:
    1. $status = 0;
    2. switch($status) {
    3.     case 0:
    4.     default:
    5.         // первый тип отчёта
    6.     break;
    7.     case 'deny':
    8.         // второй тип отчёта
    9.     break;
    10. }
    Но хотелось бы понять всё-таки почему в PHP так происходит.
     
  2. Kotofey

    Kotofey Новичок

    С нами с:
    20 окт 2016
    Сообщения:
    8
    Симпатии:
    5
    А про отсутствие строгой типизации и сравнение типов данных Вы не слышали?
    var_export('deny'===0); //false
     
  3. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    [vs], san4ez, NerdRage и 2 другим нравится это.
  4. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.792
    Симпатии:
    650
    +1

    Поверим. Правильно считает. Логика вот прям тут, где вы показали.

    Ну и изучаем таблички выше.
    --- Добавлено ---
    Точнее первую.
     
  5. alexblack

    alexblack Старожил

    С нами с:
    20 янв 2016
    Сообщения:
    640
    Симпатии:
    381
    А что собственно не логично? Ты сравниваешь строку с числом.PHP приводит строку к числу.Так как твоя строка не начинается с цифры,соответственно она 0,отсюда true.
    Почитал бы про приведение типов в PHP
    https://secure.php.net/manual/ru/language.types.type-juggling.php
    Так как в каждом языке оно разное.в PHP главнее является число,а если взять тот же JS,там строка главнее.
     
    NerdRage нравится это.
  6. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    Не знал, что в php это не обязательно, но в C рекомендовалось или даже требовалось default-секцию писать внизу оператора switch(), я так по привычке и пишу. А про ошибку все уже всё сказали
     
    Fell-x27 нравится это.
  7. NerdRage

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

    С нами с:
    6 июл 2016
    Сообщения:
    439
    Симпатии:
    42
    Слышал, но в switch-case оно не применимо.
    Я вообще в курсе, что 0 == false == ''. Но что "php" == 0 вот только сейчас узнал. :eek:
    Понял. То есть, если я сравниваю что-то что может быть строкой или числом, то нужно всё приводить к строке.
    PHP:
    1. $status = 0;
    2. switch((string)$status) {
    3.     default:
    4.         // первый тип отчёта
    5.     break;
    6.     case 'deny':
    7.         // второй тип отчёта
    8.     break;
    9. }
    В PHP это ничего не даёт.
     
    #7 NerdRage, 15 фев 2017
    Последнее редактирование: 15 фев 2017
  8. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    лучше заранее приводи к нужному типу и делай нужные действия.
    PHP:
    1. $var = (int)'php'; // 0
    поэтому и проскакивает у тебя тру.
     
  9. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    +1, какая-то нездоровая хрень. Да и чисто по логике default должен быть последним, просто для удобства восприятия.
     
  10. Drema

    Drema Новичок

    С нами с:
    20 фев 2017
    Сообщения:
    117
    Симпатии:
    30
    В switch(___) всегда должно быть строго типизированное значение.
    switch(strVal())..
    switch(intVal())..

    и тп. Иначе постоянно будут проблемы.
     
  11. Zuldek

    Zuldek Старожил

    С нами с:
    13 май 2014
    Сообщения:
    2.381
    Симпатии:
    344
    Адрес:
    Лондон, Тисовая улица, дом 4, чулан под лестницей
    говнокодить меньше надо и всё будет хорошо.
     
  12. Drema

    Drema Новичок

    С нами с:
    20 фев 2017
    Сообщения:
    117
    Симпатии:
    30
    иногда нужно написать функцию, где тебе "чтото" приходит и сделать по этому параметру switch. Это не говнокод, это особенность нетипизированного интерпретатора. Ну а default конечно в конце должен быть, это да )
     
  13. Zuldek

    Zuldek Старожил

    С нами с:
    13 май 2014
    Сообщения:
    2.381
    Симпатии:
    344
    Адрес:
    Лондон, Тисовая улица, дом 4, чулан под лестницей
    То что вы описали есть прямое определение говнокода.
    Для того чтобы приходило не "что-то", давно используется валидация во внешней (по отношению к логике) абстракции и, на худой конец, https://php.ru/manual/migration70.new-features.html
    И да, уж в совсем ленивом случае, есть приведение к типу нативным методом, как упомянуто выше.
     
  14. Drema

    Drema Новичок

    С нами с:
    20 фев 2017
    Сообщения:
    117
    Симпатии:
    30
    Чтото приходит в функцию вне зависимости от наличия какихто фич в php7. Тем более, что код зачастую должен работать и в ранних версиях. Да и вообще, причем тут php7?
    Попробуйте в функции в какойнибудь crm протипизировать вход - граблями замучаетесь махать.
     
  15. Zuldek

    Zuldek Старожил

    С нами с:
    13 май 2014
    Сообщения:
    2.381
    Симпатии:
    344
    Адрес:
    Лондон, Тисовая улица, дом 4, чулан под лестницей
    Валидация типов входных значений никоим образом не подвязана к версии PHP и языку в целом. Речь идет о том что логика проверки значений должна быть отделена от логических операций с самими значениями (неважно в каком коде). Иное - есть плохая практика.
    :)
     
  16. Drema

    Drema Новичок

    С нами с:
    20 фев 2017
    Сообщения:
    117
    Симпатии:
    30
    ну делайте так, если вы так боитесь "говнокода" :)
    PHP:
    1. $param = intVal($param);
    2. switch($param){...
     
    #16 Drema, 20 фев 2017
    Последнее редактирование модератором: 20 фев 2017
  17. Chushkin

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

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Вот так новички дурят новичков, а нам потом разгребать. :(
    Доку им в руки и научный тык на шею...
     
    igordata нравится это.
  18. Drema

    Drema Новичок

    С нами с:
    20 фев 2017
    Сообщения:
    117
    Симпатии:
    30
    и в чем я вас надурил, уважаемый? :) в том, что перед switch гораздо легче точно привести значение к какому-то типу, чем потом отлавливать баги? так это более чем 20ти летний опыт и десятки мегабайт написанного кода вам говорят, а не я )
     
  19. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    если ты не принимаешь нечеткую природу пхп, то у тебя могут быть "баги" если ты изначально не строишь свою логику на этом. Но есть люди, для которых нестрогая типизация языка - это благо, и всю свою логику я выстраиваю исходя из этого. А какой там у кого опыт и кому что проще - это вопрос субъективный. Его не надо подавать как единственно верное решение. Со своей колокольни нормально бить себя тапкой в грудь и грозить багами. А писать об этом безлично:
    это неправильно. Если ты исходишь из своего опыта - так и пиши - у меня были проблемы с этим двадцать лет, пока я не начал приводить типы перед свичем. Теперь я всем своим знакомым и незнакомым советую поступать так же. :D
     
  20. Chushkin

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

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    1) Не "уважаемый", а "уважаемые", раз уж обращаетесь ко мне/нам во множественном числе.

    Повторяю для тех, кто в танке, - "Доку Вам в руки...".

    Хотя ... "наши люди доку не читают", особенно с "20-ти летним опытом". ;)
     
  21. Drema

    Drema Новичок

    С нами с:
    20 фев 2017
    Сообщения:
    117
    Симпатии:
    30
    В следующий раз, когда в очередной раз будете трассировать код со switch, написанный знатоком сравнения типов (типа чувака "сам не знаю, но читай доки"), вспоминайте не таблицу из доков, а мой ответ. Сократите время на разработку значительно.

    switch вообще надо поменять на два других оператора switchInt и switchStr :)
    --- Добавлено ---
    Не можешь ничего сказать по существу - молчи.
     
  22. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    @Drema
    я вроде человеческим языком написал, что дело не в том, прав ты или нет, а в том, что ты подаёшь это в манипулятивной демагогической форме. Вот и всё.
     
  23. Drema

    Drema Новичок

    С нами с:
    20 фев 2017
    Сообщения:
    117
    Симпатии:
    30
    Не хотел, может быть просто так получилось )
     
  24. Chushkin

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

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Очередной троль ... с 20 летнем опытом. :)
    Или бот.
    И очередной раз бессмысленно потраченное время. Кой чёрт меня дёрнул...
     
    Zuldek нравится это.
  25. Drema

    Drema Новичок

    С нами с:
    20 фев 2017
    Сообщения:
    117
    Симпатии:
    30
    бессмысленно потратил время на изречение "читайте доки" бггг )) перетрудился