Skip to content

Instantly share code, notes, and snippets.

@polonskiy
Forked from bernik/array_of_example.php
Last active January 21, 2016 09:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save polonskiy/f1d9c27e9ea67ce9a329 to your computer and use it in GitHub Desktop.
Save polonskiy/f1d9c27e9ea67ce9a329 to your computer and use it in GitHub Desktop.
array_of realization in php
<?php
class User {
public
$name,
$lastName;
public function __construct($name, $lastName) {
$this->name = $name;
$this->lastName = $lastName;
}
}
function array_of($type, $input = []) {
$class = "ArrayOf$type";
if (!class_exists($class)) {
eval("class $class extends ArrayOf {}");
}
return new $class($type, $input);
}
abstract class ArrayOf extends ArrayObject {
private $type;
public function __construct ($type, $input = [], $flags = 0, $iterator_class = "ArrayIterator") {
$this->type = $type;
if (!is_array($input)) $input = [$input];
foreach ($input as $k => $v) $this->offsetSet($k, $v);
parent::__construct($input, $flags, $iterator_class);
}
public function offsetSet ($k, $v) {
if ($v instanceof $this->type) return parent::offsetSet($k, $v);
throw new InvalidArgumentException("Expected $this->type");
}
}
function test_typehint_function() {
$arr = array_of ('user');
$arr[] = new User('foo', 'last foo');
$arr[] = new User('bar', 'last bar');
function names (ArrayOfUser $users) { return array_map(function ($u) { return $u->name; }, $users->getArrayCopy()); }
assert(names($arr) === ['foo', 'bar']);
}
function test_add_array_later() {
$arr = array_of ('user');
$arr[] = new User('foo', 'last foo');
$arr[] = new User('bar', 'last bar');
foreach ($arr as $v) assert($v instanceof User);
}
function test_add_array() {
$arr2 = array_of ('user', [
new User(1,1),
new User(2,2)]);
foreach ($arr2 as $v) assert($v instanceof User);
}
function test_add_bad_array() {
try {
array_of('user', [new stdclass]);
assert(false);
} catch (InvalidArgumentException $e) {
assert(true);
}
}
function test_add_one_bad_item() {
try {
array_of('user', new stdclass);
assert(false);
} catch (InvalidArgumentException $e) {
assert(true);
}
}
function test_add_one_item() {
$arr = array_of('user', new User(1,1));
assert(count($arr) === 1);
assert($arr[0] == new User(1,1));
}
function test_typehint_closure() {
class Foo {};
$func = function(ArrayOfFoo $a) {};
$func(array_of('Foo', [new Foo, new Foo]));
assert(true);
}
function test_typehint_bad_type() {
$func = function(ArrayOfFoo $a) {};
try {
$func(array_of('Foo', [new stdclass, new stdclass]));
assert(false);
} catch (InvalidArgumentException $e) {
assert(true);
}
}
foreach(preg_grep('#^test#', get_defined_functions()['user']) as $test) {
echo "$test\n";
$test();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment