【问题标题】:Model with DB table insert , update带有数据库表插入、更新的模型
【发布时间】:2012-10-08 07:10:46
【问题描述】:

我的公司有这样的模型,有方法 setOptions 从数组或 Zend_DB_Table_Row 创建对象

<?php

class Model_Company 
{
    protected $c_id;
    protected $c_shortname;
    protected $c_longname;


    public function __constructor(array $options = null)
    {
        if(is_array($options)) {
            $this->setOptions($options);
        }
    }

    public function setOptions($data)
    {
        if($data instanceof Zend_Db_Table_Row_Abstract) {
            $data = $data->toArray();
        }
        if(is_object($data)) {
            $data = (array)$data;
        }
        if(!is_array($data)) {
            throw new Exception('Initial data must be object or array');
        }
        $methods = get_class_methods($this);
        foreach($data as $key => $value) {
            $method = 'set'.ucfirst($key);
            if(in_array($method, $methods)) {
                $this->{'c_'.$key} = $value;    
            }

        }
        return $this;
    }

我也有公司经理,其参数为不同的 db/soap/rest 的模型和适配器

  class Model_CompanyManager 
{
    private $_adapter;
    public function __construct(Model_Company $model,$adapter) 
    {
        $this->_adapter = $adapter;
        $this->_model = $model;
        return $this;
    }   
    /**
     * Save data
     * @var Model_Company $data
     */
    public function save(array $data)
    {
        $data = $this->_model->setOptions($data);
        $this->_adapter->save($data);
    }


}

和DBTable中的DBTable

class Model_DbTable_Company extends Zend_Db_Table_Abstract
{
    protected $_name = 'company';
    protected $_id = 'c_id';


    public function save(Model_Company $data) 
    {

        try {
            if(isset($data['c_id'])) {
                $this->update($data, 'c_id = :c_id',array('c_id' => $data['c_id']));
            } else {

                $this->insert($data);

            }    
        } catch (Zend_Db_Exception $e) {
            throw new Exception($e->getMessage());
        }
    }


}

如何插入 db,因为模型属性受到保护,我不能做 (array)$data

$this->_companyManager = new Model_CompanyManager(new Model_Company,new Model_DbTable_Company);
$this->_companyManager->save($values);

我不会像这样创建带有字段名称的数组,如下所示:

$data = array(
            'c_shortname' => $company->getShortname(),
            'c_longname' => $company->getLongName(),
            'c_description' => $company->getDescription(),
            'c_salt' => $company->getSalt(),
            'c_password' => $company->getPassword(),
            'c_updated_at' => date('YmdHis')
        );

因为当我要更改模型字段名称和其他内容时,我还必须记住要在这里更改...是否有简单的方法,模型可以保持一切并保持干净

【问题讨论】:

  • 当您调用$this-&gt;_companyManager-&gt;save($values); 时,您实际上是用$values 调用Model_DbTable_Company::save()$values 是什么? Model_DbTable_Company::save() 需要 Model_Company 作为参数。
  • 静态函数很难测试,所以这种方法是错误的。当我在 Model_Company 对象中保存值时
  • :: 并不意味着静态。对于静态,您必须使用关键字static。这是用类描述方法的语法,因此与Model_CompanyManager::save() 区分开来

标签: php zend-framework architecture


【解决方案1】:

如果您只是想通过反射获取所有对象属性的列表,您可以使用get_class_vars。对于最新版本的 PHP,这将返回所有类变量,而不管范围如何。但是由于您在这个 Manager 中折腾,通常称为Data Mapper,我假设您希望您的模型对象不会与数据库表完全对齐。否则你应该坚持 Zend_Db_Table 类的 table-row-gateway 模式。

我个人非常喜欢将数据映射器模式与 ZF 应用程序结合使用。只有最简单的应用程序才会与关系数据库表对齐。它鼓励在数据库模式之前编写更丰富的对象和编写模型和业务逻辑。

映射器的工作正是它所建议的,将您的实体映射到持久层,因此在映射器 save() 方法中处理 SQL 语句的实际分配(可能使用您的表字段名称构建一个数组并分配值,甚至可能保存到多个表中)是完全可以接受的。

如果您的某些对象更简单并且可以更好地与表格对齐(肯定会如此),那么我喜欢为对象设置一个 __toArray() 方法。它可以负责返回适合构建插入/更新语句的表示。对于需要 JSON 表示来通过 AJAX 提供服务也很有用。你可以随心所欲地写这些——使用 get_class_vars 函数或其他反射。我通常有两个映射器基类。一个具有 CRUD 功能,基本上完成 Zend_Db_Table 所做的工作,另一个更简单,我负责编写更多代码。他们应该遵循一个通用的界面。有点让你两全其美。

我发现this link 是提供一些想法的好资源。

【讨论】:

  • Thx for link ...我的问题是您有方法__toArray 将对象更改为数组...如果我不想同时更改模型和映射类,我将使用get_class_vars。你认为是正确的方法吗?应该这样做还是用所有元素创建数组......
  • Model 和 Mapping 类是什么意思?我建议在模型上使用__toArray 方法,可能是由映射器调用的。该映射器需要知道如何获取 SQL 结果并构建对象,并将对象反向转换为适合插入/更新的对象。你想避免做什么?我可以建议的一件事是开始编写一些代码。做几个对象和他们的映射器。然后返回并重新分解以消除您开始看到的“通用”代码。如果您能详细说明一下,我可以尝试更好地回答。
猜你喜欢
  • 1970-01-01
  • 2011-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-22
  • 1970-01-01
  • 2021-08-20
相关资源
最近更新 更多