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条)

报告相同问题?

悬赏问题

  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 AT89C51控制8位八段数码管显示时钟。
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 下图接收小电路,谁知道原理
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题