0

Why it stops to work on second $mysqli->prepare($query) statement?

$mysqli = @new mysqli(HOSTNAME, USERNAME, PASSWORD, DATABASE);
...
if ($stmt = $mysqli->prepare($query)) {
    // Code is working fine
    ...
    if ($stmt2 = $mysqli->prepare($query2)) {
        // Code does not work
        ...
    }
}

And work fine with repeated mysqli connection:

$mysqli = @new mysqli(HOSTNAME, USERNAME, PASSWORD, DATABASE);
$mysqli2 = @new mysqli(HOSTNAME, USERNAME, PASSWORD, DATABASE);
...
if ($stmt = $mysqli->prepare($query)) {
    // Code is working fine
    ...
    if ($stmt2 = $mysqli2->prepare($query2)) {
        // Code is working fine
        ...
    }
}

How to avoid repeated mysqli connection for second prepare statement?


Update: As I see the community wants a real example:

db table fruits with data:

CREATE TABLE IF NOT EXISTS `fruits` (
  `id` varchar(8) NOT NULL,
  `group` varchar(8) NOT NULL,
  `name` varchar(250) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

INSERT INTO `fruits` (`id`, `group`, `name`) VALUES
('03E7', '', 'Berries'),
('0618', '03E7', 'blueberry'),
('051B', '03E7', 'raspberry'),
('02AA', '03E7', 'strawberry'),
('035F', '', 'Citrus'),
('07A5', '035F', 'grapefruit'),
('0633', '035F', 'lime'),
('05E1', '', 'Pear');

php script:

<?php

$mysqli = new mysqli('localhost', 'root', 'password', 'test');
//$mysqli2 = new mysqli('localhost', 'root', 'password', 'test');

$query1 = "SELECT id, name FROM fruits WHERE `group`=''";
$query2 = "SELECT name FROM fruits WHERE `group`=?";

$stmt1 = $mysqli->stmt_init();
$stmt2 = $mysqli->stmt_init();
//$stmt2 = $mysqli2->stmt_init();

if($stmt1->prepare($query1)){
    $stmt1->execute();
    $stmt1->bind_result($id, $name1);

    while($stmt1->fetch()){
        echo $name1;

        if($stmt2->prepare($query2)){
            $stmt2->bind_param('s', $group);
            $group = $id;
            $stmt2->execute();
            $stmt2->bind_result($name2);

            echo ':';

            while($stmt2->fetch()){
                echo ' ' . $name2 . ',';
            }
        }

        echo '<br>';
    }
}

?>

Result:

Berries
Citrus
Pear

Expected result:

Berries: blueberry, raspberry, strawberry,
Citrus: grapefruit, lime,
Pear:
Binyamin
  • 7,493
  • 10
  • 60
  • 82

2 Answers2

1

To fix the issue remove

$stmt1 = $mysqli->stmt_init();
$stmt2 = $mysqli->stmt_init();

and add after $stmt1->execute();

$stmt1->store_result();

and replace $stmt1->prepare($query1), $stmt2->prepare($query1) with

$stmt1 = $mysqli->prepare($query1)
$stmt2 = $mysqli->prepare($query2)
Binyamin
  • 7,493
  • 10
  • 60
  • 82
-1

Does your code have the following?

$stmt = $mysqli->stmt_init();
$stmt2 = $mysqli->stmt_init();

Then you can do:

if($stmt->prepare($query)) ...
if($stmt2->prepare($query2)) ...

Please post all of the code so I can see better what is going on.

EDIT: OK, here is my worked example:

Here is my table links with data:

CREATE TABLE IF NOT EXISTS `links` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(32),
  `group` varchar(32),
  `array` int(32),
  PRIMARY KEY (`id`)
) ENGINE=MyISAM;

INSERT INTO `links` (`id`, `name`, `group`, `array`) VALUES
(1, 'link1', '', 1),
(2, 'link1-sub-link1', '1', 1),
(3, 'link1-sub-link2', '1', 1),
(4, 'link2', '', 2),
(5, 'link3', '', 2),
(6, 'link3-sub-link1', '5', 2),
(7, 'link3-sub-link2', '5', 3),
(8, 'link3-sub-link3', '5', 3);

The following php code executes with no errors for me:

<?php
$mysqli = new mysqli("localhost", "root", "password", "things");

$query = "SELECT id, name FROM links WHERE `group`='' ORDER BY array ASC";
$query2 = "SELECT name FROM links WHERE `group`=? ORDER BY array ASC";

$stmt1 = $mysqli->stmt_init();
$stmt2 = $mysqli->stmt_init();
if($stmt1->prepare($query)){
    $stmt1->execute();
    $stmt1->bind_result($id, $name1);
    while($stmt->fetch()){
    echo $name1;
        if($stmt2->prepare($query2)){
            $stmt2->bind_param('s', $group);
            $group = $id;
            $stmt2->execute();
            $stmt2->bind_result($name2);
            while($stmt2->fetch()){
                echo 'related to: ' . $name2 . "\n";
            }
        }
    }
}
?>
Binyamin
  • 7,493
  • 10
  • 60
  • 82
Richard
  • 1,024
  • 1
  • 7
  • 15
  • I tried your suggestion. It stops to work on second `prepare` statement `$stmt2->prepare($query2)`. Any other advice? – Binyamin Jun 18 '12 at 18:24
  • That's odd. Are you sure that $query2 is valid? – Richard Jun 18 '12 at 19:47
  • Both SQL queries are valid. The example with two MySQLi connections `$mysqli` and `$mysqli2` works fine. With one MySQLi connections `$mysqli` it stops on second `prepare` statement and probably has non-object issue, http://stackoverflow.com/questions/11043558/how-to-implement-mysqli-nested-prepared-statements ? – Binyamin Jun 19 '12 at 05:17
  • I just fixed you PHP syntax. And it does not return the excepted result on latest PHP and MySQL. I have updated also my question with full code example so you can test it. – Binyamin Jun 19 '12 at 19:06