Для тех, кто заинтересован, я расширил эту тему до небольшой статьи, в которой приведенная ниже информация представлена в несколько лучше структурированной форме: Полное руководство по isset PHP и пусто
ИМХО, вам следует подумать не просто о том, чтобы сделать приложение «совместимым с E_NOTICE», а о реструктуризации всего этого. Наличие сотен точек в вашем коде, которые регулярно пытаются использовать несуществующие переменные, звучит как довольно плохо структурированная программа. Попытки получить доступ к несуществующим переменным никогда не должны происходить, другие языки отказываются от этого во время компиляции. Тот факт, что PHP позволяет вам это делать, не означает, что вы должны это делать.
Эти предупреждения призваны помочь вам, а не раздражать вас. Если вы получаете предупреждение «Вы пытаетесь работать с тем, чего не существует!» , ваша реакция должна быть "Ой, моя проблема, позвольте мне исправить это как можно скорее". Как еще вы собираетесь отличить «переменные, которые прекрасно работают без определения» и действительно неправильный код, который может привести к серьезным ошибкам ? Это также причина, по которой вы всегда, всегда разрабатываете с отчетом об ошибках, обращенным к 11, и продолжаете работать над своим кодом, пока не останется ни одногоNOTICE
выпущен. Отключение отчетов об ошибках предназначено только для производственных сред, чтобы избежать утечки информации и улучшить взаимодействие с пользователем даже при наличии ошибок в коде.
Чтобы уточнить:
Вы всегда будете нуждаться isset
или empty
где-то в вашем коде, единственный способ уменьшить их появление - правильно инициализировать ваши переменные. В зависимости от ситуации это можно сделать разными способами:
Аргументы функции:
function foo ($bar, $baz = null) { ... }
Нет необходимости проверять, установлены ли $bar
или $baz
внутри функции, потому что вы просто устанавливаете их, все, о чем вам нужно беспокоиться, это оценивать их значение как true
или false
(или что-то еще).
Обычные переменные где угодно:
$foo = null;
$bar = $baz = 'default value';
Инициализируйте свои переменные в верхней части блока кода, в котором вы собираетесь их использовать. Это решает !isset
проблему, гарантирует, что ваши переменные всегда имеют известное значение по умолчанию, дает читателю представление о том, над чем будет работать следующий код, и тем самым также служит своего рода самодокументированием.
Массивы:
$defaults = array('foo' => false, 'bar' => true, 'baz' => 'default value');
$values = array_merge($defaults, $incoming_array);
То же, что и выше, вы инициализируете массив значениями по умолчанию и перезаписываете их фактическими значениями.
В остальных случаях, скажем, шаблон, в котором вы выводите значения, которые могут или не могут быть установлены контроллером, вам просто нужно проверить:
<table>
<?php if (!empty($foo) && is_array($foo)) : ?>
<?php foreach ($foo as $bar) : ?>
<tr>...</tr>
<?php endforeach; ?>
<?php else : ?>
<tr><td>No Foo!</td></tr>
<?php endif; ?>
</table>
Если вы обнаружите, что регулярно используете array_key_exists
, вам следует оценить, для чего вы его используете. Единственный раз, когда это имеет значение, здесь:
$array = array('key' => null);
isset($array['key']); // false
array_key_exists('key', $array); // true
Однако, как указано выше, если вы правильно инициализируете свои переменные, вам не нужно проверять, существует ли ключ или нет, потому что вы знаете, что это так. Если вы получаете массив из внешнего источника, то значение будет , скорее всего , не будет , null
но ''
, 0
, '0'
, false
или нечто подобное, то есть значение , которое можно оценить с isset
или empty
, в зависимости от вашего намерения. Если вы регулярно устанавливаете ключ массива в значение null
и хотите, чтобы он означал что угодно, но false
, например, если в приведенном выше примере разные результаты isset
и array_key_exists
имеют значение для логики вашей программы, вы должны спросить себя, почему. Само существование переменной не должно иметь значения, важно только ее значение. Если ключ - это true
/ false
flag, используйтеtrue
или false
нет null
. Единственным исключением из этого правила могут быть сторонние библиотеки, которые хотят null
что-то значить, но, поскольку их null
так сложно обнаружить в PHP, мне еще предстоит найти какую-либо библиотеку, которая это делает.