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

931

Что это?

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

Почему это?

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

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

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

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

Список

Также см

Показать ещё 4 комментария
Теги:
debugging
warnings

32 ответа

254

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

Случается, когда ваш скрипт пытается отправить 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 с BOM.

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

  • 2
    Если вы используете WordPress, проверьте файлы темы. Когда я обновил сайт до новой версии WordPress, я не смог обновить тему, потому что она не обновлялась в течение нескольких лет. Эта проблема возникла. Оказалось, что в файле functions.php было больше одного <? ?> блок с пробелами между ними.
  • 2
    @RoyLeban "Если в вашем файле более одного блока ..." Я не уверен, что это значит. Что такое «блок»? Будет ли один блок состоять из <?php ?> И поэтому "более одного блока" будет <?php ?> <?php ?> ?
Показать ещё 1 комментарий
169

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

Происходит с кодом, подобным 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();

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

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

100

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

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

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

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

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

  • 3
    error_reporting(~0); почему не -1 ? Это то, что оценивает ~0 , и гораздо менее загадочно.
  • 3
    Я думаю, что оба одинаково загадочны. ~0 является более явным IMO: отменить набор пустых битов, т.е. включить все флаги. -1 не означает «не найден», как в strpos () в C, но как набор битов со всеми установленными флагами, потому что -1 является двоичным 1111'1111'1111'1111 (для 32 бит).
Показать ещё 3 комментария
91

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

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

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

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

75

Предупреждение: mysql_fetch_array() ожидает, что параметр 1 будет ресурсом, boolean

Прежде всего:

Пожалуйста, не используйте функции mysql_* в новом коде. Они больше не поддерживаются и официально устарели. См. Красную рамку? Узнайте о подготовленных инструкциях и используйте PDO или MySQLi - эта статья поможет вам решить, какой из них. Если вы выберете PDO, вот хороший учебник.


Это происходит, когда вы пытаетесь извлечь данные из результата mysql_query но запрос не удался.

Это предупреждение и не остановит скрипт, но сделает вашу программу неправильной.

Вы должны проверить результат, возвращаемый mysql_query по

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

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

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

Другие функции mysql* которые также ожидают, что ресурс результата MySQL в качестве параметра приведет к той же ошибке по той же причине.

  • 4
    Просто записка. Если mysql_query не достаточно плох, добавление or die поверх него добавляет оскорбление ране.
  • 0
    Проблема, с которой я сталкиваюсь, состоит в том, что $res = mysql_query($query) возвращает 1, если запрос успешен, поэтому он считается верным. Поэтому при передаче результата mysql_query в mysql_fetch_array() появляется уведомление.
Показать ещё 4 комментария
67

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

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

  1. Вызовите нестатический метод как статический: PHP Неустранимая ошибка: использование $ this, когда не в контексте объекта
  2. Скопировать код: Неустранимая ошибка: использование $ this, если не в контексте объекта
  3. Все "Использование $ this, если не в контексте объекта". Вопросы по Stackoverflow
  • 2
    Вы также можете упомянуть, как это работает с замыканиями (даже в нестатических методах) и как это «исправлено» в 5.4.
  • 2
    @hakre Я говорил о статическом вызове внутри Замыкания. Как $closure = function() { self::method(); }
Показать ещё 1 комментарий
66

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

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

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

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

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

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

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

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

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

60

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

Обычно это происходит при непосредственном использовании функции с 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 проверяется только в том случае, если оно равно false. Вы можете заменить empty() здесь ! , например if (!is_null(null)) или явно сравнивать с ложным, например if (is_null(null) == false).

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

55

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
    Кроме того, если вы этого не сделаете, ваш сайт будет взломан ботами автоматически
  • 2
    @gladoscc Нажмите «изменить» и измените ответ. Я знаю, что это может быть улучшено.
Показать ещё 1 комментарий
47

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

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

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

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

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

44

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

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

Случай ошибки:

Это приведет к Unexpected T_ENCAPSED_AND_WHITESPACE:

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

Возможные исправления:

В строке с E_NOTICE 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

39

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

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

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

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

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

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

или же:

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

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

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

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

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

38

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

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

Это означает, что вы либо используете одно и то же имя функции/класса дважды, и вам нужно переименовать один из них, или это потому, что вы использовали require или include, где вы должны использовать require_once или include_once.

Когда класс или функция объявляется в PHP, он неизменен и не может быть объявлен с новым значением.

Рассмотрим следующий код:

class.php

<?php

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

index.php

<?php

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

do_stuff();
do_stuff();

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

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

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

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

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

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

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

  • 0
    Самый простой способ вызвать эту ошибку - запустить a()::b; или $a=::; ,
  • 0
    Ааа, красота T_PAAMAYIM_NEKUDOTAYIM ...
37

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

Примечание: переменная Undefined

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

Типичным примером может быть

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

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

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

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

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

30

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

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

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

Похожие ошибки:

29

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

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

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

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

Что я пытаюсь

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

Ответ

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

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

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

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

Хорошо читайте: Список токенов Parser

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

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

error_reporting(E_ALL);

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

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

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

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

29

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

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

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

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

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

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

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

  • 1
    Чаще всего это происходит на общем хосте, люди обычно не блокируют себя из каталогов :-)
25

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

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

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

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

24

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

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

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

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

В этом случае $users - это массив (а не объект), и он не имеет никаких свойств.

Это похоже на доступ к несуществующему индексу или ключу массива (см. Примечание: Undefined Индекс).

Этот пример значительно упрощен. Чаще всего такое уведомление сигнализирует неконтролируемое возвращаемое значение, например. когда библиотека возвращает NULL, если объект не существует или просто неожиданное значение, отличное от объекта (например, в результате Xpath, структуры JSON с непредвиденным форматом, XML с неожиданным форматом и т.д.), но код не проверяет наличие такого состояние.

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

Это можно легко предотвратить, проверив условия ошибки и/или переменную, соответствующую ожиданию. Здесь такое уведомление с примером 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;

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

  • 0
    json_decode теперь возвращает экземпляр stdclass по умолчанию, поэтому пример кода действительно будет работать.
  • 0
    @HugoZink: Он действительно (и всегда делал) возвращает массив для этого примера: 3v4l.org/SUDe0 - Также не могли бы вы предоставить ссылку для написания, что « json_decode теперь возвращает экземпляр stdclass по умолчанию» ? Я не могу найти это в журнале изменений.
Показать ещё 1 комментарий
21

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

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

18

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

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

Пример:

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

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

17

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

16

Предупреждение: mysql_connect(): доступ запрещен для имени пользователя '@' host '

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

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

  • Убедитесь, что вы действительно использовали $username и $password.

    • Необычно, что вы получаете доступ, не используя пароль - вот что произошло, когда Warning: said (using password: NO).
    • Только локальный тестовый сервер обычно позволяет подключаться к имени пользователя root, без пароля и имени базы данных test.

    • Вы можете проверить, правильно ли они действительно, используя клиент командной строки:
      mysql --user="username" --password="password" testdb

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

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

    • См. руководство по MySQL на Добавление учетных записей пользователей с помощью командной строки. Когда вы подключаетесь как пользователь admin, вы можете выдать запрос вроде:
       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 был фактически включен и что-то.

  • Проверьте правильность установки 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-preconfigured пароли для учетной записи/пароля.

    • Убедитесь, что mysql.default_user= и mysql.default_password= имеют значимые значения.

    • Часто это конфигурация поставщика. Поэтому обратитесь за поддержкой к несоответствиям.

  • Найдите документацию вашего хостинг-провайдера:

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

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

Дополнительные ссылки:

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

  • 2
    mysql разрешает автоматическое подключение через настройки php-ini, затем то же сообщение об ошибке выдается с другой префиксом команды, например, «Предупреждение: mysql_query (): доступ запрещен для пользователя» @ @ localhost (с использованием пароля: НЕТ) в. .. " - просто замечаю.
  • 0
    Ха, совсем забыл об этом! (Возможно, последний раз использовал это с PHP3 или около того ..)
14

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

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

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

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

11

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

Предупреждающее сообщение '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
}

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

  • 0
    Установка в 1, если это было 0, остановит ошибку, но действительно ли это лучше, чем подавление, которое вы сказали, не должно использоваться (с чем я согласен)? Я бы предположил, что в большинстве случаев может быть возвращено какое-то другое сообщение или значение.
  • 0
    В этом примере, если $var1 делает == 0, вы можете просто установить $var3 в $var2 . Даже если этого не сделать, else не требуется вообще, так как назначение в обоих случаях одно и то же, так что no else и присваивание вне 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();

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

2

Неустранимая ошибка: [TraitA] и [TraitB] определяют одно и то же свойство ([$ x]) в композиции [ClassC]

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

Пример:

<?php
trait TraitA
{
    public $x = 'a';
}
trait TraitB
{
    public $x = 'b';
}
class ClassC
{
    use TraitA, TraitB;
}

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


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

  • 0
    Обратите внимание, что это также происходит, когда TraitA :: $ x и TraitB :: $ x имеют одинаковое значение (скажем, «a»), но TraitA :: $ a является общедоступным, а TraitB :: $ a является частным или защищенным
1

Ошибка 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:…" до "в строке…") для дальнейшего поиска в Google.

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

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

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

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

0

Предупреждение: function() ожидает, что параметр X будет логическим (или целым числом, строкой и т.д.).

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


Например, этот код:

echo substr(["foo"], 23);

Результаты в этом выпуске:

PHP Предупреждение: substr() ожидает, что параметр 1 будет строкой, заданный массив

Ещё вопросы

Сообщество Overcoder
Наверх
Меню