开发者

Proper setup of Controller/Model in Zend Framework

I have an action in my controller called createAction. I also have a model My_Application_Product, that I'm using to create the product within the system. I'm following the Architecting Your Models talk. Is this the "correct" way to save my product? Code for My_Application_Product follows below.

class ProductController  extends Zend_Controller_Action {
    public function createAction() {
        $categoryAdapter = new Application_Model_Categories();
        $categories = $categoryAdapter->fetchAll('parent_id IS NOT NULL');

        $form = new My_Application_Forms_Product_Create();
        $category = $form->getElement('category');

        foreach ($categories as $cat) {
            $category->addMultiOption($cat->id, $cat->name);
        }

        if ($this->getRequest()->isPost()) {
            if (! $form->isValid($_POST)) {
                $this->view->form = $form;
                return $this->render('create');
            }

            $product = new My_Application_Product();
            $product->name = $_POST['name'];
            $product->company_id = 1;
            $product->category_id = $_POST['category'];
            $product->trade_names = $_POST['trade_names'];
            $product->website = $_POST['website'];
            $product->description = $_POST['description'];
            $product->closed_loop = $_POST['closed_loop'];
            $product->sold_as = $_POST['sold_as'];
            $product->sold_in = $_POST['sold_in'];
            $product->dilution = $_POST['dilution'];
            $id = $product->save();

            $url = $this->getHelper('Url')
                        ->url(array('action' => 'registryservices', 'id' => $id));

            $this->_redirect($url);
        }

        $this->view->form = $form;
    }
}

'

class My_Application_Product implements My_Application_Product_Inter开发者_JS百科face {
    // declare all the internally used variables here.
    // if something isn't showing up when trying to save, that's probably
    // because it's missing from here
    protected $_id;
    protected $_name;
    protected $_company_id;
    protected $_trade_names;
    protected $_website;
    protected $_description;
    protected $_closed_loop;
    protected $_sold_as;
    protected $_sold_in;
    protected $_dilution;
    protected $_category_id;
    protected $_verification_level;
    protected $_dfe_sccp;
    protected $_dfe_siicp;
    protected $_el_ccd_hsc;

    public function __set($name, $value) {
        $local_var_name = "_" . $name;
        if (property_exists($this, $local_var_name)) {
            $this->{$local_var_name} = $value;
        }
    }

    public function __get($name) {
        $local_var_name = "_" . $name;
        if (property_exists($this, $local_var_name)) {
            return $this->{$local_var_name};
        }
    }

    /**
     *
     * @param array $data The data to save
     */
    public function save() {
        // this means we're editing something
        if ($this->id) {
            $table = new My_Application_Product_Table();
            $data = $table->find($this->id)->toArray();
            $data = $data[0];

            foreach (get_class_vars(get_class($this)) as $key => $value) {
                if (! is_null($this->$key)) {
                    $data[preg_replace('/^_/', '', $key)] = $this->$key;
                }
            }
            $id = $table->update($data, sprintf('id = %d', $this->id));
        // this means we're creating, and this is the data we need
        } else {
            $data = array(
                'id' => rand(1,1000000),
                'name' => $this->name,
                'date_created' => date('Y-m-d H:i:s'),
            );
            $id = $table->insert($data);
        }

        return $id;
    }
}

'

class My_Application_Product_Table extends Zend_Db_Table_Abstract {
    protected $_name = 'products';
    protected $_primary = 'id';
}


Split your model in multiple classes :

  • 1 class representing the entity (no methods, except for accessors).

this class represents your "real-life" object, and is just a structured data container, which encapsulates data

class My_Application_Model_Product {

    protected $_id;
    protected $_name;
    protected $_company_id;
    protected $_trade_names;
    protected $_website;

    //...

    public function __set($name, $value) {
    //Implement your setter here
    }


    public function __get($name) {

    }

}
  • 1 class responsible of data mapping.

This class makes is the link between your data source (database, webservice, file...) and your entity.

 Class My_Application_Model_DataMapper_Product {

     protected $_adapter


     public function __construct($adapter)
     {
       $this->setAdapter($adapter);
     }
     public function setAdapter($adapter)
     {
       $this->_adapter = $adapter;
     }
     public function save(My_Application_Model_Product $product)
     {
       //Perform your save operation here
     }
     public function fetchAll()
     {

     }
     public function findById($id)
     {
     }
      //You may implement specific methods for any needed specific operation (search, bulk-update...
 }
  • a third class for data access and persistence (Zend_Db_table, Soap client...) This third class is passed to the datamapper as the adapter and is used inside the methods to getch/save data.

With this architecture, you have a clear separation of responsibilities, and may change one part without affecting the other : for example, you could switch from a database to a webservice without affecting your Product class.

A very simple example is given in the zf Quickstart

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜