Skip to content

Commit 2154934

Browse files
committed
PHPC-244: Cannot use object of type Person as array
1 parent f4de8a4 commit 2154934

File tree

2 files changed

+166
-0
lines changed

2 files changed

+166
-0
lines changed

src/bson.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -843,6 +843,7 @@ int bson_to_zval(const unsigned char *data, int data_len, php_phongo_bson_state
843843
MAKE_STD_ZVAL(obj);
844844
object_init_ex(obj, state->odm ? state->odm : state->map.array);
845845
zend_call_method_with_1_params(&obj, NULL, NULL, BSON_UNSERIALIZE_FUNC_NAME, NULL, state->zchild);
846+
SEPARATE_ZVAL(&state->zchild);
846847
zval_dtor(state->zchild);
847848
ZVAL_ZVAL(state->zchild, obj, 1, 1);
848849
}

tests/bson/bson-ods-001.phpt

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
--TEST--
2+
BSON encoding: Encoding data into BSON representation, and BSON into Extended JSON
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"?>
5+
--FILE--
6+
<?php
7+
require_once __DIR__ . "/../utils/basic.inc";
8+
9+
class Address implements BSON\Persistable {
10+
protected $streetAddress;
11+
protected $city;
12+
protected $postalCode;
13+
14+
function __construct($streetAddress, $city, $postalCode) {
15+
$this->streetAddress = $streetAddress;
16+
$this->city = $city;
17+
$this->postalCode = $postalCode;
18+
19+
}
20+
function bsonUnserialize(array $array) {
21+
foreach($array as $k => $v) {
22+
$this->{$k} = $v;
23+
}
24+
25+
return $this;
26+
}
27+
28+
function bsonSerialize() {
29+
return get_object_vars($this);
30+
}
31+
}
32+
33+
class Person implements BSON\Persistable {
34+
protected $_id;
35+
protected $username;
36+
protected $email;
37+
protected $name;
38+
protected $addresses = array();
39+
protected $_lastModified;
40+
protected $_created;
41+
42+
function __construct($username, $email, $name) {
43+
$this->username = $username;
44+
$this->email = $email;
45+
$this->setName($name);
46+
47+
/* Pregenerate our ObjectID */
48+
$this->_id = new BSON\ObjectID();
49+
}
50+
function addAddress(Address $address) {
51+
$this->addresses[] = $address;
52+
}
53+
54+
function bsonUnserialize(array $array) {
55+
$this->__original = $array;
56+
foreach($array as $k => $v) {
57+
$this->{$k} = $v;
58+
}
59+
}
60+
61+
function bsonSerialize() {
62+
$props = get_object_vars($this);
63+
64+
/* If __original doesn't exist, this is a fresh object that needs to be inserted */
65+
if (empty($this->__original)) {
66+
$props["_created"] = new BSON\UTCDatetime(microtime(true) * 1000);
67+
return $props;
68+
}
69+
70+
/* Track the last time this person was updated */
71+
$update = array(
72+
'$currentDate' => array(
73+
"_lastModified" => array('$type' => 'date'),
74+
),
75+
'$set' => array(),
76+
);
77+
/* Otherwise, only pluck out the changes so we don't have to do full object replacement */
78+
foreach($props as $k => $v) {
79+
if (!isset($this->__original[$k])) {
80+
/* A new field -- likely a on-the-fly schema upgrade */
81+
$updated['$set'] = array($k => $v);
82+
}
83+
}
84+
}
85+
86+
function getName() {
87+
return $this->name;
88+
}
89+
function setName($name) {
90+
return $this->name = $name;
91+
}
92+
}
93+
94+
95+
$lair77 = new Person('lair77', '[email protected]', 'Claire Corwin');
96+
$hillardhaven = new Address('4527 Kohler Square Apt. 316', 'Hillardhaven', '02622-5175');
97+
$lair77->addAddress($hillardhaven);
98+
$prudencemouth = new Address('7042 Freida Springs', 'Prudencemouth', '94805');
99+
$lair77->addAddress($prudencemouth);
100+
101+
102+
$tabitha = new Person('tabitha.mohr', '[email protected]', 'Tabitha Lehner');
103+
$konopelskichester = new Address('76650 Mina Pass', 'Konopelskichester', '69679-5471');
104+
$tabitha->addAddress($konopelskichester);
105+
106+
$hartmann = new Person('hartmann', '[email protected]', 'Hartmann Dedrick');
107+
$leannefurt = new Address('151 Delbert Hills Suite 923', 'Leannefurt', '22036');
108+
$hartmann->addAddress($leannefurt);
109+
110+
$ena = new Person('ena', '[email protected]', 'Frida Sanford');
111+
$lawsonport = new Address('3656 Jenifer Field', 'New Lawsonport', '16300');
112+
$ena->addAddress($lawsonport);
113+
114+
115+
$lockman = new Person('cartwright.garland', '[email protected]', 'Alice Carter');
116+
$herminia = new Address('37413 Kailee Spurs', 'East Herminia', '22107');
117+
$lockman->addAddress($herminia);
118+
119+
120+
$dropcoll = new MongoDB\Driver\Command(array("drop" => COLLECTION_NAME));
121+
$query = new MongoDB\Driver\Query(array());
122+
$hartmannFilter = array("username" => "hartmann");
123+
$queryHartmann = new MongoDB\Driver\Query($hartmannFilter);
124+
125+
126+
$bulk = new MongoDB\Driver\BulkWrite;
127+
$bulk->insert($lair77);
128+
$bulk->insert($tabitha);
129+
$bulk->insert($hartmann);
130+
$bulk->insert($ena);
131+
$bulk->insert($lockman);
132+
133+
$m = new MongoDB\Driver\Manager(STANDALONE);
134+
try {
135+
$m->executeCommand(DATABASE_NAME, $dropcoll);
136+
} catch(Exception $e) {}
137+
138+
$m->executeBulkWrite(NS, $bulk);
139+
140+
141+
foreach($m->executeQuery(NS, $query) as $person) {
142+
var_dump($person->getName());
143+
}
144+
145+
echo "-----\n";
146+
147+
$hartmann = $m->executeQuery(NS, $queryHartmann)->toArray()[0];
148+
var_dump($hartmann->getName());
149+
$hartmann->setName("Dr. " . $hartmann->getName());
150+
151+
$retval = $m->executeUpdate(NS, $hartmannFilter, $hartmann);
152+
var_dump($retval->getModifiedCount());
153+
?>
154+
===DONE===
155+
<?php exit(0); ?>
156+
--EXPECT--
157+
string(13) "Claire Corwin"
158+
string(14) "Tabitha Lehner"
159+
string(16) "Hartmann Dedrick"
160+
string(13) "Frida Sanford"
161+
string(12) "Alice Carter"
162+
-----
163+
string(16) "Hartmann Dedrick"
164+
int(1)
165+
===DONE===

0 commit comments

Comments
 (0)