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

Что это?

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

Почему это?

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

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

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

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

Список

Также см

38 ответов

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

Происходит, когда ваш скрипт пытается отправить 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 с спецификацией.

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

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

Бывает с кодом, похожим на 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();

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

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

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

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

Если у вас включено ведение журнала ошибок, вы найдете конкретное сообщение об ошибке в вашем журнале ошибок. Обычно это находится в файле с именем "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 для выбора собственного местоположения файла журнала.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Для дальнейшей помощи смотрите:

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

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

Обычно это происходит при использовании функции непосредственно с 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),

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

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

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

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

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

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

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

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

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

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

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

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

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

Если вы не определили $counter прежде код выше вызовет уведомление.

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

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

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

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

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

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

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

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

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

или же:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Ошибка разбора: синтаксическая ошибка, неожиданный 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 (красавица и чудовище, бесплатное программное обеспечение)

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

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

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

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

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

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

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

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

$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 ($div) {
    $divText = $div->nodeValue;
}
echo $divText;

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

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

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

Вариация 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];

Смотрите также этот пример из руководства.

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

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

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

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

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

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

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

Предупреждение: [функция] ожидает, что параметр 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);

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

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

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

Пример:

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

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

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

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

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

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

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

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

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

Не рекомендуется: синтаксис доступа к смещению массивов и строк с фигурными скобками не рекомендуется

Доступ к смещениям строк и элементам массива можно получить с помощью фигурных скобок {} до 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 скрипт, который пытается исправить это механически.

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

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

Предупреждающее сообщение "Деление на ноль" является одним из наиболее часто задаваемых вопросов среди новых разработчиков 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
}

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

Неустранимая ошибка: объект класса Closure не может быть преобразован в строку

Это означает, что вы не выполняете свою анонимную функцию (или закрытие).

В этом примере с помощью стрелочных функций будет выдана ошибка:

echo $fn = fn($x = 42) => $x;

Или для любой анонимной функции

echo function($x = 42) { return $x; };

Чтобы устранить эту ошибку, вам необходимо выполнить закрытие.

echo $fn = (fn($x = 42) => $x)(30); // take notice of the 2 sets of brackets

echo (function($x = 42) { return $x; })(30);

Такой синтаксис называется IIFE, и он был добавлен в PHP 7.

Другие вопросы по тегам