- var_dump: documentation ( source)
<?php
interface ProductRepository
{
public function findReferenceBySku(string $sku): Product;
public function findIdBySku(string $sku): int;
}
class Product
{
public function __construct(
public int $id,
) { }
}
class ProductDatabaseRepository implements ProductRepository
{
public function findReferenceBySku(string $sku): Product
{
$id = $this->findIdBySku($sku);
return $this->getProductReference($id);
}
private function getProductReference(int $id)
{
// check entity manager for existing object
// and generate proxy if not found
return new Product($id);
}
public function findIdBySku(string $sku): int
{
$this->queryDatabase();
return match($sku) {
'sku1' => 1,
};
}
protected function queryDatabase()
{
// note this method is not public
var_dump('query database');
}
}
class ProductCachedRepository implements ProductRepository
{
private array $cachedIds = [];
public function __construct(
private ProductRepository $inner
) {}
public function findReferenceBySku(string $sku): Product
{
// not able to delegate this logic directly to inner class
// (loss of findIdBySku() overridden logic)
//return $this->inner->findReferenceBySku($sku);
// as well not able call decorated method with substitude this
return $this->inner->findReferenceBySku(...)->call($this, $sku);
}
public function findIdBySku(string $sku): int
{
var_dump('check cache');
return $this->cachedIds[$sku]
??= $this->inner->findIdBySku($sku);
}
public function __call($name, $arguments)
{
// all not public methods of inner repository
// which are not declared in current class
// are delegated to inner repository
return (fn() => $this->$name(...$arguments))
->call($this->inner);
}
}
$repository = (new ProductCachedRepository(new ProductDatabaseRepository()));
var_dump('call1', $repository->findReferenceBySku('sku1'));
var_dump('call2', $repository->findReferenceBySku('sku1')); // cache hit expected
var_dump('call2', $repository->findReferenceBySku('sku1')); // cache hit expected