【问题标题】:How to model a PHP Many to Many Relationship如何为 PHP 多对多关系建模
【发布时间】:2015-10-26 13:56:19
【问题描述】:

我需要为我们的一位客户构建一个物品系统。 项目系统具有以下(给定的)数据库结构:

| item
+--------------------------
| id tinyint(4) primary key
| name varchar(30)

| attr
+--------------------------
| id tinyint(4) primary key
| name varchar(30)

| itemAttr
+--------------------------
| itemId foreign key
| attrid foreign key
| value varchar(255)

我已经有了类结构:

<?php

abstract class Item {
    private $id;

    private $name;  
}

class ShopItem extends Item {
    private $itemType;

    private $price;

    private $imageHref;

    private $description;   
}

因为它是多对多关系,所以我可以有 X 行包含有关“项目”的单个信息。

如何捆绑/分组行以便将信息映射到模型?

我需要例如一页有 20 个不同的“ShopItems”

更新

我想在一个查询中处理所有数据库操作(这就是我的任务所说的......) 所以会有这样的结果:

| id | name     | attrId | value |
+----+----------+--------+-------+
| 1  | Item1    | 1      | 1     |
| 1  | Item1    | 2      | Text  |
| 1  | Item1    | 3      | 100   |

而且我有不同的搜索条件:

Item 需要具备以下属性: 项目类型(属性 ID 1) 说明(属性 2) 价格(属性 3)

否则我不想从数据库中取出这个项目

【问题讨论】:

    标签: php model many-to-many


    【解决方案1】:

    我个人会将属性数组作为成员添加到您的 Item 类。最佳实践可以在这里找到:PHP5. Two ways of declaring an array as a class member

    在数据库理论中,您需要此数据透视表遵循规范化原则,其中禁止嵌套关系。但是你在类之间的 PHP 中并没有这个要求。

    【讨论】:

      【解决方案2】:

      基本类关系:

      class Item
      {
          private $id;
          private $name;
      
          public $attrs = array();
      
          public function addAttr(Attr &$attr) { $this->attrs[] = $attr; $attr->items[] = $this; }
          public function getAttrs() { return $this->attrs; }
      
          public function __construct($id, $name)
          {
              $this->id = $id;
              $this->name = $name;
          }
      }
      
      class Attr
      {
          private $id;
          private $name;
      
          public $items = array();
      
          public function addItem(Item &$item) { $this->items[] = $item; $item->attrs[] = $attr; }
          public function getItems() { return $this->items; }
      
          public function __construct($id, $name)
          {
              $this->id = $id;
              $this->name = $name;
          }
      }
      
      $item1 = new Item(1, "I1");
      $item2 = new Item(2, "I2");
      
      $attr1 = new Attr(1, "A1");
      $attr2 = new Attr(2, "A2");
      
      $item1->addAttr($attr1);
      $item1->addAttr($attr2);
      
      var_dump($item1->getAttrs());
      var_dump($attr1->getItems());
      

      我建议使用 ORM 库。

      【讨论】:

        【解决方案3】:

        一个选项(几个 - 像往常一样)是将它们存储在映射中并通过通用 getter 访问这些属性(使用属性名称作为第一个参数)或使用魔术函数访问它们。

        <?php
        abstract class Item {
            private $id;
        
            private $name;
        
            protected $attributes = array();
        
            /**
             * @param $name The attribute key/name
             * @return null|mixed returns NULL if the attribute was not set
             */
            public function getAttribute( $name ) {
                if( isset( $this->attributes[$name] ) ) {
                    return $this->attributes[$name];
                }
                else {
                    return null;
                }
            }
        }
        

        使用magic functions

        <?php
        abstract class Item {
            private $id;
        
            private $name;
        
            protected $attributes = array();
        
            /**
             * @param $name The attribute key/name
             * @return null|mixed returns NULL if the attribute was not set
             */
            public function __get( $name ) {
                if( isset( $this->attributes[$name] ) ) {
                    return $this->attributes[$name];
                }
                else {
                    /* Trigger an error for unknown properties */
                    $trace = debug_backtrace();
                    trigger_error(
                        'Undefined attribute: ' . $name .
                        ' in ' . $trace[0]['file'] .
                        ' line ' . $trace[0]['line'],
                        E_USER_NOTICE);
                    return null;
                }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-08-25
          • 1970-01-01
          • 2010-11-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多