JavaのGenericsっぽいのをPHPで作ってみた

JavaGenericsっぽいのをPHPでも使いたいなーと思って作ってみた。
PHPでは配列のKeyにObjectを指定出来ないから、とりあえずValueだけにした。
32bitで表現出来る数値と64bit必要な数値を共存させるならfloatに合わせる必要あり。
 
PHPの配列、使いづらい。
Keyがないだけで"Notice: Undefined offset"が出たり。
最近PHPで多次元配列を多様するのをためらうようになった。
 

ソース

GenericsArray.php
<?php

class GenericsArray implements ArrayAccess, IteratorAggregate, Countable
{
	private $arr = array();
	private $type = null;
	private static $native_types = array(
		"bool",
		"int",
		"float",
		"string",
		"array",
		"resource"
	);

	public function __construct($type)
	{
		if (!(in_array($type, self::$native_types) || class_exists($type))) {
			throw new Exception("class is not found");
		}
		$this->type = $type;
	}

	// ArrayAccess

	public function offsetSet($offset, $value)
	{
		if ($this->type!=self::getClass($value)) {
			throw new Exception("value is not ".$this->type);
		}
		if (is_null($offset)) {
			$this->arr[] = $value;
		} else {
			$this->arr[$offset] = $value;
		}
	}

	public function offsetExists($offset)
	{
		return isset($this->arr[$offset]);
	}

	public function offsetUnset($offset)
	{
		unset($this->arr[$offset]);
	}

	public function offsetGet($offset)
	{
		return isset($this->arr[$offset]) ? $this->arr[$offset] : null;
	}

	// IteratorAggregate

	public function getIterator()
	{
		return new ArrayIterator($this->arr);
	}

	// Countable

	public function count()
	{
		return count($this->arr);
	}

	// Util

	public static function getClass($obj)
	{
		if (is_object($obj)) {
			return get_class($obj);
		} else {
			foreach (self::$native_types as $type) {
				$method = "is_".$type;
				if ($method($obj)) {
					return $type;
				}
			}
		}
		return null;
	}
}

 

test.php
<?php
require_once 'GenericsArray.php';

$arr = new GenericsArray("string");
$arr[] = "aaa";
$arr[] = "bbb";
$arr[] = "ccc";

printf("count: %d\n", count($arr));
foreach ($arr as $k=>$v) {
	printf("%s: %s\n", $k, $v);
}

class TestClass{}
$arr = new GenericsArray("TestClass");
$arr[] = new TestClass();
$arr[] = new TestClass();
$arr[] = new TestClass();

$arr = new GenericsArray("float");
$arr[] = (float)123456;
$arr[] = 1234567890123456;