Сначала договоритесь о значении состояний
В учебном массиве хранится настройка уведомлений. Условимся, что отсутствие ключа означает: отдельная настройка не передана. Наличие ключа со значением null означает: настройка передана, но выбор пока не определён. Значение false обозначает явное отключение. Такое толкование задаёт наше приложение, а не сам язык программирования. В другом проекте договорённость может отличаться. Поэтому до выбора проверки полезно записать, какие состояния различает задача и какое действие соответствует каждому из них.
Наличие ключа проверяется независимо от null
Функция array_key_exists позволяет узнать, присутствует ли указанный ключ в массиве. В нашем примере она вернёт false, если ключ отсутствует, и true, если ключ есть со значением null. Для существующего ключа со значением false ответ также будет true. Такой результат относится к устройству массива, а не к разрешению отправлять уведомления. Из наличия поля нельзя заключить, что его значение является согласием. Здесь рассматривается обычный массив и ключ на его текущем уровне, без поиска внутри вложенных элементов.
Проверка isset задаёт другой вопрос
Для элемента массива isset возвращает true, когда элемент существует и его значение не равно null. Поэтому отсутствующий ключ и существующий ключ с null дадут одинаковый ответ false. А существующий ключ со значением false даст true: логическое отключение является значением, отличным от null. Именно здесь часто возникает путаница. Результат проверки установленности нельзя читать как содержимое настройки. Положительный ответ не означает, что уведомления включены, а отрицательный не различает все возможные причины отсутствия определённого значения.
Разделите проверку формы данных и решение программы
Если приложение должно различать все три состояния, одной проверки isset недостаточно. Сначала выясните наличие ключа, затем при необходимости проверьте его значение по согласованным правилам. Для учебной настройки отдельно требуется отличать null от логического false и от разрешающего значения. Не заменяйте это неявным приведением всего подряд к логическому типу. Также не принимайте текстовое слово false за логическое значение без проверки типа. Такие решения относятся к обработке входных данных и должны быть явно определены в программе.
Попробуйте на практике
Составьте ожидаемые результаты двух проверок для трёх учебных массивов. Выполнять код для этого задания необязательно.
- Обозначьте первый массив как не содержащий ключа настройки, второй как содержащий этот ключ со значением null, третий как содержащий его со значением false.
- Для каждого состояния запишите ожидаемый результат array_key_exists. Рассуждайте только о присутствии ключа.
- Рядом запишите ожидаемый результат isset. Отдельно проверьте, почему логическое false не приравнивается здесь к null.
- Добавьте четвёртое состояние с логическим true. Объясните, какой дополнительный вопрос нужен, чтобы отличить разрешение уведомлений от их явного отключения.
Как проверить результат. Для первых трёх состояний array_key_exists даёт последовательно false, true, true, а isset даёт false, false, true. При логическом true обе проверки положительны. Чтобы различить включение и отключение, необходимо проверить само значение согласно правилам приложения.
Частые вопросы
Какую проверку считать более правильной?
Обе подходят для своих вопросов. Если важно само присутствие ключа, выбирайте проверку наличия. Если требуется существующее значение, отличное от null, уместна проверка isset. Сначала формулируйте требование.
Значение null всегда означает неопределённый выбор?
Нет. Это смысл, заданный нашим учебным примером. В реальных данных он определяется соглашением программы. Документация языка описывает поведение проверки, но не заменяет правила предметной задачи.
Самостоятельный разбор темы. Содержание конкретной обучающей программы здесь не представлено.