Ссылка. Что означает эта ошибка в PHP?

Что это?

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

Почему это?

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

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

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

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

Список

Также см:

Ответ 1

Предупреждение: невозможно изменить информацию заголовка - заголовки уже отправлены

Происходит, когда ваш скрипт пытается отправить HTTP-заголовок клиенту, но ранее он уже выводился, что привело к тому, что заголовки уже отправлялись клиенту.

Это E_WARNING и он не остановит скрипт.

Типичным примером будет файл шаблона, подобный этому:

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

Функция session_start() попытается отправить заголовки с файлом cookie сеанса клиенту. Но PHP уже отправлял заголовки, когда записывал элемент <html> в выходной поток. Вам нужно переместить session_start() наверх.

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

Часто пропускаемый вывод - новые строки после закрытия PHP ?>. Это считается стандартной практикой, чтобы пропустить ?> Когда это последняя вещь в файле. Аналогичным образом, другой распространенной причиной этого предупреждения является случай, когда открывающий <?php имеет пустой пробел, строку или невидимый символ перед ним, в результате чего веб-сервер отправляет заголовки и пробел/символ новой строки, поэтому при запуске PHP синтаксический анализ не будет в состоянии представить любой заголовок.

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

Также убедитесь, что в вашем коде нет меток порядка следования байтов, например, когда код сценария UTF-8 с спецификацией.

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

Ответ 2

Неустранимая ошибка: вызов функции-члена... на не объект

Происходит с кодом, подобным 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 дескриптора базы данных $pdo не попадает в текущую область. Найдите, где он определился. Затем передайте его как параметр, сохраните его как свойство или поделите его через глобальную область.

Другой проблемой может быть условное создание объекта, а затем попытка вызова метода вне этого условного блока. Например

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

Пытаясь выполнить метод вне условного блока, ваш объект не может быть определен.

Связанные вопросы:

Ответ 3

Ничего не видно. Страница пустая и белая.

Также известна как Белая страница смерти или белый экран смерти. Это происходит, когда отчет об ошибках отключен и происходит фатальная ошибка (часто синтаксическая ошибка).

Если вы включили ведение журнала ошибок, вы найдете конкретное сообщение об ошибке в своем журнале ошибок. Обычно это будет файл "php_errors.log", либо в центральном месте (например, /var/log/apache2 во многих средах Linux), либо в каталоге самого script (иногда используемого в среде общедоступного хостинга).

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

Это легко сделать, добавив в верхней части script следующий код PHP:

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

В коде появится сообщение об ошибках и установите отчет на самый высокий уровень.

Так как ini_set() выполняется во время выполнения, он не влияет на синтаксические ошибки. Эти ошибки появятся в журнале. Если вы хотите также отобразить их на выходе (например, в браузере), вы должны установить директиву display_startup_errors в true. Сделайте это либо в php.ini, либо в .htaccess или любом другом методе, который влияет на конфигурацию перед временем выполнения.

Вы можете использовать те же методы для установки log_errors и error_log, чтобы выбрать собственное расположение файла журнала.

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

Похожие вопросы:

Связанные ошибки:

Ответ 4

Примечание: неопределенный индекс

Происходит при попытке доступа к массиву по ключу, который не существует в массиве.

Типичным примером уведомления о 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

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

Ответ 5

Предупреждение: 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 в качестве параметра, будут вызывать ту же ошибку по той же причине.

Ответ 6

Неустранимая ошибка: использование $ 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

Ответ 7

Неустранимая ошибка: вызов неопределенной функции 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, yum в Red Hat или CentOS) или Панель управления в среде общего хостинга.

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

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

В случае опечаток, исправьте опечатку.

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

Ответ 8

Ошибка анализа: синтаксическая ошибка, неожиданный T_XXX

Случается, когда в неожиданном месте есть токен T_XXX, несбалансированные (лишние) круглые скобки, использование короткого тега без активации его в php.ini и многие другие.

Связанные вопросы:

Для получения дополнительной помощи см.:

  • http://phpcodechecker.com/ - Что дает более полезные объяснения ваших синтаксических проблем.

Ответ 9

Неустранимая ошибка: невозможно использовать возвращаемое значение функции в контексте записи

Обычно это происходит при использовании функции непосредственно с empty.

Пример:

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

Это связано с тем, что empty является языковой конструкцией, а не функцией, ее нельзя вызывать с выражением в качестве аргумента в версиях PHP до 5.5. До PHP 5.5 аргумент функции empty() должен быть переменной, но в PHP 5 допускается произвольное выражение (например, возвращаемое значение функции) 5+.

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

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

Ответ 10

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-инъекция может привести к изменению, потере или изменению записи, таблицы или всей базы данных. Это очень серьезная проблема безопасности!

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

Ответ 11

Ошибка разбора: синтаксическая ошибка, неожиданный 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 и не выдает 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.

Ответ 12

Неустранимая ошибка: допустимый объем памяти в XXX байтов исчерпан (попытался выделить XXX байтов)

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

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

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

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

Ответ 13

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

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

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

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

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

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

или же:

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

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

Лучший способ быстро решить эту проблему - следовать приведенному ниже контрольному списку устранения неполадок.

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

Связанные ошибки:

Ответ 14

Примечание: использование неопределенной константы 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 при попытке доступа к константе, определенной этой библиотекой.

Связанные вопросы:

Ответ 15

Ошибка разбора: синтаксическая ошибка, неожиданный T_PAAMAYIM_NEKUDOTAYIM

Оператор разрешения контекста также называется "Paamayim Nekudotayim" с иврита פעמיים נקודתיים. что означает "двойное двоеточие".

Эта ошибка обычно возникает, если вы случайно добавили :: в свой код.

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

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

Ответ 16

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

Неустранимая ошибка: невозможно обновить [имя функции]

Это означает, что вы либо используете одно и то же имя функции/класса дважды, и вам нужно переименовать один из них, или это потому, что вы использовали 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, будет загружен только один раз, и ошибка будет устранена.

Ответ 17

Примечание: неопределенная переменная

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

Типичным примером будет

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++;
}

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

Ответ 18

Ошибка разбора: синтаксическая ошибка, неожиданный T_VARIABLE

Возможный сценарий

Я не могу найти, где мой код пошёл не так. Вот моя полная ошибка:

Ошибка разбора: синтаксическая ошибка, неожиданный T_VARIABLE в строке x

Что я пытаюсь

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

Ответ

Ошибка синтаксического анализа: проблема с синтаксисом вашей программы, такая как отсутствие точки с запятой в конце оператора или, как в предыдущем случае, отсутствие символа . оператор. Интерпретатор прекращает запуск вашей программы, когда он сталкивается с ошибкой разбора.

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

Что вы должны сделать, это внимательно проверить строки, где ошибка для любых простых ошибок.

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

Полезное чтение: список токенов парсера

Поэтому убедитесь, что вы E_PARSE хотя бы E_PARSE в своем php.ini. Ошибки разбора не должны существовать в производственных скриптах.

Я всегда рекомендовал добавлять следующее утверждение при кодировании:

error_reporting(E_ALL);

Отчеты об ошибках PHP

Кроме того, хорошая идея использовать IDE, которая позволит вам знать об ошибках разбора при наборе текста. Ты можешь использовать:

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

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

Ответ 19

Примечание: смещение неинициализированной строки: *

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

Учтите, вы пытаетесь показать каждую букву из $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, он выдаст ошибку смещения.

Подобные ошибки:

Ответ 20

Примечание: попытка получить свойство ошибки необъекта

Происходит при попытке получить доступ к свойству объекта, когда объекта нет.

Типичным примером уведомления об отсутствии объекта будет

$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;

Связанные ошибки:

Ответ 21

Предупреждение: действующее ограничение open_basedir

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

Когда он появляется, это означает, что доступ был запрещен для некоторых файлов.

Само предупреждение ничего не нарушает, но чаще всего script не работает должным образом, если предотвращается доступ к файлу.

Обычно исправление изменяет конфигурацию PHP, связанная настройка называется open_basedir.

Иногда используются неправильные имена файлов или каталогов, тогда исправление должно использовать правильные.

Вопросы, относящиеся:

Ответ 22

Ошибка анализа: синтаксическая ошибка, неожиданная '['

Эта ошибка возникает в двух вариантах:

Вариант 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

Предупреждение: [function] ожидает, что параметр 1 будет ресурсом, boolean given

(Более общая вариация Предупреждение: mysql_fetch_array() ожидает, что параметр 1 будет ресурсом, имеет значение boolean)

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

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

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

... дескриптор cURL и мультирум cURL.

Когда var_dump ed, значения выглядят следующим образом:

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

resource(1) of type (curl)

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

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


"... ожидает, что параметр 1 является ресурсом, boolean given" ошибка, как правило, является результатом непроверенной операции, которая должна была создать ресурс, но вместо этого вернула 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);

Связанные ошибки:

Ответ 24

Предупреждение: недопустимое смещение строки 'XXX'

Это происходит, когда вы пытаетесь получить доступ к элементу массива с синтаксисом квадратной скобки, но вы делаете это по строке, а не по массиву, поэтому операция явно не имеет смысла.

Пример:

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

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

Ответ 25

Код не запускается/что-то похожее на части моего кода PHP выводятся

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

Чтобы запустить сценарии PHP, вам необходимо:

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

* Если вы не переконфигурируете его, все может быть настроено.

Этот последний особенно важен. Просто дважды щелкнуть файл, скорее всего, откроет его в вашем браузере, используя адрес, например:

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

Это полностью обходит любой веб-сервер, который может быть запущен, и файл не интерпретируется. Вам нужно посетить URL-адрес файла на вашем веб-сервере, вероятно, что-то вроде:

http://localhost/my/file.php

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

Также смотрите PHP-код не выполняется, вместо этого код отображается на странице

Ответ 26

Предупреждение: 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");

Ответ 27

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

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

$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
}

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

Ответ 28

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

Предупреждающее сообщение 'Division by zero' является одним из наиболее часто задаваемых вопросов среди новых разработчиков PHP. Эта ошибка не вызовет исключения, поэтому некоторые разработчики будут иногда подавлять предупреждение, добавляя оператор подавления ошибок @перед выражением. Например:

$value = @(2 / 0);

Но, как и при любом предупреждении, наилучшим подходом было бы отслеживать причину предупреждения и разрешать его. Причина предупреждения будет происходить из любого экземпляра, где вы пытаетесь разделить на 0, переменную, равную 0, или переменную, которая не была назначена (поскольку NULL == 0), потому что результат будет "undefined.

Чтобы исправить это предупреждение, вы должны переписать свое выражение, чтобы проверить, что значение не равно 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
}

Вопросы, относящиеся:

Ответ 29

Строгие стандарты: нестатический метод [<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();

Похожие вопросы:

Ответ 30

Ошибка HTTP 500 - внутренняя ошибка сервера

Код состояния HTTP 500 и типичное предупреждение Apache или браузера - очень широкое сообщение. Это не актуальная ошибка. Чтобы выяснить, является ли это неправильной конфигурацией веб-сервера (.htaccess) или фатальной ошибкой PHP, вам нужно взглянуть на error.log.

Обычно вы можете найти веб-серверы error.log в:

  • /var/log/apache2 на серверах Linux, часто используется для локальных и виртуальных хостов.
  • /var/www/_user12345_/logs или аналогичный в планах общего хостинга.
     Обычно есть каталог logs/ рядом с каждой папкой htdocs/.
  • C:\xampp\apache\logs\error.log для WAMP/XAMPP дистрибутивов Apache + PHP.
  • В качестве альтернативы просто используйте функцию поиска файлов, чтобы найти что-то, что называется "error.log".
    Или посмотрите на свой Apache httpd.conf и его директиву ErrorLog.
  • /var/log/nginx/nginx_error.log для NGINX.
  • C:\inetpub\logs\LogFiles для IIS.

Это текстовый файл. Найдите запись, наиболее точно соответствующую времени ошибки, и используйте значительную часть сообщения об ошибке (от "Ошибка PHP:…" до "в строке…") для дальнейшего поиска.

[Mon 22:10] [:error] [pid 12345] [client 127.0.0.1] FastCGI: server "/fcgi/p73" stderr: PHP message:PHP Error: Unfiltered inputvariable $_JSON['pokestop_lng'] in filyfile.php on line 845

Для установок FPM вы будете часто просто видеть фатальные ошибки PHP здесь. Принимая во внимание, что старые конфигурации mod_php (виртуальный хостинг) часто смешиваются в предупреждениях и уведомлениях (которые обычно также стоит проверить).

Если вы не настроены на использование системы или механизма ведения журнала Apache, вы также можете посмотреть PHP error.log. Обычно проще оставить значения по умолчанию и просто включить error_display + error_reporting, чтобы выявить конкретную ошибку. В конце концов, HTTP 500 - это всего лишь разновидность белого экрана смерти PHP.

Смотрите также: