-
-
Save polonskiy/f1d9c27e9ea67ce9a329 to your computer and use it in GitHub Desktop.
array_of realization in php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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