php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #42689 Cannot bind parameter to a dimensional value within a foreach loop
Submitted: 2007-09-17 22:26 UTC Modified: 2008-03-25 18:43 UTC
Votes:5
Avg. Score:4.2 ± 1.6
Reproduced:3 of 4 (75.0%)
Same Version:2 (66.7%)
Same OS:1 (33.3%)
From: evangun2001 at yahoo dot fr Assigned: andrey (profile)
Status: Not a bug Package: MySQLi related
PHP Version: 5CVS-2007-09-17 (CVS) OS: windows
Private report: No CVE-ID: None
 [2007-09-17 22:26 UTC] evangun2001 at yahoo dot fr
Description:
------------
Hello,

As you can see in the code below, binding to $value['id'] will not work because $value is a variable generated by the foreach loop. Using a dimensional variable as a parameter causes no bugs outside a foreach loop, so I'm pretty sure it really is a bug.

$arr = array(array('id' => 1));
$stmt = $dbh -> prepare('SELECT member_login FROM members WHERE member_id = ?;');
$stmt -> bind_param('i', $value['id']);

foreach($arr as $value){
	
	echo $value['id'];	//this will output 1 as expected
	
	$stmt -> execute();
	$stmt -> bind_result($login);
	while($stmt -> fetch()){
		echo $login;	//this will output nothing
	}
}

Reproduce code:
---------------
The code I've given in description pretty much says it all !
For a quick and global understanding of the situation, I've also put a summary of what works, what does not work, and the workaround I've been using so far. Check it here :

http://trombiaudencia2.free.fr/bug.txt

Actual result:
--------------
Just to let you know, in my application, the real bind_param line looked like :

$stmt -> bind_param('si', $_POST['members'][$value['id']]['login'], $value['id']);

and in that case, php told me :
Fatal error: Only variables can be passed by reference in E:\Program Files\EasyPHP\www\create_quiz_ajaxrequests.php on line 368

which is due to the second parameter, the first one does not create any warning at all. Strange, because you'll see that in the simplified example I've given above, no error message is displayed at all.

I use loops all the time so to me, it's reeaaally a down side for MySQLi not to be able to bind parameters. I have been using PDO for a while and heard MySQLi had better performances, but this kinda cools me down :( Maybe I'll wait a bit until this bug is fixed before I migrate to MySQLi.

Thank you very much !!
Evangun

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-09-19 11:04 UTC] uwendel at mysql dot com
Can you tell me what MySQL and PHP versions you're using? Is it really a CVS version/development snapshot that you're using?

Thanks!
Ulf
 [2007-09-19 14:37 UTC] evangun2001 at yahoo dot fr
Hello,
I've run the tests on 5.2.0, 5.2.4 and CVS, MySQL 5.0.27.
Same results each time.
By the way, just to let you know, the CVS version seems unstable with my full MySQLi script (more complex than what I've shown you), whereas it works with 5.2.4.
Thanks
 [2007-10-26 12:21 UTC] c dot glaab at web dot de
Hi there,

i don't think it's a bug.

you're foreach creates a new array ($value), so the reference from bind_result will be lost.
 [2008-02-05 01:21 UTC] cool_lim_lp at yahoo dot com dot sg
there is a problem with your code.

you're binding to a $value array that does not exist outside the foreach loop. so in reality, you're binding to  a NULL value. and of course, when you executed the statement, no result will match, hence output nothing.

it 's not a bug.
 [2008-02-05 17:25 UTC] evangun2001 at yahoo dot fr
About the 2 last comments : please read the details I gave in the link I provided. You'll understand something goes wrong indeed, the function works half the way it should. Call it a bug or not, as you wish.
 [2008-03-25 18:43 UTC] andrey@php.net
Bogus issue. In the test case you have this 

$stmt -> bind_param('i', $value['id']);
foreach($arr as $value){
	echo $value['id'];	//this will output 1 as expected

Which is equivalent to the following example :

andrey@whirlpool:~/dev/vanilla/php5_3> ./php -r '
$value["id"] = 2;
var_dump($value);
$arr = array(1, 2, 3);
var_dump($arr);
foreach ($arr as $value) {
  var_dump($value);
}
var_dump($value);'
array(1) {
  ["id"]=>
  int(2)
}
array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
}
int(1)
int(2)
int(3)
int(3)
----------------

What you do is you overwrite $value, the fetch works in the background and fetches in what $value['id'] used to be (just a NULL zval). However, your foreach uses $value for iterating the values, thus you get 1 for the first (and last) iteration.
 
PHP Copyright © 2001-2022 The PHP Group
All rights reserved.
Last updated: Wed Jul 06 00:05:46 2022 UTC