I've been using the CodeIgniter framework, however after learning Java and awesome features like Interfaces, Abstract classes, packages, and that PHP 5 also supports most of these features, I'm ready to graduate and build a real OO framework in PHP which uses all of these features (including namespaces), so I can build much more elegant designs.
What I'm thinking of is that rather than everything in the system sharing a single $this-> object like its done in CodeIgniter, e.g:
$this->load->model('box');
$this->box->something();
You would do the following to load the Box model and to call its something() method.
$box = new Framework\Models\Box();
$box->something();
Or the following
abstract class BaseController
{
public function getModel($name)
{
$model = new Framework\Models\$model(); //Is this valid code?
return $model;
}
}
class MyController extends BaseController
{
public function index()
{
$box = $this->getModel('box');
$box->something();
}
}
Are there any suggestions/pointers for building this, such as which minimum system classes I would need for the framework, what namespaces I should have, or any other features?
One thing I've noticed is that a framework is usually built for a specific purpose. Generic frameworks (like CodeIgniter) are good for smaller sites and getting things up and running quickly. However once you have specific things, which fall outside of the generic framework building your own does become a reality.
The only thing I would suggest is to be consistent. That is relentlessly consistent. If you decide to name things in camelCase then don't deviate from that. Or if you decide to use the NounVerb convention of naming methods i.e. spaceJump then don't switch to jumpSpace even if it 'sounds' better at the time.
Choose how you'll accept parameters and be consistent on that. Will you accept only parameters or associative arrays of parameters? Choose and stick with it.
I would also not over-engineer before you've written anything. The consistency thing will take you pretty far before you'll need to refactor... but I wouldn't be afraid to do that as well. (A unit test or two should ease those fears).
Yup, there's usually no right or wrong way to do things as long as you're consistent. Did I mention...
Be Consistent!
A lot of experience is needed to build a technical framework (no offense) and there are already 1'000's of CMS/basic objects (session management, ORM, etc.) framworks/libraries.
Instead of wasting precious time (no offense again), you better have to:
Evaluate and select the framework that better suits your needs (some have a really good OO architecture).
Learn will using this good framework.
Build your own OO business/application framework. (This is where you can learn, differentiate and create value).
You can build your own but why not make use of the vast libraries included with frameworks available and if required extend their functionality.
Why don't you take a look at the Zend framework.
It's fairly quick to get started and includes a lot of useful libraries and classes as standard. It's good for personal projects if your just looking to gain more experience with OOP.
http://framework.zend.com/
I would look at Kohana. It came out of CodeIgnitor, and loading Models etc is done just the way you proposed.
Check out their core features, many of which relate directly to your question (I've highlighted those):
How is Kohana Different?
Although Kohana reuses many common design patterns and concepts, there are some things that make Kohana stand out:
Community, not company, driven. Kohana development is driven by a team of dedicated people that need a framework for fast, powerful solutions.
Strict PHP 5 OOP. Offers many benefits: visibility protection, automatic class loading, overloading, interfaces, abstracts, and singletons.
Extremely lightweight. Kohana has no dependencies on PECL extensions or PEAR libraries. Large, monolithic libraries are avoided in favor of optimized solutions.
GET, POST, COOKIE, and SESSION arrays all work as expected. Kohana does not limit your access to global data, but offers filtering and XSS protection.
True auto-loading of classes. True on-demand loading of classes, as they are requested in your application.
No namespace conflicts. All classes are suffixed to allow similar names between components, for a more coherent API.
Cascading resources offer unparalleled extensibility. Almost every part of Kohana can be overloaded or extended without editing core system files. Modules allow multi-file plugins to be added to your application, transparently.
Library drivers and API consistency. Libraries can use different "drivers" to handle different external APIs transparently. For example, multiple session storage options are available (database, cookie, and native), but the same interface is used for all of them. This allows new drivers to be developed for existing libraries, which keeps the API consistent and transparent.
Powerful event handler. Observer-style event handlers allow for extreme levels of customization potential.
Rapid development cycle. Rapid development results in faster response to user bugs and requests.
Related
I am using my own home grown PHP framework and it is heavily based on components mostly from pear and Zend but lately there are some better components coming up at Composer
As my apps are growing it becomes harder to switch between components, and I am wondering if there is a way I can design my programs differently. In a way that would allow me to use components like the opposite of abstract classes.
I am thinking there should be a way for me to create my own classes, which in turn just hook in to pear or zend and use those classes like as if they wore interfaces or abstract classes. Of course they would be doing the actual work and I would just link to them.
Hypothetically if I have been using pear Config/Lite, which can only work with ini and array files, and now I like to switch to pear config or Zend config to get the benefit of saving the data in a database then there should be an easy way to switch without changing all my code since what they implement is exactly the same thing.
I am asking because I been using pears Net/URL/Mapper, which isn't bad but I found something that would also take care of the dispatching, and is being actively developed. Also I am sure that this kind of situation will come up again and again.
You want to look for something like the facade design pattern, or just use delegation / composition. However beware, using something like a facade can lead to a lot of unneeded complexity as you add layers of abstraction. I recommend you read some php design patterns, especially delegation / composition of objects to get a feel for how that might fit your case.
You should use composition for this IMO. Have the classes in your library expose their own public interface, which the rest of your code depends on. If you ever change the underpinnings of a component from say PEAR to Zend, just ensure all the original public methods still honor the previous version and you should be golden. You can formalize these interfaces with the interface keyword if you wish, but that is beyond the scope of this answer ;)
I'm currently developing a framework which uses an object of a Core class (this class has huge functionality & makes the framework working). The framework follows MVC architecture & has loosely coupled Model, Control, View classes. Theses classes need a reference to the Core class heavily. What I've done so far is: creating single object of the Core class & referencing to it by PHP keyword global in Model, Control, View classes.
I don't like using this approach mainly because:
This way is not true object oriented way in my sense
The IDE (netbeans) can't provide documentation to the object of the Core class - a pain for developers who will be using this framework.
I'm really worried about performance issues - have no idea whether global is slower or whatever.
I've searched & did not find any information regarding performance issue. I've also searched stackoverflow & found Does using global create any overhead? & The advantage / disadvantage between global variables and function parameters in PHP? etc links but they don't contain much information. Right now my main concern is performance, so please help.
I must agree with NevilleK, that you Core` class sounds line an God Object antipattern.
And for anyone dumb enough to suggest use of singletons/registries i would suggest to do a little research on the subject. They create the same global state as your classical global variables.
Global state is not so much matter of performance ( though in php it has some minor impact ), but it created untestable and tightly coupled code.
You really should look into the Dependency Injection. That might show you another way , which does not require to have such a Core class in your code.
Some additional videos for you:
Global State and Singletons
Don't Look For Things!
Advanced OO Patterns
Cake is a Lie
Clean Code: Arguments
I've solved a similar problem in Agile Toolkit by creating a different pattern for adding object and using it system-wide. This passes a property to a newly created objects called "api" which always references Application class.
Application class is not really a God class but it delegates all sorts of functionality to system controllers, pages etc. This screencast explains how the very basic objects are structured, it might be something you are also looking for:
http://www.youtube.com/watch?v=bUNEHqYVOYs
Firstly, whilst you are concerned with performance, you may want to read http://en.wikipedia.org/wiki/God_object first - your "core" class sounds like a "God object", which is a fairly well-established anti pattern.
In terms of performance - the best way to find out is to test it. If you're writing a framework, I'm assuming you're writing unit tests to validate it's behaviour; it's not hard to extend that unit testing to include simple performance metrics. You might also invest in test scripts using JMeter or similar to exercise a "reference implementation" of a few pages built using the framework. You'll get far better information on your specific situation from doing this than by trying to optimize the design based on Stack Overflow's collective knowledge of the general way things work.
In general, I'd say that having a global class shouldn't impact performance too much, as long as it isn't doing much work. Simply loading the class into memory, parsing it, etc. does have a performance impact - but it's not likely to be measurably slower than any other routes you might take.
If, however, your "core" class does lots of initialization logic when it's accessed by the page, it's obviously going to impact performance.
I'm planning on creating a small web app using PHP. The last time I used PHP was sometime around 2002/2003 where the code tended to be a horrid mash of PHP/HTML and Javascript shoved in a single file. I think I might have even been using PHP3...
I now want to relearn and want to know what's changed and what helper libraries and tooklits exist that might save me from unknowingly reinventing things.
E.g is there a "standard" MySQL library, or do we still use the basic PHP functions (as a side question, do stored procedures work in MySQL yet?)? What do I need to know in order to make a "modern" website that doesn't rely on whole page HTML form posts to send data back to the server, etc.
Welcome back. PHP has gotten better!
If you can, start using 5.3 from the start; be aware though that many web hosts don't support it yet (if that is an issue). If confronted with PHP 4, run away screaming: It is no longer fit for production use.
The major development is finally proper OOP in PHP 5. Getting familiar with that is the only really mandatory thing in my eyes.
Several popular frameworks have evolved that do a lot of low-level work for you. The Zend Framework is a very high-quality code base to work with and my personal favourite because it's also usable as a component library that doesn't force its design principles upon you; there are others. (Here is a comparison site).
PDO is definitely the low-level database class de jour. It has parametrized queries preventing SQL injection and supports a number of databases.
The MVC design pattern is a very popular design pattern for building dynamic web sites and applications, and is embedded as a design philosophy into most PHP frameworks.
Class Autoloading is a great new PHP 5 feature.
A relatively little-noticed new development is the Standard PHP Library that brings clean, OOP solutions to everyday PHP problems. For example the DirectoryIterator that allows for easy recursive walking through directories; the ArrayObject provides an OOP interface to many (but not all) core array functions.
The DateTime class will replace the old UNIX timestamps over time. It provides improved functionality, and can work with dates beyond the 32 bit timestamp's 1970-2038 range.
This is some of the stuff under the hood. There are important client-side developments you want to be at least aware of; namely Ajax to fetch server-side data without reloading the page, and using a JavaScript Framework like jQuery to deal with the details. CSS you will already be familiar with.
Move to Zend framework when you start , first do some good research on OOP. Make sure you are understanding well terms as polymorphizm and inheritance. The last thing you must learn are php patterns like singletone pattern and factory pattern , abstract classes and interface implementation.
Here are solutions:
Use ORM to abstract from SQL >> E.g is there a "standard" MySQL library, or do we still use the basic PHP functions
Use MVC framework >> helper libraries and tooklits exist
Use Javascript for better user experience JS Frameworks >> make a "modern" website
My team have to maintain a large php application that was very poorly written. It is a mix of html, javascript and SQL on top of a large poorly designed database (ex. it has a table with few hundreds of columns). The only advantage of the codebase is that it works.
We are constantly bug fixing and rewriting parts of it.
I would like to give a structure to the rewrites we do, so I've though about integrating an mvc framework in to the codebase. Could you suggest any good framework for environment?
Here is a list of things that the I would expect from such framework:
The API must be very stable. We can't afford to rewrite the code on each release.
Custom session management or at least working on standard $_SESSION[] (To be able to talk with old code).
Custom authentication.
Using the raw SQL should be well supported (The database is hard to represent in terms of objects).
It shouldn't assume that I will have a table per controller.
I suggest Zend Framework for this purpose because it is a glue framework. With ZF you are not forced into the harness of how the framework expects you to work with it. You can pick what you want and gradually replace your legacy code with code from ZF. It also supports all the things you mentioned.
In addition, I suggest to run the various QA Tools found at phpqatools.org to support you in debugging and refactoring.
Framework comparisons
http://www.phpframeworks.com/
http://php-frameworks.net/
I'm echoing Zend just to list how it fits your specific requirements:
The API must be very stable. We can't afford to rewrite the code on each release.
As mentioned, the API tends to be stable between minor releases. Major releases with changes shouldn't be hard to integrate.
Custom session management or at least working on standard $_SESSION[] (To be able to talk with old code).
Zend_Session does exactly what you want. The default session store is $_SESSION to which Zend adds a namespace concept. Your existing code should be fine, and any new code can use the Zend object to ensure there are no variable name overlaps.
Custom authentication.
Zend_Auth has a few authentication backends, but it is designed to allow you to implement your own auth.
Using the raw SQL should be well supported (The database is hard to represent in terms of objects).
Zend_DB implements the table gateway pattern which will allow you to access the data via object; however, you can also just use SQL directly and get the results as arrays.
It shouldn't assume that I will have a table per controller.
Zend_Controller and the rest of Zend's MVC implementation make no assumptions about the Model, leaving that completely up to you. I'm sure some people don't like that, but it is the one area of MVC design that varies greatly from project to project - so that's left completely to the developer. You could extend some of the DB classes, or just use the existing DB access code.
That's an example of the pick-and-choose mentality of the Zend Framework. You really can use any of the library by itself. That should work well with your project. For example, you could use Zend_View without the rest of the MVC classes just to move your presentation into templates. Or just use Zend_Auth to replace the existing Auth system. With Zend you can slowly move your project into a more structured state, little by little.
why are some frameworks slow?
for example how comes that zend frameworks are slower than code igniter? if you donĀ“t use a lot of classes, just chose the classes of your needs, then it shouldn't get slow?
are you forced to use a lot of classes with zend framework or are they preloading a lot of classes automatically?
It depends how much they have taken care of the speed when writing the code of the framework. CodeIgniter has been written amazingly always keeping the speed in mind. Also big frameworks autoload a lot of nuts and bolts making the framework slower. However, if you are experienced with any of these frameworks, you can speed up the framework to a good deal by filtering out the stuff that you think is not necessary for your current project.
Zend_Loader_Autoloader automatically loads classes when they are requested, so there are no "unneeded classes". There are some tutorials on how to speed up Zend framework powered applications, ie. commenting out "require_once's" and using the PluginLoader include file cache explained here (along with some other methods) http://framework.zend.com/manual/en/performance.html
There are some things you can't beat.
Any framework can be
Simple
Extensible
Fast
Understandable
...
But you can't have all at once. It can't be fast AND extensible. If it is extensible, it has to check if you want to use the internal class or your own. It has to define interfaces for everything. Therefore it has to load a lot of files (for classes and interfaces, abstracts, ...). Note the difference between loading class MySQLDB class (one class for single purpose) and DbLayer_Interface, DbLayer_Abstract, DbLayer_MySQL (complete infrastructure, where you can substitute any part of it).
Also with easy comes with some magic. The more the framework does for you, the more "magic" is going on under the hood. THe magic can be fast, as it's done for one purpose and doesn't have to check if you want to change anything.
That's why ZF is slower then CI and others. Any class can be replaced. For example we extended and injected custom Db_Select class, that handles multilingual column names automatically. You make select like SELECT table.name_en FROM table and the underlaying logic transforms it to SELECT table.name_en, table.name_fr, table.name_de FROM table on the fly... That's the power you receive in trade for speed ;)