Чому багато PHP Devs ненавидять використовувати isset () та / або будь-яку з таких функцій захисту, як PHP, як порожній ()?


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 дозволяє використовувати безліч комбінацій конфігурацій. Наприклад, програміст може вирішити ігнорувати попередження, сповіщення та сповіщення про депресію. Більш досвідчені розробники працюватимуть із набором помилок_репортажу, щоб повідомити про все. PHP також має багато функцій, які викидають помилки та повертають коди статусу, а не кидають винятки. Треба бути дуже інтимним з мовою, щоб мати можливість кодувати оборонно і успішно. Багато інших мов не дозволяють вибрати. Як правило, строгий є типовим і єдиним варіантом.
Віль Мур III

1
Мені не подобається isset () через багатослівність, яку він додає. Краща форма @ була б гарною альтернативою.
Kzqai

Відповіді:


34

Я кодую E_STRICTі більше нічого.

Використання пустих і нерегулярних перевірок не робить ваш код некрасивим, він робить ваш код більш багатослівним. На мою думку, що є абсолютно гіршим, що може статися від їх використання? Я набираю ще кілька символів.

Вірші наслідки їх використання, принаймні застереження.


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

2
+1 Джош, я так само. Програмуючи в E_STRICT, ви знаєте, що сюрпризів у вашому коді ніколи не буде. Єдиний спосіб літати, imo.
EricBoersma

3
@Stephen: Завжди вимикайте помилки для виробництва. Це просто захисна сітка. Розвиток має бути завжди (ІМО) E_STRICT. Напишіть код та вирішіть усі попередження та помилки.
Джош К

ти мене папугуєш? :)
Стівен

@Stephen: Я згоден. :)
Josh K

17

Я думаю, що повідомлення про невідомі елементи є помилкою дизайну в PHP. Я не впевнений, що зараз можна виправити помилку, але він створює дуже багато кодового коду на кшталт if(isset($foo['abc']) && $foo['abc'] == '123')- цього коду не повинно бути isset, оскільки намір полягає в тому, щоб перевірити, чи є '123' у певному місці $fooта чи нічого там немає точно не "123". Єдина причина, що вам доведеться написати вдвічі більше коду, - це через цю нещасну помилку дизайну в PHP. І сповіщення дуже важливі для PHP, на жаль, тому просто відключення їх не є варіантом коду, коли продуктивність викликає занепокоєння.

Так так, це робить код потворним IMHO, і це мене дратує. І це не через брак досвіду - я використовую 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 : wiki.php.net/rfc/isset_ternary, даючи нам$eg = $_GET['eg'] ?? null;
Стів

Або просто зробіть це зараз за допомогою оператора придушення помилок, наприклад $eg = @$_GET['eg'] ?: null;. Я його зазвичай не використовую, але в цьому випадку ми явно очікуємо цієї помилки і вирішуємо її ігнорувати. Це один символ довше, ніж нульове з’єднання, і це не так добре (він пригнічує всі помилки, і ArrayAccess може робити там прикольні речі, а не просто масив), але в цілому це робить свою роботу.
Ель Йобо

12

Я вважаю, що PHP, як вільна мова, що інтерпретується та використовується в Інтернеті, має дуже високу частку непрофесійних, непідготовлених кодерів, які не повністю усвідомлюють, чому вони повинні кодувати оборонно і просто бачать попередження як чергову непотрібну помилку .

Я постійно чую ці моменти від молодших розробників та самовчених кодерів скриптів:

  • Навіщо ініціалізувати змінну, якщо вона все одно з'явиться?
  • Навіщо перевіряти, чи існує щось, перш ніж ми його використаємо, невизначений прирівнюється до помилкового?
  • Якщо я префікс за допомогою @ він виправляє код, навіщо ускладнювати речі?

Якщо вони ніколи не відчували сильно набраної мови або не відчували підводних каменів незадекларованих / невстановлених змінних, то вони беруть переконливе значення. Я вважаю, що вони зазвичай поступаються після того, як відчули задоволення від налагодження коду протягом години або близько того, щоб виявити, що це помилка друку в назві змінної, що спричиняє проблеми.

Іншим сильним фактором є використання PHP у веб-індустрії, яка, як правило, значно більше стосується пропускної здатності, ніж безпеки та якості коду.


10
"Я вважаю, що PHP [...] має дуже високу частку непрофесійних, непідготовлених кодерів" Як відданий розробник PHP, я більше не можу погодитися з вами. +1
Стівен

@Stephen Добре я кодую в основному в PHP та jQuery останнім часом, хоча в мене є формальна освіта, але код, який ви бачите як професіонала, за який ви станете відповідальним раніше ... він іноді не відповідає вірі. ;-)
Включення

1
Я думаю, що це справжня проблема з PHP. Окрім деяких вигадок у мові (які вони повільно вирішують у кожній новій версії) навколо неї є атмосфера аматорства. Я можу собі уявити, що професійний розробник PHP часом може засмучувати, тому що вас порівнюють із «племінником боса з-за кута».
Ерік ван Бракель

1
@Erik PHP був досить бідним родичем Perl десять років тому, тепер це досить розумна інтерпретована мова, особливо для використання в Інтернеті. Існує причина, що такі компанії, як Facebook, використовують його. Але оскільки він доступний скрізь, аматорський набір широко використовує його, і це затьмарює репутацію.
Орлінг

5

Так, вони ліниві. Дуже багато їх ...

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

Вони, як правило, також є тими, хто загадково прямує до раннього обіду, коли їх відсутність правильного поводження з помилками та звітування забирає живі сервери протягом декількох годин ...


5
-1 для суб'єктивної думки щодо PHP-кодерів.
Джош К

4
@Josh, будучи старшим кодером PHP протягом 4 1/2 років та кодував PHP увімкнення та вимкнення з 1999 року, я боюся, я дещо суб'єктивний. Я повинен був кваліфікуватись "З іншого боку, більш досвідчені кодери PHP не лінуються і роблять все правильно" ...
Gruffputs

1
Що ви повинні мати.
Джош К

5

Я намагаюся уникати використання isset () та empty (), уникаючи використання масивів як об’єктів передачі даних. Створіть клас, який може бути налаштований на прийняття обмеженого набору властивостей із розширеними значеннями за замовчуванням та підтвердження введення даних. Він навіть може реалізувати інтерфейс ArrayAccess, щоб ви могли використовувати його як масив. Це також дозволяє використовувати натяк на тип у підписах методу для лову помилок, коли хтось намагається передати неправильний тип сутності вашому методу.


Дуже цікавий підхід.
Тобі

2

Одне із запитаних питань - це моє, тому дозвольте ще раз зазначити.

Багато розробників помиляються наявністю партії isset()як знак якості. Він надає зовнішній вигляд надійності, і деякі люди вважають це навіть функцією безпеки.

Але ви повинні врахувати, що PHP - це не компільована мова. Це мова сценаріїв із системою динамічного типу. Помилки E_NOTICE - це лише помилки по імені. І якщо багато issetвикористовуються з єдиним наміром придушити повідомлення, то ви насправді просто кодуєте проти мови .

Отже, чи PHP-диски просто ледачі?

Це дійсно так, якщо ви бачите безліч повідомлень та попереджень, кинутих. Лот-новачків не цікавить сповіщення, і це зазвичай результат повністю відключеного error_reporting(0).

Однак ви помиляєтесь, що інші розробники не розпізнавали E_NOTICE, лише тому, що вони не були придушені @ або затримані. Принаймні, такий мій намір стояв за запитанням щодо збереження повідомлень . Вони не є чим позбутися, але інколи важлива інформація про налагодження.

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

Або це виключно питання культури PHP?

Ні, невизначені змінні "помилки" - це не проблема PHP. Bash, TCL і Perl або JavaScript дозволяють використовувати невизначені змінні. Однак ця незмінна мовна функція не є дефектом. Існують подібні мовні конструкції, щоб перевірити наявність невизначених значень. Однак вони не так часто використовуються, як у PHP, через те, що значення undef не визначаються як "помилка".


1

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


+1. Перехід до функції або методу класу - приємне рішення. Я на насправді DO це зробити, але в крайньому випадку мої Вищенаведені приклади ще виглядають чистими і не-роздутою мені.
Стівен

0

Я використовую безліч і порожній. Але в основному це місця, які ви згадуєте, як-от обробка $ _REQUEST, на випадок, якщо хтось псується з параметрами. У тих випадках, коли я маю контроль над усіма змінними, які летять навколо, я вважаю, що вони мені зазвичай не потрібні.


0

Мені не подобається використовувати isset, але якщо є маса коду, зроблена іншим, то це може бути благодатною економією. Я написав код wee нижче, щоб допомогти з цією проблемою, замість використання 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.