【问题标题】:Zend: Creating models for a products tableZend:为产品表创建模型
【发布时间】:2009-12-16 02:32:58
【问题描述】:

我正在尝试创建两个模型,productsproduct_manufacturers,以便我可以引入制造商和产品,如有必要,可以在管理员中编辑它们,以及通常的 CRUD 内容。这是表格的架构(它尚未最终确定,所以如果您有任何建议,请继续)。

CREATE TABLE `product_manufacturers` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `manufacturer_name` varchar(100) default NULL,
  `active` tinyint(1) default '1',
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8

CREATE TABLE `products` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `product_name` varchar(100) default NULL,
  `manufacturer_id` int(11) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8

示例数据:

(产品)-

id product_name manufacturer_id
1  iPod Nano 4g 1

(产品制造商)-

id manufacturer_name active
1  Apple             1

我已经创建了两个模型,但是我在提取基于活跃产品制造商的产品时遇到了问题(是的,我正在使用模型自动加载器)。

protected function _initAutoload ()
{
    // Add autoloader empty namespace
    $autoLoader = Zend_Loader_Autoloader::getInstance();
$resourceLoader = new Zend_Loader_Autoloader_Resource(
    array(
    'basePath' => APPLICATION_PATH ,
    'namespace' => '' ,
    'resourceTypes' => array(
        'form' => array('path' => 'forms/' ,
        'namespace' => 'Form_') ,
        'model' => array('path' => 'models/' ,
        'namespace' => 'Model_')
    )
    ));
    // Return it so that it can be stored by the bootstrap
    return $autoLoader;
}

应用程序/模型/Product.php:

<?php
require_once 'Zend/Db/Table/Abstract.php';

class Model_Product extends Zend_Db_Table_Abstract
{
    /**
     * The default table name 
     */
    protected $_name = 'products';
    protected $_dependentTables = array('Model_Manufacturer');
}

应用程序/模型/Manufacturer.php:

class Model_Manufacturer extends Zend_Db_Table_Abstract
{
    /**
     * The default table name 
     */
    protected $_name = 'product_manufacturers';
    protected $_referenceMap = array(
 'Model_Product' => array(
     'manufacturer_id' => array('id'),
     'id' => array('manufacturer_id'),
 ),
    );
}

我感觉自己完全做错了,因为我正在从 Products Model 创建一个对象并尝试打印出所有具有相应制造商并且该制造商处于活动状态的产品。

 $model = new Model_Product();
 $results = $model->fetchAll();
 foreach ($results as $result) {
     //print_r($result);
     echo $result->product_name;
 }

我是模型创建的新手,谁能提供有关如何正确更改当前代码以使产品模型正确依赖制造商模型的建议?

我有一种感觉,我不正确地设置了dependentTables/referenceMap,而不是使用通用的fetchAll 方法,我应该在任何一个模型中创建一个自定义方法来进行获取,也许是手动加入制造商表,还是适当的 referenceMap 和dependentTables 属性可以解决这个问题?

【问题讨论】:

    标签: php mysql zend-framework


    【解决方案1】:

    这里有一些问题需要解决,但这里有一些提示。

    我。如果名称是复数形式,表格模型会更好地工作。它们在魔术方法中听起来更好(例如 $product_set = findProducts() 而不是 findModel_Product())

    二。参考地图很重要,它允许那些漂亮的魔法选择方法(例如 findParentX())工作。它属于dependent表,这里是product表,因为它引用了product_manufacturer

      // in Model_Product
      protected $_referenceMap = array(
    
        // rule name
        'Manufacturer' => array(
    
          'columns'       => 'manufacturer_id',     // this column
          'refTableClass' => 'Model_Manufacturer',  // references that table object
          'refColumns'    => 'id'                   // and references that column
        )
      );
    



    iii.如果您愿意,可以将依赖表条目移动到您的 product_manufacturers 表模型:不过,它仅用于复制 ON DELETE/UPDATE CASCADE 数据库命令。 (暂时搁置)

    // in manufacturer table model
    protected $_dependentTables = array('Model_Product');
    



    正在抓取

    要获取产品的制造商,请执行以下操作:

    $manufacturer = $product_row->findParentManufacturer();
    


    要获取制造商的产品,请执行以下操作:

    $product_set = $manufacturer_row->findProducts(); // Well, findModel_Product(), which is why you should rename your table ;)
    


    对于源自每一行的其他魔术方法,请深入研究Zend_Db_Table_Row_Abstract(尤其是public function __call)的源代码。

    【讨论】:

    • 感谢您抽出宝贵时间回复。 “它真的只有在你想通过 PHP 级联删除和更新时才有用” - 所以你是说最好通过创建一个 DB Select 对象来保持它更简单,如果我不这样做,我一直在做这件事'不需要级联之类的吗?
    • 关于活跃的制造商,我知道使用 select 对象的方法就是 -&gt;where('product_manufacturers.active=?',1.. 所以你说是因为我正在以不同的方式进行操作比这还难?
    • 关于您的第一条评论,我已经澄清了我的帖子——如果您的数据库中没有外键,则 $_dependantTables 用于复制 ON DELETE/UPDATE CASCADE 数据库操作。也许暂时离开它。
    • 关于您的第二条评论,我已经编辑了帖子的最后一部分。我真的说的很简单,深入研究 Zend_Db_Table_Row_Abstract 的 __call 函数代码以了解有关魔术方法的更多信息(包括使用“选择”对象限制结果)。我认为您对“选择”的使用很好。
    【解决方案2】:

    我已经实现了参考映射,并且我正在使用 $childObject->findParentObject() 方法检索父记录的详细信息,该方法适用于子对象的单个实例。

    但是我有一个问题,使用它来检索多个子行的父对象的详细信息[用于显示目的],目前涉及使用 findParentObject() 进行选择以检索初始记录集然后遍历它方法来获得我想要的记录。因此我决定忽略参考地图并为此进行连接,完全绕过参考地图。这很好用,只有一个选择并且更快。

    我的问题是,有没有一种很好的方法来使用参考地图来获得相同的结果,使用一个查询?我目前使用参考地图的方式感觉有点做作,虽然感觉为了纯粹我应该用它来做我需要的......

    抢劫甘利

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-01
      • 2023-02-14
      • 2018-05-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多