Skip to content

Commit 6d2d6d0

Browse files
committed
TypedObjectArray merged in TypedArray
1 parent 5163ad1 commit 6d2d6d0

File tree

3 files changed

+129
-2
lines changed

3 files changed

+129
-2
lines changed

array-speed-test-v2.png

86.7 KB
Loading

src/TypedArray.php

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,33 @@ class TypedArray extends ArrayObject
4545
* //correct, only int passed to array.
4646
* $array = new TypedArray('int', [1, 2, 3, 4]);
4747
* $array[] = 5;
48+
*
4849
* //throw InvalidArgumentException.
4950
* $array[] = 'a';
5051
*
5152
* //throw InvalidArgumentException.
5253
* $array = new TypedArray('int', [1, 'a', 3, 4]);
54+
*
55+
* //correct, only Foo class instances passed to array.
56+
* $array = new TypedArray(Foo::class, [
57+
* new Foo(),
58+
* new Foo()
59+
* ]);
60+
*
61+
* $array[] = new Foo();
62+
*
63+
* //throw InvalidArgumentException.
64+
* $array[] = new Bar();
65+
*
66+
* //throw InvalidArgumentException.
67+
* $array = new TypedArray(Foo::class, [
68+
* new Foo(),
69+
* new Bar()
70+
* ]);
5371
* </code></pre>
5472
*
55-
* <b>Note</b>: Allowed types are only <i>array</i>, <i>bool</i>, <i>callable</i>,
56-
* <i>float</i>, <i>int</i>, <i>object</i> and <i>string</i>.
73+
* <b>Note</b>: Allowed types are <i>array</i>, <i>bool</i>, <i>callable</i>,
74+
* <i>float</i>, <i>int</i>, <i>object</i>, <i>string</i> and all existing classes.
5775
*
5876
* @param string $type Type for values inside array.
5977
* @param array $array Optional, if you wish initialize object with values.
@@ -64,6 +82,16 @@ class TypedArray extends ArrayObject
6482
*/
6583
public function __construct(string $type, array $array = [])
6684
{
85+
if (class_exists($type)) {
86+
//I like lambda functions ;)
87+
$this->allowedTypes[$type] = function ($a) use ($type) {
88+
if ($a instanceof $type) {
89+
return true;
90+
}
91+
return false;
92+
};
93+
}
94+
6795
//single class, multi type support :)
6896
if (!isset($this->allowedTypes[$type])) {
6997
throw new InvalidArgumentException(__CLASS__.': '.$type.' type passed to '.__METHOD__.' not supported.');
@@ -96,6 +124,12 @@ public function __construct(string $type, array $array = [])
96124
*/
97125
public function offsetSet($index, $newval)
98126
{
127+
if ($newval instanceof $this->type) {
128+
parent::offsetSet($index, $newval);
129+
130+
return;
131+
}
132+
99133
if ($this->allowedTypes[$this->type]($newval)) {
100134
parent::offsetSet($index, $newval);
101135

tests/TypedArrayTest.php

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,4 +287,97 @@ public function testIteratorClass()
287287
$this->assertEquals($value, $arrayAsParam[$key]);
288288
}
289289
}
290+
291+
/**
292+
* Test new instance with not existent class.
293+
*
294+
* @expectedException InvalidArgumentException
295+
*/
296+
public function testCreateInstanceWithNotExistentClass()
297+
{
298+
$this->assertInstanceOf(TypedArray::class, (new TypedArray(ArrayBadObject::class)));
299+
}
300+
301+
/**
302+
* Test new instance passing right typed array to constructor.
303+
*/
304+
public function testCreateInstanceWithRightObjectTypedArray()
305+
{
306+
$this->assertInstanceOf(
307+
TypedArray::class,
308+
(
309+
new TypedArray(
310+
ArrayObject::class,
311+
[
312+
new ArrayObject([1, 2, 3]),
313+
new ArrayObject([1.1, 2.2, 3.3]),
314+
new ArrayObject(['a', 'b', 'c']),
315+
]
316+
)
317+
)
318+
);
319+
}
320+
321+
/**
322+
* Test new instance passing array with invalid element to constructor.
323+
*
324+
* @expectedException InvalidArgumentException
325+
*/
326+
public function testCreateInstanceWithWrongObjectTypedArray()
327+
{
328+
$this->assertInstanceOf(
329+
TypedArray::class,
330+
(
331+
new TypedArray(
332+
ArrayObject::class,
333+
[
334+
new ArrayObject([1, 2, 3]),
335+
new ArrayObject([1.1, 2.2, 3.3]),
336+
new SplStack(),
337+
]
338+
)
339+
)
340+
);
341+
}
342+
343+
/**
344+
* Test assign to array a right typed value.
345+
*/
346+
public function testAssignrRightTypedObjectValueToArray()
347+
{
348+
$array = new TypedArray(ArrayObject::class);
349+
$array[] = new ArrayObject([1, 2, 3]);
350+
351+
$this->assertEquals(1, $array->count());
352+
}
353+
354+
/**
355+
* Test assign to array a wrong typed value.
356+
*
357+
* @expectedException InvalidArgumentException
358+
*/
359+
public function testAssignWrongTypedObjectValueToArray()
360+
{
361+
$array = new TypedArray(ArrayObject::class);
362+
$array[] = new SplStack();
363+
}
364+
365+
/**
366+
* Test iterator.
367+
*/
368+
public function testObjectIteratorClass()
369+
{
370+
$arrayAsParam = [
371+
new ArrayObject([1, 2, 3]),
372+
new ArrayObject(['1', '2', '3']),
373+
new ArrayObject([true, false, null]),
374+
new ArrayObject([1.0, 2.0, 3.0])
375+
];
376+
377+
$array = new TypedArray(ArrayObject::class, $arrayAsParam);
378+
379+
foreach ($array as $key => $value) {
380+
$this->assertEquals($value, $arrayAsParam[$key]);
381+
}
382+
}
290383
}

0 commit comments

Comments
 (0)