Я запускаю PHP-скрипт і продовжую отримувати такі помилки:
Примітка: Невизначена змінна: my_variable_name в C: \ wamp \ www \ mypath \ index.php в рядку 10
Примітка: Невизначений індекс: my_index C: \ wamp \ www \ mypath \ index.php в рядку 11
Рядки 10 і 11 виглядають так:
Що означають ці помилки?
Чому вони з'являються раптово? Я використовував цей сценарій протягом багатьох років, і у мене ніколи не було проблем.
Що мені потрібно зробити, щоб виправити їх?
Це загальний контрольний питання, на який люди посилаються як на дублікат, замість того, щоб знову і знову роз'яснювати проблему. Я вважаю, це необхідно, тому що більшість реальних відповідей на це питання дуже конкретні.
Пов'язані мета обговорення:
заданий Pekka 웃 20 травня '17 о 23:08
Це всього лише повідомлення, щоб ви використовували його правильно, і це не помилка або щось в цьому роді. - Amir Surnay 20 травня '17 о 23:08
Мінлива може не бути инициализирована. Ви ініціалізіруете змінну з повідомлення або get або будь-якого масиву? Якщо це так, у вас може не бути поля в цьому масиві. Це ваш доступ. - ASK 20 травня '17 о 23:08
«Чому вони з'являються раптово? Я використовував цей сценарій протягом багатьох років, і у мене ніколи не було проблем ». Під час написання цієї відповіді жоден з відповідей нижче не зачіпає це питання. Я починаю щедрість за це. - ChrisJJ 20 травня '17 о 23:08
@ChrisJJ, Відповідь Роббі пояснює це дуже добре. - Leith 20 травня '17 о 23:08
Що змінилося за останній час? Яку версію php ви використовуєте? Чи змінилася конфігурація? Це може бути кілька питань, які призводять до джерела помилок, оскільки, наприклад, і включення необхідного php-файлу більше не працює, так як, наприклад, короткі відкриті теги більше не допускаються, функції є застарілими і т. Д. - fabs 20 травня '17 о 23:08
@Fred Я припускаю, що аргумент може бути зроблений для обох варіантів. Є шанс, що новачки увійдуть у всю рядок, включаючи «Notice:» в свій пошуковий запит, який, я впевнений, є основним генератором трафіку для цього питання. Якщо повідомлення присутні в повному обсязі, це, швидше за все, поліпшить видимість в пошукових системах - Pekka 웃 20 травня '17 о 23:08
@ Fred-ii- Ставлячи питання, відразу відправляючи відповідь і просячи модератора задати питання, який повинен працювати Community Wiki. Не соромтеся копіювати і вставляти блок відповідальності вище. - Pekka 웃 20 травня '17 о 23:08
З великої мудрості PHP Manual
Спираючись на значення за замовчуванням неініціалізованої змінної, проблематично в разі включення одного файлу в інший, який використовує один і той же ім'я змінної. Це також головний ризик безпеки з register_globals включений. помилка рівня E_NOTICE У разі роботи з неініціалізованих змінними, однак не в разі додавання елементів до неініціалізованих масиву. isset () конструкція мови може використовуватися, щоб визначити, чи була змінна Уже инициализирован. Крім того, більш ідеальним є рішення empty (). оскільки воно не генерує попередження або повідомлення про помилку, якщо змінна не инициализирована.
Якщо змінна не існує, попередження не генерується. Це означає empty () по суті є коротким еквівалентом. Isset ($ var) || $ Вар == false.
Це означає, що ви можете використовувати тільки empty (). щоб визначити, чи встановлена змінна, і, крім того, вона перевіряє змінну на наступну, 0, "", null.
Способи вирішення проблеми:
Рекомендуємо: Оголошуйте свої змінні, наприклад, коли ви намагаєтеся додати рядок до невизначеної змінної. Або ж за допомогою isset () /! Empty (). щоб перевірити, оголошені вони перед їх посиланням, наприклад:
Це стало набагато чистіше з PHP 7.0, тепер ви можете використовувати оператор порожній коалесценции
Встановіть власний обробник помилок. Для E_NOTICE і перенаправити повідомлення від стандартного виводу (можливо, в файл журналу):
Відключити E_NOTICE від звітів. Швидкий спосіб виключити тільки E_NOTICE:
Придушити помилку за допомогою @ operator.
Примітка. Настійно рекомендується реалізувати тільки точку 1.
Це повідомлення з'являється, коли ви (або PHP) намагаєтеся отримати доступ до невизначеного індексу масиву.
Способи вирішення проблеми:
Перевірте, чи існує індекс до його доступу. Для цього ви можете використовувати isset () або array_key_exists ():
Конструкція мови list () може генерувати це, коли Намагається отримати доступ до індексу масиву, який не існує:
Для доступу до двох елементів масиву використовуються дві змінні, але є тільки один елемент масиву, індекс 0. тому він буде генерувати:
Примітка: Невизначена зміщення: 1
Нотатки вище з'являються часто при роботі з $ _POST. $ _GET або $ _SESSION. Для $ _POST і $ _GET вам просто потрібно перевірити, чи існує індекс чи ні, перш ніж використовувати їх. Для $ _SESSION ви повинні переконатися, що сеанс почався з session_start () і що індекс також існує.
Також зверніть увагу, що всі 3 змінні суперглобали. Це означає, що вони повинні бути записані у верхньому регістрі.
@ Dieselpower44 Кілька міркувань: «Оператор shut up» (@) має деякі проблеми з продуктивністю. Крім того, оскільки він пригнічує всі помилки в межах певної області, використання його без турботи може маскувати повідомлення, які ви хотіли б бачити. - IMSoP 20 травня '17 о 23:07
Приховувати проблеми - НЕ спосіб вирішення проблем. Елементи # 2. # 4 можуть використовуватися тільки на виробничих серверах, а не в загальному. - Salman A 20 травня '17 о 23:07
Чи можна відключити повідомлення inline (не в обробнику), якщо також використовується спеціальний обробник помилок? $ Var = @ $ _ GET [ 'nonexisting']; як і раніше викликає повідомлення. - Alph.Dev 20 травня '17 о 23:07
Чому рекомендується використовувати 1. $ value = isset ($ _ POST [ 'value']). $ _POST [ 'value']. ''; замість використання 4. $ value = @ $ _ POST [ 'value'] ;. - forsvunnet 20 травня '17 о 23:07
@twistedpixel Ці 4 способи незалежні, це не 4-х кроковий керівництво. Так що якщо ви вирішили використовувати спосіб 4, це означає, що ви не реалізували перші 3 способи, тому ви не подавили ніяких помилок. - Aycan Yaşıt 20 травня '17 о 23:07
Використання isset () не працює для мене. Але array_key_exists () і @ works - Mugoma J. Okomba 20 травня '17 о 23:07
Я не рекомендую використовувати isset () для масивів, наприклад $ str = '111'; (Я знаю, що це повинен бути масив) isset ($ str [0]) поверне true. Краще використовувати array_key_exist () замість isset () - Mb Rostami 20 травня '17 о 23:07
А (часто не рекомендується) альтернатива - це оператор придушення помилок @. Це спеціальна мовна конструкція, яка закриває небажані повідомлення і попередження, але повинна використовуватися з обережністю.
По-перше, він бере на себе штраф за мікропроцесорний контроль за використанням isset. Це не вимірюється в реальних додатках, але має враховуватися при важких ітераціях даних. По-друге, це може перешкоджати налагодженню, але в той же час пригнічені помилки фактично передаються обробникам призначених для користувача помилок (на відміну від виразів, прикрашених isset).
відповідь дан mario 20 травня '17 о 23:07
Якщо вам цікаво, що впливає на продуктивність, в цій статті це добре описано. derickrethans.nl/. - Gajus 20 травня '17 о 23:07
Спасибі @mario, цікаво. Тепер, якщо хтось був досить хороший для порівняння двох. 3v4l.org/CYVOn/perf#tabs 3v4l.org/FLp3D/perf#tabs Відповідно до цього тестом, схоже, що вони ідентичні (зверніть увагу, що зміни масштабу). - Gajus 20 травня '17 о 23:07
Я тестував з PHP 5.4, а продуктивність все ще поганий. - Brynner Ferreira 20 травня '17 о 23:07
Взагалі через «поганого програмування», і можливість помилок зараз або пізніше.
- Якщо це помилка, спочатку виконайте правильне присвоювання змінної: $ varname = 0;
- Якщо це дійсно тільки іноді визначається, перевірте це: if (isset ($ varname)). перш ніж використовувати його
- Якщо це сталося через неправильне написання, просто виправте це.
- Можливо навіть поворот попереджень в вас PHP-налаштувань
відповідь дан Erik 20 травня '17 о 23:07
Будь ласка, не вимикайте попередження. У більш строгих мовах вони часто означають «може бути помилка, краще перевірте цей рядок двічі» - на мові, дозвільному, як PHP, вони часто означають «цей код лайно і продиктований помилками, я спробую зробити Якийсь сенс, але краще виправте це якомога швидше ". - delnan 20 травня '17 о 23:07
Хоча я згоден з першими трьома пунктами, №4 просто помилковий. Приховувати проблему не змусить її піти, і це може навіть викликати додаткові проблеми в майбутньому. - Valentin Flachsel 20 травня '17 о 23:07
@Freek Абсолютно вірно, але в деяких сценаріях (куплений сценарій, нульові технічні знання, він повинен бути запущений до завтрашнього дня.) Це рішення для стрічкових конвеєрів - дійсно погане, що завжди потрібно підкреслювати, але варіант - Pekka 웃 20 травня '17 в 23:07
Канальна стрічка хороша. іноді. Історично попередження були перетворені в стандартних PHP-настройках, але параметри defult стали більш суворими. Занадто погано багато хто повертається до старих налаштувань, щоб не дратувати клієнтів. - Erik 20 травня '17 о 23:07
У відповідь на питання: «Чому вони з'являються раптово? Я використовував цей сценарій вже багато років, і у мене ніколи не було проблем ».
Для більшості сайтів дуже часто використовується повідомлення про помилку «за замовчуванням» «Показати всі помилки, але не« повідомлення »і« застарілі ». Це буде встановлено в php.ini і буде застосовуватися до всіх сайтів на сервері. Це означає, що ці «повідомлення», що використовуються в прикладах, будуть приховані (приховані), в той час як інші помилки, які вважаються більш критичними, будуть показані / записані.
Іншим критичним параметром є те, що помилки можуть бути приховані (тобто display_errors встановлені в «off» або «syslog»).
В цьому випадку відбудеться або те, що error_reporting було змінено, щоб також відображати повідомлення (як в прикладах) і / або що настройки були змінені на display_errors на екрані (замість того, щоб придушувати їх / реєструвати їх).
Чому вони змінилися?
Очевидним / простим відповіддю є те, що хтось скорегував будь-який з цих параметрів в php.ini, або оновлена версія PHP тепер використовує інший php.ini з раніше. Це перше місце для пошуку.
Однак також можливо перевизначити ці параметри в
- .htconf (конфігурація веб-сервера, включаючи віртуальні хости і подконфігураціі) *
- .htaccess
- В php-коді
І будь-який з них також міг бути змінений.
Існує також додаткове ускладнення, що конфігурація веб-сервера може вмикати / вимикати директиви .htaccess, тому якщо у вас є директиви в .htaccess, які раптово запускають / зупиняють роботу, вам потрібно це перевірити.
(.htconf / .htaccess припускають, що ви працюєте як apache. Якщо запущена командний рядок, це не буде застосовуватися, якщо ви використовуєте IIS або інший веб-сервер, тоді вам потрібно буде перевірити ці конфіги)
- Перевірте, що директиви error_reporting і display_errors php в php.ini не змінилися, або що ви не використовуєте інший php.ini раніше.
- Перевірити error_reporting і display_errors директиви php в .htconf (або vhosts і т. Д.) Чи не змінилося
- Перевірте, що директиви error_reporting і display_errors php в .htaccess не змінені
- Якщо у вас є директива в .htaccess, перевірте, чи дозволені вони в файлі .htconf
- Нарешті перевірте свій код; Можливо, незв'язаної бібліотеки; Щоб побачити, чи встановлені error_reporting і display_errors директиви php.
відповідь дан Robbie 20 травня '17 о 23:07
ЧОМУ ЦЕ ВІДБУВАЄТЬСЯ?
Згодом PHP став більш орієнтованим на безпеку мовою. Налаштування, які раніше були відключені за замовчуванням, тепер включені за замовчуванням. Прекрасним прикладом цього є E_STRICT. який став включений за замовчуванням, як в PHP 5.4.0.
Крім того, згідно з документацією PHP, по defualt, E_NOTICE відключений в php.ini. PHP-документи рекомендують включити його для цілей налагодження. Однак коли я завантажую PHP зі сховищ Ubuntu і з стека Windows BitNami, я бачу щось ще.
Зверніть увагу, що за замовчуванням error_reporting за замовчуванням встановлено на виробниче значення, а не на значення за замовчуванням. Це може збити з пантелику і не документується поза php.ini, тому я не перевіряв це на інших дистрибутивах.
Однак, щоб відповісти на ваше запитання, ця помилка з'являється, коли вона не спливала раніше, тому що:
Ви встановили PHP, і нові налаштування за замовчуванням кілька погано документовані, але не виключають E_NOTICE.
ЩО Я МОЖУ ЗРОБИТИ?
Вимкніть E_NOTICE. скопіювавши «Значення за замовчуванням» E_ALL
Вимкніть E_NOTICE на рівні файлу або папки. Це може бути краще, якщо у вас є застарілий код, але ви хочете зробити щось «правильне» в іншому випадку. Щоб зробити це, ви повинні проконсультуватися з Apache2, nginx або будь-яким іншим сервером за вашим вибором. В Apache ви повинні використовувати php_value всередині
Перепишіть код, щоб він був чистішим. Якщо вам потрібно зробити це під час переходу в виробничу середу або не хочете, щоб хтось бачив ваші помилки, переконайтеся, що ви відключили відображення помилок і тільки реєструєте свої помилки (див. Display_errors і log_errors в php .ini і налаштування вашого сервера) .
E_DEPRECATED. щоб зрозуміти, що може піти не так в майбутньому. Ви побачите багато незнайомих помилок, але це зупинить вас від неприємних проблем, коли вам знадобиться оновити PHP в майбутньому.
ЩО ОЗНАЧАЮТЬ ПОМИЛКИ?
Undefined variable: my_variable_name - Це відбувається, коли змінна не була визначена перед використанням. Коли скрипт PHP виконується, він внутрішньо приймає значення NULL. Однак, в якому сценарії вам потрібно було б перевіряти змінну до її визначення? В кінцевому рахунку, це аргумент для «неакуратне коду». Як розробник, я можу сказати, що мені подобається, коли я бачу проект з відкритим вихідним кодом, де змінні визначаються як високо в їх областях, оскільки вони можуть бути визначені. Це полегшує визначення змінних, які будуть з'являтися в майбутньому, і полегшує читання / вивчення коду.
Undefined index: my_index - це відбувається, коли ви намагаєтеся отримати доступ до значення в масиві і його не існує. Щоб запобігти цю помилку, виконайте умовну перевірку.
Інший варіант - оголосити порожній масив у верхній частині вашої функції. Це не завжди можливо.
(Додатковий наконечник)
- Коли я зіткнувся з цими та іншими проблемами, я використовував NetBeans IDE (безкоштовно), і він дав мені безліч попереджень і повідомлень. Деякі з них пропонують дуже корисні поради. Це не вимога, і я більше не використовую IDE, за винятком великих проектів. В наші дні я більш vim людина :).
відповідь дан smcjones 20 травня '17 о 23:08