php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #63486 mysqli_free_result leave the resource variable in a messy state
Submitted: 2012-11-11 12:52 UTC Modified: 2020-10-29 09:46 UTC
Votes:29
Avg. Score:4.5 ± 0.7
Reproduced:25 of 25 (100.0%)
Same Version:10 (40.0%)
Same OS:9 (36.0%)
From: derick@php.net Assigned: nikic (profile)
Status: Closed Package: MySQLi related
PHP Version: 5.4.8 OS:
Private report: No CVE-ID: None
 [2012-11-11 12:52 UTC] derick@php.net
Description:
------------
An Xdebug user filed the following report: http://bugs.xdebug.org/view.php?id=900

I've just investigated this, and found out that this is something I can't fix in Xdebug. mysqli_free_result() destroys the internal object, but leaves the resource (in your case, $rs) in a silly state. All Xdebug does internally is basically a var_dump( $rs ), and after it is freed with mysqli_free_result(), that throws exactly the same error (without Xdebug). This can however, easily be fixed in the MySQLi extension with the attached patch. The patch applies to PHP 5.4, but this also a problem in master and PHP 5.3. It is also possible, that other mysqli_free_* functions can benefit from a similar construct.

Test script:
---------------
<?php

$con = mysqli_init();
mysqli_real_connect($con, '127.0.0.1', 'root', 'xxxxx');
$rs = mysqli_query($con, 'show schemas');
$row = mysqli_fetch_object($rs);
mysqli_free_result($rs);

echo "hi mom";
var_dump( $rs );
?>


Expected result:
----------------
The expected result is perhaps something like "NULL" (which my patch makes it do).

Actual result:
--------------
hi mom
Warning: var_dump(): Couldn't fetch mysqli_result in /home/derick/dev/php/derickr-xdebug/tests/bug00900.php on line 10

Call Stack:
    0.0002     662616   1. {main}() /home/derick/dev/php/derickr-xdebug/tests/bug00900.php:0
    0.0032     672792   2. var_dump(class mysqli_result { public $current_field = NULL; public $field_count = NULL; public $lengths = NULL; public $num_rows = NULL; public $type = NULL }) /home/derick/dev/php/derickr-xdebug/tests/bug00900.php:10


Warning: var_dump(): Couldn't fetch mysqli_result in /home/derick/dev/php/derickr-xdebug/tests/bug00900.php on line 10

Call Stack:
    0.0002     662616   1. {main}() /home/derick/dev/php/derickr-xdebug/tests/bug00900.php:0
    0.0032     672792   2. var_dump(class mysqli_result { public $current_field = NULL; public $field_count = NULL; public $lengths = NULL; public $num_rows = NULL; public $type = NULL }) /home/derick/dev/php/derickr-xdebug/tests/bug00900.php:10


Warning: var_dump(): Property access is not allowed yet in /home/derick/dev/php/derickr-xdebug/tests/bug00900.php on line 10

Call Stack:
    0.0002     662616   1. {main}() /home/derick/dev/php/derickr-xdebug/tests/bug00900.php:0
    0.0032     672792   2. var_dump(class mysqli_result { public $current_field = NULL; public $field_count = NULL; public $lengths = NULL; public $num_rows = NULL; public $type = NULL }) /home/derick/dev/php/derickr-xdebug/tests/bug00900.php:10


Warning: var_dump(): Couldn't fetch mysqli_result in /home/derick/dev/php/derickr-xdebug/tests/bug00900.php on line 10

Call Stack:
    0.0002     662616   1. {main}() /home/derick/dev/php/derickr-xdebug/tests/bug00900.php:0
    0.0032     672792   2. var_dump(class mysqli_result { public $current_field = NULL; public $field_count = NULL; public $lengths = NULL; public $num_rows = NULL; public $type = NULL }) /home/derick/dev/php/derickr-xdebug/tests/bug00900.php:10


Warning: var_dump(): Property access is not allowed yet in /home/derick/dev/php/derickr-xdebug/tests/bug00900.php on line 10

Call Stack:
    0.0002     662616   1. {main}() /home/derick/dev/php/derickr-xdebug/tests/bug00900.php:0
    0.0032     672792   2. var_dump(class mysqli_result { public $current_field = NULL; public $field_count = NULL; public $lengths = NULL; public $num_rows = NULL; public $type = NULL }) /home/derick/dev/php/derickr-xdebug/tests/bug00900.php:10

class mysqli_result#2 (5) {
  public $current_field =>
  NULL
  public $field_count =>
  NULL
  public $lengths =>
  NULL
  public $num_rows =>
  NULL
  public $type =>
  NULL
}


Patches

mysqli-clear-result-cleanup (last revision 2012-11-11 12:53 UTC by derick@php.net)

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-11-11 12:53 UTC] derick@php.net
The following patch has been added/updated:

Patch Name: mysqli-clear-result-cleanup
Revision:   1352638381
URL:        https://bugs.php.net/patch-display.php?bug=63486&patch=mysqli-clear-result-cleanup&revision=1352638381
 [2012-11-15 17:17 UTC] uw@php.net
Derick, thanks a lot for the patch. All three of us MySQL guys are at a team meeting. We will fly back home tomorrow morning. We can have a look once home and no more tired (flight goes at 6:xx am).
 [2012-11-23 10:20 UTC] uw@php.net
-Status: Open +Status: Verified -Assigned To: +Assigned To: mysql
 [2012-11-23 10:20 UTC] uw@php.net
Thanks for the patch. It seems straight forward , however, it changes behaviour in case of user errors. This makes me wonder in which PHP version it should go.


Current behaviour:
a) var_dump() - the XDebug view 

res->free();
var_dump(res)  <-- throws a ton of warnings

b) Invalid property access - user error: why access free'd resource?

res->free();
var_dump(res->lengths) <--- throws a ton of warnings

c) Invalid method access - user error: why access free'd resource?

res->free();
res->free(); <--- trows a ton of warnings

In all three cases the user is confronted with warnings that he could ignore, if he wanted. The patch leaves the user with:

a) var_dump() - the XDebug view

res->free()
var_dump(res) <-- Warning on accessing free'd resource is gone

b) 

res->free();
var_dump(res->lengths) <-- Notice
var_dump(res)          <-- Warning gone

In sum: user gets less hints about his, well, "why are you doing that"-code.

c)

res->free();
res->free();           <-- Fatal

Application that used to work now throws fatal



Please, note that I am not saying no to fixing the var_dump() issue. Trying to explain the side effects of the proposed patch and asking what PHP version would qualify for such a change.
 [2013-01-30 12:56 UTC] dev at pp3345 dot net
Hello,

I've also experienced this bug in the past, using reflection on a freed resource. 
Are there any news on when the bug fix will be included in PHP? I think it 
wouldn't be a problem to include it in the next PHP 5.4/5.3 release since a ton of 
warnings isn't intended behavior. At least it should be in PHP 5.5.
 [2013-05-08 06:20 UTC] hugh dot messenger at gmail dot com
Just wondering if anyone has given this any thought recently?  It's been 
absolutely crippling my xdebug usage since upgrading to 5.4.14 a month ago.  I'd 
vote for including it in the next release of 5.4, given that as far as I can tell, 
most of the world is only just now starting to move from 5.3 to 5.4 as their 
minimum requirement / standard development version, so punting this till 5.5 is 
going to mean a long time for us work-a-day application developers having to deal 
with page upon page upon page of "can't fetch result" and "property access" 
warnings on xdebug sessions.  Or at the very least, make it a notice instead of a 
warning.  My $0.02.
 [2013-07-19 12:35 UTC] suchy63 at hotmail dot com
I'm experiencing this problem as well, both in 5.4 and 5.5, and it's very problematic. It makes it impossible for me to upgrade past 5.3. Our application has a custom error handler which throws an exception if error is below the reporting level. I an unable to step over the code after a breakpoint. The error handler is triggered and I am booted to the error page after an uncaught exception.
 [2014-02-28 03:34 UTC] exsysemchina at gmail dot com
Please fix this bug as soon as possible, otherwise debugging is painful with XDebug when fighting with MYSQLi.
 [2014-02-28 08:20 UTC] hugh dot messenger at gmail dot com
Pretty please can someone take a look at this?  It's still making it almost impossible to xdebug anything that involves MySQLi.
 [2015-01-16 08:57 UTC] hans dot puac at gmail dot com
This Problem still exists in different PHP-Versions.
I got it in 5.5.9 and 5.6.3 with XAMPP on Windows 7.
Please fix this bug!

And here a little workaround for all developer who want to use xDebug now.
function free_result_fix(&$rs){
  $out = mysqli_free_result($rs);
  $rs = null;
  return $out;
}

Replace every mysqli_free_result with the free_result_fix and xDebug will work :-)
 [2015-02-20 12:43 UTC] jpauli@php.net
For me, Derick's patch is all right to get merged against 5.5

I PR'ed it at https://github.com/php/php-src/pull/1104

Like ulf says, it will break bad codes reusing the mysqli resource as an object (because we now NULL it, so it's not an object anymore), but the mysqli resource was anyway in a bad state, so for me this is clearly a fix that could get merged.
 [2015-02-21 09:57 UTC] derick@php.net
Ulf said that more than two years ago, and nothing has happened since. I'll be merging this into 7 unless somebody beats me.
 [2015-02-23 13:00 UTC] ghostaldev at gmail dot com
Can anyone confirm whether or not hans dot puac's workaround is effective?

I seem to be having the same issue when debugging PHP 5.5 on Ubuntu (5.5.9-1ubuntu4.5) with xDebug, but assigning null to the result object variable after calling free() on it doesn't seem to solve the problem.

The only obvious difference I can see is that I'm using the object-oriented style.

test.php
--------
<?php

$connection = new mysqli(SOME_HOST, SOME_USER, SOME_PASSWORD, SOME_DATABASE);
$query = 'SELECT some_column FROM some_table';
$q = $connection->query($query, MYSQLI_STORE_RESULT);
$return = $q->fetch_assoc();
$row_count = $q->num_rows;
$q->free();
$q = null;
var_dump($q);
exit;

Output
------
Warning: main(): Couldn't fetch mysqli_result in /vagrant/test/test.php on line 9
Warning: main(): Couldn't fetch mysqli_result in /vagrant/test/test.php on line 9
Warning: main(): Property access is not allowed yet in /vagrant/test/test.php on line 9
Warning: main(): Couldn't fetch mysqli_result in /vagrant/test/test.php on line 9
Warning: main(): Property access is not allowed yet in /vagrant/test/test.php on line 9
Warning: main(): Couldn't fetch mysqli_result in /vagrant/test/test.php on line 9
Warning: main(): Couldn't fetch mysqli_result in /vagrant/test/test.php on line 9
Warning: main(): Property access is not allowed yet in /vagrant/test/test.php on line 9
Warning: main(): Couldn't fetch mysqli_result in /vagrant/test/test.php on line 9
Warning: main(): Property access is not allowed yet in /vagrant/test/test.php on line 9

null
 [2015-03-03 08:08 UTC] hans dot puac at gmail dot com
Hello ghostaldev at gmail dot com,

my workaround is working, but not with the object-oriented style.
But it seems that something in your query is wrong. (Couldn't fetch mysqli_result)

I tried this:
$mysqli = new sqlFix('localhost', 'xxx', 'yyy', 'zzz');
$result = $mysqli->query('SELECT * FROM `user`;');
$return = $result->fetch_assoc();
$row_count = $result->num_rows;
$result->free();
$result = null;

var_dump($result);

And in browser I get a NULL from var_dump.
But I don´t know if that will help when debugging with Xdebug, because, if you debug this line -> $result->free();, it will crash anyway. My workaround is only so helpful because it´s an own function that I´m not jumping in while debugging.
 [2015-03-09 06:45 UTC] stas@php.net
Automatic comment on behalf of jpauli
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f4c96ffcb565c1daa76aa58256e4df6f111f8803
Log: Fix #63486
 [2015-03-09 06:45 UTC] stas@php.net
-Status: Verified +Status: Closed
 [2015-03-09 06:45 UTC] stas@php.net
Automatic comment on behalf of jpauli
Revision: http://git.php.net/?p=php-src.git;a=commit;h=7684d72df8a55f9c23e80091c89818d870d7a108
Log: Fix #63486
 [2015-03-09 06:45 UTC] stas@php.net
Automatic comment on behalf of jpauli
Revision: http://git.php.net/?p=php-src.git;a=commit;h=37ecfdad09767773dfacf478e0c5a66a01f66dca
Log: Fix #63486
 [2015-03-09 09:25 UTC] laruence@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=9af1383a3f9835db99e9b68eb9bcb6a0f341e339
Log: Revert &quot;Fix #63486&quot;
 [2015-03-09 09:25 UTC] laruence@php.net
Automatic comment on behalf of jpauli
Revision: http://git.php.net/?p=php-src.git;a=commit;h=7684d72df8a55f9c23e80091c89818d870d7a108
Log: Fix #63486
 [2015-03-09 09:25 UTC] laruence@php.net
Automatic comment on behalf of jpauli
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f4c96ffcb565c1daa76aa58256e4df6f111f8803
Log: Fix #63486
 [2015-03-09 18:10 UTC] stas@php.net
-Status: Closed +Status: Re-Opened -Assigned To: mysql +Assigned To: laruence
 [2015-03-09 18:10 UTC] stas@php.net
Fix reverted by Xinchen Hui, waiting for comments.
 [2015-03-10 02:55 UTC] laruence@php.net
test fails in all branches, and <jpauli> said, he still wait for someone in mysql to review it then Stas merged it.

thanks
 [2015-03-10 06:03 UTC] stas@php.net
-Assigned To: laruence +Assigned To: mysql
 [2015-06-04 15:47 UTC] loco at andrews dot lv
This issue is still there and is extremely annoying, as xdebug is practically unusable, as it's often impossible to reach a breakpoint due to the state of mysqli_result:

"main(): Couldn't fetch mysqli_result in ...."

error is recorded into the fpm log when setting a breakpoint in PhpStorm, even before a breakpoint could even be reached..
 [2015-10-28 22:38 UTC] php dot net at mellesmoen dot com
I'm seeing this issue as well using:

PHP 5.6.14
Xdebug 2.3.3
MySQL 5.7.9

Though the work around posted by "[2015-01-16 08:57 UTC] hans dot puac at gmail dot com" fixes the issue and allows me to move forward. ;-)
 [2016-07-20 11:39 UTC] davey@php.net
Automatic comment on behalf of jpauli
Revision: http://git.php.net/?p=php-src.git;a=commit;h=37ecfdad09767773dfacf478e0c5a66a01f66dca
Log: Fix #63486
 [2016-07-20 11:39 UTC] davey@php.net
-Status: Re-Opened +Status: Closed
 [2016-07-21 07:25 UTC] davey@php.net
-Status: Closed +Status: Re-Opened
 [2016-07-21 07:25 UTC] davey@php.net
Closed accidentally. Reopening.
 [2017-10-24 05:17 UTC] kalle@php.net
-Status: Re-Opened +Status: Assigned
 [2020-08-16 00:20 UTC] marcelotpcruz at gmail dot com
This is fixed at PHP 7.4.9 (cli) (built: Aug  4 2020 11:52:41) ( ZTS Visual C++ 2017 x64 ).

Probably fixed at Version 7.4.3.

You may check for an int property to see if it's freed:
$result->free();
var_dump(isset($result->current_field));//bool(false)
var_dump($result);//object(mysqli_result)#3 (0) {}
 [2020-10-29 09:46 UTC] nikic@php.net
-Status: Assigned +Status: Closed -Assigned To: mysql +Assigned To: nikic
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Nov 22 18:01:31 2024 UTC