isset — Определяет установлена ли переменная


Содержание

Лучший способ проверить существование переменной в PHP; isset() явно сломан

В принципе, isset() не проверяет, установлена ​​ли переменная вообще, но установлено ли что-либо, кроме NULL .

Учитывая, что лучший способ проверить наличие переменной? Я попробовал что-то вроде:

( @ необходимо избегать предупреждения, если $v не задано), но is_null() имеет схожую проблему с isset() : он возвращает TRUE в unset variables! Также представляется, что:

работает точно так же, как @is_null($v) , так что тоже.

Как мы должны надежно проверять наличие переменной в PHP?

Изменить: есть явно разница в PHP между переменными, которые не установлены, и переменными, которые установлены на NULL :

PHP показывает, что $a[‘b’] существует и имеет значение NULL . Если вы добавите:

вы можете видеть двусмысленность, о которой я говорю, с помощью функции isset() . Здесь вывод всех трех этих var_dump()s :

Дальнейшее редактирование: две вещи.

Один, прецедент. Массив, который преобразуется в данные оператора SQL UPDATE , где ключи массива являются столбцами таблицы, а значения массива — значения, которые должны применяться к каждому столбцу. Любой столбец таблицы может содержать значение NULL , означаемое передачей значения NULL в массиве. Вам нужно различать не существующий ключ массива, а значение массива — NULL ; что разница между не обновлением значения столбца и обновлением значения столбца до NULL .

Во-вторых, ответ Zoredache, array_key_exists() работает корректно, для моего примера использования и для любых глобальных переменных:

Так как это правильно обрабатывает почти всюду, я вижу, что существует какая-то двусмысленность между переменными, которые не существуют, и переменными, которые установлены на NULL , Я называю array_key_exists() самым простым в PHP способом чтобы действительно проверить наличие переменной.

(Только другой случай, о котором я могу думать, относится к свойствам класса, для которых существует property_exists() , который, согласно своим документам, работает аналогично array_key_exists() тем, что он правильно различает, не устанавливая и устанавливая на NULL .)

Если переменная, которую вы проверяете, будет находиться в глобальной области действия, которую вы могли бы сделать:

Попытка дать обзор различных обсуждений и ответов:

Нет единого ответа на вопрос, который может заменить все способы использования isset . Некоторые примеры использования рассматриваются другими функциями, в то время как другие не выдерживают проверки, или имеют сомнительную ценность за пределами гольфа. В других вариантах использования, которые не являются «разбитыми» или «несогласованными», объясняется, почему реакция isset на null является логическим поведением.

Реальные варианты использования (с решениями)

1. Клавиши массива

Массивы можно рассматривать как совокупности переменных, причем unset и isset обрабатывают их так, как если бы они были. Однако, поскольку они могут быть итерированы, подсчитаны и т.д., Недостающее значение не совпадает с значением, значение которого null .

В этом случае ответ будет использовать array_key_exists() вместо isset() .

Так как это берет массив для проверки как аргумент функции, PHP все равно будет поднимать «уведомления», если сам массив не существует. В некоторых случаях можно утверждать, что каждое измерение должно быть сначала инициализировано, поэтому уведомление выполняет свою работу. В других случаях функция «рекурсивная» array_key_exists , которая поочередно проверяла каждое измерение массива, избегала бы этого, но в основном была бы такой же, как @array_key_exists . Это также несколько касательно обработки значений null .

2. Свойства объекта

В традиционной теории «объектно-ориентированного программирования» инкапсуляция и полиморфизм являются ключевыми свойствами объектов; в реализации OOP на основе класса, такой как PHP, инкапсулированные свойства объявляются как часть определения класса и заданные уровни доступа ( public , protected или private ).

Тем не менее, PHP также позволяет динамически добавлять свойства к объекту, например, вы должны использовать ключи для массива, а некоторые люди используют объекты без классов (технически, экземпляры встроенного stdClass , который не имеет методов или частная функциональность) аналогично ассоциативным массивам. Это приводит к ситуациям, когда функция может захотеть узнать, добавлено ли какое-либо конкретное свойство к предоставленному ему объекту.

Как и в случае с ключами массива, решение для проверки свойств объекта включено в язык, называемый достаточно разумным property_exists .

Неоправданные варианты использования, с обсуждением

3. register_globals и другое загрязнение глобального пространства имен

Функция register_globals добавила переменные в глобальную область, имена которой были определены аспектами HTTP-запроса (параметры GET и POST и файлы cookie). Это может привести к ошибочному и небезопасному коду, поэтому по умолчанию он отключен, поскольку PHP 4.2, выпущенный в августе 2000 г. и полностью удален в PHP 5.4, выпущенный в марте 2012 г.. Однако возможно, что некоторые системы все еще работают с включенной или эмулируемой функцией. Также возможно «загрязнять» глобальное пространство имен другими способами, используя ключевое слово global или массив $GLOBALS .

Во-первых, сам register_globals неожиданно создает переменную null , так как значения GET, POST и cookie всегда будут строками (с » , все еще возвращающим true из isset ), и переменные в сеансе должны полностью находиться под контролем программиста.

Во-вторых, загрязнение переменной значением null является проблемой только в том случае, если эта чрезмерная запись предшествует инициализации. «Переписывание» неинициализированной переменной с null было бы проблематичным, если бы код где-то еще различал два состояния, поэтому сама по себе эта возможность является аргументом против такого различия.

4. get_defined_vars и compact

Несколько редко используемых функций в PHP, таких как get_defined_vars и compact , вы можете обрабатывать имена переменных, как если бы они были ключами в массиве. Для глобальных переменных суперглобальный массив $GLOBALS обеспечивает аналогичный доступ и чаще встречается. Эти методы доступа будут вести себя по-разному, если переменная не определена в соответствующей области.

Как только вы решили обработать набор переменных в виде массива с использованием одного из этих механизмов, вы можете делать с ним все те же операции, что и на любом нормальном массиве. Следовательно, см. 1.

Функциональность, которая существовала только для предсказания того, как эти функции будут вести себя (например, «будет ли ключ» foo «в массиве, возвращаемом get_defined_vars ?» ) является излишним, поскольку вы можете просто запустить функцию и найти без побочных эффектов.

4а. Переменные переменные ( $$foo )

Хотя они не совсем такие же, как функции, которые превращают набор переменных в ассоциативный массив, в большинстве случаев используется «переменные переменные» ( «присваивать к переменной, названной на основе этой другой переменной» ), может и должно быть изменено, чтобы вместо этого использовать ассоциативный массив.

Имя переменной, в основном, является меткой, присвоенной программисту; если вы определяете его во время выполнения, это не действительно метка, а ключ в каком-то хранилище ключей. Более практично, не используя массив, вы теряете способность подсчитывать, итерировать и т.д.; также может оказаться невозможным иметь переменную «снаружи» хранилища значений ключа, поскольку она может быть переписана с помощью $$foo .

После изменения использования ассоциативного массива код будет поддаваться решению 1. Доступ к косвенным объектным свойствам (например, $foo->$property_name ) можно решить с помощью решения 2.

5. isset гораздо легче набрать, чем array_key_exists

Я не уверен, что это действительно актуально, но да, имена функций PHP могут быть довольно длинными и непоследовательными иногда. По-видимому, доисторические версии PHP использовали длину имени функции как хэш-ключ, поэтому Rasmus намеренно составлял имена функций, такие как htmlspecialchars , поэтому у них было бы необычное количество символов.

Тем не менее, по крайней мере, мы не пишем Java, а?;)

6. Неинициализированные переменные имеют тип

На странице справочной страницы на основе основных переменных содержится следующее утверждение:

Неинициализированные переменные имеют значение по умолчанию для своего типа в зависимости от контекста, в котором они используются

Я не уверен, есть ли в Zend Engine понятие «неинициализированный, но известный тип», или это слишком много читает в заявлении.

Ясно, что это не имеет никакого практического значения для их поведения, поскольку поведение, описанное на этой странице для неинициализированных переменных, идентично поведению переменной, значение которой null . Чтобы выбрать один пример, оба $a и $b в этом коде заканчиваются как целое число 42 :

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

99. Обнаружение, если функция выполнялась

(Сохраняя это последнее, так как он намного длиннее других. Возможно, я отредактирую его позже. )

Рассмотрим следующий код:

Если some_function может возвращать null , существует вероятность того, что echo не будет достигнута, даже если some_test возвращен true . Целью программиста было определить, когда $result никогда не устанавливался, но PHP не позволяет им это делать.

Однако есть и другие проблемы с этим подходом, которые становятся ясными, если вы добавляете внешний цикл:

Поскольку $result никогда не инициализируется явно, он принимает значение, когда проходит первый тест, что делает невозможным определить, прошли ли последующие тесты или нет. На самом деле это чрезвычайно распространенная ошибка, когда переменные не инициализируются должным образом.

Чтобы исправить это, нам нужно что-то сделать в строке, где я прокомментировал, что что-то не хватает. Наиболее очевидным решением является установка $result на «конечное значение», которое some_function никогда не может вернуться; если это null , тогда остальная часть кода будет работать нормально. Если нет никакого естественного кандидата для конечного значения, потому что some_function имеет чрезвычайно непредсказуемый тип возврата (который, вероятно, является плохим знаком сам по себе), то дополнительное логическое значение, например. $found , можно использовать вместо этого.

Мысленный эксперимент: константа very_null

PHP теоретически может предоставить специальную константу, а также null — для использования здесь в качестве конечного значения; предположительно, было бы незаконным возвращать это из функции или было бы принуждено к null , и то же самое, вероятно, применимо для передачи его в качестве аргумента функции. Это сделало бы этот конкретный случай немного более простым, но как только вы решили перефакторировать код, например, чтобы включить внутренний цикл в отдельную функцию — это станет бесполезным. Если константа может быть передана между функциями, вы не можете гарантировать, что some_function не вернет ее, поэтому она больше не будет полезной в качестве универсального значения терминала.

Аргумент для определения неинициализированных переменных в этом случае сводится к аргументу для этой специальной константы: если вы замените комментарий на unset($result) и относитесь к нему иначе, чем к $result = null , вы вводите «значение» для $result , которые не могут быть переданы и могут быть обнаружены только определенными встроенными функциями.

Мысленный эксперимент два: счетчик присваивания

Еще один способ подумать о том, что спрашивает последний if , — «что-нибудь сделало присвоение $result ?»? Вместо того, чтобы рассматривать это как особое значение $result , вы могли бы подумать об этом как о «метаданных» об этой переменной, немного о Perl-переменной «tainting». Поэтому вместо isset вы можете назвать его has_been_assigned_to , а не unset , reset_assignment_state .

Но если так, зачем останавливаться на логическом? Что делать, если вы хотите узнать, сколько раз прошло испытание? вы можете просто расширить свои метаданные до целого числа и иметь get_assignment_count и reset_assignment_count .

Очевидно, что добавление такой функции будет иметь компромисс в сложности и производительности языка, поэтому его нужно будет тщательно взвешивать с учетом ожидаемой полезности. Как и в случае константы very_null , это было бы полезно только в очень узких условиях и было бы так же устойчиво к повторной факторизации.

Надежно очевидный вопрос: почему механизм выполнения PHP должен заранее предположить, что вы хотите отслеживать такие вещи, а не оставлять вас явно, используя обычный код.

Иногда я немного теряюсь, пытаясь выяснить, какую операцию сравнения использовать в данной ситуации. isset() применяется только к неинициализированным или явно нулевым значениям. Передача/присвоение значения null — отличный способ гарантировать, что логическое сравнение работает как ожидалось.

Тем не менее, немного сложно подумать, так вот простая матрица, сравнивающая, как различные значения будут оцениваться различными операциями:

Чтобы подогнать таблицу, я немного сжал эти метки:

  • $a; относится к объявленной, но неназначенной переменной
  • все остальное в первом столбце относится к назначенному значению, например:
    • $a = null;
    • $a = [];
    • $a = 0;
    • .
  • столбцы относятся к операциям сравнения, например:
    • $a === null
    • isset($a)
    • empty($a)
    • $a ? true : false
    • .

Все результаты булевы, true печатается и false опущен.

Вы можете запускать тесты самостоятельно, проверьте этот смысл:
https://gist.github.com/mfdj/8165967

Вы можете использовать компактную конструкцию языка для проверки существования нулевой переменной. Переменные, которые не существуют, не будут отображаться в результате, пока будут отображаться нулевые значения.

В случае вашего примера:

Конечно, для переменных в глобальной области действия вы также можете использовать array_key_exists().

B.t.w. лично я бы избегал ситуаций, подобных чуме, где существует семантическая разница между переменной, не существующей, и переменной, имеющей нулевое значение. PHP и большинство других языков просто не думаю, что есть.

Объяснение NULL, логическое мышление

Я думаю, очевидный ответ на все это. Не инициализируйте свои переменные как NULL, и сделайте их как что-то относящееся к тому, к чему они предназначены.

Правильно относиться к NULL

NULL следует рассматривать как «несуществующее значение», что означает значение NULL. Переменная не может быть классифицирована как существующая для PHP, потому что ей не было рассказано, какой тип сущности она пытается быть. Возможно, этого не существует, поэтому PHP просто говорит «Хорошо, это не потому, что в этом нет никакого смысла, и NULL — мой способ сказать это».

Аргумент

Теперь спорьте. «Но NULL — это как сказать 0 или FALSE или».

Неверно, 0-FALSE- » все еще классифицируются как пустые значения, но они ARE указаны как некоторый тип значения или предопределенный ответ на вопрос. ЛОЖЬ — ответ на да или нет, » — это ответ на заголовок, который был отправлен, а — это ответ на количество или время и т.д. Они заданы как некоторый тип ответа/результата, который делает их действительными как заданные.

NULL просто не отвечает, что так всегда, он не говорит нам «да» или «нет», и это не говорит нам о времени, и это не говорит нам, что пустая строка была отправлена. Это основная логика в понимании NULL.

Резюме

Это не о создании сумасшедших функций, чтобы обойти проблему, она просто меняет то, как ваш мозг смотрит на NULL. Если он NULL, предположите, что он не установлен ни во что. Если вы предварительно определяете переменные, тогда предопределяйте их как 0, FALSE или «» в зависимости от типа использования, которое вы им намереваетесь.

Не стесняйтесь процитировать это. Это от вершины моей логической головы:)

Свойства объекта можно проверить для существования property_exists

Пример из unit test:

В качестве дополнения к великим биговым обсуждением того, что означает NULL, рассмотрите, что на самом деле означает «существование переменной».

На многих языках вы должны явно объявлять каждую переменную, прежде чем использовать ее; это может определить его тип, но, что более важно, он заявляет о своем объеме. Переменная «существует» повсюду в своей области действия и нигде вне нее — будь то целая функция или один «блок».

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

В PHP переменные не должны быть объявлены — они оживают, как только они вам понадобятся. Когда вы пишете в переменную в первый раз, PHP выделяет запись в памяти для этой переменной. Если вы читаете переменную, которая в настоящее время не имеет записи, PHP считает, что переменная имеет значение NULL .

Однако автоматические детекторы качества кода обычно предупреждают вас, если вы используете переменную без «инициализации» ее сначала. Во-первых, это помогает обнаружить опечатки, такие как назначение $thingId , но чтение из $thing_id ; но, во-вторых, это заставляет вас рассмотреть область, в которой эта переменная имеет значение, точно так же, как декларация.

Любой код, который заботится о том, является ли переменная «существует» частью области действия этой переменной — независимо от того, была ли она инициализирована, вы, как программист, указали, что значение метки в этой точке код. Поскольку вы используете его, он должен в некотором смысле «существовать», и если он существует, он должен иметь неявное значение; в PHP это неявное значение NULL .

Из-за того, как работает PHP, можно написать код, который обрабатывает пространство имен существующих переменных не как область ярлыков, которые вы указали, а как своего рода хранилище значений ключа. Например, вы можете запустить код следующим образом: $var = $_GET[‘var_name’]; $$var = $_GET[‘var_value’]; . Просто потому, что вы можете, это не значит, что это хорошая идея.

Оказывается, PHP имеет гораздо лучший способ представления хранилищ для ключей, называемых ассоциативными массивами. И хотя значения массива можно рассматривать как переменные, вы также можете выполнять операции над массивом в целом. Если у вас есть ассоциативный массив, вы можете проверить, содержит ли он ключ, используя array_key_exists() .

Вы также можете использовать объекты аналогичным образом, динамически настраивая свойства, и в этом случае вы можете использовать property_exists() точно так же путь. Конечно, , если вы определяете класс, вы можете объявить, какие свойства у него есть, вы можете выбрать только public , private и protected .

Хотя существует техническая разница между переменной (в отличие от ключа массива или свойства объекта), которая не была инициализирована (или явно явно unset() ), и значением, значением которого является NULL , любой код, который считает, что разница имеет смысл, использует переменные так, как они не предназначены для использования.

Функция Isset

Функция Isset определяет, была ли установлена переменная значением отличным от NULL.
Функция Isset вернет FALSE, если проверяемая переменная Var имеет значение NULL, или TRUE, если переменная определена.

Переменная считается NULL, если:

— присвоена константа NULL.

— не присвоено никакого значения.

— удалена с помощью Unset.

Если были переданы несколько параметров, то функция Isset вернет TRUE только в том случае, если все параметры определены. Проверка происходит слева направо и заканчивается, как только будет встречена неопределенная переменная.

В параметре Var должны быть указаны проверяемые переменные.

Зачем проверять оба isset () и!пустой()

есть ли разница между isset и !empty . Если я сделаю эту двойную булеву проверку, это правильно или избыточно? и есть ли более короткий способ сделать то же самое?

9 ответов

это совершенно излишним. empty более или менее стенография для !isset($foo) || !$foo и !empty аналогично isset($foo) && $foo . Т. е. empty делает обратную вещь isset плюс дополнительная проверка для truthiness значения.

или другими словами, empty Это то же самое, что !$foo , но не выдает предупреждения, если переменная не существует. Это основной момент этой функции: выполните логическое сравнение, не беспокоясь о том, что переменная набор.

empty() напротив (boolean) var , за исключением того, что предупреждение не генерируется, когда переменная не задана.

вы можете просто использовать !empty($vars[1]) здесь.

isset() проверяет, установлена ли переменная, а не null:

empty() может возвращать true, когда переменная имеет определенные значения:

чтобы продемонстрировать это, попробуйте следующий код с $the_var неназначенным, равным 0 и равным 1.

принятый ответ неверен.

isset () is не эквивалентно !пустой.)(

вы создадите некоторые довольно неприятные и трудные для отладки ошибки, если вы пойдете по этому маршруту. например, попробуйте запустить этот код:

Empty просто проверьте, является ли ссылочная переменная / массив имеет значение, если вы проверяете php doc(пустой) вы увидите, что эти вещи считаются emtpy

в то время как isset проверяет, является ли переменная isset, а не null, которая также может быть найдена в php doc (isset)

«пустой»: работает только с переменными. Пустой может означать разные вещи для разных типов переменных (проверьте руководство:http://php.net/manual/en/function.empty.php).

«isset»: проверяет, существует ли переменная и проверяет значение true NULL или false. Можно отключить, вызвав «unset». Еще раз Проверьте инструкцию.

использование одного из них зависит от типа переменной, которую вы используете.

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

если мы используем ту же страницу для добавления / редактирования с помощью кнопки отправки, как показано ниже

затем мы не должны использовать

bcoz edit_id устанавливается все время, будь то добавить или редактировать страницу, вместо этого мы должны использовать проверку ниже условия

предупреждение не генерируется, если переменная не существует. это означает, что empty() по существу является кратким эквивалентом !использования isset($VAR) как / / $var == ложный.

  • С веб-сайта PHP, ссылаясь на :

возвращает FALSE если var имеет непустое и ненулевое значение.

это хорошая вещь, чтобы знать. Другими словами, все от NULL , to 0 в «» вернется TRUE при использовании .

  • Вот описание isset() функция возвращает:

возвращает TRUE если ; FALSE иначе.


другими словами, только переменные, которые не существуют (или переменные со строго NULL значение) возвращает FALSE на

Лучший способ проверить существование переменной в PHP; isset () явно нарушен

по сути, isset() не проверяет, установлена ли переменная вообще, но установлена ли она на что-нибудь, кроме NULL .

учитывая это, каков наилучший способ проверить существование переменной? Я попробовал что-то вроде:

(the @ необходимо избегать предупреждения, когда $v не установлен), но is_null() имеет аналогичную проблему с isset() : он возвращает TRUE на неопределенные переменные! Также оказывается, что:

работает точно так же, как @is_null($v) , так что тоже.

как мы должны надежно проверить наличие переменной в PHP?

Edit: существует явная разница в PHP между переменными, которые не установлены, и переменными, которые установлены в NULL :

PHP показывает, что $a[‘b’] существует, и есть NULL значение. Если вы добавить:

вы можете видеть двусмысленность, о которой я говорю с . Вот вывод всех трех из них var_dump()s :

дальнейшее редактирование: две вещи.

один, прецедент. Массив превращается в данные SQL UPDATE оператор, где ключи массива-это столбцы таблицы, а значения массива-это значения, применяемые к каждому столбцу. Любой из столбцов таблицы может содержать NULL значение, обозначается путем передачи NULL значение в массиве. Ты нужно способ различения между ключом массива, который не существует, и значением массива, установленным в NULL ; это разница между не обновлением значения столбца и обновлением значения столбца до NULL .

второе, Zoredache это, array_key_exists() работает правильно, для моего выше случая использования и для любого глобального переменные:

так как это правильно обрабатывает почти везде, я вижу, что существует какая-то двусмысленность между переменными, которые не существуют, и переменными, которые установлены в NULL ,я звоню array_key_exists() официальный самый простой способ в PHP по-настоящему проверить наличие переменной.

(только в другом случае я могу думать о свойствах класса, для которых есть property_exists() , который, согласно его документы, работает аналогично array_key_exists() в том, что он правильно различает между не устанавливается и устанавливается в NULL .)

17 ответов:

если переменная, которую вы проверяете, будет находиться в глобальной области, вы можете сделать:

попытка дать обзор различных обсуждений и ответов:

нет единого ответа на вопрос, который может заменить все пути isset можно использовать. некоторые варианты использования рассматриваются другими функциями, в то время как другие не выдерживают проверки или имеют сомнительную ценность за пределами кода golf. Далеко не «сломанный» или «непоследовательный», другие варианты использования демонстрируют, почему isset реакция на null — это логично поведение.

реальные случаи использования (с решениями)

1. Ключи массива

массивы можно рассматривать как коллекции переменных, с unset и isset относиться к ним так, как если бы они были. Однако, поскольку они могут быть повторены, подсчитаны и т. д., отсутствующее значение не совпадает с тем, значение которого null .

ответ в этом случае —использовать array_key_exists() вместо isset() .

так как это принимает массив для проверки в качестве аргумента функции, PHP все равно будет вызывать «уведомления», если сам массив не существует. В некоторых случаях можно обоснованно утверждать, что каждое измерение должно было быть инициализировано первым, поэтому уведомление выполняет свою работу. В других случаях «рекурсивный» array_key_exists функция, которая проверяла каждое измерение массива по очереди, избежала бы этого, но в основном была бы такой же, как @array_key_exists . Это также несколько касательно к обработке null значения.

2. Свойства объекта

в традиционной теории «объектно-ориентированного программирования» инкапсуляция и полиморфизм являются ключевыми свойствами объектов; в реализации ООП на основе классов, таких как PHP, инкапсулированные свойства объявляются как часть определения класса и задаются уровни доступа ( public , protected или private ).

однако PHP также позволяет динамически добавлять свойства к объекту, как вы бы ключи к массиву, и некоторые люди используют объекты без классов (технически, экземпляры встроенного stdClass , который не имеет методов или частной функциональности) аналогично ассоциативным массивам. Это приводит к ситуациям, когда функция может захотеть узнать, было ли добавлено определенное свойство к заданному ей объекту.

как и с ключами массива,решение для проверки свойств объекта включено в язык, называется, достаточно разумно, property_exists .

неоправданные случаи использования, с обсуждением

3. register_globals и другие загрязнения глобального пространства имен

The register_globals функция добавила переменные в глобальную область, имена которых определялись аспектами HTTP-запроса (параметры GET и POST, а также файлы cookie). Это может привести к багги и небезопасный код, поэтому он был отключен по умолчанию с PHP 4.2, выпущен Aug 2000 и удалено полностью в PHP 5.4, выпущен в марте 2012 года. Однако возможно, что некоторые системы все еще работают с включенной или эмулированной этой функцией. Также можно» загрязнить » глобальное пространство имен другими способами, используя global ключевое слово, или $GLOBALS массив.

во-первых, register_globals сам по себе вряд ли неожиданно произведет null переменная, так как значения GET, POST и cookie всегда будут строками (с » все еще возвращается true от isset ), и переменные в сессии должна быть полностью под контролем программиста.

во-вторых, загрязнение переменной со значением null это только проблема, если это переписывает некоторые предыдущие инициализации. «Перезапись» неинициализированной переменной с null было бы проблематично, если бы код где-то еще различал два состояния, поэтому сама по себе эта возможность является аргументом против сделать такое различие.

4. get_defined_vars и compact

несколько редко используемых функций в PHP, таких как get_defined_vars и compact , позволяет обрабатывать имена переменных, как если бы они были ключами в массиве. Для глобальных переменных, супер-глобальный массив $GLOBALS позволяет подобный доступ, и является более распространенным. Эти методы доступа будут вести себя иначе, если переменная не определена в соответствующей области.

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

функциональность, которая существовала только для прогнозирования того, как эти функции будут вести себя (например, «будет ли ключ ‘foo’ в массиве, возвращенном get_defined_vars ?») это лишнее, так как вы можете просто запустить функцию и выяснить, без вредных последствий.

4а. Переменные ( $$foo )

хотя и не совсем то же самое, что функции, которые превращают набор переменных в ассоциативный массив, в большинстве случаев используют «переменные» («назначить переменной с именем на основе этой другой переменной») можно и нужно изменить, чтобы вместо этого использовать ассоциативный массив.

имя переменной, по сути, является меткой, присвоенной значению программистом; если вы определяете его во время выполнения, это на самом деле не метка, а ключ в некотором значении ключа магазин. Более практично, не используя массив, вы теряете возможность подсчета, итерации и т. д.; Также может стать невозможным иметь переменную «вне» хранилища ключей, поскольку она может быть перезаписана $$foo .

после изменения для использования ассоциативного массива код будет поддаваться решению 1. Косвенный доступ к свойству объекта (например, $foo->$property_name ) можно решить с помощью решения 2.

5. isset — это гораздо легче, чем array_key_exists

я не уверен, что это действительно актуально, но да, имена функций PHP могут быть довольно многословными и непоследовательными иногда. По-видимому, доисторические версии PHP использовали длину имени функции в качестве хэш-ключа, поэтому Расмус намеренно составил имена функций, такие как htmlspecialchars так они будут иметь необычное количество символов.

тем не менее, по крайней мере, мы не пишем Java, а? ;)

6. Неинициализированные переменные имеют типа

The страница руководства по переменным основам включает в себя следующее утверждение:

неинициализированные переменные имеют значение по умолчанию, тип в зависимости от контекста, в котором они используются

я не уверен, есть ли какое-то понятие в Zend Engine «неинициализированного, но известного типа» или это слишком много читает в заявлении.

ясно, что это не имеет никакого практического значения для их поведения, поскольку поведение, описанное на этой странице для неинициализированных переменных, идентично поведению переменной, значение которой null . Чтобы выбрать один пример, оба $a и $b в этом коде будет в конечном итоге как целое число 42 :

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

99. Обнаружение, если функция выполнила

(сохраняя это последнее, так как это намного дольше, чем другие. Может быть, я отредактирую его позже. )

рассмотрим следующий код:

если some_function может возвратить null , есть вероятность, что echo не будет достигнуто, даже если some_test вернулся true . Намерение программиста состояло в том, чтобы определить, когда $result никогда не был установлен, но PHP не позволяет им это делать так.

однако, есть и другие проблемы с этим подходом, которые становятся ясными, если вы добавляете внешний цикл:

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

чтобы исправить это, мы должны сделать что-то на линии где я заметил, что чего-то не хватает. Самое очевидное решение-установить $result к «терминальному значению», которое some_function никогда не может вернуться; если это null , то остальная часть кода будет работать нормально. Если нет естественного кандидата для терминала, так как some_function имеет чрезвычайно непредсказуемый тип возврата (что, вероятно, само по себе плохой знак), а затем дополнительное логическое значение, например $found , можно использовать вместо этого.

мысленный эксперимент один: very_null константа

PHP теоретически может предоставить специальную константу-а также null — для использования в качестве терминального значения здесь; предположительно, было бы незаконно возвращать это из функции, или это было бы принудительно null , и то же самое, вероятно, относится к передаче его в качестве аргумента функции. Что бы убедиться в этом очень конкретном случае немного проще, но как только вы решили повторно вынести код — например, поставить внутренний цикл в отдельную функцию — это стать бесполезными. Если константа может быть передана между функциями, вы не можете гарантировать, что some_function не вернуть его, так что он больше не будет полезен в качестве универсального терминала.

аргумент для обнаружения неинициализированных переменных в этом случае сводится к аргументу для этой специальной константы: если вы замените комментарий на unset($result) , и относиться к этому иначе, чем $result = null , вы вводите «значение» для $result это не может быть передано, и может обнаруживается только с помощью специальных встроенных функций.

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

другой способ думать о том, что последнее if просит «что-нибудь сделал задание $result ?»Вместо того, чтобы считать это особой ценностью $result , вы могли бы подумать об этом как о «метаданных»о переменная, немного похожая на «переменную tainting» Perl. Так что вместо isset вы можете назвать это has_been_assigned_to , а чем unset , reset_assignment_state .

но если так, то зачем останавливаться на логическом? Что делать, если вы хотите знать во сколько раз тест пройден; вы можете просто расширить свои метаданные до целого числа и иметь get_assignment_count и reset_assignment_count .

очевидно, что добавление такой функции будет иметь компромисс в сложности и производительности языка, поэтому его необходимо будет тщательно взвесить против его ожидаемой полезности. Как и в случае с very_null постоянная, было бы полезно только в очень узкие обстоятельства, и были бы так же устойчивы к повторному факторингу.

надеюсь, очевидный вопрос заключается в том, почему PHP runtime engine должен заранее предполагать, что вы хотите отслеживать такие вещи, а не оставлять вас делать это явно, используя обычный код.

иногда я немного теряюсь, пытаясь выяснить, какую операцию сравнения использовать в данной ситуации. isset() применяется только к неинициализированным или явно нулевые значения. Передача / назначение null-отличный способ обеспечить логическое сравнение, как ожидалось.

тем не менее, это немного трудно думать о так вот простая матрица сравнения, как разные значения будут оцениваться различными операциями:

чтобы соответствовать таблице я сжал этикетки немного:

  • $a; относится к объявленной, но неназначенной переменной
  • все остальное в первом столбце относится к назначенному значению, например:
    • $a = null;
    • $a = [];
    • $a = 0;
    • .

  • столбцы относятся к операциям сравнения , как:
    • $a === null
    • isset($a)
    • empty($a)
    • $a ? true : false
    • .

все результаты являются булевыми, true печатается и false опущен.

вы можете запустить тесты самостоятельно, проверьте эту суть:
https://gist.github.com/mfdj/8165967

вы можете использовать конструкцию compact language для проверки существования нулевой переменной. Переменные, которые не существуют, не будут отображаться в результате, в то время как значения null будут отображаться.

в случае вашего примера:

конечно, для переменных в глобальной области вы также можете использовать array_key_exists().

B. t. w. лично я бы избегал таких ситуаций, как чума, где есть семантическая разница между переменной, не существующей и переменная, имеющая нулевое значение. PHP и большинство других языков просто не думают, что есть.

объясняя нуль, логически думая

Я думаю, очевидный ответ на все это. Не инициализируйте свои переменные как NULL, инициализируйте их как что-то относящееся к тому, чем они должны стать.

лечить NULL правильно

NULL следует рассматривать как» несуществующее значение», которое является значением NULL. Переменная не может быть классифицирована как существующая для PHP, потому что ей не было сказано, каким типом сущности она пытается быть. А может и нет существует, поэтому PHP просто говорит: «Хорошо, это не так, потому что в этом нет смысла, и NULL-это мой способ сказать это».

аргумент

давайте теперь поспорим. «Но NULL-это как сказать 0 или FALSE или «.

неверно, 0-FALSE — » все еще классифицируются как пустые значения, но они указываются как некоторый тип значения или заранее определенный ответ на вопрос. ложные это ответ да или нет« это ответ на название кто-то подал, и это ответ на количество или время и т. д. Они устанавливаются как некоторый тип ответа/результата, который делает их действительными как установленные.

NULL-это просто не ответ, что так когда-либо, он не говорит нам да или нет, и он не говорит нам время, и он не говорит нам, что пустая строка была отправлена. Это основная логика в понимании NULL.

резюме

речь идет не о создании дурацких функций, чтобы обойти проблему, это просто меняет способ вашего мозг смотрит на нуль. Если он равен нулю, предположим, что он не установлен как что-либо. Если вы предварительно определяете переменные, то предварительно определите их как 0, FALSE или «» в зависимости от типа использования, которое вы для них предназначаете.

Не стесняйтесь цитировать это. Это с верхней части моей логической головы :)

свойства объекта можно проверить на существование с помощью property_exists

пример из модульного теста:

как дополнение к обсуждение greatbigmassive того, что означает NULL, рассмотрим, что на самом деле означает» существование переменной».

во многих языках, вы должны явно объявить каждую переменную, прежде чем использовать его; это может определить его тип, но что более важно, он объявляет его scope. Переменная «существует» везде в своей области, и нигде за ее пределами-будь то целая функция или одна «блок.»

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

в PHP переменные не нужно объявлять — они оживают, как только вы нуждаетесь в них. Когда вы пишете в переменную в первый раз, PHP выделяет запись в памяти для этого переменная. Если Вы читаете из переменной, которая в настоящее время не имеет записи, PHP считает, что эта переменная имеет значение NULL .

однако автоматические детекторы качества кода обычно предупреждают вас, если вы используете переменную без ее «инициализации». Во-первых, это помогает обнаружить опечатки, такие как назначение $thingId но чтение $thing_id ; но во-вторых, это заставляет вас рассматривать область, над которой эта переменная имеет значение, как объявление бы.

любой код, который заботится о том, существует ли переменная, является частью области действия этой переменной — независимо от того, был ли он инициализирован, вы, как программист, дали эту метку, означающую в этой точке кода. Поскольку вы используете его, он должен в некотором смысле «существовать», и если он существует, он должен иметь неявное значение; в PHP это неявное значение null .

из-за того, как работает PHP, можно написать код, который обрабатывает пространство имен существующих переменных не как область меток, которым вы придали значение, а как своего рода хранилище ключей-значений. Вы можете, например, запустить такой код: $var = $_GET[‘var_name’]; $$var = $_GET[‘var_value’]; . просто потому, что вы можете, не означает, что это хорошая идея.

оказывается, PHP имеет гораздо лучший способ представления хранилищ ключей-значений, называемых ассоциативными массивами. И хотя значения массива можно рассматривать как переменные, вы также можете выполнять операции над массивом в целом. если вы есть ассоциативный массив, вы можете проверить, если он содержит ключ, используя array_key_exists() .

вы также можете использовать объекты аналогичным образом, динамически устанавливая свойства, в этом случае вы можете использовать property_exists() точно так же. Конечно,если вы определяете класс, вы можете объявить, какие свойства он имеет — вы даже можете выбрать между public , private и protected объем.

хотя есть технические разница между переменной (в отличие от ключа массива или свойства объекта), которая не была инициализирована (или была явно unset() ) и тот, чье значение null любой код, который считает, что разница должна быть значимую использует переменные таким образом, что они не предназначены для использования.

isset проверяет, установлена ли переменная и, если да, то является ли ее стоимостью не является нулем. Последняя часть (на мой взгляд) не входит в сферу этой функции. Нет достойного обходного пути, чтобы определить, является ли переменная NULL потому что он не установлен или так он явно установлен в NULL.

вот одно из возможных решений:

другой обходной путь зондировать выход get_defined_vars() :

Я не согласен с вашими рассуждениями о NULL, и говорить, что вам нужно изменить свое мышление о NULL, просто странно.

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

Что делать, если вы проверяете значения, возвращаемые из базы данных, и один из столбцов имеет нулевое значение, вы все равно хотите знать, существует ли оно, даже если значение равно NULL. нет, не доверяйте isset () здесь.

isset () должен был быть разработан, чтобы работать следующим образом:

таким образом, мы оставляем программисту проверять типы и не оставляем его до isset (), чтобы предположить, что его нет, потому что значение равно NULL — его просто глупый дизайн

Я собираюсь добавить два цента к этому. Одна из причин, по которой эта проблема сбивает с толку, заключается в том, что этот сценарий, похоже, возвращает тот же результат с сообщением об ошибке не на полном:

вы могли бы предположить из этого результата, что разница между $a = null и не определение $b вообще ничего.

Crank сообщение об ошибке вверх:

Примечание: он бросил неопределенную переменную ошибку, но выходное значение var_dump по-прежнему NULL .

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

Я думаю, что принятый ответ хорош по большей части, но если бы я собирался реализовать его, я бы написал обертку для него. Как уже упоминалось ранее в ответ, я должен согласиться, что я на самом деле не сталкивались с ситуацией, когда это было проблемой. Кажется, я почти всегда оказываюсь в сценарии, где мои переменные либо установлены и определены, либо они не определены (undefined, unset, null, blank и т. д.). Не сказать, что такая ситуация не произойдет в будущем, но поскольку это, кажется, довольно уникальная проблема, я не удивлен, что разработчики PHP не потрудились это сделать.

если я запускаю следующий:

Я получаю сообщение об ошибке:

если я запускаю следующий:

Я не получаю ошибку.

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

таким образом, позже в скрипте я могу безопасно использовать $foo и знать, что он «установлен», и что по умолчанию он равен null. Позже я смогу if ( is_null($foo) ) < /* . */ >если мне нужно и знаю уверен, что переменная существует, даже если она равна нулю.

полное документация isset и читает немного больше, чем просто то, что было изначально наклеена. Да, он возвращает false для переменной, которая была ранее установлена, но теперь равна null, но он также возвращает false, если переменная еще не была установлена (когда-либо) и для любой переменной, которая была помечена как unset. Он также отмечает, что нулевой байт («\0») не считается нулевым и возвращает true.

определить установлена ли переменная.

если переменная была удалена с unset (), он больше не будет установлен. isset () вернет FALSE при тестировании a переменная, которая была установлена в NULL. Также обратите внимание, что нулевой байт («\0») является не эквивалентно PHP NULL постоянный.

Кажется, что единственный раз, когда переменная не задана, это когда она специально не задана ($v). Похоже, что ваш смысл «существования» отличается от определения PHP. NULL, конечно, существует, это NULL.

Я должен сказать, что за все годы программирования PHP, я никогда не сталкивался с проблемой с isset() возвращает false для нулевой переменной. ОТО, у меня возникли проблемы с isset() сбой на нулевой записи массива-но array_key_exists() работает правильно в этом случае.

для некоторого сравнения Icon явно определяет неиспользуемую переменную как returning &null значит вы используете это-нуль, испытание на значок, чтобы проверить неопределенная переменная. Это делает вещи проще. С другой стороны, Visual BASIC имеет несколько состояний для переменной, которая не имеет значения (Null, Empty, Nothing. ), и вам часто приходится проверять более одного из них. Это, как известно, является источником ошибок.

согласно руководству PHP для функции empty (), » определите, считается ли переменная пустой. Переменная считается пустой, если она не существует или если ее значение равно FALSE. пустой () не создает предупреждение, если переменная не существует.»(Мой акцент.) Это означает, что функция empty () должна квалифицироваться как «лучший способ проверить существование переменной в PHP», согласно вопросу заголовка.

, это не достаточно хорошо, потому что функция empty() может быть обманут переменной, которая существует и имеет значение NULL.

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

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

вы можете следовать этим двум строкам с чем-нибудь подходящим, например, это пример:

Я хотел поместить вызов ob_start () и ($testvar===null) внутри функции и просто передать переменную в функцию, но она не работает. Даже если вы попытаетесь использовать» pass by reference » переменной для функции, переменная становится определенной, и тогда функция никогда не сможет обнаружить, что она ранее не была определена. То, что здесь представлено, является компромиссом между тем, что я хотел сделать, и тем, что на самом деле работает.

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

просто вызовите эту функцию, прежде чем что-то делать с вашим $testvar:

значение вновь созданной переменной имеет значение null, конечно!

Итак, после некоторого изучения и экспериментов, вот что-то гарантированно работает:


объяснение: переменная $er инициализируется значением по умолчанию «no error». Определена «функция обработчика». Если $testvar (переменная, которую мы хотим знать, является ли она неопределенной) проходит предварительный тест функции empty (), то мы делаем более тщательный тест. Мы вызываем функцию set_error_handler () для использования ранее определенной функции обработчика. Затем мы делаем простое сравнение идентичности с использованием $testvar, которое если НЕОПРЕДЕЛЕННЫЙ ВЫЗОВЕТ ОШИБКУ. Функция обработчика фиксирует ошибку и специально проверяет, является ли причиной ошибки тот факт, что переменная не определена. Результат помещается в переменную error-information $er, которую мы можем позже протестировать, чтобы сделать все, что мы хотим, в результате зная наверняка, был ли определен $testvar. Поскольку нам нужна только функция обработчика для этой ограниченной цели, мы восстанавливаем исходную функцию обработки ошибок. Функция «myHndlr» только должен быть объявлен один раз; другой код может быть скопирован в любые подходящие места, для $testvar или любой другой переменной, которую мы хотим проверить таким образом.

Я думаю, что единственным полным решением является уведомления отчет С

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

включение уведомления отчетности не может быть хорошей альтернативой во всех ситуациях, но есть веские причины, чтобы включить его:

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

единственный способ узнать, определена ли переменная в текущей области ( $GLOBALS не заслуживает доверия) — это array_key_exists( ‘var_name’, get_defined_vars() ) .

Я предпочитаю использовать not empty как лучший метод для проверки существования переменной, которая a) существует, а b) не является нулевой.

Isset — Определяет установлена ли переменная

isset Должен ли я всегда использовать isset () для аргументов URL? Открыть

isset PHP !isset & empty & session check turning true every time Открыть

isset Состояние isset ведет себя по-разному на разных кликах Открыть

isset Нужно ли определять массив перед добавлением к нему? Открыть

isset PHP — это одно значение, а не другое Открыть

isset Окно выбора, отображающее пустую строку с использованием набора сеансов Открыть

isset Сначала проверьте значение, прежде чем поместить его в оператор if (ЗАКРЫТО) Открыть

isset Варианты доставки в зависимости от веса корзины и класса доставки Открыть

isset Isset для использования переменной PHP в HTML-форме Открыть

isset Если GET нет . или если GET пуст Открыть

isset isset () создание свойства объекта Открыть

isset Переменная установлена ​​как строка, но не определена как свойство объекта Открыть

isset Can I assign a value to a var from another which I don’t know if exist in one row? Открыть

isset Ошибка в обновлении и вставке запроса в php mysql Открыть

isset PHP проверяет, получили ли переменные определенные значения Открыть

isset $ _SESSION PHP не работает без www Открыть

isset Эквивалент php isset в питоне Открыть

isset Как установить POST ссылку href с isset Открыть

isset Сбой PHP при использовании функции isset Открыть

isset (PHP) хранение IP-адреса кликов Открыть

isset PHP Альтернатива if (! Isset (. )) <. >=> GetVar ($ Variable, $ ValueIfNotExists) Открыть

isset isset не работает в laravel Открыть

isset Почему функция isset не обновляет мою базу данных? Открыть

isset Применение определенного формата JSON для запросов в PHP Открыть

isset Isset ($ _ POST ()) возвращает false в форме Открыть

isset Isset возвращает неопределенный индекс, хотя он установлен Открыть

isset Как присвоить массиву несколько значений с помощью ввода isset в форме в php Открыть

isset Как проверить, существует ли флажок PHP Открыть

isset isset($_POST[‘remember’]) checkbox issue in PHP Открыть

isset isset $ _GET не показывает правильную информацию Открыть

isset

(PHP 4, PHP 5, PHP 7)

isset — Determine if a variable is declared and is different than NULL

Description

Determine if a variable is considered set, this means if a variable is declared and is different than NULL .

If a variable has been unset with the unset() function, it is no longer considered to be set.

isset() will return FALSE when checking a variable that has been assigned to NULL . Also note that a null character («\0») is not equivalent to the PHP NULL constant.

If multiple parameters are supplied then isset() will return TRUE only if all of the parameters are considered set. Evaluation goes from left to right and stops as soon as an unset variable is encountered.

Parameters

The variable to be checked.

Return Values

Returns TRUE if var exists and has any value other than NULL . FALSE otherwise.

Changelog

Checking non-numeric offsets of strings now returns FALSE .

Examples

Example #1 isset() Examples

// This will evaluate to TRUE so the text will be printed.
if (isset( $var )) <
echo «This var is set so I will print.» ;
>

// In the next examples we’ll use var_dump to output
// the return value of isset().

$a = «test» ;
$b = «anothertest» ;

var_dump (isset( $a )); // TRUE
var_dump (isset( $a , $b )); // TRUE

var_dump (isset( $a )); // FALSE
var_dump (isset( $a , $b )); // FALSE

$foo = NULL ;
var_dump (isset( $foo )); // FALSE

This also work for elements in arrays:

= array ( ‘test’ => 1 , ‘hello’ => NULL , ‘pie’ => array( ‘a’ => ‘apple’ ));

var_dump (isset( $a [ ‘test’ ])); // TRUE
var_dump (isset( $a [ ‘foo’ ])); // FALSE
var_dump (isset( $a [ ‘hello’ ])); // FALSE

// The key ‘hello’ equals NULL so is considered unset
// If you want to check for NULL key values then try:
var_dump ( array_key_exists ( ‘hello’ , $a )); // TRUE

// Checking deeper array values
var_dump (isset( $a [ ‘pie’ ][ ‘a’ ])); // TRUE
var_dump (isset( $a [ ‘pie’ ][ ‘b’ ])); // FALSE
var_dump (isset( $a [ ‘cake’ ][ ‘a’ ][ ‘b’ ])); // FALSE

Example #2 isset() on String Offsets

PHP 5.4 changes how isset() behaves when passed string offsets.

Output of the above example in PHP 5.3:

Output of the above example in PHP 5.4:


Notes

isset() only works with variables as passing anything else will result in a parse error. For checking if constants are set use the defined() function.

Note: Because this is a language construct and not a function, it cannot be called using variable functions.

When using isset() on inaccessible object properties, the __isset() overloading method will be called, if declared.

See Also

  • empty() — Determine whether a variable is empty
  • __isset()
  • unset() — Unset a given variable
  • defined() — Checks whether a given named constant exists
  • the type comparison tables
  • array_key_exists() — Checks if the given key or index exists in the array
  • is_null() — Finds whether a variable is NULL
  • the error control @ operator

User Contributed Notes 42 notes

I, too, was dismayed to find that isset($foo) returns false if ($foo == null). Here’s an (awkward) way around it.

unset($foo);
if (compact(‘foo’) != array()) <
do_your_thing();
>

Of course, that is very non-intuitive, long, hard-to-understand, and kludgy. Better to design your code so you don’t depend on the difference between an unset variable and a variable with the value null. But «better» only because PHP has made this weird development choice.

In my thinking this was a mistake in the development of PHP. The name («isset») should describe the function and not have the desciption be «is set AND is not null». If it was done properly a programmer could very easily do (isset($var) || is_null($var)) if they wanted to check for this!

A variable set to null is a different state than a variable not set — there should be some easy way to differentiate. Just my (pointless) $0.02.

«empty() is the opposite of (boolean) var, except that no warning is generated when the variable is not set.»

So essentially
if (isset( $var ) && $var )
?>
is the same as
if (!empty( $var ))
?>
doesn’t it? :)

!empty() mimics the chk() function posted before.

How to test for a variable actually existing, including being set to null. This will prevent errors when passing to functions.

// false
var_export (
array_key_exists ( ‘myvar’ , get_defined_vars ())
);

$myvar ;
// false
var_export (
array_key_exists ( ‘myvar’ , get_defined_vars ())
);

$myvar = null ;
// true
var_export (
array_key_exists ( ‘myvar’ , get_defined_vars ())
);

unset( $myvar );
// false
var_export (
array_key_exists ( ‘myvar’ , get_defined_vars ())
);

if ( array_key_exists ( ‘myvar’ , get_defined_vars ())) <
myfunction ( $myvar );
>
?>

Note: you can’t turn this into a function (e.g. is_defined($myvar)) because get_defined_vars() only gets the variables in the current scope and entering a function changes the scope.

in PHP5, if you have

class Foo
<
protected $data = array( ‘bar’ => null );

function __get ( $p )
<
if( isset( $this -> data [ $p ]) ) return $this -> data [ $p ];
>
>
?>

and
= new Foo ;
echo isset( $foo -> bar );
?>
will always echo ‘false’. because the isset() accepts VARIABLES as it parameters, but in this case, $foo->bar is NOT a VARIABLE. it is a VALUE returned from the __get() method of the class Foo. thus the isset($foo->bar) expreesion will always equal ‘false’.

You can safely use isset to check properties and subproperties of objects directly. So instead of writing

isset($abc) && isset($abc->def) && isset($abc->def->ghi)

or in a shorter form

isset($abc, $abc->def, $abc->def->ghi)

you can just write

without raising any errors, warnings or notices.

Examples
= (object) array( «def» => 123 );
var_dump (isset( $abc )); // bool(true)
var_dump (isset( $abc -> def )); // bool(true)
var_dump (isset( $abc -> def -> ghi )); // bool(false)
var_dump (isset( $abc -> def -> ghi -> jkl )); // bool(false)
var_dump (isset( $def )); // bool(false)
var_dump (isset( $def -> ghi )); // bool(false)
var_dump (isset( $def -> ghi -> jkl )); // bool(false)

var_dump ( $abc ); // object(stdClass)#1 (1) < ["def"] =>int(123) >
var_dump ( $abc -> def ); // int(123)
var_dump ( $abc -> def -> ghi ); // null / E_NOTICE: Trying to get property of non-object
var_dump ( $abc -> def -> ghi -> jkl ); // null / E_NOTICE: Trying to get property of non-object
var_dump ( $def ); // null / E_NOTICE: Trying to get property of non-object
var_dump ( $def -> ghi ); // null / E_NOTICE: Trying to get property of non-object
var_dump ( $def -> ghi -> jkl ); // null / E_NOTICE: Trying to get property of non-object
?>

Careful with this function «ifsetfor» by soapergem, passing by reference means that if, like the example $_GET[‘id’], the argument is an array index, it will be created in the original array (with a null value), thus causing posible trouble with the following code. At least in PHP 5.

= array();
print_r ( $a );
ifsetor ( $a [ «unsetindex» ], ‘default’ );
print_r ( $a );
?>

will print

Any foreach or similar will be different before and after the call.

I tried the example posted previously by Slawek:

$foo = ‘a little string’;
echo isset($foo)?’yes ‘:’no ‘, isset($foo[‘aaaa’])?’yes ‘:’no ‘;

He got yes yes, but he didn’t say what version of PHP he was using.

I tried this on PHP 5.0.5 and got: yes no

But on PHP 4.3.5 I got: yes yes

Apparently, PHP4 converts the the string ‘aaaa’ to zero and then returns the string character at that position within the string $foo, when $foo is not an array. That means you can’t assume you are dealing with an array, even if you used an expression such as isset($foo[‘aaaa’][‘bbb’][‘cc’][‘d’]), because it will return true also if any part is a string.

PHP5 does not do this. If $foo is a string, the index must actually be numeric (e.g. $foo[0]) for it to return the indexed character.

The new (as of PHP7) ‘null coalesce operator’ allows shorthand isset. You can use it like so:

// Fetches the value of $_GET[‘user’] and returns ‘nobody’
// if it does not exist.
$username = $_GET [ ‘user’ ] ?? ‘nobody’ ;
// This is equivalent to:
$username = isset( $_GET [ ‘user’ ]) ? $_GET [ ‘user’ ] : ‘nobody’ ;

// Coalescing can be chained: this will return the first
// defined value out of $_GET[‘user’], $_POST[‘user’], and
// ‘nobody’.
$username = $_GET [ ‘user’ ] ?? $_POST [ ‘user’ ] ?? ‘nobody’ ;
?>

Quoted from http://php.net/manual/en/migration70.new-features.php#migration70.new-features.null-coalesce-op

Note that isset() is not recursive as of the 5.4.8 I have available here to test with: if you use it on a multidimensional array or an object it will not check isset() on each dimension as it goes.

Imagine you have a class with a normal __isset and a __get that fatals for non-existant properties. isset($object->nosuch) will behave normally but isset($object->nosuch->foo) will crash. Rather harsh IMO but still possible.

// pretend that the methods have implementations that actually try to do work
// in this example I only care about the worst case conditions

public function __get ( $name ) <
echo «(getting < $name >) » ;

// if property does not exist <
echo «Property does not exist!» ;
exit;
// >
>

public function __isset ( $name ) <
echo «(isset < $name >?) » ;
// return whether the property exists
return false ;
>

$obj = new FatalOnGet ();

// works
echo «Testing if ->nosuch exists: » ;
if (isset( $obj -> nosuch )) echo «Yes» ; else echo «No» ;

// fatals
echo «\nTesting if ->nosuch->foo exists: » ;
if (isset( $obj -> nosuch -> foo )) echo «Yes» ; else echo «No» ;

// not executed
echo «\nTesting if ->irrelevant exists: » ;
if (isset( $obj -> irrelevant )) echo «Yes» ; else echo «No» ;

?>

Testing if ->nosuch exists: No
Testing if ->nosuch->foo exists: Property does not exist!

Uncomment the echos in the methods and you’ll see exactly what happened:

Testing if ->nosuch exists: (isset nosuch?) No
Testing if ->nosuch->foo exists: (getting nosuch) Property does not exist!

On a similar note, if __get always returns but instead issues warnings or notices then those will surface.

Return Values :
Returns TRUE if var exists and has value other than NULL, FALSE otherwise.

= NULL ;
$b = FALSE ; //The out put was TRUE.
$c = TRUE ;
$d = » ;
$e = «» ;
if(isset( $b )):
echo «TRUE» ;
else:
echo «FALSE» ;
endif;
?>
Could any one explain me in clarity.

1) Note that isset($var) doesn’t distinguish the two cases when $var is undefined, or is null. Evidence is in the following code.

unset( $undefined );
$null = null ;
if ( true === isset( $undefined )) else if ( true === isset( $null )) else ?>

2) If you want to distinguish undefined variable with a defined variable with a null value, then use array_key_exist

unset( $undefined );
$null = null ;

if ( true !== array_key_exists ( ‘undefined’ , get_defined_vars ())) else // ‘$undefined does not exist’
if ( true === array_key_exists ( ‘null’ , get_defined_vars ())) else // ‘$null exists’
?>

To organize some of the frequently used functions..

/**
* Returns field of variable (arr[key] or obj->prop), otherwise the third parameter
* @param array/object $arr_or_obj
* @param string $key_or_prop
* @param mixed $else
*/
function nz ( $arr_or_obj , $key_or_prop , $else ) <
$result = $else ;
if(isset( $arr_or_obj )) <
if( is_array ( $arr_or_obj ) <
if(isset( $arr_or_obj [ $key_or_prop ]))
$result = $arr_or_obj [ $key_or_prop ];
>elseif( is_object ( $arr_or_object ))
if(isset( $arr_or_obj -> $key_or_prop ))
$result = $arr_or_obj -> $key_or_prop ;
>
>
return $result ;
>

/**
* Returns integer value using nz()
*/
function nz_int ( $arr_or_obj , $key_or_prop , $else ) <
return intval ( nz ( $arr_or_obj , $key_or_prop , $else ));
>

$my_id = nz_int ( $_REQUEST , ‘id’ , 0 );
if( $my_id > 0 ) <
//why?
>
?>


Sometimes you have to check if an array has some keys. To achieve it you can use «isset» like this: isset($array[‘key1’], $array[‘key2’], $array[‘key3’], $array[‘key4’])
You have to write $array all times and it is reiterative if you use same array each time.

With this simple function you can check if an array has some keys:

function isset_array () <
if ( func_num_args () 2 ) return true ;
$args = func_get_args ();
$array = array_shift ( $args );
if (! is_array ( $array )) return false ;
foreach ( $args as $n ) if (!isset( $array [ $n ])) return false ;
return true ;
>
?>

Use: isset_array($array, ‘key1’, ‘key2’, ‘key3’, ‘key4’)
First parameter has the array; following parameters has the keys you want to check.

The following is an example of how to test if a variable is set, whether or not it is NULL. It makes use of the fact that an unset variable will throw an E_NOTICE error, but one initialized as NULL will not.

function var_exists ( $var ) <
if (empty( $GLOBALS [ ‘var_exists_err’ ])) <
return true ;
> else <
unset( $GLOBALS [ ‘var_exists_err’ ]);
return false ;
>
>

function var_existsHandler ( $errno , $errstr , $errfile , $errline ) <
$GLOBALS [ ‘var_exists_err’ ] = true ;
>

$l = NULL ;
set_error_handler ( «var_existsHandler» , E_NOTICE );
echo ( var_exists ( $l )) ? «True » : «False » ;
echo ( var_exists ( $k )) ? «True » : «False » ;
restore_error_handler ();

The problem is, the set_error_handler and restore_error_handler calls can not be inside the function, which means you need 2 extra lines of code every time you are testing. And if you have any E_NOTICE errors caused by other code between the set_error_handler and restore_error_handler they will not be dealt with properly. One solution:

function var_exists ( $var ) <
if (empty( $GLOBALS [ ‘var_exists_err’ ])) <
return true ;
> else <
unset( $GLOBALS [ ‘var_exists_err’ ]);
return false ;
>
>

function var_existsHandler ( $errno , $errstr , $errfile , $errline ) <
$filearr = file ( $errfile );
if ( strpos ( $filearr [ $errline — 1 ], ‘var_exists’ ) !== false ) <
$GLOBALS [ ‘var_exists_err’ ] = true ;
return true ;
> else <
return false ;
>
>

$l = NULL ;
set_error_handler ( «var_existsHandler» , E_NOTICE );
echo ( var_exists ( $l )) ? «True » : «False » ;
echo ( var_exists ( $k )) ? «True » : «False » ;
is_null ( $j );
restore_error_handler ();

?>

Outputs:
True False
Notice: Undefined variable: j in filename.php on line 26

This will make the handler only handle var_exists, but it adds a lot of overhead. Everytime an E_NOTICE error happens, the file it originated from will be loaded into an array.

PHP, функция isset(), нюансы в определении (php, документация)

По мотивам заведенного бага (см. внизу секцию «comments»)

В английской документации сказано:

isset — Determine if a variable is set and is not NULL

В русской переведено так:

isset — Определяет, была ли установлена переменная значением отличным от NULL

Автор багрепорта настаивает на исправлении перевода на следующий:

isset — Определяет, была ли создана переменная и установлена значением отличным от NULL

И все бы ничего, но в процессе дискуссии всплыло следующее:

Именно в моей учебной группе пару учеников не смогли понять что isset определяет что переменная была создана! И с точки зрения ЛОГИКИ они правы.

И вот тут я впал в ступор. Мне кажется, что вопрос ушел в какую то совсем не ту степь, и упор на то, что isset определяет что переменная была создана несет скорее вред, чем пользу.

Собственно хочется услышать мнение профессионалов в PHP, это я дурак и ничего не понимаю или автору багрепорта хочется странного?

Ответы (2)

Если Вы хотите установить значение переменной то isset здесь нипричем.. isset реагирует только на null, ведь если переменная ровняется null то какой смысл isset-у говорить что она есть. Веть она неактивная.. она даже не пустая, а именно скрипт ее не воспринимает вообще.

isset стоит визывать только если переменной присвоено хоть какоето значетие

Или как минимум нужно указать что она пустая:

Пустую переменную isset видит (ведь она есть, просто пустая). А вот переменную со значеним null нет.

Я просто не доконца понял Ваш вопрос..

В PHP, созданная переменная — это такая, запись о которой присутствует в symbol table . Запись в symbol table появляется тогда, когда переменной присваивается значение (хоть бы и null).

Т.е. если рассуждать в контексте исполнения PHP-скрипта, переменная создана и переменной присвоено значение — по сути синонимы.

isset возвращает возвращает false в двух случаях:

  1. Переменная равна null
  2. Переменная отсутствует в symbol table

Фактически, isset возвращает true , если переменной было присвоено любое значение, кроме null , что и написано в текущем варианте страницы описания.

Т.е. предложенный вариант

isset — Определяет, была ли создана переменная и установлена значением отличным от NULL

по сути является маслом масляным, так как при исполнении PHP-скрипта, была ли создана переменная и установлена значением — означают одно и тоже, но при этом, переусложняют и запутывают определение.

Функции ISSET и UNSET в PHP

Продолжаем изучать PHP и сегодня рассмотрим две замечательные функции ISSET и UNSET.

Функция isset предназначена для определения в коде наличия переменной. В качестве параметра в данную функцию передается проверяемая переменная.

На следующем примере мы хотим проверить существует ли у нас переменная $g:

Результатом выполнения данного кода будет вывод на экран цифры 1. Это означает, что переменная существует. В случае проверки заведомо несуществующей переменной, результатом выполнения будет пустота, то есть по другому, ничего не будет выведено на экране.

Функция isset применяется в основном с оператором if. Рассмотрим следующий пример, в котором мы проверим существует ли переменная, и если это так, то выведем её значение. В случае если это не так, то выведем сообщение, что переменная не существует:

$g = 5;
if (isset($g))
<
echo «Переменная g существует и её значение равно: $g»;
>
else
<
echo «Переменная g не существует»;
>

Мы научились создавать переменные в php и придавать им значения. Теперь рассмотрим функцию unset, которая позволяет уничтожать данные переменные.

Результатом выполнения данной программы будет ошибка, а не вывод на экран числа 10. Так произойдет потому, что до выполнения echo «$g», переменая $g будет уничтожена функцией unset и уже она просто не будет физически существовать.

Похожие статьи:

Подписаться на рассылку

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

Как проверить, установлена ​​ли переменная в Bash?

Как узнать, установлена ​​ли переменная в Bash?

Например, как я могу проверить, передал ли пользователь первый параметр функции?

18 ответов

(Обычно) Правильный путь

, где $ — расширение параметра , которое ничего не оценивает, если var не установлено, и заменяет строку x в противном случае.

Цитаты Отступление

Цитаты могут быть опущены (поэтому мы можем сказать $ вместо «$» ), потому что этот синтаксис & amp; использование гарантирует, что это будет расширяться только до чего-то, что не требует кавычек (поскольку оно либо расширяется до x (которое не содержит разрывов слов, поэтому не нуждается в кавычках), либо до нуля (что приводит к [ -z ] , который удобно оценивать как то же значение (true), что [ -z «» ] делает то же самое)).

Однако, хотя кавычки могут быть безопасно опущены, и это было не сразу очевидно для всех (это даже не было очевидно для первого автора этого объяснения цитат , который также является основным Bash-кодером), иногда было бы лучше написать решение с кавычками как [ -z «$» ] , при очень небольшой возможной стоимости штрафа за скорость O (1). Первый автор также добавил это в качестве комментария рядом с кодом, использующим это решение, в котором указан URL-адрес этого ответа, который теперь также включает в себя объяснение того, почему кавычки можно безопасно опускать.

(Часто) Неправильный путь

Это часто неправильно, потому что не различает переменную, которая не установлена, и переменную, которая установлена ​​в пустую строку. То есть, если var=» , то вышеупомянутое решение выведет «var is blank».

Различие между unset и «set to the empty string» является существенным в ситуациях, когда пользователь должен указать расширение или дополнительный список свойств, и если не указывать их, по умолчанию используется непустое значение, тогда как указание пустой строки должно заставить скрипт использовать пустое расширение или список дополнительных свойств.

Различие не может быть существенным в каждом сценарии, хотя. В этих случаях [ -z «$var» ] будет просто отлично.

Разница между isset и empty

Необходимо чётко понимать разницу между isset и empty. Часто новички путают эти две функции, давайте разберёмся как именно работает каждая из них.

isset()

isset() — проверяет переменную на существование, а также, что её значение не null. Если переменная существует и её значение не null, то функция вернёт true, все остальные случаи — это false;

empty()

empty() — проверяет переменную на существование и на пустоту. Если в переменной есть какое-то не пустое значение или true, то функция вернёт false, всё остальные случаи — это true;

Таблица ниже поможет вам лучше понять как работает isset и empty

Илон Маск рекомендует:  Информация о занятости и принадлежности домена Domain information
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL
Version Description
5.4.0