За последние 24 часа нас посетили 17354 программиста и 1723 робота. Сейчас ищут 1573 программиста ...

Как бороться с неопределёнными переменными?

Тема в разделе "PHP для новичков", создана пользователем Алексей87К, 19 окт 2017.

Метки:
  1. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.583
    Симпатии:
    1.761
  2. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    @mkramer ничоси! А выглядит, будто просто if(!$var)...
     
  3. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    PHP:
    1. <?php
    2. $a = 0;
    3. echo $a ?? 1; // 0
    4. echo $a ?: 1; // 1, но выдаст нотис на несуществующую переменную
    Короче, ни что не совершенно ))
     
  4. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    @romach вот что ?? не даёт нотис, а ?: - даёт, это уже нереальная индусятина...
     
  5. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.794
    Симпатии:
    1.330
    Адрес:
    Лень
  6. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    @MouseZver
    Мне нравится сокращение, но я его не использую этот тернарный оператор, хотя и запись короче становится.
     
  7. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.770
    Адрес:
    :сердА
    Два слова - обратная совместимость.
    Хотел было написать про нулькоалесцентный оператор, фейспалмнув на то, что его в первом же комменте не упомянули, но, @mkramer спас положение. Спасиб те, милчеловек. А то, блин, три страницы полемики из-за такой простой хрени :)
    --- Добавлено ---
    Оператор "??" - не тернарный, а нулькоалесцентный. Не путай их никогда. Они совершенно разные.

    Так, например, ты можешь писать $a ?? $b ?? $c ?? $d ?? 'Пыщ'

    В JS роль нулькоалесцента вполняет обычное логическое ИЛИ, оно же ||. Ввиду того, что в JS логические операции, по возможности, возвращают не TRUE, а значение трушного операнда. И это широко используется.

    В итоге, выражение a = b || 3 можно буквально читать как "присвоить переменной a значение переменной b или число три, если переменная b пуста или не существует". Но в JS такой подход таки спотыкается об значимые false и 0.

    В PHP пошли своим путем и, вместо перегрузки || запилили оператор ??, лишенный вышеописанных недостатков.

    Пользуйтесь им и будьте счастливы.
     
    #57 Fell-x27, 22 окт 2017
    Последнее редактирование: 22 окт 2017
  8. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.794
    Симпатии:
    1.330
    Адрес:
    Лень
    его название два вопросика или нуль колыдоадфывоаыршфр
     
  9. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.770
    Адрес:
    :сердА
    От себя добавлю - нужно, при этом, не забывать класть ошибки в лог. А то бывают перцы, которые эррор логи папача/fpm отключают вместе с аккцессами, "патамушта в интернете так сововают, штобы праизвадительнасть расла, у миня ж хайловад ажидается!!!" А кастомное логгирование написать не подумали. А потом приходят на форум с просьбами помочь с неизвестной ошибкой, а на вопрос "что в логах", отвечают, блиять, "а в логах пусто.."
     
  10. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
  11. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.770
    Адрес:
    :сердА
    ?: это краткая форма записи тернарного оператора:
    Код (Text):
    1. (condition)?(if_true):(if_false)
    , у которого опущена средняя часть. То есть, в случае, если condition==true, будет возвращен именно он.

    Звучит неплохо, но в реальной жизни не везде применимо. Если речь идет о проверках на isset, то в принципе не применимо. Нулькоалесцентный же ведет себя по-другому. Он просто идет слева-направо по операндам в выражении, и возвращает первый попавшийся не null-операнд. При этом значимые 0 и false не являются причиной для "неожиданного поведения" и не будут пропущены или приведены к null во время проверки.
    --- Добавлено ---
    И нет, тернарный оператор, в свою очередь, не является "краткой формой IF", как некоторые его называют.
     
  12. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    @MouseZver ну в примере надо объявление $a убрать и тогда окажется, что нотис дает только второй оператор.
    --- Добавлено ---
    почему?
     
  13. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.794
    Симпатии:
    1.330
    Адрес:
    Лень
    ( isset ( .. ) ? ... : throw new ... )
    будут юзаться сразу две стороны а выбираться одно
     
  14. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    PHP:
    1. function foo() {
    2.     echo 'foo';
    3.     return true;
    4. }
    5.  
    6. function bar() {
    7.     echo 'bar';
    8.     return true;
    9. }
    10.  
    11. function baz() {
    12.     echo 'baz';
    13.     return true;
    14. }
    15.  
    16. baz() ? bar() : throw new Exception(); // syntax error, unexpected 'throw' (T_THROW)
    17. baz() ?: foo(); // baz
    18. baz() ?? foo(); // baz
    19. baz() ? bar() : foo(); // bazbar
     
  15. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.770
    Адрес:
    :сердА
    Потому что:
    1) В ветках if ты можешь писать произвольный код. В тернарном операторе - только выражения.
    2) У веток if нет прямого назначения. У тернарного оператора каждая ветвь обязана вернуть значение.
    3) Возврат значения в ветках тернарного оператора производится автоматически, без return.
    4) Тернарный оператор может быть частью любого другого выражения. IF - не может.
    5) Назначение IF - ветвление логики. Назначение тернарного оператора - возврат значения по условию.
    6)
    Вот это вот:
    PHP:
    1. if ($condition){
    2.     $var = val1;
    3. } else{
    4.     $var = val2;
    5. }
    Не тернарный оператор. Это нельзя использовать вместо него. Это совершенно иначе пускает логику построения выражения, заставляя рвать его на части, что усложняет поддержку, порой, сильнее, чем грамотно составленные вложенные тернарники.

    Вот, краткой записью чего является тернарный оператор:
    PHP:
    1. function tern($cond, $if_true, $if_false){
    2.     if ($cond){
    3.         return $if_true;
    4.     } else{
    5.         return $if_false;
    6.     }
    7. }
    Это не просто if, как видишь. Это один частный случай использования оного, не более того. Один из бесконечного количества. Но именно этот частный случай настолько востребован, что для него запилили более удобный синтаксис еще во времена Си. Вот и все. Вышеописанный код может заменить тернарник на 100% просто заменой в выражении.

    Лишь на основании того, что и у if и у тернарного оператора есть понятие логических веток, нельзя говорить, что одно является краткой формой другого.
     
    #65 Fell-x27, 22 окт 2017
    Последнее редактирование: 22 окт 2017
    [vs] и mkramer нравится это.
  16. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    @Fell-x27 спасибо, исчерпывающе!

    Ага, конечно
    PHP:
    1. $val = $var ? print 'Ok!' : false;
    :D
     
  17. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.770
    Адрес:
    :сердА
    Что не так?
    PHP:
    1. <?php
    2.  
    3. function tern($cond, $if_true, $if_false){
    4.     if ($cond){
    5.         return $if_true;
    6.     } else{
    7.         return $if_false;
    8.     }
    9. }
    10.  
    11. $var = 1;
    12.  
    13. $val1 = tern($var , print 'Ok!' , false);
    14. $val2 = $var ? print 'Ok!' : false;
    15.  
    16. echo '<hr>';
    17. var_dump($val1,$val2);
    Я не вижу разницы в поведении, а ты?
     
  18. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.583
    Симпатии:
    1.761
    Не, @Fell-x27, кстати, разница есть в конкретно твоём случае. С тернарником print "OK" не будет вычисляться если $var ложно, и OK выведено не будет, а с функцией выполнится в обоих случаях. Поэтому твой функциональный аналог тернарника не совсем точен.
     
  19. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.770
    Адрес:
    :сердА
    Ох, окей. Тогда все еще лучше: в качестве параметров нужно будет передавать анонимную функцию, которая будет выполняться по условию. В итоге синтаксис станет окончательно монструозным.

    И все равно это будет не то же, что и тернарник:)
     
    #69 Fell-x27, 23 окт 2017
    Последнее редактирование: 23 окт 2017
  20. Vladson

    Vladson Старожил

    С нами с:
    4 фев 2006
    Сообщения:
    4.040
    Симпатии:
    26
    Адрес:
    Estonia, Tallinn
    Вот руки бы за такое вырывал из задницы...
     
    [vs] и Fell-x27 нравится это.
  21. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.794
    Симпатии:
    1.330
    Адрес:
    Лень
    Ты просто не понимаешь всех тонкостей и изыска в таком чуде (с)

    вырвать, вставить и снова вырвать, и глаза за копикейшен.
     
  22. Vladson

    Vladson Старожил

    С нами с:
    4 фев 2006
    Сообщения:
    4.040
    Симпатии:
    26
    Адрес:
    Estonia, Tallinn
    Там такого нету. Там есть место за которое я бы вырывал руки, но там оно оправдано (и есть пояснение что обычно такое делать нельзя)

    (причём код был написан во времена РНР 5.0 и почти без изменений дожил до РНР7, неплохо для кода написанного "одной рукой с закрытыми глазами")
     
  23. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.794
    Симпатии:
    1.330
    Адрес:
    Лень
    нотисы в постах как и тут у афтара с написанным со времен 5.0 кодом
    --- Добавлено ---
    ай сори долблюсь в глаза там везде array_key_exists
     
  24. Vladson

    Vladson Старожил

    С нами с:
    4 фев 2006
    Сообщения:
    4.040
    Симпатии:
    26
    Адрес:
    Estonia, Tallinn
    Там проблема лишь в том что в БД хранятся уже обработанные данные, а не исходник. Но там это оправдано ибо обработаны они почти без потерь и при случае (например переписывая под MySQL или ещё что) можно конвертануть всё обратно (даже была версия под SQLite но смысла нет) и такое хранение упрощает модерацию (тупо в блокноте можно редактировать всю базу) в обсуждаемом коде данные кастрируются стриптагсом при том что этого можно (нужно) избежать.

    Опять же мой скрипт был написан по фану, там много что можно изменить, но в силу того где он стоит в этом нет никакой нужды, там работает прицып "и так сойдёт"
     
  25. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.794
    Симпатии:
    1.330
    Адрес:
    Лень
    Мои былые годы :)