Почему многие разработчики PHP ненавидят использование isset () и / или любых других защитных функций PHP, таких как empty ()?


27

На стеке потока я вижу эту проблему все время:

Даже Пекка (который предлагает множество полезных советов по PHP) натолкнулся на страшного E_NOTICEмонстра и надеется на лучшее решение, чем использование isset(): isset () и empty () делают код уродливым

Лично я использую isset()и empty()во многих местах для управления потоком своих приложений. Например:

public function do_something($optional_parameter = NULL) {
    if (!empty($optional_parameter)) {
        // do optional stuff with the contents of $optional_parameter
    }
    // do mandatory stuff
}  

Даже простой фрагмент вроде этого:

if (!isset($_REQUEST['form_var'])) {
    // something's missing, do something about it.
}

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

Я предполагаю, что другие языки обрабатывают вещи по-другому. Судя по опыту, JavaScript не так вежлив, как PHP. Неопределенная переменная обычно останавливает выполнение скрипта. Кроме того (если говорить неопытно ), я уверен, что такие языки, как C / C ++, просто откажутся от компиляции.

Итак, разработчики PHP просто ленивы? (не говоря о вас, Пекка, я знаю, что вы рефакторинг старого приложения.) Или другие языки обрабатывают неопределенные переменные более изящно, чем требование программиста сначала проверить, определены ли они?

(Я знаю, что есть и другие E_NOTICEсообщения, помимо неопределенных переменных, но, похоже, именно они вызывают наибольшее огорчение)

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


4
К сожалению, я видел работу php-разработчиков с отключенными «предупреждениями».
Viper_Sb

Уч. То есть печально.
Стивен

1
Не будучи пользователем PHP, я задаюсь вопросом: зачем вам проверять неопределенные переменные?
Уинстон Эверт

2
@Winston: проблема с PHP (в отличие от многих других языков) заключается в том, что PHP допускает множество комбинаций конфигурации. Например, программист может решить игнорировать предупреждения, уведомления и уведомления об устаревании. Более опытные разработчики будут работать с параметром error_reporting, чтобы сообщать обо всем. PHP также имеет много функций, которые выдают ошибки и возвращают коды состояния, а не генерируют исключения. Нужно быть очень близким с языком, чтобы иметь возможность защищаться и успешно кодировать. Многие другие языки не позволяют выбирать. Строгий обычно является единственным вариантом по умолчанию.
Уил Мур III

1
Мне не нравится isset () из-за многословия, которое он добавляет. Лучшая форма @ будет хорошей альтернативой.
Kzqai

Ответы:


34

Я пишу код E_STRICTи ничего больше.

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

Стихи о последствиях неиспользования их, как минимум предупреждений.


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

2
+1 Джош, я такой же. Когда вы программируете на E_STRICT, вы знаете, что в вашем коде никогда не будет сюрпризов. Единственный способ летать, имо.
EricBoersma

3
@Stephen: всегда отключайте ошибки для производства. Это всего лишь сеть безопасности. Развитие должно (ИМО) всегда быть E_STRICT. Напишите код и устраните все предупреждения и ошибки.
Джош К

ты меня попугаешь? :)
Стивен

@ Стефан: я согласен. :)
Джош К

17

Я думаю, что уведомления о неизвестных элементах являются ошибкой дизайна в PHP. Я не уверен, что сейчас можно исправить ошибку, но она генерирует много стандартного кода, как if(isset($foo['abc']) && $foo['abc'] == '123')- этот код не должен иметь isset, поскольку цель состоит в том, чтобы проверить, есть ли «123» в определенном месте, $fooи если там ничего нет, это определенно не «123». Единственная причина, по которой вам приходится писать вдвое больше кода, это из-за этой неудачной ошибки проектирования в PHP. К сожалению, уведомления в PHP очень дороги, поэтому просто отключить их нельзя для кода, где важна производительность.

Так что да, это делает код уродливым ИМХО, и это меня раздражает. И это не из-за отсутствия опыта - я использую PHP с 1998 года, и я помню, когда было .php3расширение, и это означало «это не PHP 2». Может быть, я ленивый :) Но лень - по крайней мере, определенный тип - это добродетель для программиста.

С другой стороны, допустимое использование issetи empty- как и в оригинальном посте - хорошо. Я просто думаю, что PHP чрезмерно усердствует в отношении предупреждений в тех местах, где isset/emptyони на самом деле не нужны.


3
Правильно. Это вопрос многословия. $eg = isset($_GET['eg'])? $_GET['eg'] : null;смешно многословно. Я действительно хотел бы, чтобы был еще один оператор, который не был «подавлением ошибок» как таковой, чтобы заменить краткий смысл $eg = @$_GET['eg'];«принять-не-существование-этого-массива-ключа-как-ноль». В эти дни я склонен использовать короткую функцию.
Kzqai

7
Согласовано. 4 года спустя, введите Null Coalesce Operator: wiki.php.net/rfc/isset_ternary, дающий нам$eg = $_GET['eg'] ?? null;
Стив

Или просто сделайте это сейчас с помощью оператора подавления ошибок, например $eg = @$_GET['eg'] ?: null;. Я обычно не использую его, но в этом случае мы явно ожидаем эту ошибку и решаем игнорировать ее. Он на один символ длиннее, чем null coalesce, и он не так хорош (он подавляет все ошибки, и, возможно, ArrayAccess делает там что-то интересное, а не только массив), но в целом он выполняет свою работу.
Эль Йобо

12

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

Я постоянно слышу эти замечания от начинающих разработчиков и сценаристов-самоучек:

  • Зачем инициализировать переменную, если она все равно появится?
  • Зачем проверять, существует ли что-то перед тем, как мы его используем, неопределенное равно равно false?
  • Если я ставлю префикс @, это исправляет мой код, зачем все усложнять?

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

Другим важным фактором является использование PHP в веб-индустрии, которая, как правило, гораздо больше заботится о пропускной способности, чем о безопасности и качестве кода.


10
«Я считаю, что в PHP [...] очень много непрофессиональных, неподготовленных программистов». Как отдельный разработчик PHP, я не могу с вами согласиться. +1
Стивен

@Stephen Ну, в последнее время я пишу в основном на PHP и jQuery, хотя у меня есть формальное образование, но код, который вы видите как профессионал, перед которым вы становитесь ответственным ... иногда он бросает вызов вере. ;-)
Orbling

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

1
@Erik PHP был довольно плохим родственником Perl десять лет назад, теперь это довольно разумный интерпретируемый язык, особенно для использования в Интернете. Существует причина, по которой такие компании, как Facebook, используют его. Но поскольку это доступно везде, любительский набор использует это широко, и это бросает тень на репутацию.
Orbling

5

Да, они ленивы. В любом случае их много ...

К сожалению, менталитет многих PHP-программистов таков: «Нет смысла защищать код, если вы можете получить тот же конечный результат быстрее, полагаясь на язык для обработки ошибок, вызванных отсутствием переменных и т. Д.» Я знаю, я работал с несколькими из них.

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


5
-1 за субъективное мнение о PHP кодерах.
Джош К

4
@ Джош, будучи старшим программистом PHP в течение 4 с половиной лет и кодируя PHP с 1999 года, боюсь, я несколько субъективен. Я должен был уметь «С другой стороны, более опытные PHP-кодеры не ленивы и делают все правильно» ...
Gruffputs

1
Это вы должны иметь.
Джош К

5

Я стараюсь избегать использования isset () и empty (), избегая использования массивов в качестве объектов передачи данных. Создайте класс, который можно настроить для принятия ограниченного набора свойств со стандартными значениями по умолчанию, и проверьте входные данные для этих свойств. Он может даже реализовать интерфейс ArrayAccess, чтобы вы могли использовать его как массив. Это также позволяет вам использовать подсказки типов в сигнатурах вашего метода, чтобы перехватывать ошибки, когда кто-то пытается передать неправильный тип сущности вашему методу.


Очень интересный подход.
Тоби

2

Один из поставленных вопросов - мой, поэтому позвольте мне повторить.

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

Но вы должны принять во внимание, что PHP не является компилируемым языком. Это язык сценариев с динамической системой типов. Ошибки E_NOTICE - это только ошибки по имени. И если многие из issetних используются с единственной целью подавления уведомлений, то вы фактически просто программируете против языка .

Итак, разработчики PHP просто ленивы?

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

Однако вы ошибаетесь, что другие разработчики не распознали E_NOTICE только потому, что они не были @ или isset-suppressed. По крайней мере, это было мое намерение за вопросом о сохранении уведомлений . Это не то, от чего нужно избавляться, а иногда важная отладочная информация.

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

Или это исключительно вопрос культуры PHP?

Нет, неопределенная переменная «ошибки» - не проблема PHP. Bash, TCL и Perl или JavaScript позволяют использовать неопределенные переменные. Однако эта имманентная языковая особенность не рассматривается как недостаток. Существуют похожие языковые конструкции для проверки неопределенных значений. Однако они не так часто используются, как в PHP, поскольку значения undef не ошибочно характеризуются как «ошибка».


1

Интересный. Я почти никогда не использую isset (). Мой PHP-код редко находится в состоянии, когда я не знаю, была ли переменная установлена ​​в первую очередь. Доступ к каждой используемой переменной GET или POST осуществляется через функцию, которая обеспечивает ее по умолчанию, если она не существует. Значения по умолчанию в вызовах функций обычно явно равны 0 или пустым строкам.


+1. Переход к функции или классу метода является хорошим решением. Я действительно ДЕЛАЮ это, но в крайнем случае мои приведенные выше примеры все еще выглядят чистыми и не раздутыми для меня.
Стивен

0

Я использую isset и пустое множество. Но в основном это те места, которые вы упоминаете, например, обработка $ _REQUEST, на случай, если кто-то возится с параметрами. В случаях, когда у меня есть контроль над всеми переменными, я нахожу, что они мне обычно не нужны.


0

Я не люблю использовать isset, но если есть масса кода, сделанная другим, то это может быть спасительной грацией. Я написал приведенный ниже код, чтобы помочь с этой проблемой, вместо использования isset () isseter ($ a, $ b) вернет $ b, если $ a не определено или пусто, или функция возвращает ноль. Любые улучшения, добро пожаловать:

//returns var or NULL (if undefined)
//$reserve optional second value is returned as $default if undefined
function isseter(&$default,&$reserve=NULL)
{
$default = isset($default) ? $default : NULL;
$reserve = isset($reserve) ? $reserve : NULL;
if ((!$default) && ($reserve)) $default=$reserve;
return $default;
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.