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.
The main reason for that varies from framework to framework, but one case they all shared was a lack of proper AJAX support. Most have AJAX support, but it’s tacked on as an afterthought. I’m baking this into the core. It will continue to work without javascript mind you, but there will be parts that are specifically catered to js to enhance the site.
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.
Responders aren’t just templates though. Javascript responders prep outgoing javascript snippets and responses. XML Responders compose, well, XML responses. It is possible for a page to parse multiple responses - an email responder would compose an email and send it even while an HTML responder tells the user the process is complete. Any outgoing data passes through a responder.
Model PDO is at the heart, with a Database class on top of it with enhanced query methods. The conversion to PDO is a major switch for my framework and I haven’t done too much on this side except the bare minimum to get the database reads done. That said, I plan to continue having table, row and field objects. The table and row objects will each implement array so that PHP can foreach over their contents cleanly. Field objects contain most of the validation brute work. In the rewrite I want javascript to be able to quickly shoot an isValid query to each field object onBlur of the field rather than wait for form submit.
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.
Weirdest structural thing I’ve done that I am starting to get comfortable with is the fact that there is a loadOrder.ini file in the js directory. As mentioned before the framework, and all of its files, reside outside the htdocs directory. This includes the javascript. The loadOrder.ini file tells PHP which javascript files are going to be used and in what order to load them. When the framework resolves the header of the html page file it uses this ini file to write the script tags. It is also used one other time, by the collator. Once debug mode is switched off the framework points to index.js. This “file” is just a collation of all javascript files that the loadOrder.ini file calls out in the order they are called out (Note, if you create an index.js file and put it in the load order you’ll trip an illegal script name Exception).
It’s odd, but it feels right to have the file that talks about the javascript load order in the js directory alongside the javascripts. Also, it’s a file that doesn’t need referencing except during development (since after dev the cache will get written and Apache wills start hitting that file).