dongluyi5123 2009-02-28 17:16
浏览 112
已采纳

如何构建PHP中的ORM框架?

I want to build a small ORM (Object Relational Mapping) framework in PHP. I want to do a mixture of an MVC approach, with the same controller/method/variable approach used by CodeIgniter.

There are a few frameworks out there already which do this, but things like

  • Form validation
  • Pagination
  • CRUD
  • And AJAX

are very difficult to do in these frameworks. My main goal, other than to have the entire functioning of the system be done using objects, is to use the DRY principle as much as possible. This mainly means very little repetitive code for form validation and CRUD etc.

I'm looking for ideas on how such a framework would be organized, what the architecture would be, and how a typical request such as a signup form and how to validate it, would be handled by this framework.

Please share your thoughts/ideas. This will be released as an open source framework, free of charge, when its finished.

  • 写回答

6条回答 默认 最新

  • duanhuan6857 2009-02-28 18:36
    关注

    I would probably suggest that rather than building your validation rules around forms (ala Zend Framework), you should build the validation within your domain objects. Then submit your form data directly to the domain object for validation. I am using Zend Framework, but I use this basic structure for my validation needs:

    /**
     * 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;
        }
    }
    

    Some of the limitations with my current approach with validation is that I can't call any necessary custom setters on the object properties and the fact that I need to figure out a way to keep the original data for the object available after running the validate function. But otherwise it has worked well so far.

    As far as CRUD is concerned, the answer depends in part on the complexity of the problems you want to address and in part on what patterns you are familiar with and do/don't like and do/don't want to try to implement.

    Obviously the most robust design to implement is to use Data Mapper with separate Domain Objects sitting on top. However, in most cases this is overkill and so you could just use the much (inappropriately) maligned Active Record pattern. This is basically what CodeIgniter and Zend Framework have done with what they have provided.

    I ended up having to construct a custom ORM layer that uses the Data Mapper pattern because I needed to handle cases of Inheritance Mapping in my design and its worked pretty slick but I do regret losing the metadata mapping functionality that came with the Table and Row Gateway implementations in Zend Framework. (If you could find a way to effectively create metadata mapping using data mappers I want you to show me how you did it. :P). Even though you are trying to build your own, you might consider looking at Zend Framework as it has some of the finest PHP code I've seen and follows standard design patterns very closely.

    One thing that would be nice to see in a Pagination class would be the ability to tie directly to a database object in such a way that the limit clause can be applied to the query based on what range of values the page should display. Otherwise, the key components with pagination are to keep track of current page, number of records to display per page, and some sort of collection object that contains the values to be iterated over.

    At the very least though, you want to make certain that you don't preload the entire collection and then only display a certain range of records as this will provide a huge performance hit.

    As far as Ajax requests are concerned, I would suggest building in some sort of context helper that can check for whether an HTTP Request is an XHR or not and then handling it specifically based on that context.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(5条)

报告相同问题?

悬赏问题

  • ¥15 做个有关计算的小程序
  • ¥15 MPI读取tif文件无法正常给各进程分配路径
  • ¥15 如何用MATLAB实现以下三个公式(有相互嵌套)
  • ¥30 关于#算法#的问题:运用EViews第九版本进行一系列计量经济学的时间数列数据回归分析预测问题 求各位帮我解答一下
  • ¥15 setInterval 页面闪烁,怎么解决
  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化