Mysqli + xdebug关闭语句后的断点导致许多警告


mysqli + xdebug breakpoint after closing statement result in many warnings

我有一段这样的代码:

$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

这工作得很好。我得到了我期望的结果,没有错误或任何不应该发生的事情。

但是如果我在 $stmt->close();之后设置一个断点(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)到行,我会得到许多像

这样的警告

还不允许访问属性

无法读取mysqli_stmt

我以为我错过了关闭另一个mysqli语句,但我得到了所有结果。我的代码似乎没有问题……

有办法摆脱这个错误的警告吗?

更新:此问题在PHP 7.0.1/Xdebug 2.4.0 RC3中仍然存在

有一些类似的问题报告
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的另一个原因。

FWIW,这是PHP中的一个错误(https://bugs.php.net/bug.php?id=67348&edit=1),应该在PHP 7.4中修复:https://github.com/php/php-src/commit/579562176b71820ad49d43b2c841642fef12fe57

/* 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);
              }

在没有IDE的情况下,尝试在控制台中测量测试覆盖率时,我一直在使用PHP 7.1.1/Xdebug 2.5.1获得类似的错误:

mysqli_init(): Property access is not allowed yet in /home/www/wp-includes/wp-db.php on line 1515

解决方案是注释掉php.ini中所有与xdebug相关的设置。在我的情况下,它们似乎是从早期版本复制粘贴的,并造成了问题。没有这些设置,一切都开始完美地工作。

注::我在删除之前的配置是:

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

Alan想说明的是,您可以按照以下方式使用这些代码片段:

$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对象。但这似乎不是调试器停止显示调试信息的理由:->我还没有时间弄清楚为什么。

在使用PHP 7.2.19和Xdebug 2.7.2时,大量的异常和警告从VSCode中喷涌出来。unset()方法对我不起作用,但我设法用一个虚拟的'noop'语句作为执行代码的最后一行来阻止它们,例如,

function do_mysqli_stuff() {
   ...
   while(false); // noop
}

或者您可以使用assert(true);,如果这冒犯了您的敏感性。

无论如何,我希望这对某些人有所帮助,因为警告非常烦人;-)