views:

77

answers:

2

I use mysqli extension and bind the result to an object:

class Item {
    public $id, $name;
    }
$Item = new Item;
$stmt->bind_result($Item->id, $Item->name);

Every call to $stmt->fetch() will overwrite $Item's properties which became references. If I simply clone the object — these references remain and both instances change simultaneously:

object(Item)#1 (2) {
  ["id"]=>
  &int(1)
  ["name"]=>
  &string(4) "name"
}

So there should be a way to dereference them so clone really makes a copy, not a set of referenced data. Is there a simple, flexible way to retrieve all the data so it's stored as an array of objects? The main problem is how to remove the references: &string.

The only solution I see is to instantiate another object and manually copy all the properties:

$Item2 = new Item;
foreach ($Item as $prop => $val)
    $Item2->$prop = $val;

but this seems to be an overkill: it will copy all properties (including some extra ones which were not actually referenced) which is not necessary, and moreover — is a penalty to the performance.

A: 

If I understand you correctly, you want to fetch the data into objects? MysqlI has a fetch_object method/function: http://www.php.net/manual/en/mysqli-result.fetch-object.php Use it like this:

$foobar = $conn->escape_string($foobar);
$stmt = $conn->query("SELECT * FROM foo WHERE bar = '$foobar'");
while ($item = $stmt->fetch_object("Item")) {
    $items[] = $item;
}
$stmt->close();
jmz
It has, but I'd like to use prepared statements for this :)
o_O Tync
I updated the answer
jmz
Still wont work unfortunately
Mchl
fetch_object() is a method of mysqli_result which unfortunately has nothing to do swith mysqli_stmt
o_O Tync
Oh, yes. So you must use `mysqli_query` or your own cloning solution.
jmz
+1  A: 

You can implement your own __clone() magic function so that it will create an unreferenced' copy of your object. I think it should work.

http://www.php.net/manual/en/language.oop5.cloning.php

<?php

class Item {
  public $id, $name;

  public function __clone() {
    $id = $this->id;
    unset($this->id);
    $this->id = $id;
    $name = $this->name;
    unset($this->name);
    $this->name = $name;
  }
}

$id = 1;
$name = 'o_0 Tync';

$i1 = new Item();
$i1->id = &$id;
$i1->name = &$name;

$i2 = clone $i1;

$id = 2;
$name = 'Mchl';
var_dump($i1,$i2);

Output

object(Item)#1 (2) {
  ["id"]=>
  &int(2)
  ["name"]=>
  &string(4) "Mchl"
}
object(Item)#2 (2) {
  ["id"]=>
  int(1)
  ["name"]=>
  string(8) "o_0 Tync"
}

Ugly as hell, but works...

Mchl
So, there's no known magic which will dereference the properties? :)
o_O Tync
Added some code as example.
Mchl