views:

581

answers:

5

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.

+2  A: 

There are a lot of good open source frameworks out there that accomplish what you are looking to do much more easily and quickly than writing one from scratch! Having said that, I had an MVC framework that I developed that taught me a lot about framework development and object-oriented design. It is recommended if you have a lot of time and want to do it as a learning experiment (which may end with a pretty good framework).

As far as your idea of an ORM framework ... I think there may be some confusion about what ORM is. ORM is a technique that maps your objects to your relational database, handling retrieval and storage of data. It is usually one component in a larger framework, and does not necessarily characterize the framework itself. Most people throw around MVC framework, for the basic Model-View-Controller architecture on which an application can be built.

Some PHP frameworks provide more out-of-the box functionality, such as what you are interested in doing.

So, there are other threads on this, but I would say, build your own framework if you have time and want to learn. Use one of the many existing frameworks if you want to do something as easily as possible and in the shortest amount of time.

jonstjohn
A: 

Go with Zend, you can make so that each model object is "linked" to each of your tables, it does cover everything you said you need quite good.

Take a look at http://www.zendframeworkinaction.com/ its a good book for starting up with this. Even if you dont go with zend, it will teach you a lot of how it is build(if you decide you want to learn a lot about wheels by crafting your own, its a great starting point too!)

DFectuoso
+3  A: 

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.

Noah Goodrich
A: 

I would encourage you to take a look at http://www.qcodo.com. It's CRUD through the "Code Generator" is incredibly powerful, and seems to satisfy the requirements you've outlined.

Alex
A: 

Great post by gabriel1836 but one neat technique you could use is pointed out by Matthew Weier O'Phinney where he shows a technique to "attach" the form to the model and use it for input filtering and validation. Very ZF specific but might come in handy.

Polygraf