Php 如何启动一个新的大型ZF2项目?

Php 如何启动一个新的大型ZF2项目?,php,doctrine-orm,zend-framework2,Php,Doctrine Orm,Zend Framework2,我将使用ZF2创建一个新项目。事实上,我将不得不升级一个项目ZF1,但我决定从头开始 我的项目非常大,已经被翻译成10种不同的语言​​来自世界各地的志愿者 我遇到的困难是分析ZF2告诉我要遵循的模块的结构 该软件允许ISP世界中的中小企业管理其客户数据库、服务、订单、发票、域、技术援助、电子商务、知识库等 假设ZF2鼓励程序员创建可在其他应用程序中重用的小模块,并且在所有情况下,我们都尽量简化和抽象类的结构,项目数据库中的许多表通过各种外键相互连接,我无法理解如何创建具有自己的实体文件的独立模块

我将使用ZF2创建一个新项目。事实上,我将不得不升级一个项目ZF1,但我决定从头开始

我的项目非常大,已经被翻译成10种不同的语言​​来自世界各地的志愿者

我遇到的困难是分析ZF2告诉我要遵循的模块的结构

该软件允许ISP世界中的中小企业管理其客户数据库、服务、订单、发票、域、技术援助、电子商务、知识库等

假设ZF2鼓励程序员创建可在其他应用程序中重用的小模块,并且在所有情况下,我们都尽量简化和抽象类的结构,项目数据库中的许多表通过各种外键相互连接,我无法理解如何创建具有自己的实体文件的独立模块,同时在与项目断开连接的情况下不造成崩溃

例如:

我的应用程序运行:

  • 顾客
  • 命令
  • 发票
  • 付款
  • 信息
  • 私人票据
以下是该项目的web界面截图:

正如您所见,该项目通过嵌入同一项目的各个部分,尽可能全面地展示了法律和秩序状况。起初我想创建一个单独的模块,但我需要你的一些建议


您建议我采用什么策略来进行大型项目的结构?

模块可能很多。他们几乎什么都不是。这就是他们的魅力所在。尽量不要想得太复杂。设想一个
新闻模块
和一个
分类模块
。想想把这两个粘在一起。如果你能做到这一点,像你这样的大项目也会一样简单。如果您无法管理它,最好建议您等待启动新项目,直到您可以这样做

最终,大型项目总是一团糟。从某种意义上说,当你看到你写的第一行代码时,一两年后你会感到震惊。重构代码段的能力非常重要,这正是为什么您应该尽可能地分离每个模块的关注点


首先,您的“我的应用程序运行”列表似乎是一个很好的独立模块的第一个分离。诀窍是保持接口简单,以便适配器易于互换(客户订单)。

我本人目前正在ZF2中从事一个非常大规模的项目,并且相信成功的关键是接受框架提供的模块化

我觉得有些建议会很有帮助:

  • 创建抽象/基本模块

    创建“基本”模块将允许您包含可在任何模块中使用的大多数共享/抽象接口/类。这意味着基本模块是系统中其他模块的依赖项

  • 模块具有相互依赖关系

    一些模块虽然分开,但取决于其他模块的功能(例如,付款可能需要用户信息)

    您应该仔细考虑这些服务是什么,并确保尽管它们是共享的,但不会在每个模块中引入耦合/代码复制

    我广泛使用了
    forward()
    插件,它允许我从另一个控制器中调用另一个控制器操作并构建聚合视图,同时仍将每个模块封装在各自的模块中

  • 有效的服务层

    实际上,这是一个通用的MVC设计原则,但是请确保您不是在控制器中编码业务逻辑,而是使用注入控制器的“服务”类。如果你不这样做,你会很快发现它难以管理

  • 创建服务工厂

    首选具体的工厂类(实现
    Zend\ServiceManager\FactoryInterface
    )作为闭包,否则您会很快发现您需要的工厂数量会膨胀到
    模块.php
    ,并且这些工厂不能像配置那样缓存-这意味着性能受到影响

  • 查看插件/控制器插件

    滥用控制器和视图插件的灵活性。这些是封装和注入额外视图/控制器逻辑而不必扩展现有类的非常强大的方法

  • 表格

    表单可能是一件痛苦的事情,因为有很多依赖项需要满足。我认为创建直接映射到您的域模型(实体)的可重用字段集是至关重要的。然后,所有输入过滤器/水合器都连接到此字段集,如果您希望使用这些过滤器/水合器,则只需将其连接到表单即可

    例如,如果您有一个
    CompanyFieldset
    ,您可以在
    CompanyEditForm
    CompanyCreateForm
    CompanyEditForm

我的项目中的一个示例:

 class CompanyCreate extends EntityForm
 {
  public function init()
  {
    $this->add(array(
      'name'    => 'company',
      'type'    => 'Company\Form\CompanyFieldset', // <-- reused!!
      'options' => array(
        'use_as_base_fieldset' => true
      )
    ));
    // Only the button differs between forms!
    $this->add(array(
      'name'     => 'submit',
      'priority' => -100,
      'options'  => array(
        'skipLabel' => true,
      ),
      'attributes' => array(
        'type'  => 'submit',
        'class' => 'btn',
        'value' => 'Create'
      )
    ));
  }
}
class CompanyCreate扩展了EntityForm
{
公共函数init()
{
$this->add(数组)(
“名称”=>“公司”,
'type'=>'Company\Form\CompanyFieldset',//数组(
“将_用作_基本_字段集”=>true
)
));
//只有按钮在表单之间有所不同!
$this->add(数组)(
'名称'=>'提交',
“优先级”=>-100,
“选项”=>数组(
“skipLabel”=>正确,
),
'属性'=>数组(
'类型'=>'提交',
“类”=>“btn”,
'值'=>'创建'
)
));
}
}
就您的模块而言:

我的应用程序运行:客户、订单、发票、付款、消息、私人票据

这个