Mysqli + xdebug точка останова после закрытия оператора приводит к многочисленным предупреждениям
У меня есть такой код:
$conn = new mysqli($host, $username, $passwd, $dbname);
...
$stmt = $conn->prepare('SELECT ...');
$stmt->bind_param(...);
$stmt->execute();
$stmt->bind_result(...);
while($stmt->fetch())
{
// do something here
}
$stmt->close();
...
// do something more here that has absolutely nothing to do with $stmt
Это работает отлично. Я получаю ожидаемые результаты, нет ошибок или чего-либо, что не должно происходить.
Но если я установил точку останова (Xdebug 2.2.5/2.2.6/2.2.8/2.3.2 и PHP 5.5.3/5.5.15/5.6.0/5.6.6/5.6.10), чтобы строка после $stmt->close();
, я получаю много предупреждений, например
Доступ к ресурсу еще не разрешен
или
Не удалось получить mysqli_stmt
Я думал, что пропустил, чтобы закрыть другое выражение mysqli, но я получаю все результаты. Кажется, в моем коде просто нет проблем...
Есть ли способ избавиться от этих неправильных предупреждений?
Обновление. Эта проблема все еще существует в PHP 7.0.1/Xdebug 2.4.0 RC3.
Ответы
Ответ 1
Есть некоторые похожие проблемы, сообщаемые
http://bugs.xdebug.org/view.php?id=900
https://bugs.php.net/bug.php?id=60778
Один из способов избавиться от этих сообщений - добавить
unset($stmt);
после закрытия оператора и до точки останова. Если это не помогает, вы также должны добавить
unset($connection);
после закрытия соединения, как указано в комментарии @Martin.
Это не решает проблему, но позволяет продолжить работу, пока это не может быть исправлено некоторое время.
EDIT: теперь есть сообщенная проблема:)
EDIT. Это, кажется, ошибка в драйвере MySQLi, как сообщается здесь.
EDIT. Похоже, эта ошибка не появляется, если вы используете PDO. Так что это, возможно, другая причина переключиться на PDO.
Ответ 2
Кстати, это была ошибка в PHP (https://bugs.php.net/bug.php?id=67348&edit=1), которая должна быть исправлена в PHP 7.4: https://github.com/php/php-src/commit/579562176b71820ad49d43b2c841642fef12fe57
Ответ 3
/* PHP 7.0.5 - MYSQLi (mysqlnd 5.0.12-dev) - XDEBUG 2.4 */
/* This one will allow breakpoints before / after / step through */
if (function_exists('xdebug_disable'))
{
$errorlevel=error_reporting();
$displayerrors=ini_get('display_errors');
ini_set('display_errors',0);
error_reporting(0);
xdebug_disable();
}
mysqli_close($DATA_DBH);
unset($DATA_DBH);
if (function_exists('xdebug_enable'))
{
xdebug_enable();
error_reporting($errorlevel);
ini_set('display_errors',$displayerrors);
}
Ответ 4
Я получаю аналогичную ошибку с PHP 7.1.1/Xdebug 2.5.1, пытаясь измерить охват тестирования в консоли, без IDE:
mysqli_init(): Property access is not allowed yet in /home/www/wp-includes/wp-db.php on line 1515
Решение заключалось в том, чтобы прокомментировать все связанные с xdebug параметры в php.ini
. Кажется, в моем случае они были скопированы с более ранней версии и вызвали проблемы. Без этих настроек все начали работать безупречно.
P.S.: Что я имел в конфигурации перед удалением:
xdebug.auto_trace = 1
xdebug.collect_includes = 1
xdebug.collect_params = 1
xdebug.collect_return = 1
xdebug.default_enable = "On"
xdebug.extended_info = 1
xdebug.idekey = "xdebug"
xdebug.max_nesting_level = 100
xdebug.remote_enable = 1
xdebug.remote_autostart=1
xdebug.remote_handler = "dbgp"
xdebug.remote_host = "127.0.0.1"
xdebug.remote_port = 9000
xdebug.show_local_vars = 9
xdebug.var_display_max_children = 128
Ответ 5
Алан хочет заявить, что вы можете использовать эти фрагменты следующим образом:
$stmt = $conn->prepare('SELECT ...');
$stmt->bind_param(...);
$stmt->execute();
$stmt->bind_result(...);
while($stmt->fetch())
{
// do something here
}
// Disable the buggy interconnection between xDebug and PHP/MySQLi for a certain period
if (function_exists('xdebug_disable'))
{
$errorlevel=error_reporting();
$displayerrors=ini_get('display_errors');
ini_set('display_errors',0);
error_reporting(0);
xdebug_disable();
}
$stmt->close();
unset($stmt);
unset($conn);
// finalle bring back the functionality
if (function_exists('xdebug_enable'))
{
xdebug_enable();
error_reporting($errorlevel);
ini_set('display_errors',$displayerrors);
}
Для меня это также работало в PHP 5.6 И я использую его как обходное решение в https://github.com/joshcam/PHP-MySQLi-Database-Class
как в MSQLiDB.php → _dynamicBindResults():
/* BUG http://stackoverflow.com/questions/25377030/mysqli-xdebug-breakpoint-after-closing-statment-result-in-many-warnings
temporarily disable the buggy module interconnection */
if (function_exists('xdebug_disable'))
{
$errorlevel=error_reporting();
$displayerrors=ini_get('display_errors');
ini_set('display_errors',0);
error_reporting(0);
xdebug_disable();
}
/* Returning to normal xDebugging is only possible after $this->_mysqli->close
if (function_exists('xdebug_enable'))
{
xdebug_enable();
error_reporting($errorlevel);
ini_set('display_errors',$displayerrors);
}
*
*/
$stmt->close();
Обратите внимание, что я действительно не могу повторно подключить xDebugging, потому что эта библиотека очень сильно разрушает объект MySQLi. Но для отладчика, похоже, нет причин прекращать показывать отладочную информацию: → У меня не было времени, чтобы понять, почему.
Ответ 6
Для меня было большое количество исключений и предупреждений из VSCode, использующего PHP 7.2.19 с Xdebug 2.7.2. Подход unset()
не работал для меня, но мне удалось остановить их с помощью фиктивного оператора noop в качестве последней строки исполняемого кода, например,
function do_mysqli_stuff() {
...
while(false); // noop
}
или вы можете использовать assert(true);
, если это оскорбляет ваши чувства.
В любом случае, я надеюсь, что это кому-то поможет, потому что предупреждения довольно раздражающие ;-)
php7 xdebug noop