tags:

views:

241

answers:

7

I'm going to write a framework for my web projects in PHP. Please don't tell me about considering to use some existing framework (Cake, CodeIgniter, Symfony, etc.) - I have already had a look at them and decided to write one for myself.

The framework itself will mainly consist of a module system, a database handler and a template parser. (Many other things too, of course)

With module system I mean that every module has exactly one PHP file and one or more templates associated with it. An example module would be modules/login.php that uses templates/login.tpl for its design.

These days everyone(?) is talking about the MVC (Model View Controller) concept and most of the existing frameworks use it, too.

So my questions are the following:

  • Is MVC really effective for a personal framework?
  • Would it be a bad idea to use a module system?
  • Did you ever write a framework for yourself? What are your experiences?
+7  A: 

Is MVC really effective for a personal framework?

Yes, it can be. Although, it might be a little overkill (which, is not necessarily a bad thing if you are trying to learn)

Would it be a bad idea to use a module system?

This is never a bad idea.

Did you ever write a framework for yourself? What are your experiences?

I wrote a common security framework for my group's PHP applications when I was an intern. I learned alot, but the project as a whole might have benefited more from a pre-built solution.

Of course, I wouldn't have learned as much if I just installed a pre-built solution. So you always have to take that into account, especially for personal projects. Sometimes re-inventing the wheel is the only way you will learn something well.

Robert Greiner
A: 
  1. MVC doesn't work
  2. you don't want to be constrained in the structure of your "modules"; also, keep templates close to the code (the templates directory is a bad idea)
  3. no

re 1.: see Allen Holub's Holub on Patterns. briefly: MVC basically requires you to give up object oriented principles.

Tell Don't Ask is a catchy name for a mental trick that helps you keep the data and code that acts on it together. Views cause the Model to degrade into a heap of getters and setters, with few if any meaningful operations defined on them. Code that naturally belongs in the Model is then in practice spread among Controllers and Views(!), producing the unhealthy Distant Action and tight coupling.

Model objects should display themselves, possibly using some form of Dependency Injection:

interface Display
{
    function display($t, array $args);
}

class SomePartOfModel
...
{
    function output(Display $d)
    {
        $d->display('specific.tpl', array(
            'foo' => $this->whatever,
            ...
        ));
    }
}

OTOH, in practice I find most web applications call for a different architectural pattern, where the Model is replaced with Services. An active database, normalized schema and application specific views go a long way: you keep the data and code that acts on it together, and the declarative nature makes it much shorter than what you could do in PHP.

Ok, so SQL is a terribly verbose language. What prevents you from generating it from some concise DSL? Mind you, I don't necessarily suggest using an ORM. In fact, quite the opposite. Without Model, there's little use for an ORM anyway. You might want to use something to build queries, though those should be very simple, perhaps to the point of obviating such a tool...

First, keep the interface your database exposes to the application as comfortable for the application as possible. For example, hide complex queries behind views. Expose update-specific interfaces where required.

Most web applications are not only the owners of their respective underlying databases, they're their only consumers. Despite this fact, most web applications access their data through awkward interfaces: either a normalized schema, bare-bones, or a denormalized schema that turned out to make one operation easier at the price of severe discomfort elsewhere (various csv-style columns etc). That's a bit sad, and needlessly so.

re 2.: it's certainly good to have a unified structure. what you don't want to do is to lock yourself into a situation where a module cannot use more than one file.

templates should be kept close to code that uses them for the same reason that code that works together should be kept together. templates are a form of code, the V in MVC. you'll want fine-grained templates to allow (re)use. there's no reason the presentation layer shouldn't be as DRY as other parts of code.

just somebody
Care to elaborate on why MVC 'doesn't work' or why a separate template folder is a bad idea?
Bryan M.
Elaboration on any of these wouldn't be a bad thing...
richsage
"keep templates close to the code"Yeah thanks for that...
lamas
this is a *really* hated answer, yay! i don't mind the downvotes at the slightest, but would appreciate if future downvoters could indicate here in the comments what upset them the most. bring on the flames!
just somebody
@just somebody, I agree with your comment about MVC ruining good OO practice and appreciate that someone mentioned it on this thread. I am working right now with a framework (Robotlegs for AS3) that does exactly that. I agree that models should have more functionality than try usually do in MVC but maybe not to display itself (especially if it means having a template name in the model). Your DB answer could be expanded. But, I'm not one of your down voters :)
Renesis
+1  A: 

I am also actually writing a php framework with a friend of mine. I absolutely can understand what you do.

I thing what you are doing is near mvc. You have the templates as views. And the modules as controller. So I think that is ok. The only thing you need is the model. That would be some kind of active records.

In my framework there are simular concepts, except we are writing our own active records engine at the moment. I think what you do isn't bad. But it's hard to say without seeing code.

I see only one problem you have to solve. A framework should be perfectly integrated. It is always a complicated to make your module look nice integrated without always have to think of module while you are coding application.

FSY
A: 

I would say that MVC makes more sense to me, since it feels better, but the only practical difference is that your login.php would contain both the model (data structure definitions) and the controller (code for page actions). You could add one file to the module, e.g. class.login.php and use __autoload() for that, which would essentially implement an MVC structure.

kb
+1  A: 
  • Is MVC really effective for a personal framework?
  • Would it be a bad idea to use a module system?

Yes it is. But MVC is such a loosy-goosy design pattern that you can draw the line between model, view, and controller anywhere you want. To me, the most important parts are the model and the view. I simply have pages, php modules, that generate html by filling in a template from a database. The pages are the view and the database is the model. Any common application-specific code can be factored out into "controllers". An example might be a common, sophisticated query that multiple pages must use to render data.

Other than that I have utilities for safe database access, simple templating, and other stuff.

  • Did you ever write a framework for yourself? What are your experiences?

Yes. I'm very glad I did. I can keep it simple. I know intimately how it works. I'm not dependent on anyone but myself. I can keep it simple yet useful.

Some pointers (0x912abe25...):

Every abstraction comes with a cost.

Don't get to fancy. You might regret not keeping it simple. Add just the right amount of abstraction. You may find you over-abstracted and something that should be simple became excessively complex. I know I've made this mistake. Remember You-aint-gonna-need-it.

Scope your variables well

Don't load your pages by doing

      include_once('...page file ...');

where it's expected that page file will have a bunch of inline php to execute looking up different global variables. You lose all sense of scope. This can get nasty if you load your page file from inside a function:

      function processCredentials()
      { 
           if (credentialsFail)
           {
                 include_once('loginpage.php');
           }
      }

Additionally, when it comes to scoping, treat anything plugged into templates as variables with scope. Be careful if you fill in templates from something outside the page file associated with that template (like a master index.php or something). When you do this it's not clear exactly what's filled in for you and what you are required to plug into the template.

Don't over-model your database with OO.

For simple access to the database, create useful abstractions. This could be something as simple as fetching a row into an object by a primary index.

For more complex queries, don't shy away from SQL. Use simple abstractions to guarantee sanitization and validation of your inputs. Don't get too crazy with abstracting away the database. KISS.

Doug T.
A: 

Writing a framework could be a rewarding experience. The important thing to consider is that you do not write a framework for its own sake. The reason one writes a framework is to make development easy.

Since it is a personal framework you should think in terms of how it could help you develop with less hassle.

I do not think a template system is a good idea. Think of it - what is the major benefit of using a template system? The answer is that it helps teams with different skill sets jointly develop an application. In other words, some members of the team can work on the user interface and they do not need to be PHP coders. Now, a personal framework will most likely be used by a single person and the benefit of template system becomes irrelevant.

All in all, you should look at your own coding habits and methods and discover tasks that take most of your time on a typical project. Then you should ask yourself how you can automate those tasks to require less time and effort. By implementing those automation mechanisms you will have to stick to some sort of conventions (similar to an API). The sum of the helper mechanisms and the conventions will be your personal framework.

Good luck.

Majid
Thanks but I didn't ask if I should write a framework, nor why I should write framework. And separating content from PHP code (templates, etc.) is always a good idea in my opinion.
lamas
I agree about the templating comments, templates always add some overhead to the execution of the page, so why use it unless it is absolutely needed? If you would like to have template support in your framework, I personally would make it be a module that you can optionally use on a per project basis. That is just the way i am doing it.
jasondavis
@lamas - I am sorry I couldn't help you with my answer. I do believe in taking liberty in what you think is useful for you - in this case, merits of using a template system. But I think coders should, at one point in their career development, start to break away from following trends and try to find why a certain approach may be useful or useless for a given situation.
Majid
+2  A: 

Is MVC really effective for a personal framework?

What MVC means anymore, due to its vague interpretation, is business logic, presentation, and input handling. So, unless you aim to design an application that does not involve any three of those, MVC is, in its vague sense, very suitable.

Often it can be more formal than you desire, however, as it demands physical separation of ideas into different code files. Quick and dirty tasks or rapid prototyping might be more quickly setup if the formalities are avoided.

In the long term, what MVC asks for is beneficial to the sustainability of the application in ways of maintenance and modification or addition. You will not want to miss this. Not all frameworks encourage the right practices, though. I am not surprised that you find the various implementations you've tried insufficient. My personal favourite is Agavi. To me and others, in a world of PHP frameworks that do not feel right, Agavi emerges to do the right things. Agavi is worth the shot.

Would it be a bad idea to use a module system?

MVC asks you to separate components of business logic, presentation, and input handling, but it does not suggest how to layout the files. I presume this is the challenge you are addressing with a module system. To answer your question: modules serve identically to sub-directories. If the items are few, its probably more hassle to bother with subdirectories even if the files could logically be separated into them. When the number of items grow large, its now cumbersome to locate them all and sub-directories become a better option.

Frameworks will tack on functionality that allows you to deal with modules as their own configurable entity. The same functionality could just as well exist without modules, perhaps in a more cumbersome manor. Nonetheless, do not consider modules primarily as a system. Systems are so wonderfully vague that you can adapt them to whatever setup you find suitable.

Did you ever write a framework for yourself? What are your experiences?

Yes I have wrote several frameworks with various approaches to solving the issues of web applications. Every such framework I wrote became nothing but a vital learning curve. In each framework I made I discovered more and more the issues with building software. After failing to create anything interesting, I still gained because when asked to make a program I could fully do so with justice.

I recommend you continue if this is the sort of learning experience you want. Otherwise, give Agavi a shot. If that too fails, ensure that you have a clear and detailed specification of what your framework will do. The easiest way to barge into making software, work really hard, and accomplish nothing is to not decide before-hand what exactly your software will do. Every time I ran into making code the only thing in my mind was I will do it right. What happened was a different story: oh, well I need to make a routing system as that seems logical; hmm, okay, now I need a good templating system; alright, now time for the database abstraction; but gee, what a lot of thinking; I should look to the same system from software XXY for inspiration. Therein is the common cry that pleads to use existing software first.

The reason I thought I could do it right was not because all the nuts and bolts of the framework felt wrong. In fact, I knew nothing about how right or wrong they were because I never worked with them. What I did work with was the enamel, and it felt wonky. The quickest way to derive your own framework is really to steal the nuts and bolts from another and design your own enamel. That is what you see when building an application and frankly is the only part that matters. Everything else is a waste of your time in boilerplate. For learning how to build software, however, its not a waste of time.

If you have any other questions, please ask. I am happy to answer with my own experience.

erisco