Слабая печать в PHP: зачем вообще использовать isset?

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

if ($tx) 

или

 if (isset($tx)) 

почему я должен делать второй, когда писать труднее?

Related of "Слабая печать в PHP: зачем вообще использовать isset?"

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

«isset () вернет FALSE, если тестирует переменную, которая была установлена ​​в NULL» ( php.net/isset ).

Это означает, что в некоторых случаях, например, проверка параметров GET или POST, использование isset () достаточно, чтобы определить, установлена ​​ли переменная (потому что она будет либо строкой, либо не будет установлена). Однако в случаях, когда NULL является возможным значением для переменной, что довольно часто встречается при попадании в объекты и более сложные приложения, isset () оставляет вас высоко и сухо.

Например (протестировано с PHP 5.2.6 с Suhosin-Patch 0.9.6.2 (cli) (построено: 17.08.2008 09:05:31)):

 <?php $a = ''; $b = NULL; var_dump(isset($a)); var_dump(isset($b)); var_dump(isset($c)); 

выходы:

 bool(true) bool(false) bool(false) 

Спасибо, PHP!

 if ($tx) 

Этот код будет оцениваться как false для любого из следующих условий:

 unset($tx); // not set, will also produce E_WARNING $tx = null; $tx = 0; $tx = '0'; $tx = false; $tx = array(); с unset($tx); // not set, will also produce E_WARNING $tx = null; $tx = 0; $tx = '0'; $tx = false; $tx = array(); 

Приведенный ниже код будет оцениваться только в false при следующих условиях:

 if (isset($tx)) // False under following conditions: unset($tx); // not set, no warning produced $tx = null; с if (isset($tx)) // False under following conditions: unset($tx); // not set, no warning produced $tx = null; 

Для некоторых людей типизация очень важна. Однако PHP по дизайну очень гибкий с переменными типами. Вот почему были созданы функции обработки переменных .

isset () не имеет ничего общего с TYPE или VALUE – только с СУЩЕСТВОВАНИЕМ.

if ($ condition) … будет оценивать значение VARIABLE как логическое значение.

if (isset ($ condition)) … будет оценивать СУЩЕСТВУЮЩЕЕ ВАРИАМНОЕ значение как логическое.

isset () может быть ложным по двум причинам.

Во-первых, потому что переменная не установлена ​​и поэтому не имеет значения.

Во-вторых, потому что переменная имеет значение NULL, что означает «неизвестное значение» и не может считаться установленным, поскольку оно включает «нет значения» и потому, что многие люди используют $ v = null для обозначения того же самого, что и unset ($ v).

(Помните, если вы специально хотите проверить значение null, используйте is_null ().)

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

Например, если у вас есть страница с именем page.php, она имеет следующее:

 ini_set('display_errors', 1); error_reporting(E_ALL); if ( $_GET["val"] ) { // Do Something } else { // Do Nothing } 

он будет работать нормально для любого из этих URL:

 http://www.example.com/page.php?val=true // Something will be done. http://www.example.com/page.php?val=monkey // Something will be done. http://www.example.com/page.php?val=false // Nothing will be done. http://www.example.com/page.php?val=0// Nothing will be done. 

Однако вы получите сообщение об ошибке для этого URL:

 http://www.example.com/page.php 

потому что в URL-адресе нет аргумента «val», поэтому в массиве $ _GET нет индекса «val».

Правильный способ сделать это:

 if ( isset($_GET["val"]) ) { if ( $_GET["val"] ) { // Do Something } else { // Do Nothing } } else { // $_GET["value"] variable doesn't exist. It is neither true, nor false, nor null (unknown value), but would cause an error if evaluated as boolean. } 

Хотя для этого есть ярлыки.

Вы можете проверить комбинацию существования и определенных булевых условий с пустым (),

 if ( !empty($_GET["val"]) ) { // Do someting if the val is both set and not empty // See http://php.net/empty for details on what is considered empty // Note that null is considered empty. } 

или

 if ( isset($_GET["val"]) and $_GET["val"] ) { // Do something if $_GET is set and evaluates to true. // See php.net logical operators page for precedence details, // but the second conditional will never be checked (and therefor // cause no error) if the isset returns false. } 

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

Я бы никогда не выполнил первую проверку (boolean cast), не проверив тип переменной.

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

Первый работает только в зависимости от того, как настроен ваш сервер. На многих производственных серверах он сломается.

Используйте isset() и будьте веселы.

Или попробуйте свой код со следующим в начале источника PHP и посмотрите, как он сломается:

 ini_set('display_errors', 1); error_reporting(E_ALL); 

Потому что первый может также проверить истину / ложь, которую вы можете или не хотите.

Поскольку первый вызывает предупреждение, а также возвращает true, если $ tx === false, который не совпадает с неопределенным

Эти два совершенно разные, как указал каждый ответ. Если вы не используете isset, многие вещи будут оценивать значение false, особенно массивы, значения false, числовые значения 0 (и другие) и т. Д. Верно это.

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

 if ($tx) 

оценивает значение false, когда оно действительно имеет значение, но если вы хотите проверить, является ли он объектом транзакции или нет , он либо работает, либо нет. Оказывается, что с картой Doctrine этот код

 if (isset($tx)) 

всегда оценивает значение true после захвата первого объекта запроса. Вместо этого я должен сказать

 if ($tx instanceof PurchaseRecord) 

Поэтому я хочу сказать, что в PHP вы знаете, что тестируете! Например, если это параметр из запроса GET, он будет либо пустым, либо пустым, либо иметь значение. Вы должны справиться с этими тремя случаями. Или два случая, или любое количество случаев, которые у вас есть в вашем конкретном коде. Как только вы это сделаете, если он работает на вашем сервере разработки, и он работает на вашем производственном сервере, возможно, вы можете сказать, что он работает и работает на вашей жизни?

(В Java или C # он должен компилироваться, а затем запускаться без метаданных Исключения. Большинство исключений NullPointer в Java на самом деле бросаются без каких-либо проблем: Java API не могут проверить все нули в коде, потому что это невозможно, а также потому, что это не так проблема. Если он компилируется и работает, когда это предполагается, вы знаете, что ваш код в порядке, а затем вы можете беспокоиться о том, чтобы выбрасывать более корректные Исключения.)

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

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

 <?php function exists($var) { if (isset($var) && $var != "") { return true; } else { return false; } } ?>