【问题标题】:How would an ORM framework in PHP be structured?PHP 中的 ORM 框架将如何构建?
【发布时间】:2010-10-10 13:05:01
【问题描述】:

我想用 PHP 构建一个小型 ORM (Object Relational Mapping) 框架。我想混合使用 MVC 方法,与 CodeIgniter 使用的控制器/方法/变量方法相同。

已经有一些框架可以做到这一点,但是像

  • 表单验证
  • 分页
  • CRUD
  • 和 AJAX

在这些框架中很难做到。我的主要目标,除了让系统的整个功能使用对象来完成之外,是尽可能地使用 DRY 原则。这主要意味着用于表单验证和 CRUD 等的重复代码非常少。

我正在寻找有关如何组织这样一个框架、架构是什么以及一个典型的请求(如注册表单以及如何验证它)将如何由该框架处理的想法。

请分享您的想法/想法。完成后,它将作为一个开源框架免费发布。

【问题讨论】:

标签: php orm oop frameworks


【解决方案1】:

正如 OT 所说,AJAX 和分页很难以足够灵活的方式实现。它要求框架了解您屏幕上的内容,但大多数框架只生成 HTML,并不关心客户端呈现。

显然需要 Web 用户界面框架。

这就是为什么我建议调查Agile Toolkit。或许下面的例子会让我们更容易看到集成 AJAX 的威力:

$b=$page->add('Button')->setLabel(rand(1,100));
$b->js('click')->reload();

这将在页面上生成一个带有随机数作为标签的按钮。单击按钮将使用 AJAX 请求重新加载显示新号码的按钮内容。

有了这样的基础,想象如何以非常 AJAX 友好的方式构建分页器是轻而易举的事。太糟糕的分页器已经实现并附带工具包。

涵盖其他主题。 CRUD 也是一个类/对象。

$page->add('CRUD')->setModel('User');

表单验证是在服务器端完成的,但错误会很好地显示出来。所有表单均使用 AJAX 请求提交。

【讨论】:

    【解决方案2】:

    gabriel1836 的帖子很棒,但Matthew Weier O'Phinney 指出了一种您可以使用的巧妙技术,他在其中展示了一种将表单“附加”到模型并将其用于输入过滤和验证的技术。非常特定于 ZF,但可能会派上用场。

    【讨论】:

      【解决方案3】:

      我会鼓励你看看http://www.qcodo.com。它通过“代码生成器”进行的 CRUD 非常强大,并且似乎满足了您概述的要求。

      【讨论】:

        【解决方案4】:

        我可能会建议,与其围绕表单(ala Zend Framework)构建验证规则,不如在域对象中构建验证。然后将表单数据直接提交给域对象进行验证。我正在使用 Zend 框架,但我使用这个基本结构来满足我的验证需求:

        /**
         * Contains the domain object properties.
         * @var array
         */
        protected $_data = null;
        
        /**
         * @var array
         */
        protected $_filters = null;
        
        /**
         * @var array
         */
        protected $_validators = null;
        
        public function validate($data = null)
        {
            if(!$data) {
                $data = (array) $this->_data;
            } else {
                $data = array_merge((array) $this->_data, $data);
            }
        
            $this->_input = new Zend_Filter_Input($this->_filters, $this->_validators, $data, $options);
            $this->_input->addValidatorPrefixPath('LP_Validate_', 'LP/Validate/');
            $this->_input->addFilterPrefixPath('LP_Filter_', 'LP/Filter/');
        
            if($this->_input->isValid()) {
                $this->_data = (object) $this->_input->getEscaped();
                return true;
            } else {
                $this->_data = (object) $data;
                return false;
            }
        }
        

        我目前的验证方法的一些限制是我无法在对象属性上调用任何必要的自定义设置器,而且我需要找出一种方法来保持对象的原始数据在运行后可用验证功能。但除此之外,它到目前为止运行良好。

        就 CRUD 而言,答案部分取决于您要解决的问题的复杂性,部分取决于您熟悉和喜欢/不喜欢和喜欢/不想做的模式尝试实施。

        显然,要实现的最健壮的设计是使用数据映射器和位于顶部的单独域对象。但是,在大多数情况下,这太过分了,因此您可以只使用受到很大(不恰当)诽谤的 Active Record 模式。这基本上是 CodeIgniter 和 Zend Framework 用他们提供的东西所做的。

        我最终不得不构建一个使用数据映射器模式的自定义 ORM 层,因为我需要在我的设计中处理继承映射的情况,而且它的工作非常流畅,但我很遗憾失去了表附带的元数据映射功能Zend 框架中的行网关实现。 (如果您能找到一种使用数据映射器有效地创建元数据映射的方法,我希望您向我展示您是如何做到的。:P)。即使您正在尝试构建自己的框架,您也可以考虑查看 Zend 框架,因为它包含一些我见过的最好的 PHP 代码,并且非常遵循标准设计模式。

        在分页类中很高兴看到的一件事是能够直接绑定到数据库对象,从而可以根据页面应显示的值范围将限制子句应用于查询.否则,分页的关键组件是跟踪当前页面、每页显示的记录数以及包含要迭代的值的某种集合对象。

        不过,您至少要确保不要预加载整个集合,然后只显示特定范围的记录,因为这会对性能造成巨大影响。

        就 Ajax 请求而言,我建议构建某种上下文帮助器,它可以检查 HTTP 请求是否是 XHR,然后根据该上下文专门处理它。

        【讨论】:

          【解决方案5】:

          使用 Zend,您可以使每个模型对象“链接”到您的每个表,它确实涵盖了您所说的所有内容,非常好。

          看看http://www.zendframeworkinaction.com/ 这是一本很好的入门书籍。即使您不使用 zend,它也会教您很多关于它的构建方式(如果您决定通过自己制作轮子来学习很多关于轮子的知识,那么它也是一个很好的起点!)

          【讨论】:

            【解决方案6】:

            有很多优秀的开源框架可以比从头开始编写更轻松、更快速地完成您想做的事情!话虽如此,我开发了一个 MVC 框架,它教会了我很多关于框架开发和面向对象设计的知识。如果您有大量时间并希望将其作为学习实验(可能以一个非常好的框架结束),建议您这样做。

            就您对 ORM 框架的想法而言……我认为 ORM 是什么可能有些混淆。 ORM 是一种将对象映射到关系数据库、处理数据检索和存储的技术。它通常是更大框架中的一个组件,并不一定是框架本身的特征。大多数人都在使用 MVC 框架,用于构建应用程序的基本模型-视图-控制器架构。

            一些 PHP 框架提供更多开箱即用的功能,例如您有兴趣做的事情。

            因此,这方面还有其他主题,但我想说,如果您有时间并想学习,请构建自己的框架。如果您想在最短的时间内尽可能轻松地做某事,请使用众多现有框架之一。

            【讨论】:

              猜你喜欢
              • 2018-02-04
              • 1970-01-01
              • 1970-01-01
              • 2010-10-29
              • 2016-05-31
              • 2012-09-02
              • 2017-12-29
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多