For the last two weeks I've been rewriting my old framework at my leisure taking ideas I've picked up in the last year and a half and some ideas I never found time to incorporate and put them into a new framework. This after taking a long look at the existing ones and finding none of them to my liking.
I'm still at a point where I can abort problems without too much pain. Only the first 20 or so files are being worked on. So I'm going to go over things here for review and comment, see if anyone spots any obvious trainwrecks.
First, the pattern is EDMVC - Event Driven Model View Control. Base flow is as follows.
- Apache looks for file, either finds the cache or nothing. Assuming no cache PHP is started.
- First object to be instantiated is Core - the core services module. This holds the "global" variables and objects of the project, as well as essential methods such autoload. It sets the environment, loads the core settings either from the database or from cache, then determines the proper page controller for the request and starts it.
- The Page controller determines the requested event based on path, validates it, and if required athenticates the user's permission to perform the event. It then fires the event.
- Any remaining path parsing is performed by the event so that settings can be embedded into the URL, then the event does what it does. Events can be view based or model based - but it isn't proper to think of them as views or models. They exist between the control and these elements. An event will by its conclusion create a responder or another event and pass it back to the page control.
- The page controller fires the event if it received one, or commands the responder to send out its reply and returns flow back to core.
- Core calls the shutdown function and does final cleanup.
With that outline in mind some other notes and principles.
Coupling - Decoupling: All class objects are loosely coupled back to core and can be decoupled simply by giving them the information they need to function. For example, the HTMLResponder class references the Core::paths map - but it has a setPaths() method that allows you to assign a set of paths to use. You'll need to call that method if you want to use it outside the framework. By similar means all of the classes can work without Core.
Restful State: $_REQUEST does not appear in the code. It is evil, do not use it. Initial events care about whether they are POST or GET based and will raise a bad request exception if accessed by the wrong method.
DRY: The code follows DRY principle - don't repeat yourself.
No PHP is best: The framework does not reside in the htdocs directory - it lives elsewhere except for a single landing.php file. The framework by default wants write access to the htdocs directory so it can cache it's work where Apache can find it without instating PHP on the next page request, or at least without instantiating the whole framework (for example, a file might be given a small PHP header to expire the file and force the framework to rewrite once an hour). Security is also improved by having only one exposed PHP file.
JIT Loading: Just In Time - No object is loaded until it's use is unavoidable. This includes starting sessions, the database, what have you. Overhead is not incurred until it must be incurred.
View The view consists of templates and Responder classes. The Responder does the actual coupling of template to data. Template files are *phtml files written in braceless syntax. Unlike Code Igniter or some other frameworks out there at NO point does HTML ever get echoed out in any way from anywhere but a template file. This is one of the laws of the framework - if it's HTML it is in some template somewhere and can be edited.
I also plan to place Collection objects into the works. A collection is a set of related tables. Finally any table can be a field, recursively.
I have other ideas jumbling that aren't sorted, this is hardly final.