Для тех, кто заинтересован, я расширил эту тему в небольшую статью, в которой приведенная ниже информация представлена в несколько лучше структурированной форме: Полное руководство по 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
, используйте true
или false
, а не null
. Единственным исключением из этого являются сторонние библиотеки, которые хотят, чтобы null
что-то значило, но так как null
так трудно обнаружить в PHP, мне еще не удалось найти какую-либо библиотеку, которая делает это.