如何将CakePHP用于客户组合管理应用程序

时间:2013-09-12 10:22:57

标签: php cakephp cakephp-appmodel

我理解问题标题看起来很开放,但我已经做过一些阅读/试验这个主题,除了构建我自己的程序式应用程序之外,还有Cake的某个地方。我的目标是将我的程序应用程序带到CakePHP。

应用程序做什么(或想要做什么)

所以,我有一堆clients,每个客户有1个或更多accounts。每个account都有holdings,其值存储在特定日期。这是数据库结构的一个例子

database structure

我们的想法是为客户,帐户等设置标准的CRUD页面。但也有更复杂的页面,例如,为客户帐户提供返回历史记录以及投资组合统计信息。 (我有其他表格中有更多信息,但为了简单起见,我暂时从这个问题中省略了它们)

我做了什么

因此,遵循这些教程,我为客户端和帐户建立了模型,并设法链接(关联?)CakePHP中的客户端和帐户表。我还制作了控制器和视图,允许我检索客户端和帐户,并制作索引,查看,编辑视图。

以下是我的模型类:

//Client.php
class Client extends AppModel {
    public $hasMany = 'Account';
}

//Account.php
class Account extends AppModel {
    public $belongsTo = 'Client';
    public $hasMany = 'Holding';
}

//Holding.php
class Holding extends AppModel {
        public $belongsTo = 'Account';
    }

我之前做了什么

假设我想制作一个页面,显示给定客户的投资组合回报。我在上一个(原始)应用程序中所做的只是制作一个php文件(portfolio.php)。然后,我将使用原始SQL语句在数据库中查询每个月末客户端持有的总和。然后我循环计算从一个月到下一个月的值变化百分比的返回数组。

然后可以在html表格中显示这些数据,然后我甚至可以在图表等上绘制值。

这当然是一个简单的例子。此页面/视图将引入其他信息,如基准比较(通过另一个数据库表),像夏普比率,体积,年化回报等统计数据。

我的问题

如何在CakePHP中实现与上一节类似的功能?它似乎不符合我对MVC意识形态的看法/页面。进行计算所涉及的逻辑在哪里(例如,计算值数组的返回值)?

如果我能解释一下MVC / CakePHP中是如何实现的,那将非常有用。

博客教程很有意义,但我还不知道它将如何扩展到更复杂的应用程序。

1 个答案:

答案 0 :(得分:2)

CakePHP作为一个框架可以让你完全摆脱你的逻辑。它告诉你应该在哪里进行数据库调用(模型)以及应该在哪里控制应用程序(控制器)的流程,但是当涉及到场景逻辑时,文档并没有说太多。

MVC 我理解 另一方面很清楚

  • 处理数据的所有内容都应该放在模型中。
  • 处理用户交互/流量控制的所有内容都应该放在控制器中。
  • 处理用户界面的所有内容都应该放在视图中。

应用于CakePHP

这意味着您的大多数逻辑都保留在Models中,而Controllers中的逻辑很少。这种方式也更好,因为您可以轻松地从任何链接控制器调用$this->Model->foo(),而由于性能问题,很难鼓励调用另一个控制器中定义的函数,这实际上不是一个好习惯。

您可以调查的其他事项包括ComponentsBehaviors

Components基本上是一组要在控制器之间共享的功能。它与Controller具有或多或少相同的功能,但没有专用的routesviewsmodel

Behaviors是模型的等价物,如果你有几个具有类似行为的模型,并且你想让你的代码干掉,那么它就很好。

您的案例

在您的特定情况下,我会使用模型中的小功能。例如,操纵馆藏信息的所有功能都应该在Holding模型中。这很好,因为您可以从Controller或其他模型调用这些函数,您可以在preparePortfolio()模型中使用User函数调用Holding模型中的一些函数,执行所有操作一种安排,然后将合并数据返回到准备传递给视图的UserController

最后一件事

如果您处理数组和循环,我强烈建议您查看Hash类。您可以通过使用某些函数来避免循环遍历多维数组,如果您处理大型数组,它可以从字面上提升您的性能。它具有比具有复杂循环更清晰的语法。


代码示例帮助

应用/控制器/ ClientsController.php

<?php
App::uses( 'AppController', 'Controller' );
class ClientController extends AppController {
    public function portfolio( $clientId ) {
        $this->Client->id = $clientId;

        if( !$this->Client->exists() ) {
            throw new NotFoundException( 'There are no client with this id' );
        }

        $data = $this->Client->portfolio( $clientId );

        $this->set( compact( 'data' ) );
    }
}

应用/型号/ Client.php

<?php
App::uses( 'AppModel', 'Model' );
class Client extends AppModel {

    public $hasMany = array(
        'Account' => array(
            'className'    => 'Account',
            'foreignKey'   => 'client_id'
        )
    );

    public function portfolio( $clientId ) {
        $holdings = $this->Account->Holding->find( 'all', $findParameters );
        $foo = $this->Account->Holding->doThings( $holdings );
        return $foo;
    }
}

应用/型号/ Account.php

<?php
App::uses( 'AppModel', 'Model' );
class Account extends AppModel {
    public $hasMany = array(
        'Holding' => array(
            'className'    => 'Holding',
            'foreignKey'   => 'account_id'
        )
    );

    public $belongsTo = array(
        'Client' => array(
            'className'    => 'Client',
            'foreignKey'   => 'client_id'
        )
    );
}

应用/型号/ Holding.php

<?php
App::uses( 'AppModel', 'Model' );
class Holding extends AppModel {
    public $belongsTo = array(
        'Account' => array(
            'className'    => 'Account',
            'foreignKey'   => 'account_id'
        )
    );

    public function doThings( $holdings ) {
        foreach( $holdings as $key => $value ) {
            // code...
        }
        return $bar;
    }
}