Довідка - Що означає ця помилка в PHP?


1137

Що це?

Це низка відповідей про попередження, помилки та повідомлення, з якими ви можете зіткнутися під час програмування PHP, і не маєте поняття, як їх виправити. Це також спільнота Wiki, тому всіх запрошують до участі, додаючи та підтримуючи цей список.

Чому це?

Питання, такі як "Заголовки вже надіслані" або "Виклик члена не-об'єкта" , часто виникають у "Переповнення стека". Першопричина цих питань завжди однакова. Тож відповіді на ці запитання, як правило, повторюють їх, а потім показують ОП, який рядок потрібно змінити в конкретному випадку. Ці відповіді не додають ніякої цінності сайту, оскільки вони стосуються лише конкретного коду ОП. Інші користувачі, що мають таку ж помилку, не можуть легко прочитати рішення з нього, оскільки вони занадто локалізовані. Це сумно, тому що, коли ви зрозуміли першопричину, виправлення помилки є дрібницею. Отже, цей список намагається пояснити рішення загальним способом застосування.

Що мені тут робити?

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

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

Список

Також дивіться:


7
Крім того, щоб вивести дискусію з коментарів, перейдіть до цього мета-питання
Earlz



Відповіді:


275

Попередження: Неможливо змінити інформацію заголовка - заголовки вже надіслані

Трапляється, коли ваш скрипт намагається надіслати клієнтський заголовок HTTP, але він вже був виведений раніше, в результаті чого заголовки вже надсилаються клієнту.

Це є E_WARNINGі це не зупинить сценарій.

Типовим прикладом може бути такий шаблон шаблону:

<html>
    <?php session_start(); ?>
    <head><title>My Page</title>
</html>
...

session_start()Функція спробує відправити заголовки з куки сесії для клієнта. Але PHP вже надіслав заголовки, коли він записав <html>елемент у вихідний потік. Вам доведеться перенести session_start()верхню частину.

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

Часто недоотримуваний вихід - це нові рядки після закриття PHP ?>. Стандартною практикою вважається пропускати, ?>коли це остання річ у файлі. Крім того, ще одна поширена причина цього попередження полягає в тому, що перед відкриттям <?phpпорожній пробіл, рядок або невидимий символ перед ним, через що веб-сервер надсилає заголовки та пробіл / новий рядок, тому, коли PHP починає розбиратись, не вдасться подати будь-який заголовок

Якщо у вашому файлі більше одного <?php ... ?>блоку коду, у вас не повинно бути проміжків між ними. (Примітка. Якщо у вас був автоматично сконструйований код, у вас може бути кілька блоків)

Також переконайтеся, що у вашому коді немає позначок замовлення на байт, наприклад, коли кодування сценарію UTF-8 з BOM.

Пов’язані запитання:


2
Якщо ви використовуєте WordPress, перевірте файли тем. Коли я оновив сайт до нової версії WordPress, я не зміг оновити тему, оскільки вона не оновлювалася протягом декількох років. Цю проблему вирішено. Виявилося, що у файла function.php було більше одного <? ?> блок з пробілами між ними.
Рой Ліван

2
@RoyLeban "Якщо у вашому файлі є більше одного блоку ..." Я не впевнений, що це означає. Що таке "блок"? Чи складався б один блок <?php ?>і так було б "більше одного блоку" <?php ?> <?php ?>?
Ендрю Фокс

2
Будь ласка, увімкніть функцію 'буферизація виводу' у файлі конфігурації PHP.ini, якщо це можливо. Він використовується для усунення цієї проблеми. Він надсилає файл HTML, який зберігається у вихідному буфері і надсилається клієнтові лише після зупинки сценарію, тому якщо два заголовки видаються в іншому місці, тоді старий заголовок буде замінено новим заголовком.
Нідхін Давид

191

Фатальна помилка: виклик функції члена ... на не-об'єкті

Відбувається з кодом, подібним до того, xyz->method()де xyzце не об'єкт, і тому methodйого не можна назвати.

Це фатальна помилка, яка зупинить скрипт (повідомлення про сумісність вперед: Це стане помилкою, яку можна знайти, починаючи з PHP 7).

Найчастіше це знак того, що в коді відсутні перевірки на умови помилок. Перевірте, що об’єкт насправді є об'єктом, перш ніж викликати його методи.

А Типовий приклад може бути

// ... some code using PDO
$statement = $pdo->prepare('invalid query', ...);
$statement->execute(...);

У наведеному вище прикладі запит не може бути підготовлений і prepare() призначить falseдо $statement. Якщо спробувати викликати execute()метод, то це призведе до Fatal Error, оскільки falseце "не-об'єкт", оскільки значення булеве.

З’ясуйте, чому ваша функція повертає булевий замість об'єкта. Наприклад, перевірте $pdoоб'єкт на останню помилку, яка сталася. Деталі про те, як налагодити це, залежатимуть від того, як обробляються помилки для конкретної функції / об'єкта / класу, про які йдеться.

Якщо навіть ->prepareпровал, то ваш$pdo об'єкт обробки бази даних не перейшов у поточну область . Знайдіть, де це було визначено. Потім передайте його як параметр, збережіть його як властивість або поділіться ним через глобальну область застосування.

Іншою проблемою може бути умовне створення об'єкта, а потім спроба викликати метод поза цим умовним блоком. Наприклад

if ($someCondition) {
    $myObj = new MyObj();
}
// ...
$myObj->someMethod();

Спроби виконувати метод поза умовним блоком, ваш об'єкт може бути не визначений.

Пов’язані запитання:


115

Нічого не видно. Сторінка порожня і біла.

Також відомий як Біла сторінка смерті або Білий екран смерті . Це відбувається, коли повідомлення про помилки вимкнено і сталася фатальна помилка (часто помилка синтаксису).

Якщо увімкнено реєстрацію помилок, ви знайдете конкретне повідомлення про помилку у своєму журналі помилок. Зазвичай це буде у файлі під назвою "php_errors.log" або в центральному місці (напр/var/log/apache2 у багатьох середовищах Linux), або в каталозі самого сценарію (іноді використовується у спільному середовищі хостингу).

Іноді може бути більш простим тимчасове включення відображення помилок. Потім на білій сторінці відобразиться повідомлення про помилку. Будьте уважні, оскільки ці помилки помітні всім, хто відвідує веб-сайт.

Це легко зробити, додавши у верхній частині сценарію наступний PHP-код:

ini_set('display_errors', 1); error_reporting(~0);

Код увімкне відображення помилок і встановить звітність на найвищий рівень.

Оскільки виконання ini_set()виконується під час виконання, воно не впливає на синтаксичний аналіз / помилки синтаксису. Ці помилки з’являться в журналі. Якщо ви хочете відобразити їх і у висновку (наприклад, у браузері), вам слід встановити display_startup_errorsдирективу true. Зробіть це або в, php.iniабо в, .htaccessабо будь-яким іншим методом, який впливає на конфігурацію перед виконанням .

Ви можете використовувати ті самі методи, щоб встановити директиви log_errors та error_log для вибору свого власного файлу журналу.

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

Пов’язані запитання:

Пов'язані помилки:


3
error_reporting(~0);чому ні -1? Це те, що ~0оцінює, і є набагато менш виразним.
Fabrício Matté

3
Я думаю, що і те, і інше схоже напевне. ~0Більш чіткий IMO: заперечуйте порожній набір бітів, тобто вмикайте всі прапори. -1 не позначається як «не знайдено», як у strpos () в C, а як біт з усіма встановленими прапорами, оскільки -1 є двійковим 1111'1111'1111'1111(для 32 біт).
nalply

2
На жаль, 1111'1111'1111'1111це дійсно 16 біт, але я сподіваюся, ви зрозуміли, що я маю на увазі.
nalply

3
@IvanSolntsev, вибачте, ні, для версій до 5.4 E_STRICTне входить E_ALL. php.net/manual/en/errorfunc.constants.php та прокрутіть униз до E_STRICT.
nalply

102

Примітка: Не визначений індекс

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

Типовим прикладом Undefined Indexповідомлення може бути ( демонстрація )

$data = array('foo' => '42', 'bar');
echo $data['spinach'];
echo $data[1];

І те, spinachі 1інше не існує в масиві, що спричиняє E_NOTICEспрацьовування.

Рішення полягає в тому, щоб переконатися, що індекс або зсув існують до доступу до цього індексу. Це може означати, що вам потрібно виправити помилку у вашій програмі, щоб переконатися, що ці індекси існують, коли ви очікуєте їх. Або це може означати , що вам необхідно перевірити , чи існують індекси , використовуючи array_key_existsабо isset:

$data = array('foo' => '42', 'bar');
if (array_key_exists('spinach', $data)) {
    echo $data['spinach'];
}
else {
    echo 'No key spinach in the array';
}

Якщо у вас є код типу:

<?php echo $_POST['message']; ?>
<form method="post" action="">
    <input type="text" name="message">
    ...

тоді $_POST['message']не буде встановлено, коли ця сторінка буде завантажена вперше, і ви отримаєте вищевказану помилку. Індекс масиву існуватиме лише тоді, коли форма подається та цей код запускається вдруге. Ви зазвичай перевіряєте це за допомогою:

if ($_POST)  ..  // if the $_POST array is not empty
// or
if ($_SERVER['REQUEST_METHOD'] == 'POST') ..  // page was requested with POST

Пов’язані запитання:


Я схильний використовуватиif(!empty($_POST['message'])){ //do stuff }
kurdtpage

85

Попередження: mysql_fetch_array () очікує, що параметр 1 буде ресурсом, задано булеве значення

В першу чергу:

Будь ласка, не використовуйте mysql_*функції в новому коді . Вони більше не підтримуються і офіційно застаріли . Бачите червоний ящик ? Дізнайтесянатомістьпро підготовлені заяви , а також використовуйте PDO або MySQLi - ця стаття допоможе вам вирішити, які саме. Якщо ви вибрали PDO, ось хороший підручник .


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

Це попередження і не зупинить сценарій, але зробить вашу програму неправильною.

Вам потрібно перевірити результат, який повернув mysql_queryкористувач

$res = mysql_query($sql);
if (!$res) {
   die(mysql_error());
}
// after checking, do the fetch

Пов’язані запитання:

Пов'язані помилки:

Інші mysql*функції, які також очікують, що ресурс результату MySQL в якості параметра буде створювати ту ж помилку з тієї ж причини.


5
Просто записка. Якщо mysql_queryце недостатньо погано, додавання or dieна додаток - це образа для травми.
Привид

Проблема, з якою я стикаюся, - це $res = mysql_query($query)повернення 1, якщо запит успішний, тому він вважається істинним. Тому при передачі результату mysql_query до mysql_fetch_array() повідомлення повідомляється.
mboy

@mboy Для SELECT, SHOW, DESCRIBE, EXPLAIN та інших висловлювань, що повертають набір результатів, mysql_query () повертає ресурс на успіх або FALSE на помилку. Для інших типів операторів SQL, INSERT, UPDATE, DELETE, DROP тощо, mysql_query () повертає TRUE на успіх або FALSE на помилку.
xdazz

@xdazz Це проблема я зіткнувся, Insert повертає TRUE , оновлення , так що я не можу позбутися від цієї помилки mysql_fetch_array() expects parameter 1 to be resource, boolean given in select будь ласка , см - gist.github.com/romelemperado/93af4cdbd44ebf3a07cbfa0e3fc539d7 Будь-яка пропозиція GIT позбутися цієї помилки?
mboy

2
@mboy mysql_fetch_array()призначений для вибору запиту, для вставки та оновлення вам не потрібно отримувати набір результатів (і набір результатів не дозволяє вам отримати).
xdazz

79

Фатальна помилка: використання $ this, коли не в об'єктному контексті

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

Ця помилка може статися:

  1. Якщо нестатичний метод викликається статичним. Приклад:

    class Foo {
       protected $var;
       public function __construct($var) {
           $this->var = $var;
       }
    
       public static function bar () {
           // ^^^^^^
           echo $this->var;
           //   ^^^^^
       }
    }
    
    Foo::bar();

    Як виправити: перегляньте свій код ще раз,$thisйого можна використовувати лише в об'єктному контексті і ніколи не слід використовувати в статичному методі. Також статичний метод не повинен мати доступ до нестатичного властивості. Використовуватиself::$static_propertyдля доступу до статичної властивості.

  2. Якщо код з класового методу був скопійований у звичайну функцію або просто глобальну область застосування та збереження $thisспеціальної змінної.
    Як виправити: перегляньте код та замініть $thisіншою змінною заміни.

Пов’язані запитання:

  1. Називайте нестатичний метод статичним: PHP Фатальна помилка: Використання $ this, коли не в об'єктному контексті
  2. Скопіювати код: Фатальна помилка: Використання $ this, коли не в об'єктному контексті
  3. Усі "Використання $ this, коли не в об'єктному контексті" Питання щодо Stackoverflow

2
Ви також можете згадати, як це працює без закриття (навіть у нестатичних методах) і як це "фіксується" в 5.4.
Кендалл Хопкінс

2
@hakre Я говорив про статичний дзвінок всередині закриття. Як $closure = function() { self::method(); }.
Кендалл Хопкінс

2
@KendallHopkins: Це інша помилка: "Фатальна помилка: Не можу отримати доступ до себе :: коли жодна область класу не активна" Однак $thisви можете спровокувати описану "Фатальну помилку: Використання $ this, коли не в об'єктному контексті" :$closure = function() { $this->method(); };
hakre

75

Фатальна помилка: виклик невизначеної функції XXX

Відбувається, коли ви намагаєтеся викликати функцію, яка ще не визначена. Загальні причини включають відсутні розширення і включають, умовне оголошення функції, функцію в оголошенні функції або прості друкарські помилки.

Приклад 1 - Декларація умовної функції

$someCondition = false;
if ($someCondition === true) {
    function fn() {
        return 1;
    }
}
echo fn(); // triggers error

У цьому випадку fn()ніколи не буде оголошено, оскільки $someConditionце неправда.

Приклад 2 - Функція у декларації функції

function createFn() 
{
    function fn() {
        return 1;
    }
}
echo fn(); // triggers error

У цьому випадку fnбуде оголошено лише після отримання createFn()дзвінка. Зауважте, що наступні виклики до createFn()спровокують помилку щодо переоформлення існуючої функції.

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

У разі відсутнього розширення встановіть це розширення та ввімкніть його в php.ini. Зверніться до Інструкції з установки в Посібнику PHP щодо розширення, в якому відображається ваша функція. Ви також можете ввімкнути або встановити розширення за допомогою менеджера пакунків (наприклад, aptу Debian або Ubuntu, yumRed Hat або CentOS) або на панелі керування у спільному хостинг-середовищі.

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

У разі відсутності включає, обов’язково включіть файл, який декларує функцію, перш ніж викликати функцію.

У разі помилок, зафіксуйте помилку друку.

Пов’язані запитання:


73

Помилка розбору: помилка синтаксису, несподівана T_XXX

Трапляється , коли ви T_XXXжетон в несподіваному місці, неврівноваженою (зайвої) дужка, використанні короткого тега без його активації в php.ini, і багатьох інших.

Пов’язані запитання:

Для подальшої допомоги див:

  • http://phpcodechecker.com/ - Що дає ще кілька корисних пояснень щодо ваших синтаксичних проблем.

70

Фатальна помилка: неможливо використовувати повернене значення функції в контексті запису

Зазвичай це відбувається при використанні функції безпосередньо з empty.

Приклад:

if (empty(is_null(null))) {
  echo 'empty';
}

Це тому empty, що мовна конструкція, а не функція, її не можна викликати виразом як аргументом у версіях PHP до 5.5. До PHP 5.5, аргумент empty()має бути змінною , але довільне вираження (наприклад, зворотне значення функції) допустиме в PHP 5.5+.

empty, незважаючи на свою назву, насправді не перевіряє, чи змінна "порожня". Натомість він перевіряє, чи немає змінної, або == false. Вирази (як is_null(null)у прикладі) завжди вважатимуться такими, тому тут emptyлише перевіряється, чи він дорівнює хибному. Ви можете замінити empty()тут !, наприклад if (!is_null(null)), або явно порівняти з помилковими, наприклад if (is_null(null) == false).

Пов’язані запитання:


64

MySQL: у вашому синтаксисі SQL помилка; перевірте посібник, який відповідає вашій версії сервера MySQL, чи правильний синтаксис для використання поруч ... у рядку ...

Ця помилка часто виникає через те, що ви забули належним чином уникнути даних, переданих на запит MySQL.

Приклад того, що не робити ("погана ідея"):

$query = "UPDATE `posts` SET my_text='{$_POST['text']}' WHERE id={$_GET['id']}";
mysqli_query($db, $query);

Цей код може бути включений на сторінку із формою для надсилання, з такою URL-адресою, як http://example.com/edit.php?id=10 (для редагування допису № 10)

Що буде, якщо поданий текст містить єдині цитати? $queryзакінчиться:

$query = "UPDATE `posts` SET my_text='I'm a PHP newbie' WHERE id=10';

І коли цей запит буде надіслано на MySQL, він поскаржиться, що синтаксис неправильний, оскільки в середині є додаткова одинарна цитата.

Щоб уникнути подібних помилок, ОБОВ'ЯЗКОВО завжди уникати даних перед використанням у запиті.

Уникнення даних перед використанням у запиті SQL також дуже важливо, тому що якщо цього не зробити, ваш сценарій буде відкритий для ін'єкцій SQL. Ін'єкція SQL може спричинити зміни, втрату або модифікацію запису, таблиці або всієї бази даних. Це дуже серйозне питання безпеки!

Документація:


3
Крім того, якщо ви цього не зробите, ваш сайт буде зламаний ботами автоматично
apscience

2
@gladoscc Клацніть "редагувати" та змініть відповідь. Я знаю, що це можна вдосконалити.
Джоселін

2
Або скористайтеся підготовленим запитом sql.
Матей

53

Фатальна помилка: Дозволений розмір пам'яті в XXX байтів вичерпано (намагався виділити XXX байт)

Для запуску сценарію недостатньо пам'яті. PHP досягла межі пам'яті і припиняє її виконувати. Ця помилка є фатальною, сценарій зупиняється. Значення межі пам'яті можна налаштувати або у php.iniфайлі, або за допомогою ini_set('memory_limit', '128 M');сценарію (який замінить значення, визначене в php.ini). Мета межі пам’яті - не допустити, щоб один скрипт PHP збивав всю наявну пам’ять і збивав весь веб-сервер.

Перше, що потрібно зробити - це мінімізувати об'єм пам'яті, який потрібен вашому сценарію. Наприклад, якщо ви читаєте великий файл у змінній або вибираєте безліч записів із бази даних і зберігаєте їх у масиві, це може зайняти багато пам'яті. Змініть свій код, щоб замість цього прочитати файл за рядком або отримати записи в базі даних по одному, не зберігаючи їх у пам'яті. Це вимагає трохи концептуальної обізнаності про те, що відбувається за лаштунками, і коли дані зберігаються в пам'яті порівняно з іншими місцями.

Якщо ця помилка виникла, коли ваш сценарій не займався значною пам’яттю, вам потрібно перевірити код, щоб перевірити, чи є витік пам'яті. memory_get_usageФункція є вашим другом.

Пов’язані запитання:


53

Помилка розбору: помилка синтаксису, несподівана T_ENCAPSED_AND_WHITESPACE

Ця помилка найчастіше виникає при спробі посилання на значення масиву з котируваним ключем для інтерполяції всередині подвійного котирування рядка, коли вся складна конструкція змінної не укладена {}.

Випадок помилки:

Це призведе до Unexpected T_ENCAPSED_AND_WHITESPACE:

echo "This is a double-quoted string with a quoted array key in $array['key']";
//---------------------------------------------------------------------^^^^^

Можливі виправлення:

У дворядковому рядку PHP дозволить використовувати рядки ключових рядків без котирування , і не видаватиме E_NOTICE. Отже, вище можна записати як:

echo "This is a double-quoted string with an un-quoted array key in $array[key]";
//------------------------------------------------------------------------^^^^^

Весь складний змінний масив і ключ (и) можуть бути додані до них {}, і в цьому випадку їх слід цитувати, щоб уникнути E_NOTICE. Документація PHP рекомендує цей синтаксис для складних змінних.

echo "This is a double-quoted string with a quoted array key in {$array['key']}";
//--------------------------------------------------------------^^^^^^^^^^^^^^^
// Or a complex array property of an object:
echo "This is a a double-quoted string with a complex {$object->property->array['key']}";

Звичайно, альтернативою будь-якому з перерахованих вище є об'єднання змінної масиву в замість того, щоб інтерполювати її:

echo "This is a double-quoted string with an array variable". $array['key'] . " concatenated inside.";
//----------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^

Для ознайомлення дивіться розділ « Змінне пробірки» на сторінці керівництва PHP Strings


45

Попередження: [функція] : не вдалося відкрити потік: [причина]

Це трапляється, коли ви викликаєте файл звичайно include, requireабо fopenPHP не зміг знайти файл або не має достатнього дозволу для завантаження файлу.

Це може статися з різних причин:

  • шлях до файлу неправильний
  • шлях файлу відносний
  • включити шлях неправильно
  • дозволи занадто обмежувальні
  • Діє SELinux
  • та багато іншого ...

Одна поширена помилка - не використовувати абсолютний шлях. Це можна легко вирішити, використовуючи повний шлях або магічні константи типу __DIR__або dirname(__FILE__):

include __DIR__ . '/inc/globals.inc.php';

або:

require dirname(__FILE__) . '/inc/globals.inc.php';

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

Найкращий спосіб швидко вирішити цю проблему - це дотримуватися наведеного нижче списку усунення несправностей.

Пов’язані запитання:

Пов'язані помилки:


44

Помилка розбору: помилка синтаксису, несподівана T_PAAMAYIM_NEKUDOTAYIM

Оператор роздільної здатності області також називається "Paamayim Nekudotayim" від івриту פעמיים נקודתיים. що означає "подвійна кишка".

Ця помилка зазвичай трапляється, якщо ви ненавмисно ввели ::свій код.

Пов’язані запитання:

Документація:


Найпростіший спосіб запустити цю помилку - це запуску a()::b;або $a=::;.
Ісмаїл Мігель

43

Примітка: Використання невизначеної константи XXX - припущена "XXX"

або, в PHP 7.2 або пізнішої версії:

Попередження: Використання невизначеної константи XXX - припущена "XXX" (це призведе до помилки в майбутній версії PHP)

Це повідомлення виникає, коли маркер використовується в коді і здається постійним, але константа за цим ім'ям не визначається.

Однією з найпоширеніших причин цього повідомлення є відмова цитувати рядок, який використовується як асоціативний ключ масиву.

Наприклад:

// Wrong
echo $array[key];

// Right
echo $array['key'];

Ще одна поширена причина - це відсутність $знака (долара) перед іменем змінної:

// Wrong
echo varName;

// Right
echo $varName;

Або, можливо, ви неправильно написали якусь іншу константу чи ключове слово:

// Wrong
$foo = fasle;

// Right
$foo = false;

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

Пов’язані запитання:


2
Я б сказав, що найпоширенішою причиною є забуття $ перед змінною, а не масивами.
Перебіг

42

Фатальна помилка: Не вдалося передекларувати клас [назва класу]

Фатальна помилка: Неможливо повторно визначити [ім'я функції]

Це означає, що ви або два рази використовуєте одне і те саме ім’я функції / класу і вам потрібно перейменувати одну з них, або це тому, що ви використовували requireабо includeтам, де ви повинні використовувати require_onceабо include_once.

Коли клас або функція оголошена в PHP, він є незмінним і не може бути пізніше оголошений з новим значенням.

Розглянемо наступний код:

class.php

<?php

class MyClass
{
    public function doSomething()
    {
        // do stuff here
    }
}

index.php

<?php

function do_stuff()
{
   require 'class.php';
   $obj = new MyClass;
   $obj->doSomething();
}

do_stuff();
do_stuff();

Другий дзвінок до do_stuff()видасть помилку вище. Змінившись requireна require_once, ми можемо бути впевнені, що файл, що містить визначення, MyClassбуде завантажений лише один раз, і помилка буде уникнена.


3
Варто згадати використання автозавантаження, а такі стандарти, як PSR-4 або навіть застарілий PSR-0, в значній мірі позбавляються від цього, врятувавши вас від необхідності використовувати вимагати / включати себе (позбавити кількох химерних випадків).
DanielM

39

Примітка: Не визначена змінна

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

Типовим прикладом може бути

foreach ($items as $item) {
    // do something with item
    $counter++;
}

Якщо ви $counterраніше не визначились , код буде викликано вище.

Правильним способом було б встановити змінну перед її використанням, навіть якщо це просто порожній рядок

$counter = 0;
foreach ($items as $item) {
    // do something with item
    $counter++;
}

Примітка: Не визначене майно

Ця помилка означає майже те саме, але стосується властивості об'єкта. Якщо повторно використати приклад вище, цей код призведе до помилки, оскільки counterвластивість не було встановлено.

$obj = new stdclass;
$obj->property = 2342;
foreach ($items as $item) {
    // do something with item
    $obj->counter++;
}

Пов’язані запитання:


35

Помилка розбору: помилка синтаксису, несподівана T_VARIABLE

Можливий сценарій

Я не можу знайти, де мій код пішов не так. Ось моя повна помилка:

Помилка розбору: помилка синтаксису, несподівана T_VARIABLE у рядку x

Що я намагаюся

$sql = 'SELECT * FROM dealer WHERE id="'$id.'"';

Відповідь

Помилка розбору: проблема з синтаксисом вашої програми, наприклад, залишення крапки з комою в кінці оператора або, як у випадку вище, відсутній .оператор. Інтерпретатор припиняє запускати вашу програму, коли зустрічається помилка розбору.

Простими словами, це синтаксична помилка, тобто щось у вашому коді перешкоджає правильному розбору та тому виконанню.

Що вам слід зробити, це уважно перевірити рядки, де є помилка, чи є прості помилки.

Це повідомлення про помилку означає, що у рядку x файлу інтерпретатор PHP очікував побачити відкриті дужки, але натомість зіткнувся з чимось так званим T_VARIABLE. Ця T_VARIABLEріч називається а token. Це спосіб інтерпретатора PHP висловлювати різні основні частини програм. Коли перекладач читає програму, він переводить те, що ви написали, у список лексем. Де б ви не помістили змінну у свою програму, T_VARIABLEу списку перекладача є маркер.

Добре прочитати: Список маркерів парсера

Тому переконайтеся, що ви включите принаймні E_PARSEу своєму php.ini. Помилки розбору не повинні існувати у виробничих сценаріях.

Я завжди рекомендував додавати таке твердження під час кодування:

error_reporting(E_ALL);

Звіт про помилки PHP

Також хороша ідея використовувати IDE, який дозволить вам знати помилки розбору під час набору тексту. Ви можете використовувати:

  1. NetBeans (прекрасний твір краси, вільне програмне забезпечення) (найкращий на мій погляд)
  2. PhpStorm (дядько Гордон любить це: P, платний план, містить власне та безкоштовне програмне забезпечення)
  3. Eclipse (краса та звіра, вільне програмне забезпечення)

Пов’язані запитання:


34

Повідомлення: Неніціалізований зсув рядка: *

Як вказує ім’я, такий тип помилок виникає, коли ви, швидше за все, намагаєтесь повторити або знайти значення з масиву з неіснуючим ключем.

Подумаємо, ви намагаєтесь показати кожен лист від $string

$string = 'ABCD'; 
for ($i=0, $len = strlen($string); $i <= $len; $i++){
    echo "$string[$i] \n"; 
}

Наведений вище приклад генерує ( демонстрація в Інтернеті ):

A
B
C
D
Notice: Uninitialized string offset: 4 in XXX on line X

І як тільки сценарій закінчиться луною, Dви отримаєте помилку, оскільки всередині for()циклу ви сказали PHP показати вам символ від першого до п’ятого рядка, 'ABCD'який існує, але оскільки цикл починає рахуватись 0і лунає Dдо того моменту, до якого вона досягне 4, це призведе до помилки зсуву.

Подібні помилки:


32

Примітка. Спроба отримати властивість помилки, що не є об'єктом

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

Типовим прикладом для сповіщення про об'єкти може бути

$users = json_decode('[{"name": "hakre"}]');
echo $users->name; # Notice: Trying to get property of non-object

У цьому випадку $usersце масив (тому не об’єкт) і він не має ніяких властивостей.

Це аналогічно доступу до неіснуючого індексу або ключа масиву (див. Примітка: Не визначений індекс ).

Цей приклад значно спрощений. Найчастіше таке повідомлення сигналізує про неперевірене повернене значення, наприклад, коли бібліотека повертається, NULLякщо об'єкт не існує або просто несподіване значення, що не є об'єктом (наприклад, в результаті Xpath, структури JSON з несподіваним форматом, XML з несподіваним форматом тощо) але код не перевіряє на такий стан.

Оскільки ці необ'єкти часто обробляються далі, часто при виклику методу об'єкта на не-об'єкті виникає фатальна помилка (див.: Фатальна помилка: Виклик функції члена ... на не-об'єкт ), зупиняючи сценарій.

Це можна легко запобігти, перевіривши умови помилок та / або чи відповідає змінна очікуванню. Ось таке повідомлення із прикладом DOMXPath :

$result  = $xpath->query("//*[@id='detail-sections']/div[1]");
$divText = $result->item(0)->nodeValue; # Notice: Trying to get property of non-object

Проблема полягає у доступі до nodeValueвластивості (поля) першого елемента, поки він не був перевірений, чи існує він чи ні в $resultколекції. Натомість платить зробити код більш явним, призначивши змінні об'єктам, над якими працює код:

$result  = $xpath->query("//*[@id='detail-sections']/div[1]");
$div     = $result->item(0);
$divText = "-/-";
if (is_object($div)) {
    $divText = $div->nodeValue;
}
echo $divText;

Пов'язані помилки:


1
json_decodeтепер повертає екземпляр stdclassза замовчуванням, так що приклад код буде реально працювати.
Гюго Цинк

@HugoZink: Він насправді (і завжди робив) повертає масив для цього прикладу: 3v4l.org/SUDe0 - Також ви можете надати, будь ласка, посилання для свого написання, що " json_decodeтепер повертає екземпляр stdclassза замовчуванням" ? Я не можу знайти це в журналі змін.
хакре

Відповідно до сторінки керівництва PHP на json_decode , за замовчуванням assocпараметр встановлюється на значення false. Цей параметр визначає, чи повертається функція stdclassзамість асоціативного масиву.
Гюго Цинк

json_decode('[{"name": "hakre"}]', true)поверне масив, інакше stdclassоб’єкт
zanderwar

29

Попередження: діє дію обмеження open_basedir

Це попередження може з’являтися з різними функціями, пов’язаними з доступом до файлів і каталогів. Він попереджає про проблему з конфігурацією.

Коли це з'являється, це означає, що доступ до деяких файлів був заборонений.

Саме попередження нічого не порушує, але найчастіше сценарій не працює належним чином, якщо недоступний доступ до файлів.

Виправлення зазвичай змінюється конфігурацією PHP , викликається відповідне налаштування open_basedir.

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

Пов’язані запитання:


1
Найчастіше це відбувається на спільному хості, люди зазвичай не блокуються з каталогів :-)
uınbɐɥs

28

Помилка розбору: помилка синтаксису, несподівана '['

Ця помилка складається з двох варіантів:

Варіація 1

$arr = [1, 2, 3];

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

$arr = array(1, 2, 3);

Дивіться також цей приклад з посібника.

Варіація 2

$suffix = explode(',', 'foo,bar')[1];

Результати функції перенаправлення масиву також були представлені в PHP 5.4. Якщо оновлення неможливо, потрібно використовувати (тимчасову) змінну:

$parts = explode(',', 'foo,bar');
$suffix = $parts[1];

Дивіться також цей приклад з посібника.


23

Попередження: [функція] очікує, що параметр 1 буде ресурсом, задано булеве значення

(Більш загальна варіація попередження: mysql_fetch_array () очікує, що параметр 1 буде ресурсом, задано булеве значення )

Ресурси - це тип PHP (наприклад, рядки, цілі числа чи об'єкти). Ресурс - це непрозорий блок, який не має власне значущого значення. Ресурс специфічний і визначений певним набором функцій PHP або розширенням. Наприклад, розширення Mysql визначає два типи ресурсів :

У модулі MySQL використовуються два типи ресурсів. Перший - це ідентифікатор посилання для з'єднання з базою даних, другий - ресурс, який містить результат запиту.

Розширення CURL визначає ще два типи ресурсів :

... ручка CURL та мультиварка CURL.

У var_dumpредакторі значення виглядають так:

$resource = curl_init();
var_dump($resource);

resource(1) of type (curl)

Ось і всі більшість ресурсів - це числовий ідентифікатор ( (1)) певного типу ( (curl)).

Ви переносите ці ресурси навколо і передаєте їх різним функціям, для яких такий ресурс щось означає. Зазвичай ці функції виділяють певні дані у фоновому режимі, а ресурс - лише посилання, яке вони використовують для внутрішнього відстеження цих даних.


Помилка " ... очікує, що параметр 1 буде ресурсом, булева дані ", як правило, є результатом неперевіреної операції, яка повинна була створити ресурс, але повернена falseзамість цього. Наприклад, fopenфункція має такий опис:

Повернення цінностей

Повертає ресурс вказівника на файл на успіх чи FALSEпомилку.

Тож у цьому коді $fpбуде resource(x) of type (stream)або false:

$fp = fopen(...);

Якщо ви не перевірите, чи fopenвдала операція чи не вдалася, а значить, чи $fpдійсний ресурс, чи falseпереходите $fpдо іншої функції, яка очікує ресурс, ви можете отримати вищевказану помилку:

$fp   = fopen(...);
$data = fread($fp, 1024);

Warning: fread() expects parameter 1 to be resource, boolean given

Вам завжди потрібно помилитися, щоб перевірити повернене значення функцій, які намагаються виділити ресурс і можуть вийти з ладу :

$fp = fopen(...);

if (!$fp) {
    trigger_error('Failed to allocate resource');
    exit;
}

$data = fread($fp, 1024);

Пов'язані помилки:


22

Попередження: Незаконне зміщення рядка "XXX"

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

Приклад:

$var = "test";
echo $var["a_key"];

Якщо ви думаєте, що змінна повинна бути масивом, подивіться, звідки вона походить, і вирішіть проблему там.


20

Код не працює / як виглядають частини мого PHP-коду

Якщо ви не бачите жодного результату зі свого PHP-коду і / або бачите частини вашого буквального вихідного коду PHP на веб-сторінці, ви можете бути впевнені, що ваш PHP насправді не виконується. Якщо ви використовуєте View Source у своєму браузері, ви, ймовірно, бачите весь файл вихідного коду PHP таким, який є. Оскільки PHP-код вбудований у <?php ?>теги, браузер спробує інтерпретувати їх як HTML-теги, і результат може виглядати дещо заплутаним.

Щоб реально запустити сценарії PHP, вам потрібно:

  • веб-сервер, який виконує ваш сценарій
  • встановити розширення файлу на .php, інакше веб-сервер не інтерпретуватиме його як такий *
  • для доступу до .php-файлу через веб-сервер

* Якщо ви не переконфігуруєте це, все можна налаштувати.

Цей останній особливо важливий. Просто двічі клацніть файл, ймовірно, відкрийте його у вашому браузері, використовуючи таку адресу:

file://C:/path/to/my/file.php

Це повністю обходить будь-який веб-сервер, на якому ви можете працювати, і файл не інтерпретується. Вам потрібно відвідати URL-адресу файлу на вашому веб-сервері, ймовірно, щось подібне:

http://localhost/my/file.php

Ви також можете перевірити, чи використовуєте ви <?замість них короткі відкриті теги, <?phpі ваша конфігурація PHP вимкнула короткі відкриті теги.

Також дивіться, що PHP-код не виконується, натомість код відображається на сторінці


18

Попередження: mysql_connect (): Доступ заборонено для користувача 'name' @ 'host'

Це попередження з’являється під час підключення до сервера MySQL / MariaDB з недійсними або відсутніми обліковими записами (ім'ям користувача / паролем). Отже, це, як правило, не проблема коду, а проблема конфігурації сервера.

  • Для mysql_connect("localhost", "user", "pw")прикладів див. Сторінку з посібником на .

  • Перевірте, що ви справді використовували $usernameта $password.

    • Нечасто ви отримуєте доступ, не використовуючи пароля - саме це сталося, коли було сказано попередження (using password: NO).
    • Тільки локальний тестовий сервер, як правило, дозволяє з'єднуватися з ім'ям користувача root, паролем та назвою testбази даних.

    • Ви можете перевірити, чи справді вони правильні, використовуючи клієнт командного рядка:
      mysql --user="username" --password="password" testdb

    • Ім'я користувача та пароль залежать від регістру, і пробіл не ігнорується. Якщо ваш пароль містить такі мета-символи $, уникніть їх або поставте пароль в одній лапки .

    • Більшість постачальників послуг хостингу визначають облікові записи mysql щодо облікового запису користувача Unix (іноді просто префікси або додаткові числові суфікси). Дивіться документи щодо шаблону чи документації та CPanel або будь-який інший інтерфейс для встановлення пароля.

    • Дивіться посібник MySQL щодо Додавання облікових записів користувачів за допомогою командного рядка. Підключившись як користувач адміністратора, ви можете надіслати запит на зразок:
      CREATE USER 'username'@'localhost' IDENTIFIED BY 'newpassword';

    • Або використовуйте Adminer або WorkBench або будь-який інший графічний інструмент для створення, перевірки або виправлення даних облікового запису.

    • Якщо ви не можете виправити свої облікові дані, то прохання в Інтернеті "будь ласка допоможіть" не матиме жодного ефекту. Тільки ви та ваш хостинг-провайдер маєте дозволи та достатній доступ для діагностики та виправлення речей.

  • Переконайтесь, що ви могли отримати доступ до сервера баз даних, використовуючи ім'я хоста, вказане вашим постачальником:
    ping dbserver.hoster.example.net

    • Перевірте це з консолі SSH безпосередньо на своєму веб-сервері. Тестування від локального клієнта розвитку на вашому спільному сервері хостингу рідко має сенс.

    • Часто ви просто хочете бути ім'ям сервера "localhost", яке зазвичай використовує локальний названий сокет, коли він є. Інші часи ви можете спробувати "127.0.0.1"як резервний.

    • Якщо ваш сервер MySQL / MariaDB прослуховує інший порт, тоді використовуйте "servername:3306".

    • Якщо це не вдасться, то, можливо, проблема брандмауера. (Поза темою, а не про програмування. Немає можливості віддаленої здогадки.)

  • При використанні константи , такі як , наприклад , DB_USERабо DB_PASSWORD, переконайтеся , що вони на насправді визначені .

    • Якщо ви отримаєте а "Warning: Access defined for 'DB_USER'@'host'"і а "Notice: use of undefined constant 'DB_PASS'", то це ваша проблема.

    • Переконайтесь, що ваш напр. xy/db-config.phpБув насправді включений і whatelse.

  • Перевірте, чи правильно встановлені GRANTдозволи .

    • Мало мати пару username+ password.

    • Кожен обліковий запис MySQL / MariaDB може мати доданий набір дозволів.

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

    • Таким чином, попередження "Відмовлено у доступі" може також з'являтися для mysql_queryдзвінків, якщо у вас немає дозволів на SELECTпевну таблицю, або INSERT/ UPDATEта ще більше DELETEнічого.

    • Ви можете адаптувати дозволи облікового запису при підключенні до клієнта командного рядка за допомогою облікового запису адміністратора з таким запитом:
      GRANT ALL ON yourdb.* TO 'username'@'localhost';

  • Якщо сповіщення з’являється спочатку, Warning: mysql_query(): Access denied for user ''@'localhost'тоді у вас може бути налаштована php.ini попередньо налаштована пара облікових записів / паролів .

    • Перевірте це mysql.default_user=та mysql.default_password=маєте значущі значення.

    • Часто це конфігурація провайдера. Тому зверніться до їх підтримки щодо невідповідностей.

  • Знайдіть документацію вашого спільного провайдера хостингу:

  • Зверніть увагу, що ви, можливо, також вичерпали доступний пул з'єднань . Ви отримаєте попередження про відмову в доступі для занадто багатьох одночасних з'єднань. (Ви повинні дослідити налаштування. Це проблема конфігурації сервера поза темою, а не питання програмування.)

  • Ваша клієнтська версія libmysql може бути не сумісна з сервером бази даних. Зазвичай сервери MySQL та MariaDB можна отримати за допомогою PHP, зібраних у драйвері. Якщо у вас є власна установка, або застаріла версія PHP, і набагато новіший сервер баз даних, або значно застарілий - тоді невідповідність версій може перешкоджати з'єднанню. (Ні, ви повинні розслідувати себе. Ніхто не може здогадатися про ваше налаштування).

Більше посилань:

До речі, ви, мабуть, більше не хочете використовувати mysql_*функції . Новачки часто мігрують до mysqli , що, однак, так само нудно. Натомість читайте на PDO та готуйте заяви .
$db = new PDO("mysql:host=localhost;dbname=testdb", "username", "password");


2
mysql дозволяє автоматично підключитися через налаштування php-ini, тоді те саме повідомлення про помилку подається з іншою командою з префіксом, наприклад, "Попередження: mysql_query (): Доступ заборонено для користувача" "@" localhost "(використовуючи пароль: НЕТ) у. .. " - просто зазначаючи.
хакре

Ха, зовсім забув про це! (Напевно, востаннє це використовували з PHP3 або близько того ..)
mario

18

Примітка: Перетворення масиву в рядок

Це просто відбувається, якщо ви спробуєте трактувати масив як рядок:

$arr = array('foo', 'bar');

echo $arr;  // Notice: Array to string conversion
$str = 'Something, ' . $arr;  // Notice: Array to string conversion

Масив не може бути просто echo'd або об'єднаний рядком, оскільки результат недостатньо визначений. PHP використовуватиме рядок "Array" замість масиву та запустить повідомлення, щоб вказати, що це, мабуть, не те, що було призначено, і що вам слід перевірити свій код тут. Ви, напевно, хочете чогось подібного:

echo $arr[0];  // displays foo
$str = 'Something ' . join(', ', $arr); //displays Something, foo, bar

Або зациклюйте масив:

foreach($arr as $key => $value) {
    echo "array $key = $value";
    // displays first: array 0 = foo
    // displays next:  array 1 = bar
}

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


12

Попередження: Ділення на нуль

Попереджувальне повідомлення "Поділ на нуль" - одне з найбільш часто задаваних питань серед нових розробників PHP. Ця помилка не спричинить винятку, тому деякі розробники час від часу придушуватимуть попередження, додаючи оператор @ подання помилок до виразу. Наприклад:

$value = @(2 / 0);

Але, як і будь-яке попередження, найкращим підходом було б виявити причину попередження та усунути його. Причина попередження буде надходити з будь-якого випадку, коли ви намагаєтесь розділити на 0, змінну, рівну 0, або змінну, яка не була призначена (бо NULL == 0), оскільки результат буде "невизначений".

Щоб виправити це попередження, слід переписати вираз, щоб перевірити, чи не значення 0, якщо воно є, зробіть щось інше. Якщо значення дорівнює нулю, ви або не повинні ділити, або ви повинні змінити значення на 1, а потім розділити, так що ділення призводить до еквіваленту поділу лише на додаткову змінну.

if ( $var1 == 0 ) { // check if var1 equals zero
    $var1 = 1; // var1 equaled zero so change var1 to equal one instead
    $var3 = ($var2 / $var1); // divide var1/var2 ie. 1/1
} else {
    $var3 = ($var2 / $var1); // if var1 does not equal zero, divide
}

Пов’язані запитання:


Якщо встановити значення 1, це призведе до зупинки помилки, але чи справді це краще, ніж придушення, яке ви сказали, не слід використовувати (з чим я згоден)? Я б припускав, що в більшості випадків може бути повернене якесь інше повідомлення чи значення.
Джеймс

У цьому прикладі, якщо $var1так == 0, то ви можете просто встановити $var3значення $var2. Навіть якщо цього не робити, інше взагалі не потрібно, оскільки завдання в обох випадках однакове, тому більше немає і призначати його позаif
Джеймс,

8

Суворі стандарти: нестатичний метод [<class> :: <method>] не повинен називатися статично

Виникає, коли ви намагаєтеся викликати нестатичний метод класу, як він був статичним, і у вас також є E_STRICTпрапор у ваших error_reporting()налаштуваннях.

Приклад:

class HTML {
   public function br() {
      echo '<br>';
   }
}

HTML::br() або $html::br()

Ви дійсно можете уникнути цієї помилки, не додаючи E_STRICTїї error_reporting(), наприклад

error_reporting(E_ALL & ~E_STRICT);

оскільки щодо PHP 5.4.0 і вище, E_STRICTвін включений у E_ALL[ ref ]. Але це не доцільно. Рішення полягає у визначенні призначеної статичної функції як фактичної static:

public static function br() {
  echo '<br>';
}

або викликати функцію умовно:

$html = new HTML();
$html->br();

Пов’язані запитання:


7

Застаріло: синтаксис доступу до масиву та рядка з фігурними дужками застарілий

До зміщення рядків та елементів масиву можна отримати фігурні дужки {}до PHP 7.4.0:

$string = 'abc';
echo $string{0};  // a

$array = [1, 2, 3];
echo $array{0};  // 1

Це було знято з PHP 7.4.0 і створює попередження:

Застаріло: синтаксис доступу до масиву та рядка з фігурними дужками застарілий

Ви повинні використовувати квадратні дужки []для доступу до зміщення рядків та елементів масиву:

$string = 'abc';
echo $string[0];  // a

$array = [1, 2, 3];
echo $array[0];  // 1

RFC цього зміни посилань на PHP скрипт , який намагається виправити це механічно.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.