2

我的公司有这样的模型,有方法 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());
        }
    }


}

我如何插入数据库,因为模型属性受到保护,我不能做 (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')
        );

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

4

1 回答 1

2

如果您只是想通过反射获取所有对象属性的列表,您可以使用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 所做的工作,另一个更简单,我负责编写更多代码。他们应该遵循一个通用的界面。有点让你两全其美。

我发现这个链接是一些想法的好资源。

于 2012-10-17T23:16:07.473 回答