Squeak.ru - шаблоны программирования

Исправление пустой функции PHP

PHP имеет привычку оценивать (int)0 и (string)"0" как пустые при использовании функции empty(). Это может привести к непредвиденным результатам, если вы ожидаете, что числовые или строковые значения равны 0. Как я могу «исправить» это, чтобы возвращать true только для пустых объектов, массивов, строк и т. д.?

03.01.2009

  • Лично я считаю, что (int)0 следует оценивать как false; просто (string)0 этого не должно быть. Также обратите внимание, что пустые объекты не считаются empty(), и принятый ответ не меняет этого. 24.07.2013
  • @Brilliand - учитывая общий дизайн php, целые и числовые строки взаимозаменяемы, это, вероятно, не будет хорошим изменением. 25.02.2019
  • ... ИМХО Было бы проще, если бы empty было ложным для значений, эквивалентных 0. Тогда это часто было бы полезно как есть; нам не нужны обходные пути, подобные этому Q&A. В тех случаях, когда кто-то хотел включить 0-эквиваленты, просто сделал бы if (empty($var) || $var == 0). Ах хорошо. 25.02.2019

Ответы:


1

Это не сработало для меня.

if (empty($variable) && '0' != $variable) {
  // Do something
}

Вместо этого я использовал:

if (empty($variable) && strlen($variable) == 0) {
  // Do something
}
04.01.2009
  • Первый терпит неудачу, потому что вы используете != вместо !==. (empty($variable) && $variable !== '0') на самом деле был бы хорошим и кратким способом проверить это. 30.09.2014
  • @thomasrutter - надеюсь, ваш код никогда не встретит " 0", "00" или "-0". Они не будут обнаружены !== '0', но имеют содержимое. Хороший пример того, почему нужно писать код, говорящий о ваших намерениях, а не умничать. 24.02.2019

  • 2

    Я редко использую empty() по описанной вами причине. Он путает законные ценности с пустотой. Возможно, это потому, что я много работаю с SQL, но предпочитаю использовать NULL для обозначения отсутствия значения.

    В PHP есть функция is_null(), которая проверяет, является ли переменная или выражение NULL.

    $foo = 0;
    if (is_null($foo)) print "integer 0 is null!\n"; 
    else print "integer 0 foo is not null!\n";
    
    $foo = "0";
    if (is_null($foo)) print "string '0' is null!\n"; 
    else print "string '0' is not null!\n";
    
    $foo = "";
    if (is_null($foo)) print "string '' is null!\n"; 
    else print "string '' is not null!\n";
    
    $foo = false;
    if (is_null($foo)) print "boolean false is null!\n"; 
    else print "boolean false is not null!\n";
    

    Вы также можете использовать оператор точного равенства ===, чтобы выполнить аналогичный тест:

    if ($foo === null) print "foo is null!\n";
    

    Это верно, если $foo равно NULL, но не если это false, ноль, "" и т. д.

    03.01.2009
  • isset будет более подходящей заменой, чем is_null. Если OP выбрал empty вместо простого (вероятно, неявного) приведения к логическому значению, то я бы предположил, что переменная может быть неопределенной. 24.07.2013
  • Я бы не стал использовать is_null, если, конечно, вы не хотите, чтобы $foo = "" рассматривалось как NOT NULL. 01.01.2019
  • @Brett, правильно, в PHP и в SQL строка нулевой длины не совпадает с нулевым значением. База данных Oracle предполагает, что "" совпадает с NULL, но это нестандартно. 01.01.2019
  • @BillKarwin Да, я согласен, но моя точка зрения была больше связана с этим вопросом, поскольку кажется, что они не хотели бы, чтобы пустая строка рассматривалась как допустимый контент, но если бы вы использовали is_null, это было бы так. 01.01.2019

  • 3

    "0" всегда считается ложным (или пустой) в PHP, и это имеет большой смысл (не то чтобы я буду спорить с этим здесь). Если вы хотите, чтобы нуль также оценивался как true, используйте strlen($value).

    03.01.2009
  • Хороший совет, хотя вы, вероятно, захотите использовать функцию trim() вокруг $value. 04.01.2009

  • 4

    Я всегда добавляю в свою кодовую базу

    function is_blank($value) {
        return empty($value) && !is_numeric($value);
    }
    

    и используйте его вместо empty(). Это решает проблему хранения нулей (int, float или string) как непустых.

    См. http://www.php.net/manual/en/function.empty.php#103756, добавленный в мае 2011 г.

    08.05.2011
  • отличное решение, я назвал его is_nothing() вместо is_blank, но это только я. 23.06.2021

  • 5

    "Исправление" - это одна точка зрения. Другим было бы предположить, что он не «сломан», и научиться работать с ним так, как он был намеренно разработан.

    Учитывая проблему, как вы ее описываете, лучше всего было бы усовершенствовать ваш код, чтобы переменная не могла быть помещена в состояние неопределенного типа. В противном случае вам нужно проверить тип данных с помощью gettype().

    03.01.2009
  • Насколько я понимаю, теперь рекомендуется использовать is_x, а не старую функцию gettype(). 04.01.2009
  • Проблема в том, что OP, похоже, хочет независимого от типа решения. В PHP полное перечисление is_? параметры могут измениться. Во-первых, гораздо лучше избегать крушения поезда. На самом деле, они, вероятно, хотят получить баллы за абстрактный вопрос. :) 04.01.2009
  • +1 за комментарий о рыбалке. Похоже, что ОП немного поторопился с собственным решением несуществующей проблемы. Тем не менее, если вам нужно независимое от типа решение, я бы вместо этого использовал оператор ===. 04.01.2009
  • Верно, и даже тогда независимое от типа решение — это плохо, в первую очередь. 04.01.2009
  • У меня реакция противоположная @NoahGoodrich. -1 за зацикливание на слове fix вместо ответа на ключевое предложение Это может привести к непредвиденным результатам, если вы ожидаете числовых или строковых значений 0. Это очень распространенная проблема при использовании php — не устраняется затяжкой вашего кода. 24.02.2019

  • 6

    Вообще говоря, вы хотите использовать оператор тройного равенства, чтобы определить, действительно ли значение является нулевым или ложным. Это более конкретно, и результаты ВСЕГДА возвращаются точно так, как ожидалось.

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

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

    03.01.2009
  • Настоящая проблема с ним, ИМХО, заключается в том, что он отбрасывает точность и способствует небрежному мышлению. 04.01.2009
  • В SQL, как указал Билл, NULL — это несуществующее значение, а пустая строка — это пустая строка. Мне нравится явно проверять NULL, а также недопустимые строки и целые числа в зависимости от потребностей программы. 04.01.2009
  • Другими словами, иногда нулевая или пустая строка допустима, но их следует проверять независимо от проверки нулевых значений. 04.01.2009

  • 7

    Вы пытаетесь использовать empty() для чего-то, для чего он не предназначен. Лично я думаю, что это поведение исходит из более старой парадигмы программирования в PHP, и его, вероятно, можно было бы удалить.

    Вместо этого сделайте свои проверки более явными. Вместо того, чтобы проверять, является ли значение бесполезным, убедитесь, что оно полезно. Например, если вам нужен массив, проверьте, является ли он массивом (is_array()), а не строкой.

    Кроме того, вы можете полагаться на тот факт, что все переменные $_POST и $_GET являются строками, поэтому вы можете сравнивать их с "" или проверять, что strlen() == 0.

    05.01.2009
  • Иногда переменные $_POST или $_GET являются массивами. 24.07.2013
  • иногда $_POST или $_GET не будут иметь ключа, что означает значение NULL 23.12.2019

  • 8

    Я использую это для обнаружения пустоты:

    ''  --> true
    '0' --> false
    0   --> false
    

    функция:

    function is_empty_or_zero($str) {
     return (is_null($str) || ($str === ''));
    }
    
    05.04.2016
  • is_empty_or_zero не подходит для этой функции. is_null_or_empty_string это то, что вы тестируете. В частности, ноль возвращает false. Возможно, вы имели в виду is_empty_but_not_zero как имя; хотя это не так хорошо, как прямо говорить о своих намерениях. Другой подход состоит в том, чтобы определить противоположное (отрицание) этой функции и назвать ее has_contents. if (!has_contents(...)) вполне читабельно, ИМХО. 25.02.2019

  • 9

    Я создал IsEmpty() краткую быструю функцию.

    function IsEmpty($mData) {
        return is_int($mData) ? false : 
            is_string($mData) ? $mData=="" : 
            empty($mData);
    }
    
    03.01.2009
  • Отвечаете на свой вопрос, прежде чем увидеть какие-либо другие ответы? -- Ваше решение объединяет все в одно сложное утверждение, эффективно запутывая его (в большинстве случаев это не считается хорошим стилем). 04.01.2009
  • @le dorfier: нет проблем с ответами на ваши собственные вопросы: это просто создает больше информации для других, чтобы читать и учиться. @null: одно из ключевых преимуществ использования empty() заключается в том, что вы можете тестировать неопределенные переменные, не вызывая предупреждения. эта функция не имеет такой возможности. 04.01.2009

  • 10

    Я использовал функцию ord, чтобы проверить, было ли переданное значение пустым или нет.

    /*
    * SPACE is not empty - Please do trim before using this function for your own purpose
    *  var_dump(is_having_value(0));        // true
       var_dump(is_having_value(0000));     // true
       var_dump(is_having_value("    0"));  // true
       var_dump(is_having_value(""));       // false
       var_dump(is_having_value("  "));     // true
       var_dump(is_having_value('\t'));     // true
       var_dump(is_having_value(''));       // false
       var_dump(is_having_value('o'));      // true
       var_dump(is_having_value('O'));      // true
       var_dump(is_having_value('0'));      //true
       var_dump(is_having_value(null));     //false
       var_dump(is_having_value());         //false
    */
    function is_having_value($val = null) {
        if (is_array($val) || is_object($val)):
            $logic_empty = empty($val);
            return !$logic_empty;
        else:
            $ascii = ord($val);
            if ($ascii == 48 || $ascii = 0 || $ascii == 32):
                return true;
            else:
                $logic_empty = empty($val);
                return !$logic_empty;
            endif;
        endif;
    }
    
    06.05.2016
  • В чем преимущество этого подхода по сравнению с использованием is_numeric, как в ответе Стемара? 24.02.2019

  • 11

    Если вам нужен эквивалент empty($var), который возвращает false, когда var является строкой 0, вы можете использовать:

    if (($var ?? 0) != '')
    

    Причина, по которой это работает:

    • $var ?? 0 — это ярлык для тернера isset($var) ? $var : 0. То есть, если переменная слева не существует, она принимает значение справа без выдачи предупреждения или уведомления, как в случае с isset() или empty().

    • <value> != '' выполняет неявное приведение пустой строки, когда левое значение не является строкой. Это возвращает false для любого ложного значения <value>, такого как null, false или (числовое) 0. Однако для строки 0 это вернет true, поскольку приведение не будет выполнено, а "0" != "" истинно.

    11.11.2020

    12

    Наиболее эффективное решение этой проблемы - проверить, является ли переменная ложной, например.

    
    if (!$variable_name) {echo $variable_name;}
    
    

    Неважно, является ли переменная пустой или нулевой, все равно ложно, если вводится в условие if.

    03.01.2009
  • это почти то же самое, что и empty(), в том смысле, что 0 или 0 будут ложными, чего ОП пытался избежать. 04.01.2009
  • также выдает строгое уведомление, если переменная не установлена 04.01.2009
  • Он также немного более запутан по сравнению с empty(). Я бы посоветовал этого не делать, если переменные не являются только истинными или ложными. 05.01.2009

  • 13
  • В чем преимущество этого подхода по сравнению с использованием is_numeric, как в ответе Стемара? 25.02.2019
  • Новые материалы

    Угловая структура архитектуры
    Обратите внимание, что эта статья устарела, я решил создать новую с лучшей структурой и с учетом автономных компонентов: https://medium.com/@marekpanti/angular-standalone-architecture-b645edd0d54a..

    «Данные, которые большинство людей используют для обучения своих моделей искусственного интеллекта, поставляются со встроенным…
    Первоначально опубликовано HalkTalks: https://hacktown.com.br/blog/blog/os-dados-que-a-maioria-das-pessoas-usa-para-treinar-seus-modelos-de-inteligencia-artificial- ja-vem-com-um-vies-embutido/..

    Сильный ИИ против слабого ИИ: различия парадигм искусственного интеллекта
    В последние годы изучению и развитию искусственного интеллекта (ИИ) уделяется большое внимание и прогресс. Сильный ИИ и Слабый ИИ — две основные парадигмы в области искусственного интеллекта...

    Правильный способ добавить Firebase в ваш проект React с помощью React Hooks
    React + Firebase - это мощная комбинация для быстрого и безопасного создания приложений, от проверки концепции до массового производства. Раньше (знаете, несколько месяцев назад) добавление..

    Создайте API с помощью Python FastAPI
    Создание API с помощью Python становится очень простым при использовании пакета FastAPI. После установки и импорта вы можете создать приложение FastAPI и указать несколько конечных точек. Каждой..

    Веселье с прокси-сервером JavaScript
    Прокси-серверы JavaScript — это чистый сахар, если вы хотите создать некоторую общую логику в своих приложениях, чтобы облегчить себе жизнь. Вот один пример: Связь клиент-сервер Мы..

    Получить бесплатный хостинг для разработчиков | Разместите свой сайт за несколько шагов 🔥
    Статические веб-сайты — это веб-страницы с фиксированным содержанием и его постоянным содержанием. Но теперь статические сайты также обрабатывают динамические данные с помощью API и запросов...