我有一段这样的代码:
$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);
,如果这冒犯了您的敏感性。
无论如何,我希望这对某些人有所帮助,因为警告非常烦人;-)