php-extended/php-reifier-object

A library that implements the php-extended/php-reifier-interface library


README

A library that implements the php-extended/php-reifier-interface library.

coverage build status

Installation

The installation of this library is made via composer and the autoloading of all classes of this library is made through their autoloader.

  • Download composer.phar from their website.
  • Then run the following command to install this library as dependency :
  • php composer.phar php-extended/php-reifier-object ^7

Basic Usage

You may use this library the following way :


use PhpExtended\Reifier\Reifier;

class Matrix
{
	
	/**
	 * @var integer[][][]
	 */
	protected $_3dm;
	
	/**
	 * @param integer[][][] $_3dm
	 */
	public function __construct(array $_3dm)
	{
		$this->_3dm = $_3dm;
	}
	
	/**
	 * @return integer[][][]
	 */
	public function get3dm() : array
	{
		return $this->_3dm;
	}
	
}

$collectionFactory = new Reifier();

$matrix = [
	[
		[1, 2, 3],
		[4, 5, 6],
		[7, 8, 9],
	],
	[
		[11, 12, 13],
		[14, 15, 16],
		[17, 18, 19],
	],
];

$this->_config->setIterableInnerTypes(TestMatrixBuildableObject::class, ['_3dm'], 'array');
$this->_config->setIterableInnerTypes(TestMatrixBuildableObject::class, ['_3dm[]'], 'array');
$this->_config->setIterableInnerTypes(TestMatrixBuildableObject::class, ['_3dm[][]'], 'int');

$matrixObject = $reifier->reify(Matrix::class, ['_3dm' => $matrix]);
// $matrixObject instanceof Matrix

Or :


use PhpExtended\Reifier\Reifier;
use PhpExtended\Reifier\ReifierConfiguration;


class RecursiveLvThreeObject
{
	
	/**
	 * @var integer
	 */
	protected $_index;
	
	/**
	 * @param integer $index
	 */
	public function __construct(int $index = 0)
	{
		$this->_index = $index;
	}
	
	/**
	 * @param integer $index
	 */
	public function setIndex(int $index) : void
	{
		$this->_index = $index;
	}
	
	/**
	 * @return integer
	 */
	public function getIndex() : int
	{
		return $this->_index;
	}
	
}


class RecursiveLvTwoObject
{
	/**
	 * @var RecursiveLvThreeObject
	 */
	protected $_lv3;
	
	/**
	 * @var \Iterator<RecursiveLvThreeObject>
	 */
	protected $_lv3s;
	
	/**
	 * @var RecursiveLvThreeObject[]
	 */
	protected $_arrlv3s;
	
	/**
	 * Constructor.
	 *
	 * @param RecursiveLvThreeObject $lv3
	 * @param \Iterator<RecursiveLvThreeObject> $lv3s
	 * @param RecursiveLvThreeObject[] $arrlv3s
	 */
	public function __construct(RecursiveLvThreeObject $lv3, Iterator $lv3s, array $arrlv3s)
	{
		$this->_lv3 = $lv3;
		$this->_lv3s = $lv3s;
		$this->_arrlv3s = $arrlv3s;
	}
	
	/**
	 * The lv3.
	 *
	 * @return RecursiveLvThreeObject
	 */
	public function getLv3() : RecursiveLvThreeObject
	{
		return $this->_lv3;
	}
	
	/**
	 * The lv3s.
	 *
	 * @return \Iterator<RecursiveLvThreeObject>
	 */
	public function getLv3s() : Iterator
	{
		return $this->_lv3s;
	}
	
	/**
	 * The other lv3s.
	 * 
	 * @return RecursiveLvThreeObject[]
	 */
	public function getArrLv3s() : array
	{
		return $this->_arrlv3s;
	}
	
}

class RecursiveLvOneObject
{
	
	/**
	 * @var ?RecursiveLvTwoObject
	 */
	protected $_lv2;
	
	/**
	 * @var \Iterator<RecursiveLvTwoObject>
	 */
	protected $_lv2s;
	
	/**
	 * @var RecursiveLvTwoObject[]
	 */
	protected $_arrlv2s;
	
	/**
	 * Constructor.
	 * 
	 * @param ?RecursiveLvTwoObject $lv2
	 * @param \Iterator<RecursiveLvTwoObject> $lv2s
	 * @param RecursiveLvTwoObject[] $arrlv2s
	 */
	public function __construct(?RecursiveLvTwoObject $lv2, Iterator $lv2s, array $arrlv2s)
	{
		$this->_lv2 = $lv2;
		$this->_lv2s = $lv2s;
		$this->_arrlv2s = $arrlv2s;
	}
	
	/**
	 * The lv2.
	 * 
	 * @return ?RecursiveLvTwoObject
	 */
	public function getLv2() : ?RecursiveLvTwoObject
	{
		return $this->_lv2;
	}
	
	/**
	 * The lv2s.
	 * 
	 * @return \Iterator<RecursiveLvTwoObject>
	 */
	public function getLv2s() : Iterator
	{
		return $this->_lv2s;
	}
	
	/**
	 * @return RecursiveLvTwoObject[]
	 */
	public function getArrlv2s() : array
	{
		return $this->_arrlv2s;
	}
	
}

$data = [
	'lv2' => [
		'lv3' => [
			'index' => 1,
		],
		'lv3s' => [
			[
				'index' => 2,
			],
			[
				'index' => 3,
			],
		],
		'arrlv3s' => [
			[
				'index' => 4,
			],
			[
				'index' => 5,
			],
		],
	],
	'lv2s' => [
		[
			'lv3' => [
				'index' => 6,
			],
			'lv3s' => [
				[
					'index' => 7,
				],
				[
					'index' => 8,
				],
			],
			'arrlv3s' => [
				[
					'index' => 9,
				],
				[
					'index' => 10,
				],
			],
		],
		[
			'lv3' => [
				'index' => 11,
			],
			'lv3s' => [
				[
					'index' => 12,
				],
				[
					'index' => 13,
				],
			],
			'arrlv3s' => [
				[
					'index' => 14,
				],
				[
					'index' => 15,
				],
			],
		],
	],
	'arrlv2s' => [
		[
			'lv3' => [
				'index' => 16,
			],
			'lv3s' => [
				[
					'index' => 17,
				],
				[
					'index' => 18,
				],
			],
			'arrlv3s' => [
				[
					'index' => 19,
				],
				[
					'index' => 20,
				],
			],
		],
		[
			'lv3' => [
				'index' => 21,
			],
			'lv3s' => [
				[
					'index' => 22,
				],
				[
					'index' => 23,
				],
			],
			'arrlv3s' => [
				[
					'index' => 24,
				],
				[
					'index' => 25,
				],
			],
		],
	],
];

$config = new ReifierConfiguration();
$config->setIterableInnerTypes(RecursiveLvOneObject::class, ['lv2s', 'arrlv2s'], RecursiveLvTwoObject::class);
$config->setIterableInnerTypes(RecursiveLvTwoObject::class, ['lv3s', 'arrlv3s'], RecursiveLvThreeObject::class);

$structure = $reifier->reify(RecursiveLvOneObject::class, $data);
// $structure instanceof RecursiveLvOneObject

This class also suports polymorphic reification structures :


class Point
{
	
	/**
	 * 
	 * @var float
	 */
	protected $x;
	
	/*
	 *
	 * @var float
	 */
	protected $y;
	
	public function __construct(float $x, float $y)
	{
		$this->x = $x;
		$this->y = $y;
	}
	
}

interface ShapeInterface
{
	public function getCoordinates() : array;
}

class Triangle implements ShapeInterface
{
	
	public $a;
	public $b;
	public $c;
	
	public function __construct(Point $a, Point $b, Point $c)
	{
		$this->a = $a;
		$this->b = $b;
		$this->c = $c;
	}
	
	public function getCoordinates() : array
	{
		return [$this->a, $this->b, $this->c];
	}
	
}

class Square implements ShapeInterface
{
	
	public $a; // top left
	public $b; // bottom right
	
	public function __construct(Point $a, Point $b)
	{
		$this->a = $a;
		$this->b = $b;
	}
	
	public function getCoordinates() : array
	{
		return [$this->a, $this->b];
	}
	
}

class MultiShape
{
	
	public $shapes;
	
	public function __construct(array $shapes)
	{
		$this->shapes = $shapes;
	}
	
}

$data = [
	'shapes' => [
		[
			'clazz' => 'tri',
			'a' => [0, 1],
			'b' => [1, 2],
			'c' => [0, 3],
		],
		[
			'clazz' => 'sq',
			'a' => [2, 0],
			'b' => [0, 2],
		],
	],
];

$config = new ReifierConfiguration();
$config->setIterableInnerTypes(MultiShape::class, ['shapes'], ShapeInterface::class);
$config->addPolymorphism(ShapeInterface::class, 'clazz', 'tri', Triangle::class);
$config->addPolymorphism(ShapeInterface::class, 'clazz', 'sq', Square::class);

// if the 'clazz' field is not present in implementations, like here, add :
$config->addIgnoreExcessFields(Triangle::class, 'clazz');
$config->addIgnoreExcessFields(Square::class, 'clazz');

$structure = $reifier->reify(MultiShape::class, $data);
// $structure instanceof MultiShape

More examples of reifiable structures and reifiying biehavior in the test classes.

License

MIT (See license file).