实体-属性-值模式
实体-属性-值模式(EAV)的目标是用 PHP 实现 EAV 模型。
目的
实体-属性-值模型(EAV 模型),是一种描述实体的数据模型。在这种模型中,用于描述实体属性(特性、参数)的数量可能非常多,但实际应用于某个实体的数量却相对较少。
UML 类图

代码
Entity.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| <?php declare(strict_types = 1);
namespace DesignPatterns\Extend\EAV;
use SplObjectStorage;
class Entity {
private $values;
private string $name;
public function __construct(string $name, $values) { $this->values = new SplObjectStorage(); $this->name = $name;
foreach ($values as $value) { $this->values->attach($value); } }
public function __toString(): string { $text = [$this->name];
foreach ($this->values as $value) { $text[] = (string) $value; }
return join(', ', $text); } }
|
Attribute.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <?php declare(strict_types = 1);
namespace DesignPatterns\Extend\EAV;
use SplObjectStorage;
class Attribute { private SplObjectStorage $values; private string $name;
public function __construct(string $name) { $this->values = new SplObjectStorage(); $this->name = $name; }
public function addValue(Value $value) { $this->values->attach($value); }
public function getValues(): SplObjectStorage { return $this->values; }
public function __toString(): string { return $this->name; } }
|
Value.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <?php declare(strict_types = 1);
namespace DesignPatterns\Extend\EAV;
class Value { private Attribute $attribute; private string $name;
public function __construct(Attribute $attribute, string $name) { $this->name = $name; $this->attribute = $attribute;
$attribute->addValue($this); }
public function __toString(): string { return sprintf('%s: %s', (string) $this->attribute, $this->name); } }
|
测试
Tests/EAVTest.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <?php declare(strict_types = 1);
namespace DesignPatterns\Extend\EAV\Tests;
use DesignPatterns\Extend\EAV\Attribute; use DesignPatterns\Extend\EAV\Entity; use DesignPatterns\Extend\EAV\Value; use PHPUnit\Framework\TestCase;
class EAVTest extends TestCase { public function testCanAddAttributeToEntity() { $colorAttribute = new Attribute('color'); $colorSilver = new Value($colorAttribute, 'silver'); $colorBlack = new Value($colorAttribute, 'black');
$memoryAttribute = new Attribute('memory'); $memory8Gb = new Value($memoryAttribute, '8GB');
$entity = new Entity('MacBook Pro', [$colorSilver, $colorBlack, $memory8Gb]);
$this->assertEquals('MacBook Pro, color: silver, color: black, memory: 8GB', (string) $entity); } }
|