ttp/zf2-eav

Zend Framework 2 EAV

dev-master 2013-08-31 13:42 UTC

This package is not auto-updated.

Last update: 2024-09-24 05:58:58 UTC


README

Zend Framework 实体-属性-值库。

什么是EAV?

快速入门

准备表

例如,如果你有一个 产品 表并且你想为这个表保存EAV属性,那么请创建几个用于存储EAV属性的表。示例:

  • products_int,
  • products_decimal
  • products_string
  • products_text

每个表都应该包含以下字段

  • id(INT) – 主键(自增)
  • entity_id(INT) – 在产品表中的记录标识符
  • attribute_id(INT) – 属性标识符
  • value – 在此字段中存储属性值。此字段的类型应针对每个表不同(int, decimal, varchar, text)

此外,你还应该有一个包含以下字段的属性表

  • id, 主键
  • type, 属性类型
  • name, 属性名称

这些字段的名称不一定必须像上面那样。这里我们使用了默认的字段名称。如果你没有这样的表,请创建它。

然后在 attributes 表中创建几个记录

|  *attribute_id* | *attribute_type*  | *attribute_name* |
| --------------- | ----------------- |------------------|
| 1               | int               | quantity         |
| 2               | string            | title            |
| 3               | text              | description      |

扩展Eav

你可以指定所需字段的名称

use Eav\Eav;

class EavProduct extends Eav
{
    protected $_entitiesTableFieldId = 'id'; // name of primary key of products table

    protected $_attributesTableName = 'attributes'; // name of 'attributes' table
    protected $_attributesTableFieldId   = 'attribute_id'; // name of primary key of attributes table
    protected $_attributesTableFieldType = 'attribute_type'; // field where attribute type is stored
    protected $_attributesTableFieldName = 'attribute_name'; // field where attribute name is stored
}

保存属性

use Zend\Db\TableGateway\TableGateway;

$productsTable = new TableGateway('products', $adapter);
$eav = new EavProduct($productsTable);

$products = $productsTable->select(array('id' => array(1,2,3)));

foreach ($products as $product) {
    $eav->setAttributeValue($product, 'quantity', 10);
    $eav->setAttributeValue($product, 'title', 'product title');
    $eav->setAttributeValue($product, 'description', 'my description');
}

获取属性

$productsTable = new TableGateway('products');
$eav = new EavProduct($productsTable);

$product = $productsTable->select(array('id' => 1))->current();
echo $eav->getAttributeValue($product, 'quantity');
echo $eav->getAttributeValue($product, 'title');
echo $eav->getAttributeValue($product, 'description');

// or using attribute id
echo $eav->getAttributeValue($product, '1');

// or using attribute object(Row)
$attributesTable = $eav->getAttributesTable();
$attribute = $attributeTable->select(array('id' => 2))->current();
echo $eav->getAttributeValue($product, $attribute);

// or using eav object
$attribute = $eav->getAttribute('title');
echo $eav->getAttributeValue($product, $attribute);

完整示例

控制器

$productsTable = new TableGateway('products', $adapter);
$eav = new EavProduct($productsTable);
$attributesTable = $eav->getAttributesTable();

$products = $productsTable->select(array('id' => array(1,2,3)));
$attributes = $attributesTable->select();

视图

<?php foreach ($this->products as $product): ?>

    <b><?php echo $product->title; ?></b><br />
    <?php foreach ($this->attributes as $attribute): ?>

        <?php echo $attribute->label; ?>:
        <?php echo $this->eav->getAttributeValue($product, $attribute); ?><br />

    <?php endforeach; ?>

<?php endforeach; ?>

加速

使用上述方法,每次你想要获取属性值时,都需要对数据库进行查询。你可以使用仅一个数据库查询来获取属性值。以下是一些示例:

$productsTable = new TableGateway('products', $adapter);
$eav = new EavProduct($productsTable);
$attributesTable = $eav->getAttributesTable();

$products = $productsTable->select(array('id' => array(1,2,3)));

// Loading all attributes
$attributes = $attributesTable->select();
$cache = $eav->loadAttributes($products, $attributes);

foreach ($products as $product) {
    // no more queries
    echo $eav->getAttributeValue($product, 'title', $cache);
    echo $eav->getAttributeValue($product, 'description', $cache);
    echo $eav->getAttributeValue($product, 'quantity', $cache);
}

// Loading some attributes
$where = array("name" => array('title', 'description'))
$attributes = $attributesTable->select($where);

$cache = $eav->loadAttributes($products, $attributes);

foreach ($products as $product) {
    // no more queries
    echo $eav->getAttributeValue($product, 'title', $cache);
    echo $eav->getAttributeValue($product, 'description', $cache);

    // here we have query to database since this attribute was not cached
    echo $eav->getAttributeValue($product, 'quantity', $cache);
}

$cachedValues = $cache->toArray(); // returns array('entity_id' => array('attribute_id' => 'value'))