Это ряд ответов о предупреждениях, ошибках и уведомлениях, с которыми вы можете столкнуться при программировании PHP, и не знаете, как их исправить. Это также Вики Сообщества, поэтому каждый приглашен принять участие в добавлении и поддержании этого списка.
Такие вопросы, как "Заголовки уже отправлены" или "Вызов члена необъекта", часто появляются при переполнении стека. Коренная причина этих вопросов всегда одна и та же. Таким образом, ответы на эти вопросы обычно повторяют их, а затем показывают ОП, какую линию изменить в его/ее конкретном случае. Эти ответы не добавляют никакой ценности сайту, поскольку они относятся только к определенному коду OP. Другие пользователи, имеющие ту же ошибку, не могут легко прочитать решение из нее, потому что они слишком локализованы. Это печально, потому что, как только вы поняли основную причину, исправление ошибки становится тривиальным. Следовательно, этот список пытается объяснить решение в общем виде для применения.
Если ваш вопрос был помечен как дубликат этого, найдите ваше сообщение об ошибке ниже и примените исправление к вашему коду. Ответы обычно содержат дополнительные ссылки для расследования в случае, если это не должно быть ясно только из общего ответа.
Если вы хотите внести свой вклад, пожалуйста, добавьте свое "любимое" сообщение об ошибке, предупреждение или уведомление, по одному на ответ, краткое описание того, что это значит (даже если оно только выделяет термины на их странице руководства), возможное решение или подход отладки и список существующих вопросов и ответов, которые имеют значение. Кроме того, не стесняйтесь улучшать любые существующие ответы.
Также см
Случается, когда ваш скрипт пытается отправить 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.
Связанные вопросы:
<?php ?>
И поэтому "более одного блока" будет <?php ?> <?php ?>
?
Происходит с кодом, подобным 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();
Пытаясь выполнить метод вне условного блока, ваш объект не может быть определен.
Связанные вопросы:
Также известна как Белая страница смерти или белый экран смерти. Это происходит, когда отчет об ошибках отключен и происходит фатальная ошибка (часто синтаксическая ошибка).
Если вы включили ведение журнала ошибок, вы найдете конкретное сообщение об ошибке в своем журнале ошибок. Обычно это будет файл "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.
Похожие вопросы:
Связанные ошибки:
error_reporting(~0);
почему не -1
? Это то, что оценивает ~0
, и гораздо менее загадочно.
~0
является более явным IMO: отменить набор пустых битов, т.е. включить все флаги. -1 не означает «не найден», как в strpos () в C, но как набор битов со всеми установленными флагами, потому что -1 является двоичным 1111'1111'1111'1111
(для 32 бит).
Случается, когда вы пытаетесь получить доступ к массиву с помощью ключа, который не существует в массиве.
Типичным примером уведомления о 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
Связанные вопросы:
Прежде всего:
Пожалуйста, не используйте функции
mysql_*
в новом коде. Они больше не поддерживаются и официально устарели. См. Красную рамку? Узнайте о подготовленных инструкциях и используйте PDO или MySQLi - эта статья поможет вам решить, какой из них. Если вы выберете PDO, вот хороший учебник.
Это происходит, когда вы пытаетесь извлечь данные из результата mysql_query
но запрос не удался.
Это предупреждение и не остановит скрипт, но сделает вашу программу неправильной.
Вы должны проверить результат, возвращаемый mysql_query
по
$res = mysql_query($sql);
if (!$res) {
die(mysql_error());
}
// after checking, do the fetch
Связанные вопросы:
Связанные ошибки:
Другие функции mysql*
которые также ожидают, что ресурс результата MySQL в качестве параметра приведет к той же ошибке по той же причине.
mysql_query
не достаточно плох, добавление or die
поверх него добавляет оскорбление ране.
$res = mysql_query($query)
возвращает 1, если запрос успешен, поэтому он считается верным. Поэтому при передаче результата mysql_query
в mysql_fetch_array()
появляется уведомление.
$this
специальная переменная в PHP, которая не может быть назначена. Если он доступен в контексте, где он не существует, эта фатальная ошибка дается.
Эта ошибка может произойти:
Если нестатический метод называется статическим. Пример:
class Foo {
protected $var;
public function __construct($var) {
$this->var = $var;
}
public static function bar () {
// ^^^^^^
echo $this->var;
// ^^^^^
}
}
Foo::bar();
Как исправить: снова просмотрите свой код, $this
может использоваться только в контексте объекта и никогда не должен использоваться в статическом методе. Кроме того, статический метод не должен обращаться к нестатистическому свойству. Используйте self::$static_property
для доступа к статическому свойству.
Если код из метода класса был скопирован в нормальную функцию или только глобальную область и сохранил $this
специальную переменную $this
.
Как исправить: просмотрите код и замените $this
на другую переменную замещения.
Связанные вопросы:
$closure = function() { self::method(); }
Случается, когда в неожиданном месте есть токен T_XXX
, несбалансированные (лишние) круглые скобки, использование короткого тега без активации его в php.ini и многие другие.
Связанные вопросы:
Для получения дополнительной помощи см.:
Случается, когда вы пытаетесь вызвать функцию, которая еще не определена. Общие причины включают в себя отсутствие расширений и включает в себя объявление условной функции, функцию в объявлении функции или простые опечатки.
Пример 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, найдите информацию о том, почему, поскольку это может быть уже не нужно.
В случае отсутствия включено, обязательно включите файл, объявляющий функцию перед вызовом функции.
В случае опечаток исправьте опечатку.
Связанные вопросы:
Обычно это происходит при непосредственном использовании функции с 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)
.
Связанные вопросы:
Эта ошибка часто возникает из-за того, что вы забыли правильно избежать данных, переданных в 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-инъекция может привести к изменению, потере или изменению записи, таблицы или всей базы данных. Это очень серьезная проблема безопасности!
Документация:
Недостаточно памяти для запуска script. PHP достиг предела памяти и перестает его выполнять. Эта ошибка является фатальной, останавливается script. Значение ограничение памяти можно настроить либо в файле php.ini
, либо с помощью ini_set('memory_limit', '128 M');
в script (который будет перепишите значение, определенное в php.ini
). Цель ограничения памяти состоит в том, чтобы не допустить, чтобы один PHP скрипт перебирал всю доступную память и выводил весь веб-сервер.
Первое, что нужно сделать, это минимизировать объем памяти, необходимый вашим script. Например, если вы читаете большой файл в переменной или извлекаете много записей из базы данных и сохраняете их все в массиве, которые могут использовать много памяти. Измените свой код, чтобы вместо этого читать строки по строке или извлекать записи базы данных по одному, не сохраняя их все в памяти. Это требует немного концептуального понимания того, что происходит за кулисами и когда данные хранятся в памяти и в других местах.
Если эта ошибка возникла, когда ваш script не выполнял интенсивную работу с памятью, вам нужно проверить свой код, чтобы узнать, есть ли утечка памяти. Функция memory_get_usage
- ваш друг.
Вопросы, относящиеся:
Эта ошибка чаще всего встречается при попытке ссылаться на значение массива с цитированным ключом для интерполяции внутри строки с двумя кавычками, когда вся сложная конструктивная переменная не заключена в {}
.
Это приведет к 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
Это происходит, когда вы вызываете файл обычно с помощью include
, require
или fopen
и PHP не может найти файл или не имеет достаточного разрешения на загрузку файла.
Это может произойти по разным причинам:
Одна из распространенных ошибок заключается в том, чтобы не использовать абсолютный путь. Это можно легко решить, используя полный путь или магические константы, такие как __DIR__
или dirname(__FILE__)
:
include __DIR__ . '/inc/globals.inc.php';
или же:
require dirname(__FILE__) . '/inc/globals.inc.php';
Обеспечение правильного пути используется одним шагом в устранении этих проблем, это также может быть связано с несуществующими файлами, правами файловой системы, препятствующими доступу или открытыми ограничениями на основе самого PHP.
Лучший способ быстро решить эту проблему - следовать нижеприведенному списку устранения неполадок.
Связанные вопросы:
Связанные ошибки:
Это означает, что вы либо используете одно и то же имя функции/класса дважды, и вам нужно переименовать один из них, или это потому, что вы использовали 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
, будет загружен только один раз, и ошибка будет устранена.
Оператор разрешения области также называется "Paamayim Nekudotayim" с иврита פעמיים נקודתיים. что означает "двойная двоеточие" или "двойная точка дважды".
Эта ошибка обычно возникает, если вы случайно поместите ::
в свой код.
Вопросы, относящиеся:
Документация:
a()::b;
или $a=::;
,
или, в PHP 7.2 или новее:
Это уведомление возникает, когда токен используется в коде и представляется константой, но константа с этим именем не определена.
Одной из наиболее распространенных причин этого уведомления является неспособность указать строку, используемую в качестве ассоциативного массива.
Например:
// Wrong
echo $array[key];
// Right
echo $array['key'];
Другой распространенной причиной является отсутствие знака $
(доллара) перед именем переменной:
// Wrong
echo varName;
// Right
echo $varName;
Или, возможно, у вас есть ошибка с другой константой или ключевым словом:
// Wrong
$foo = fasle;
// Right
$foo = false;
Это также может быть признаком отсутствия необходимого расширения или библиотеки PHP при попытке доступа к константе, определенной этой библиотекой.
Связанные вопросы:
Случается, когда вы пытаетесь использовать переменную, которая ранее не была определена.
Типичным примером может быть
foreach ($items as $item) {
// do something with item
$counter++;
}
Если вы еще не определили $counter
, код, указанный выше, вызовет уведомление.
Правильный способ - установить переменную перед ее использованием, даже если она просто пустая строка, например
$counter = 0;
foreach ($items as $item) {
// do something with item
$counter++;
}
Вопросы, относящиеся:
*
Как видно из названия, возникает такой тип ошибки, когда вы, скорее всего, пытаетесь перебрать или найти значение из массива с несуществующим ключом.
Подумайте, вы пытаетесь показать каждую букву из $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
, он выдает ошибку смещения.
Похожие ошибки:
Возможный сценарий
Я не могу найти, где мой код поступил неправильно. Вот моя полная ошибка:
Ошибка анализа: синтаксическая ошибка, неожиданный 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);
Кроме того, хорошая идея использовать среду IDE, которая позволит вам знать ошибки разбора при наборе текста. Ты можешь использовать:
Связанные вопросы:
Это предупреждение может появляться с различными функциями, связанными с доступом к файлам и каталогам. Он предупреждает о проблеме с конфигурацией.
Когда он появляется, это означает, что доступ был запрещен для некоторых файлов.
Само предупреждение ничего не нарушает, но чаще всего script не работает должным образом, если предотвращается доступ к файлу.
Обычно исправление изменяет конфигурацию PHP, связанная настройка называется open_basedir
.
Иногда используются неправильные имена файлов или каталогов, тогда исправление должно использовать правильные.
Вопросы, относящиеся:
Эта ошибка возникает в двух вариантах:
$arr = [1, 2, 3];
Синтаксис инициализатора массива был введен только в PHP 5.4; это приведет к возникновению ошибки парсера в версиях до этого. Если возможно, обновите свою установку или используйте старый синтаксис:
$arr = array(1, 2, 3);
См. также этот пример из руководства.
$suffix = explode(',', 'foo,bar')[1];
Результаты функции разыменования массива также были введены в PHP 5.4. Если обновление невозможно, вам нужно использовать временную переменную:
$parts = explode(',', 'foo,bar');
$suffix = $parts[1];
См. также этот пример из руководства.
Случается, когда вы пытаетесь получить доступ к объекту объекта, пока нет объекта.
Типичным примером для уведомления об отсутствии объекта было бы
$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;
Связанные ошибки:
json_decode
теперь возвращает экземпляр stdclass
по умолчанию, поэтому пример кода действительно будет работать.
json_decode
теперь возвращает экземпляр stdclass
по умолчанию» ? Я не могу найти это в журнале изменений.
(Более общая вариация Предупреждение: 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);
Связанные ошибки:
Это происходит, когда вы пытаетесь получить доступ к элементу массива с синтаксисом квадратной скобки, но вы делаете это по строке, а не по массиву, поэтому операция явно не имеет смысла.
Пример:
$var = "test";
echo $var["a_key"];
Если вы считаете, что переменная должна быть массивом, посмотрите, откуда она взялась, и устраните проблему.
Если вы не видите никакого результата из вашего кода PHP и/или видите части своего литерального исходного кода PHP на веб-странице, вы можете быть уверены, что ваш PHP на самом деле не выполняется. Если вы используете View Source в своем браузере, вы, вероятно, видите весь исходный код PHP файла. Поскольку PHP-код встроен в теги <?php ?>
, браузер попытается интерпретировать их как теги HTML, и результат может выглядеть несколько смущенным.
Чтобы запустить сценарии PHP, вам необходимо:
* Если вы не переконфигурируете его, все может быть настроено.
Этот последний особенно важен. Просто дважды щелкнуть файл, скорее всего, откроет его в вашем браузере, используя адрес, например:
file://C:/path/to/my/file.php
Это полностью обходит любой веб-сервер, который может быть запущен, и файл не интерпретируется. Вам нужно посетить URL-адрес файла на вашем веб-сервере, вероятно, что-то вроде:
http://localhost/my/file.php
Вы также можете проверить, используете ли вы короткие открытые теги <?
вместо <?php
, и ваша конфигурация PHP отключила короткие открытые теги.
Также смотрите PHP-код не выполняется, вместо этого код отображается на странице
Это предупреждение появляется при подключении к серверу MySQL/MariaDB с недопустимыми или отсутствующими учетными данными (имя пользователя/пароль). Таким образом, это обычно не проблема с кодом, а проблема с конфигурацией сервера.
Для примера см. страницу руководства mysql_connect("localhost", "user", "pw")
.
Убедитесь, что вы действительно использовали $username
и $password
.
(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=
имеют значимые значения.
Часто это конфигурация поставщика. Поэтому обратитесь за поддержкой к несоответствиям.
Найдите документацию вашего хостинг-провайдера:
например. HostGator, GoDaddy, 1 и 1, DigitalOcean, BlueHost, DreamHost, MediaTemple, ixWebhosting, lunarhosting или просто google yours'.
Проконсультируйтесь с вашим провайдером веб-хостинга через их каналы поддержки.
Обратите внимание, что вы также исчерпали доступный пул подключений. Вы получите доступ к запрещенным предупреждениям для слишком большого количества параллельных подключений. (Вы должны исследовать настройку. Это проблема конфигурации сервера вне темы, а не вопрос программирования.)
Ваша версия клиента libmysql может быть несовместима с сервером базы данных. Обычно MySQL и MariaDB-серверы можно получить с помощью PHP, скомпилированных в драйвере. Если у вас есть пользовательская настройка или устаревшая версия PHP, а также гораздо более новый сервер базы данных или значительно устаревший - тогда несоответствие версии может препятствовать подключению. (Нет, вам нужно исследовать себя. Никто не может угадать вашу настройку).
Дополнительные ссылки:
Btw, вы, вероятно, больше не хотите использовать функции
mysql_*
. Новички часто переносятся на mysqli, что, однако, так же утомительно. Вместо этого прочитайте PDO и подготовленные заявления.
$db = new PDO("mysql:host=localhost;dbname=testdb", "username", "password");
Это просто происходит, если вы попытаетесь обработать массив как строку:
$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
}
Если это уведомление появляется где-то, чего вы не ожидаете, это означает, что переменная, которую вы считаете строкой, на самом деле является массивом. Это означает, что у вас есть ошибка в коде, которая делает эту переменную массив вместо ожидаемой строки.
Предупреждающее сообщение '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
}
Вопросы, относящиеся:
$var1
делает == 0, вы можете просто установить $var3
в $var2
. Даже если этого не сделать, else не требуется вообще, так как назначение в обоих случаях одно и то же, так что no else и присваивание вне if
Происходит при попытке вызвать нестатический метод для класса, поскольку он был статичным, а также у вас есть флаг 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();
Похожие вопросы:
Происходит, когда класс пытается use
несколько признаков, где две или более из этих черт имеют определил свойство с тем же именем и с свойством, имеющим разные начальные значения.
Пример:
<?php
trait TraitA
{
public $x = 'a';
}
trait TraitB
{
public $x = 'b';
}
class ClassC
{
use TraitA, TraitB;
}
Проблема:. В то время как можно разрешить конфликты между конкурирующие методы, в настоящее время нет синтаксиса, который бы разрешил конфликт между двумя конкурирующими свойствами. Единственное решение в это время - refactor; то есть избежать конфликта между именами свойств, которые приводят к фатальной ошибке.
Вопросы, относящиеся:
Код состояния 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.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.
Смотрите также:
Если неправильный тип параметра передается функции - и PHP не может автоматически преобразовать его - выдается предупреждение. Это предупреждение указывает, какой параметр является проблемой, и какой тип данных ожидается. Решение: измените указанный параметр на правильный тип данных.
Например, этот код:
echo substr(["foo"], 23);
Результаты в этом выпуске:
PHP Предупреждение: substr() ожидает, что параметр 1 будет строкой, заданный массив