带DB表插入的模型,更新

时间:2012-10-17 22:18:07

标签: php zend-framework architecture

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

<?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;
    }

我还有公司经理,其中包括模型和适配器的param,用于不同的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中,因为模型属性受到保护,我无法执行(数组)$ 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')
        );

因为当我要更改模型字段名称和其他东西时我必须记住也要在这里进行更改...是否有简单的方法,模式保持一切都清洁

1 个答案:

答案 0 :(得分:2)

如果您只想使用反射获取所有对象属性的列表,可以使用get_class_vars。使用最新版本的PHP,无论范围如何,都将返回所有类变量。但是,由于您正在抛弃这个 Manager ,通常称为Data Mapper,我假设您希望模型对象不会与数据库表完全对齐。否则,您应该坚持使用Zend_Db_Table类的表行网关模式。

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

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

如果你的某些对象更简单并且与表格更好地对齐,那肯定是这样的,我喜欢做的是对象有一个__toArray()方法。它可以负责返回适合构建插入/更新语句的表示。对于需要JSON表示以通过AJAX提供它也很有用。你可以像写这些一样懒惰 - 使用get_class_vars函数或其他反射。我通常有两个映射器基类。一个是CRUD函数,它基本上是Zend_Db_Table所做的,另一个是更多的骨架,我负责编写更多的代码。他们应该遵循一个共同的界面。有点让你两全其美。

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