Справка - Что означает эта ошибка в PHP?


1138

Что это?

Это ряд ответов о предупреждениях, ошибках и уведомлениях, с которыми вы можете столкнуться при программировании PHP, и не знаете, как их исправить. Это также Вики Сообщества, поэтому каждый может принять участие, добавляя и поддерживая этот список.

Почему это?

Такие вопросы, как «Заголовки уже отправлены» или «Вызов члена необъекта» , часто появляются при переполнении стека. Коренная причина этих вопросов всегда одна и та же. Таким образом, ответы на эти вопросы, как правило, повторяют их, а затем показывают ОП, какую строку изменить в их конкретном случае. Эти ответы не добавляют никакой ценности сайту, поскольку они применяются только к определенному коду ОП. Другие пользователи, имеющие ту же ошибку, не могут легко прочитать решение из нее, потому что они слишком локализованы. Это печально, потому что, как только вы поняли основную причину, исправить ошибку - тривиально. Следовательно, этот список пытается объяснить решение в общем виде для применения.

Что мне здесь делать?

Если ваш вопрос был помечен как дубликат этого вопроса, найдите ваше сообщение об ошибке ниже и примените исправление к своему коду. Ответы обычно содержат дополнительные ссылки для расследования в случае, если это не должно быть ясно только из общего ответа.

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

Список

Также см:


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 с спецификацией.

Смежные вопросы:


2
Если вы используете WordPress, проверьте файлы темы. Когда я обновил сайт до новой версии WordPress, я не смог обновить тему, потому что она не обновлялась в течение нескольких лет. Эта проблема возникла. Оказалось, что файл functions.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()метода приведет к фатальной ошибке, потому что 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оценивает, и гораздо менее загадочно.
Фабрисио Мате

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

2
К сожалению, 1111'1111'1111'1111это действительно 16 бит, но я надеюсь, вы понимаете, о чем я.
Вскоре

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

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 Это проблема, с которой я сталкиваюсь, обновление вставки возвращает TRUE, поэтому я не могу избавиться от этой ошибки, mysql_fetch_array() expects parameter 1 to be resource, boolean given in select см. - gist.github.com/romelemperado/93af4cdbd44ebf3a07cbfa0e3fc539d7 Любое предложение, чтобы избавиться от этой ошибки?
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: Это другая ошибка: «Неустранимая ошибка: невозможно получить доступ к self ::, когда область действия класса не активна». Однако $thisвы можете вызвать $closure = function() { $this->method(); };
сделанную по заказу «Неустранимая

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, yumв каком расширении отображается ваша функция. Вы также можете включить или установить расширение, используя менеджер пакетов (например, в Debian или Ubuntu, в Red 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 аргумент to 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.";
//----------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^

Для справки, смотрите раздел Variable Разбор в странице PHP Струны вручную


45

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

Это происходит при вызове файла обычно include, requireили fopenи PHP не может найти файл или не иметь достаточно прав для загрузки файла.

Это может произойти по разным причинам:

  • неверный путь к файлу
  • путь к файлу относительно
  • неверный путь
  • разрешения слишком ограничительны
  • SELinux в силе
  • и многое другое ...

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

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

или:

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

Использование правильного пути - это один из шагов по устранению этих проблем, это также может быть связано с несуществующими файлами, правами файловой системы, препятствующими доступу, или ограничениями open basedir самим 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
Я бы сказал, что самая распространенная причина - забывать $ перед переменной, а не над массивами.
Overv

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();

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


3
Стоит ли упоминать об использовании автозагрузки, и стандарты, такие как PSR-4 или даже устаревшая PSR-0, в значительной степени избавляются от этого, избавляя вас от необходимости использовать require / include самостоятельно (за исключением нескольких странных крайних случаев).
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 будет ресурсом, учитывая логическое значение

(Более общий вариант Warning: mysql_fetch_array () ожидает, что параметр 1 будет ресурсом, учитывая логическое значение )

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

В модуле MySQL используются два типа ресурсов. Первый - это идентификатор ссылки для соединения с базой данных, второй - ресурс, который содержит результат запроса.

Расширение cURL определяет еще два типа ресурсов :

... ручка cURL и мульти ручка.

Когда var_dumped, значения выглядят так:

$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".

    • Если это не помогает, возможно, проблема с брандмауэром. (Не по теме, не вопрос программирования. Дистанционная подсказка невозможна.)

  • При использовании констант типа eg DB_USERили DB_PASSWORDпроверьте, что они на самом деле определены .

    • Если вы получаете "Warning: Access defined for 'DB_USER'@'host'"и"Notice: use of undefined constant 'DB_PASS'" , то это ваша проблема.

    • Убедитесь, что ваш eg 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 (с использованием пароля: НЕТ) в. .. " - просто замечаю.
hakre

Ха, совсем забыл об этом! (Вероятно, последний раз использовал это с PHP3 или около того ..)
Марио

18

Примечание: преобразование массива в строку

Это просто происходит, если вы пытаетесь рассматривать массив как строку:

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

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

Массив не может быть просто echo'd' или конкатенирован со строкой, потому что результат не очень хорошо определен. PHP будет использовать строку «Массив» вместо массива и инициировать уведомление, чтобы указать, что это, вероятно, не то, что было задумано, и что вы должны проверять свой код здесь. Вы, вероятно, хотите что-то вроде этого:

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, если это было 0, остановит ошибку, но действительно ли это лучше, чем подавление, которое вы сказали, не должно использоваться (с чем я согласен)? Я бы предположил, что в большинстве случаев может быть возвращено какое-то другое сообщение или значение.
Джеймс

Для этого примера, если $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.