4.3. Entity-Attribute-Value (EAV)
The Entity–attribute–value (EAV) pattern in order to implement EAV model with PHP.
4.3.1. Purpose
The Entity–attribute–value (EAV) model is a data model to describe entities where the number of attributes (properties, parameters) that can be used to describe them is potentially vast, but the number that will actually apply to a given entity is relatively modest.
4.3.2. UML Diagram
4.3.3. Code
You can also find this code on GitHub
Entity.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\More\EAV;
6
7use SplObjectStorage;
8
9class Entity implements \Stringable
10{
11 /**
12 * @var SplObjectStorage<Value,Value>
13 */
14 private $values;
15
16 /**
17 * @param Value[] $values
18 */
19 public function __construct(private string $name, array $values)
20 {
21 $this->values = new SplObjectStorage();
22
23 foreach ($values as $value) {
24 $this->values->attach($value);
25 }
26 }
27
28 public function __toString(): string
29 {
30 $text = [$this->name];
31
32 foreach ($this->values as $value) {
33 $text[] = (string) $value;
34 }
35
36 return join(', ', $text);
37 }
38}
Attribute.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\More\EAV;
6
7use SplObjectStorage;
8
9class Attribute implements \Stringable
10{
11 private SplObjectStorage $values;
12
13 public function __construct(private string $name)
14 {
15 $this->values = new SplObjectStorage();
16 }
17
18 public function addValue(Value $value): void
19 {
20 $this->values->attach($value);
21 }
22
23 public function getValues(): SplObjectStorage
24 {
25 return $this->values;
26 }
27
28 public function __toString(): string
29 {
30 return $this->name;
31 }
32}
Value.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\More\EAV;
6
7class Value implements \Stringable
8{
9 public function __construct(private Attribute $attribute, private string $name)
10 {
11 $attribute->addValue($this);
12 }
13
14 public function __toString(): string
15 {
16 return sprintf('%s: %s', (string) $this->attribute, $this->name);
17 }
18}
4.3.4. Test
Tests/EAVTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\More\EAV\Tests;
6
7use DesignPatterns\More\EAV\Attribute;
8use DesignPatterns\More\EAV\Entity;
9use DesignPatterns\More\EAV\Value;
10use PHPUnit\Framework\TestCase;
11
12class EAVTest extends TestCase
13{
14 public function testCanAddAttributeToEntity(): void
15 {
16 $colorAttribute = new Attribute('color');
17 $colorSilver = new Value($colorAttribute, 'silver');
18 $colorBlack = new Value($colorAttribute, 'black');
19
20 $memoryAttribute = new Attribute('memory');
21 $memory8Gb = new Value($memoryAttribute, '8GB');
22
23 $entity = new Entity('MacBook Pro', [$colorSilver, $colorBlack, $memory8Gb]);
24
25 $this->assertEquals('MacBook Pro, color: silver, color: black, memory: 8GB', (string) $entity);
26 }
27}