Zend框架和防止脂肪控制器

时间:2010-07-28 16:33:45

标签: php zend-framework controller datamapper

避免脂肪控制器

所以我正在使用Zend Framework,我有一个问题涉及使用我的一个动作来防止胖控制器。基本上我正在将CSV文件规范化到我的数据库中。

这意味着我必须获取Feed然后使用我的模型。 饲料抓取只是为了展示它是如何工作的,但现在是一个行动助手。

我在Zend Framework中使用Data Mapper模式。我讨厌我在我的控制器中这样做。所有这些setProperty() - > setProperty() - > setProperty()看起来非常难看,我觉得我在错误的地方做它?如果只是创建某种服务层,我会传递整个 $ feed ,然后在该类中实例化我的模型和我的Mapper,这是一个更好的选择吗?

另外,我需要规范化,这意味着我应该使用一个事务,但我不确定应该在哪里开始我的事务。由于我目前正在做的事情,我唯一能考虑的地方是我的控制器。 哇..那将是一个糟糕的地方

如何从控制器中获取模型行为和操作?

ImportController.php

public function indexAction() {
        $start = $this->getRequest()->getParam('start');
        $end = $this->getRequest()->getParam('end');
        $url = "http://www.domain.com/admin/GetBookingData.aspx";       

        $client = new Zend_Http_Client();
        $client->setParameterGet('dateEnteredMin', $start);
        $client->setParameterGet('dateEnteredMax', $end);
        $client->setParameterGet('login', 'login');
        $client->setParameterGet('password', 'password');
        $client->setUri( $url );
        $client->setConfig(array(
            'maxredirects' => 0,
            'timeout'      => 30));
        // Send the request. 
        $response = $client->request();

        // Grab the feed from ->getBody and add it to $feed
        $feed = $this->csv_to_array(trim($response->getBody()));


        // The first item in the array is the heading in the CSV, so we can remove it from the array using shift().
        $title = array_shift($feed);

        // Create my Models and Mappers.
            // ***  EVERYTHING BELOW HERE IS WHAT I DON'T LIKE ***
        $bookings =         new Bookings_Models_Bookings();
        $property =         new Bookings_Models_Property();
        $clients =      new Bookings_Models_Clients();

        $bookingsMapper =   new Bookings_Models_Bookings_Mapper();
        $propertyMapper =   new Bookings_Models_Property_Mapper();
        $clientsMapper =    new Bookings_Models_Clients_Mapper();

        $bookings->setId($feed[9])
            ->setPropertyId($feed[1])
            ->setClientId($feed[2])
            ->setDate($feed[4]);
        $bookingsMapper->save($bookings);

        $property->setId($feed[1])
            ->setPropertyName($feed[23])
        $propertyMapper->save($bookings);

        $clients->setId($feed[2])
            ->setFirstName($feed[20])
            ->setLastName($feed[21])
        $clientsMapper->save($clients);

}

2 个答案:

答案 0 :(得分:3)

服务层可能就是我的方式。所以你要创建一个看起来像这样的服务类:

class Your_Service_Import
{
    public function importFromCsv($csv)
    {
        // etc.
    }
}

然后将所有在csv_to_array调用之后的控制器方法代码移动到该方法中,让控制器方法的结尾看起来像这样:

$feed = $this->csv_to_array(trim($response->getBody()));

$service = new Your_Service_Import();
$service->importFromCsv($feed);

这样可以更轻松地测试导入代码(因为它位于独立的类中),并且更容易在应用程序的其他部分重用。

答案 1 :(得分:1)

我比@Tim Fountain更进一步(或两步)

  1. 创建一个服务或域帮助程序,它接受一个开始,结束(并且可以使用用户名密码和URL配置)并将csv列表作为数组返回。
  2. 创建一个映射已知维度数组(csv)并将其映射到数据库的服务。
  3. 您的控制器将只是

    $start = $this->getRequest()->getParam('start');
    $end = $this->getRequest()->getParam('end');
    $dataService = new Your_Service_Get();
    $data = $dataService->get($start, $end);
    $mapService = new Your_Service_Map();
    $mapService->map($data);