Skip to content

Commit 4e11c07

Browse files
committed
[PropertyAccess] refactor type checks to remove duplicate logic
and thus improve performance
1 parent 19aa6dc commit 4e11c07

File tree

2 files changed

+31
-50
lines changed

2 files changed

+31
-50
lines changed

src/Symfony/Component/PropertyAccess/PropertyAccessor.php

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,6 @@ public function setValue(&$objectOrArray, $propertyPath, $value)
7575
$objectOrArray = & $propertyValues[$i][self::VALUE];
7676

7777
if ($overwrite) {
78-
if (!is_object($objectOrArray) && !is_array($objectOrArray)) {
79-
throw new UnexpectedTypeException($objectOrArray, 'object or array');
80-
}
81-
8278
$property = $propertyPath->getElement($i);
8379
//$singular = $propertyPath->singulars[$i];
8480
$singular = null;
@@ -108,13 +104,13 @@ public function setValue(&$objectOrArray, $propertyPath, $value)
108104
*/
109105
private function &readPropertiesUntil(&$objectOrArray, PropertyPathInterface $propertyPath, $lastIndex)
110106
{
107+
if (!is_object($objectOrArray) && !is_array($objectOrArray)) {
108+
throw new UnexpectedTypeException($objectOrArray, 'object or array');
109+
}
110+
111111
$propertyValues = array();
112112

113113
for ($i = 0; $i < $lastIndex; ++$i) {
114-
if (!is_object($objectOrArray) && !is_array($objectOrArray)) {
115-
throw new UnexpectedTypeException($objectOrArray, 'object or array');
116-
}
117-
118114
$property = $propertyPath->getElement($i);
119115
$isIndex = $propertyPath->isIndex($i);
120116

@@ -137,6 +133,11 @@ private function &readPropertiesUntil(&$objectOrArray, PropertyPathInterface $pr
137133

138134
$objectOrArray = & $propertyValue[self::VALUE];
139135

136+
// the final value of the path must not be validated
137+
if ($i + 1 < $propertyPath->getLength() && !is_object($objectOrArray) && !is_array($objectOrArray)) {
138+
throw new UnexpectedTypeException($objectOrArray, 'object or array');
139+
}
140+
140141
$propertyValues[] = & $propertyValue;
141142
}
142143

src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php

Lines changed: 22 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,20 @@ protected function setUp()
2929
$this->propertyAccessor = new PropertyAccessor();
3030
}
3131

32+
public function getPathsWithUnexpectedType()
33+
{
34+
return array(
35+
array('', 'foobar'),
36+
array('foo', 'foobar'),
37+
array(null, 'foobar'),
38+
array(123, 'foobar'),
39+
array((object) array('prop' => null), 'prop.foobar'),
40+
array((object) array('prop' => (object) array('subProp' => null)), 'prop.subProp.foobar'),
41+
array(array('index' => null), '[index][foobar]'),
42+
array(array('index' => array('subIndex' => null)), '[index][subIndex][foobar]'),
43+
);
44+
}
45+
3246
public function testGetValueReadsArray()
3347
{
3448
$array = array('firstName' => 'Bernhard');
@@ -198,27 +212,13 @@ public function testGetValueThrowsExceptionIfPropertyDoesNotExist()
198212
}
199213

200214
/**
215+
* @dataProvider getPathsWithUnexpectedType
201216
* @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException
217+
* @expectedExceptionMessage Expected argument of type "object or array"
202218
*/
203-
public function testGetValueThrowsExceptionIfNotObjectOrArray()
204-
{
205-
$this->propertyAccessor->getValue('baz', 'foobar');
206-
}
207-
208-
/**
209-
* @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException
210-
*/
211-
public function testGetValueThrowsExceptionIfNull()
219+
public function testGetValueThrowsExceptionIfNotObjectOrArray($objectOrArray, $path)
212220
{
213-
$this->propertyAccessor->getValue(null, 'foobar');
214-
}
215-
216-
/**
217-
* @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException
218-
*/
219-
public function testGetValueThrowsExceptionIfEmpty()
220-
{
221-
$this->propertyAccessor->getValue('', 'foobar');
221+
$this->propertyAccessor->getValue($objectOrArray, $path);
222222
}
223223

224224
public function testGetValueWhenArrayValueIsNull()
@@ -311,33 +311,13 @@ public function testSetValueThrowsExceptionIfGetterIsNotPublic()
311311
}
312312

313313
/**
314+
* @dataProvider getPathsWithUnexpectedType
314315
* @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException
316+
* @expectedExceptionMessage Expected argument of type "object or array"
315317
*/
316-
public function testSetValueThrowsExceptionIfNotObjectOrArray()
318+
public function testSetValueThrowsExceptionIfNotObjectOrArray($objectOrArray, $path)
317319
{
318-
$value = 'baz';
319-
320-
$this->propertyAccessor->setValue($value, 'foobar', 'bam');
321-
}
322-
323-
/**
324-
* @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException
325-
*/
326-
public function testSetValueThrowsExceptionIfNull()
327-
{
328-
$value = null;
329-
330-
$this->propertyAccessor->setValue($value, 'foobar', 'bam');
331-
}
332-
333-
/**
334-
* @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException
335-
*/
336-
public function testSetValueThrowsExceptionIfEmpty()
337-
{
338-
$value = '';
339-
340-
$this->propertyAccessor->setValue($value, 'foobar', 'bam');
320+
$this->propertyAccessor->setValue($objectOrArray, $path, 'value');
341321
}
342322

343323
/**

0 commit comments

Comments
 (0)