I've got a somewhat primitive framework I've been using for most of my projects, but a general design issue came to mind that I haven't been able to work out yet. For a given application, should I separate the application-specific class structure from the framework's structure, or is building on top of the framework not such a bad thing?
For example, say I had a framework with a base Controller class and extended it for a given part of my application. Which arrangement makes the most sense, and why?
Class Structure A:
Intuitive, easy to find source files when debugging.
File naming/directory structure mirrors class heirarchy.
- Framework_Control "Framework\Control.php"
- Framework_Control_Index "Framework\Control\Index.php"
- Framework_Control_Home "Framework\Control\Home.php"
- Framework_Control_Contact "Framework\Control\Contact.php"
- Framework_Control_About "Framework\Control\About.php"
Class Structure B:
Keeps framework modular and easily to replace/update.
Adds some complexity to directory structure, directory/file naming no longer follows class heirarchy all the time.
- Framework_Control "Framework\Control.php"
- Application_Control_Index "Application\Control\Index.php"
- Application_Control_Home "Application\Control\Home.php"
- Application_Control_Contact "Application\Control\Contact.php"
- Application_Control_About "Application\Control\About.php"
I know overall it's going to come down to personal preference, but I want to make sure I weigh out all the pros and cons before I decide which way to go. It really comes down to class naming and directory structure as the actual hierarchy would remain the same in either case.
I would suggest that you view your source code in two different categories, external dependencies or code that is used across multiple sites and not native to any single one and native dependencies or the code that is native to the particular site that you're working on.
It sounds like Framework/Control.php is part of a larger external dependency and should be managed as such, while the Application/Control files are all native the particular website.
Using this differentiation in our code structure has made it much easier to reuse our in-house framework between multiple sites very easily.
As a final thought, you might consider looking at what the major frameworks out there are doing such as Zend Framework, Symfony and others. Even though the entire framework might be more than you want the structure of the frameworks can provide a lot of insights into common, good practices that are being used by PHP developers everywhere.
What it really comes down to is what are you going to do when you update Framework\Control.php in Application XYZ. Are you going to go back to Application ABC and make that same change? What if it's a critical bug?
For maintainability of all of your projects I'd go with your second option.
Related
What I'm looking for is a way to remove the model from a set of PHP files that make up a website. It's difficult (for me) to explain.
By models I mean models in an MVC sense.
As an example say I have this website:
index.php
about.php
shop.php
checkout.php
All of the above PHP files use the same database. I have separated the views by adding templates using a view.php file that renders the correct template with values passed to it.
I am not looking to use a framework that's already out there. I'm looking at writing my own in some senses, with only the bits I need to use in it.
If anyone would like to explain why this is not necessary, or a better way of doing things, then I'm open to that too.
Thanks in advance.
Writing you own MVC framework will take time, but you will learn a lot in the process. So, if you have the time/resources to do it I definitely encourage you to do so.
In this context here are some small pieces of advise that may help you:
Create your domain model first. I'm assuming that you are going in the OO way, so think about your domain problem and create the abstractions that best represent your problem. Try to keep it decoupled from cross-cutting concerns, like persistence.
Test a lot, test often. Try to test (and run your tests) as you create your domain model. This will be specially valuable when in 6 months you add a new feature and want to make sure that you haven't break anything. If you can separate your domain model from anything external (like the persistence layer or third party web services) the testing it is going to be a lot simpler. Today PHPUnit is pretty much the de-facto standard for unit testing in PHP.
You don't have to write everything from scratch. There are a lot of libraries that can help you to ease the development of an MVC framework, so that you can concentrate on what you really want to develop. For example, you could use Slim to handle the page routing or you could delegate the persistence stuff to Doctrine 2.
It is always nice to analyze how other frameworks solve things. You may want to look at products like Symfony or Kohana or even check how Elgg handles its views system. Also, if you want to check out something radically different you can take a look at Seaside's architecture.
Coming back to your original question, for me the key is to keep things from different layers as decoupled as possible. While I have only used the version 1, Doctrine 2 seems like a good candidate for persistence, since it allows you to create a domain model that is quite independent from the DB. This is a huge step. The second thing is how handle the view system. This is quite developer-taste dependent. For example, I like to model everything with objects, so I like Seaside's approach. On the other hand, Elgg's way of handling views is quite nice and maybe fits better with the way things are handled in PHP. Here is when you may benefit on doing some research before deciding on a route to go.
HTH
As someone who has written his own PHP framework, and with the same sensibility as yours, I can tell you that using a framework is a fine thing to do. That said, start by writing your own - you'll gain greater appreciation for the true structure and utility of a framework.
You'll want to learn about the Singleton object pattern. It is a major differentiator in the kinds of objects you can develop in your framework.
When you have written a few models that your files/controllers (presuming MVC) include, you will begin to see where to abstract a 'base mode' from which others extend (hint: the DB singleton).
When you start pulling in configs and the like, then you'll have your first framework object from which all other bases do their extension.
I am thinking to create my own simple MVC framework in PHP. I thought it would be good idea to improve my skill in PHP.
I have a questions about admin section, how do you create it?
In kohana, controllers can be in sub-folders:
for example: /controller/admin/admin.php
What is other way? As long code can be shared to parent helpers/libs or parent models.
First thing you have to notice is that Kohana is a HMVC framework. It is a bit different beast, compared to the rest of bunch. In this case admin is not so much a module as it is a namespace (though kohana is still using the PEAR-like "namespacing") for controllers and other classes.
This way additionally lets separate out other parts of application .. lets say you have a lot of code dealing with tagging and tag clouds. Then you can create another namespace/module just for that. And use them as sub-controllers. That's one of HMVC perks.
One other way of separating admin section from general application would be to treat them as separate applications, but then you need another location for shared components (most likely from model layer). Then you have more then one /appliation/ folder on your server.
Or you can do combination of two.
I am assuming here that the reason you want to create yet another MVC framework is indeed to improve your PHP skills, and not to try to create a framework to use in a daily basis at your company, for example. I know that you didn't ask for such advice, but there are so many great MVC frameworks out there (and you probably know many of them already). I think it is a great approach to learn design patterns and increment your skills in PHP (or any other language), though.
As of your question, the most common approaches I have seen is to use different directories, like the "admin" subdirectory you mentioned, for then enforce name suffixes or prefixes for the controllers, like "UsersAdminController.php" e.g, adding "AdminController" at the end.
One thing that using a subdirectory may be better is that it enforces a better separation of concerns, and reduces the possibility of you ending with a lot of classes with simmilar in the same directory, which may cause confusion at some point.
I think creating your own framework is a great idea, if only as an exercise to better understand the structure behind a web app.
I'm doing it so myself, and I think your approach depends very much on how far you want to go.
I started with a multilanguage support subsystem and user database management classes and now I'm moving to content management and database query sanitization.
I keep my classes separated in files and grouped by subsystems in folders, like multilang or admin, I think it's the best approach.
I wrote in PHP a learning management system for a small private school. It started a while ago when a lot of programming stuff was new to me. It is mostly scripts and includes based and doesn't contain classes or any MVC style organization, but it has grown big. What I am trying to do is to organize the current code without rewriting, so that it is good for fast iterations.
So far I changed it so that every role has its own folder/index/actions and all of them use one shared lib.php file to do sql queries and other related actions.
I talked to couple of MVC folks and considered PHPCake and Tonic as an option, but those seem to change dramatically what I already have. I am not sure if it just in my practice, but I just don't see how MVC will make it easier for me to develop faster. Can someone give tips or experience advise/opinions or maybe some helpful links. Thanks.
MVC can be a useful framework for developing applications into logically separated components in a somewhat 'natural' way. It can increase your ability to develop quickly based mainly off the fact that some portions of the framework will end up being reusable and allow you to leverage that fact to develop new views and similar quickly. However, it is not necessary to use any particular framework or scheme to develop quickly as it can be done with a properly designed application of any nature.
An important thing to consider when developing an application in such a manner is code reuse. For example, making it simple to display pages with common layouts through a centralized mechanism, or having user-related functions placed into a user class/function set which can be reused site-wide instead of having individual functionality to handle it on each page.
In terms of modifying an existing application, I would focus on trying to centralize the components you are able to and making use of those components henceforth. This also makes modifying routines simpler because instead of potentially changing functionality on many areas of the codebase, you can change it in a single location and effect the application as a whole.
Trying to make a pattern fit a problem is a very silly approach. Patterns are what code is not what what the code should be. In any object-oriented project presenting a user interface there will be instances of models, views and controllers - but there will also be lots of other patterns in the code - observers, decorators, iterators and more. They are useful learning constructs (e.g. "Here's how to implement a factory to build objects from relational data") and (human) language constructs (e.g. "That database connection class should be implemented as a singleton"). They are not design constructs.
so that every role has its own folder/index/actions
Unless you've got a rather unusual definition of 'role', this architecture makes no sense. The most common criteria for dividing up high-level functionality are separation of concerns and grouping around common data sources.
You've mentioned frameworks - trying to adapt existing code to fit into a framework is usually a bad idea - it won't fit. They can be of benefit in structure your application and reducing the amount of effort if you sse them from the start of the project. Not from the middle / end.
Put the new code you write under test. As the old code isn't, put it under test part-by-part as well. At the moment you've put everything under test, you should be fine for faster iterations.
I've recently inherited a medium-sized php site which is horribly coded. It violates every best-practices methodology, from MVC to DRY, is vulnerable to SQL-injection and everything in between.
I've visited the other questions and already put everything on a VCS and am considering the framework alternatives. However I'd like your opinions on a framework that lets me slowly migrate from the actual site to a framework controlled one.
Thanks.
Zend Framework would actually be the best choice in my opinion, as it has a great use-at-will structure and it is no full-stack framework like most of the others.
That means that you can start with migrating the model-layer first without having to touch the view or controller part. And even when it comes to the controller part, you could first put everything into controllers without having to rely on the router, so you could still use your old URLs.
I will put my vote in for CakePHP (http://www.cakephp.org). It has the ability to manage everything very nicely.
Template
This will allow you to create the base template / layout for the site. It is the main body of the site. You can store multiple layouts all in the views/layouts directory. You can identify what layout you want to use for any given page within the site.
Static Content
If you have static content pages, they all reside in views/pages. These will load into the layout wherever you put the <?php echo $content_for_layout; ?>.
Custom Code
Many times, you will have custom code that may not fit in the framework. No worries, you can add this to the libs or vendors folders and call the functionality from there.
Speedy Upgrade Via Bake
One of the cool features of cake is the bake feature. Once you have added your schema to the database, you can use bake to have CakePHP write all of the models (with relationships), the controllers (with basic CRUD and admin sections), and the views for each action within the controller.
Cake has been a great fit for all of the projects I have worked on. It keeps the code well organized, has a very active community, and their documentation is very well written and understandable.
UPDATE: For additional information about some sites who use cakephp you can see a sample list here: http://book.cakephp.org/view/510/Sites-in-the-wild
A few notable (high traffic sites) would be:
https://addons.mozilla.org
http://scratch.mit.edu/
Kohana is my framework of choice, but I won't start to wax about its good points, I'm sure it can do anything the others can do.
Faced with the same legacy codebase problem as you described, my response was to take Kohana and disable the request routing, so that you can just use it as an include on a page-by-page basis until you're ready.
The changes are minimal; if you're interested the fork of kohana is up on github
You may need to adjust the php error level settings depending on the kludgey-ness of your codebase ;)
Zend Framework is awesome.
Even better, this excellent post from Chris Abernethy shows how to gradually migrate an existing site from a twisted plate of pasta into a nice MVC structure using ZF.
Take a look at Fat-Free Framework. It allows both procedural and OOP code, so you can have a two-stage approach. If the base code is currently procedural, then you can focus all efforts first on transformation to MVC architecture. That way you can have a proof of concept that all future efforts can be as fruitful as the first phase. Then you can move too strictly-OOP. No other framework will give you this kind of flexibility. And your end-users will not feel any delays, or worse, a culture shock.
You will get as many answers as framework users there are in this place. It's obvious that someone using framework of his choice will advice it to the others.
I opt for symfony.
However, if you care about best practices than both symfony and Zend are a good (and only) choice.
This sounds like a massive undertaking.
I can only recommend CakePHP because that is what I use, but that does not mean another framework would be less or more suitable. They're all pretty much the same when it boils down to it.
Choose on whatever criteria you wish, such as public support/user base (Cake's is massive), feel, name, colours on the webpage, whatever. But my advice is to stick with that choice and ride the learning curve.
All the frameworks mentioned are good, but you will need to rewrite loads of things like the queries. You might not want to use an ORM like Doctrine or Eloquent. Just stick with something like Active Records. Codeigniter, CakePHP and Yii will do just fine.
but it is not going to be an easy task. be warned!
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?
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.
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.
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.
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.
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.
I have refactored a big PHP project to make it more MVC compliant.
I found especially usefull to create a DAO layer to centralize all database accesses. I created a daoFactory function, which creates the DAO and injects the database handle into it (also the logger, I used log4php, got injected).
For the DAO, i used a lot the functionalities of the database (mysql), like stored procedure and triggers. I completly agree with Doug T. about avoid over-abstraction, especially for database access : if you use the DB properly (prepared statements, etc.) you don't need any ORM and your code will be much faster. But of course you need to learn mysql (or postgress) and you become dependant on it (especially if you use a lot of stored procedure, like I tend to do).
I am currently refactoring a step further, using the Slim php framework and moving toward a restfull api : in this case there is no view anymore because everything is outputted as json. But I still use smarty because its caching works well and I know it.
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.
MVC doesn't work
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)
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.