我有一段这样的代码:
$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中仍存在此问题。
答案 0 :(得分:18)
报告了一些类似的问题
http://bugs.xdebug.org/view.php?id=900
https://bugs.php.net/bug.php?id=60778
摆脱此消息的一种方法是添加
unset($stmt);
在关闭语句之后和断点之前。如果这没有帮助,您还应该添加
unset($connection);
关闭@Martin在评论中提到的连接。
这不能解决问题本身,但让你继续工作,直到可以修复一段时间。
编辑:现在还有reported issue:)
编辑:这似乎是MySQLi驱动程序中的一个错误报告here。
编辑:如果您使用PDO,似乎不会出现此错误。所以这可能是切换到PDO的另一个原因。
答案 1 :(得分:2)
FWIW,这是PHP(https://bugs.php.net/bug.php?id=67348&edit=1)中的一个错误,应该在PHP 7.4中修复:https://github.com/php/php-src/commit/579562176b71820ad49d43b2c841642fef12fe57
答案 2 :(得分:1)
/* 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);
}
答案 3 :(得分:1)
我尝试在没有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相关的设置。在我的情况下,它们似乎是从早期版本复制粘贴并导致问题。没有这些设置,一切都开始完美无缺。
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
答案 4 :(得分:0)
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对象。但这似乎没有理由让调试器停止显示调试信息: - >我还没有时间弄明白为什么。
答案 5 :(得分:0)
使用PHP 7.2.19和Xdebug 2.7.2时,VSCode冒出了很多异常和警告。 par(font.main=3, font.lab=1, font.sub=1, cex.main=2, cex.lab=1.7, cex.sub=1.2)
plot(plot.DE$Monat,cumsum(log10(1+plot.DE$`12.2`)),type="l",col="blue",main="Momentum-Performance Deutschland",ylab="Portfolio Wert",xlab="Jahr",ylim=c(-0.5,2.5),yaxt ="n"
,cex.main=1.5,cex.lab=1,cex.axis=1)
lines(plot.DE$Monat,cumsum(log10(1+plot.DE$`12.7`)),type="l",col="green")
lines(plot.DE$Monat,cumsum(log10(1+plot.DE$`6.2`)),type="l",col="red")
lines(plot.DE$Monat,cumsum(log10(1+plot.DE$Markt)),type="l",col="yellow")
legend("topleft",legend = c("12-2","12-7","6-2","Markt"),col = c("blue","green","red","yellow"),pt.cex = 1, cex=1.5,adj = c(0, 0.5),lty=1, ,bg="grey",y.intersp = 0.8,x.intersp = 1.2)
axis(2, at=seq(0,2,by=1),labels=c("1$","10$","100$"), col.axis="black", las=2,cex.axis=1)
方法对我不起作用,但是我设法用一个虚拟的'noop'语句作为执行代码的最后一行来终止它们,例如
unset()
或者如果您冒犯了您的敏感性,则可以使用function do_mysqli_stuff() {
...
while(false); // noop
}
。
无论如何,我希望这对某人有帮助,因为警告很烦人;-)