Подтвердить что ты не робот

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.

4b9b3361

Ответ 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.

Ответ 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);, если это оскорбляет ваши чувства.

В любом случае, я надеюсь, что это кому-то поможет, потому что предупреждения довольно раздражающие ;-)