Skip to content

Instantly share code, notes, and snippets.

@ralphschindler
Last active November 22, 2020 04:03
Show Gist options
  • Save ralphschindler/5405695 to your computer and use it in GitHub Desktop.
Save ralphschindler/5405695 to your computer and use it in GitHub Desktop.
A aop based Unit Of Work prototype/example with minimal code
<?php
/**
* Foo is an Entity
*/
class Foo
{
protected $bar = 'original';
public function getBar()
{
return $this->bar;
}
public function setBar($bar)
{
$this->bar = $bar;
}
}
/**
* Unit of work that requires and consumes AopJoinPoint
*
*/
class UnitOfWork
{
protected $data = array();
public function register($class)
{
// setup aop
aop_add_before("write $class->*", array($this, 'track'));
}
public function track(AopJoinPoint $p)
{
$obj = $p->getObject();
$objHash = spl_object_hash($obj);
if (!isset($this->data[$objHash])) {
$this->data[$objHash] = array(
'dirty' => array(),
'values' => array(),
'obj' => $obj
);
}
$propName = $p->getPropertyName();
$objRef = new ReflectionObject($obj);
$pRef = $objRef->getProperty($propName);
$pRef->setAccessible(true);
$this->data[$objHash]['dirty'][$propName] = true;
if (!isset($this->data[$objHash]['values'][$propName])) {
$this->data[$objHash]['values'][$propName] = $pRef->getValue($obj);
}
}
public function renderDirties()
{
foreach ($this->data as $hash => $objData) {
$obj = $objData['obj'];
echo 'For object type ' . get_class($obj) . " [hash: $hash]" . PHP_EOL;
$refl = new ReflectionObject($obj);
foreach ($objData['dirty'] as $prop => $isDirty) {
$propRefl = $refl->getProperty($prop);
$propRefl->setAccessible(true);
echo ' "' . $prop . '" value changed: ' . $objData['values'][$prop] . ' -> ' . $propRefl->getValue($obj);
}
}
}
}
$uow = new UnitOfWork;
$uow->register('Foo');
// do something with your entity
$f = new Foo;
$f->setBar('bam');
// figure out what happened in our entities state:
$uow->renderDirties();
/**
* Output:
*
* For object type Foo [hash: 0000000043455f9600000000597c323d]
* "bar" value changed: original -> bam
*
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment