Right way(tm) to use entities and repositories in Symfony2/Doctrine - php

Okay, so this is not a specific "what am I doing wrong" coding question, sorry. If it's better suited to one of the other stack* sites, let me know.
Today I was fired from a contracting gig where they're using Symfony2 and Doctrine. I'm a senior programmer, but not very experienced in either of these two frameworks - though I felt sure I could get up and running fast. After all, it's PHP - what could go wrong?</cynicism>
My assigned teammate (brought on as a "Symfony expert", so I was at first perfectly happy to watch and learn) kept insisting that 'entities should be immutable, and all custom business logic should go in repositories'. Reading the documentation (the getting started guide, no less) this simply seems to be untrue - repositories are for 'custom getters', but data manipulation goes in entities (Doctrine-speak for models). Made perfect sense to me (a database can't know if bitflag 1 means 'active' and 2 'confirmedEmail'), but the guy was adament. When pressed for an example of how I should add custom data editing methods in a repository (since I fooled around for a bit but couldn't get Symfony to see them without going through hoops and manually replacing entities with repositories), he sent a code sample implementing a more or less manual update query. Then why use an ORM in the first place?
He also repeatedly stated that one should never touch entities, since changes might get overwritten when they're regenerated. Apart from the fact that Doctrine seems to normally assume you write entities and generate the database scheme from those - not the other way around - unless my knowledge of the English language is mysteriously failing, the manual seems to clearly state that when (re)generating entities, existing methods are left alone so it's perfectly safe.
End of story, client decided we couldn't work together and chose the other guy. They also had this weird argumentation where I was "the most expensive guy on the project" and I "wasn't providing enough seniorness". I did point out that telling others they're simply wrong and getting yelled at for it (true story, well, they were typing in ALL CAPS which counts as yelling in my book) didn't make me very happy either, so that was that - I wished them the best of luck and we went seperate ways.
Am I losing my mind here? Am I missing something glaringly obvious? Or is the other guy simply misguided (my current working theory) as to what belongs in entities and what in repositories? Anyone experienced in Doctrine/Symfony care to elaborate? I'd be happy to provide more specific examples of what we were supposed to be building. I'm mostly extremely curious to learn the "right way"(tm) of doing things in these frameworks (for future reference, they didn't quite whet my appetite yet), if there indeed is a better way to abstrahate model code away from entities.

Symfony2 is built to allow you to choose how you answer these questions. It's structured to be modular, allowing you to pick and use only the components you need. There are many common design patterns but obviously a team needs to pick one and stick with it. If you guys couldn't do that, it is probably good that you didn't try to complete a project together.
I consider it good practice in Symfony2 to keep the entities and controllers as sparse and easy to read as possible. I put almost nothing in repositories that is not building queries and running them. Pretty much everything else should go in a service of one kind or another. How you enforce separation of concerns among services is left as an exercise to the development team.
Here's an article talking about a set of common design patterns:
http://www.ricardclau.com/2012/02/where-is-the-model-in-symfony2-entities-repositories-and-services/
Another good thing to look at when getting a handle on how to do things and where to put thins, is take a through some of the core/big symfony bundles, see where they put things and how much the different styles of organization make sense for different purposes (some do it better than others).
His specific claims:
1) entities should be immutable
This seems to cause you to lose out of much of the functionality provided by Doctrine's EntityManger and UnitOfWork. If you then update them only using manual queries, you will have to reload your entities to get them to match the updated DB state. I guess this makes sense if you want to load one state at the start of a request and progressively process updates to the DB based solely on the original data. (Doctrine does provide functionality in the EntityManger to mark Entities as read-only so that changes to them will not be persisted.)
2) all custom business logic should go in repositories
In Symfony, replace 'repositories' with 'services' and this would be pretty much 100% correct. Repositories should generally only hold code for re-usable complicated queries beyond what Doctrine's findBy methods get you.
3) He also repeatedly stated that one should never touch entities, since changes might get overwritten when they're regenerated.
True...ish as far as the overwriting goes. Whenever you add changes to your entities from a schema file using doctrine command line tools this 'could' happen so backups are made. However, the tool is fairly smart and I haven't seen any of my changes overwritten.
Your specific claims:
1) but data manipulation goes in entities (Doctrine-speak for models)
Entities are not the 'M' in 'MVC' but are generally just the part of the 'M' where the state is stored. The related logic is generally kept separate in forms, data transformers, validators and other services.
2) he sent a code sample implementing a more or less manual update query. Then why use an ORM in the first place?
Even if you only update data through manual queries rather than using the EntityManger, Doctrine provides many other advantages: Programatic Query Generation, Input Cleaning, Entity Hyrdation, Query/Result Caching, Nested Transactions, ETC.
Just hearing your side of the story, it sounds like a more senior developer with less framework experience working with a less senior developer with more framework experience. I would guess that the other developer had never worked solo/lead on a greenfield Symfony2 project and was just parroting the design decisions made by his prior Senior developer.
Neither of you sounds completely 'right' and both of you were wrong in that you got bogged down in an argument that had to be adjudicated by your client. Maybe if you had been less keen on showing yourself right, and been more willing to utilize and explore your partner's experience by delving into the the reasons behind the practices he was advocating you might have been able to turn this into a success.... Or perhaps the other developer was just a tool and you saved yourself a boatload of stress and drama trying to cover his ass :)

Related

Refactoring Code To Psr standard and making the code testable in Laravel 4

When i started making a mobile app (that uses laravel on the server) i decided to not dig into testing or coding standards as i thought it was better to actually get a working app first.
A few months later i have a working app but my code doesn't follow any standards and nor have i written any tests.
Current directory structure i'm using is:
app/controllers : Contains all the controllers the app uses. The controllers aren't exactly thin, they contain most of the logic and some of them even have multiple conditional statements (if/else). All the database interactions occur in the controllers.
app/models : Define relationships with other models and contain certain functions relative to the particular model eg. A validate function.
app/libraries : contain custom helper functions.
app/database : contains the migrations and seeds.
My app is currently working and the reason for the slack is probably because i work alone on the app.
My concerns:
Should i go ahead and release the app and then see if its even worth
making the effort to refactor or should i first refactor.
I do wish to refactor the code but i'm unsure on as to what approach
i should take. Should i first get the standards right and then make
my code testable? Or should i not worry about standards( and
continue using classmap to autoload) and just try and make my code
testable?
How should i structure my files?
Where should i place interfaces,abstract classes etc?
Note: I am digging into testing and coding standards from whatever resources i can find, but if you guys could point me to some resource i would appreciate it.
Oh dear. Classic definition of legacy code, is code with no unit tests. So now you are in that unfortunate position where, if you are ever going to have to amend/enhance/resuse this code base, you are going to have to absorb a significant cost. The further away from your current implementation you get, the higher that cost is going to get. That's called technical debt. Having testable code doesn't get rid of it though, it simply reduces the interest rate.
Should you do it? Well if you release now, and it achieves some popularity and therefore need to do more to it...
If it's going to be received with total indifference or screams of dismay, then there's no point in releasing it at all, in fact that would be counter-productive.
Should you choose to carry on with the code base, I can't see any efficient way to re-factor for a coding standard without a unit test to prove you haven't broken the app in doing so. If you find a coding standard where testable and tested aren't a key part of it, ignore it, it's drivel.
Of course you still have the problem of how do you change code to make it testable without breaking it. I suspect you can iterate towards that with say delegation in your fat controllers without too much of a difficulty.
Two key points.
Have at least some test first, even if it's a wholly manual one, say a printout of the web page before you do anything. A set of integration tests, perhaps using an automation suite would be very useful, especially if you already have a coupling problem.
The other is, don't make too many changes at once and by too many I mean how many operations in the app will be affected by this code.
Robert C Martin's (no affiliation whatsoever) Working With Legacy Code would be a good purchase if you want to learn more.
Hopefully this lesson has already been learnt. Don't do this again.
Last but not least doing this sort of exercise is a great learning experience, rest assured you will run into situations (lots of them) where this perennial mistake has been made.

How do I design a simple web application?

I have basic knowledge of PHP and had done a few small personal projects before. Since my programs were small and usually consisted of less than five classes, I jumped into coding right away -- thinking of my database tables and user interface design as I went along. The problem was that I often found myself lost in my own ideas at the middle of my project. Hence, I thought that some form of formal planning would be practical to begin with.
I have been reading several software engineering books lately. One book said that, in web engineering, agile processes such as extreme programming and scrum should be used. I was introduced to tools such as use cases, CRC cards, and UML -- all I believe are too complicated and impractical for the simple projects I have in mind.
On the other hand, a web article I read simply suggested a rough sketch of the UI, a sitemap, and a simple workflow diagram. They seemed practical but too rudimentary and informal.
What would be a practical but formal approach to building a simple web application?
Don't be so quick to discard use cases, or some similar concept, e.g. 'user stories'. The benefit these tools bring is to make you think about what the site needs to do. That can guide all the further technical work, and help you focus on what's important instead of getting lost in interesting but low-value work.
Think about the top n things the site needs to do, and for each of these list out:
the ultimate goal for the user in this particular case
the kinds of people and other systems involved (actors, in use-case terminology)
what needs to be in place before starting this activity (the preconditions)
the basic steps the primary actor needs to perform to successfully achieve the goal
what should happen if one of those steps can't be completed
what the system looks like if the case is successfully completed (the postconditions)
what the system should look like if there were errors along the way
With a handful of these use cases, you can get an overall feel for what needs to be built to fulfill the goals. If it starts to look like too much work, you can look at which goals are of greater or lesser importance, and cut or defer those that provide less value. And if you think of new things the site should do, the existing use cases either:
provide a home for that feature, so modify the appropriate use case to incorporate the feature,
don't provide a home, indicating you missed a use case or discovered a new one, so you should elaborate on it as described above, or
don't provide a home, and therefore indicate the isn't necessary and so you shouldn't spend time on it.
The trick is to pick the proper level of abstraction and formality. Work at a high level, write informally, and you can knock these out quickly. When they're no longer useful (you have most of the application sketched out and are now heads-down working on details), put them aside. When you think of new things, see if they fit. Lather, rinse, repeat.
You have to ask yourself a few simple questions first:
1) Do I want to re-use and extend this code later?
If so, it may be a good idea to use some basic pattern such as MVC (Model-View-Controller) or use one of the many PHP frameworks available. The already established frameworks are more format in their design and how you use it. You could always use them as a basis to design your own as well.
2) Is the site you are making going to grow or change frequently? If the site isn't going to change much you could probably make something very simple and not worry too much about good design principles.
3) Do you want to learn and apply some of the techniques you mentioned? If so, then go to town and try the different techniques and see which ones appeal to you.
These kinds of questions will help you decide how you want to decide you build your website.
Start small, mock up a few simple screens, their database structure, etc. Use whatever method works for you - if that is UML diagrams, then fine. Get something finished, evaluate, and iterate from there.
This may not be quite what you are looking for, but also do yourself a favor and choose a framework such as CodeIgniter to make your life easier writing your server-side code. And similarly, consider using a client-side framework such as jQuery. This will make it easier for you when you are ready to actually sit down and write the code.
The Bare Essentials
I find there is a (roughly) four-step process that make application development a lot easier, and helps me avoid getting lost along the way. I make no pretense about using agile development methods. This is just the way I work.
Decide what the application needs to do. By "need", I mean, absolutely must do and nothing else. If it's a "nice to have" feature, write it down and come back to it later.
Figure out what data you need to keep track of to make everything work. Slugs, titles, datetimes, etc. Design the database. (I use MySQL Workbench for this.)
With your feature shortlist, prototype a user-interface with Balsamiq. Remember to add only the features you need right now.
You might consider doing HTML / CSS templates in this step.
Now that you have the data model and the UI, connect them. Business logic should focus on two things:
Abstract away from the data model so you can easily retrieve and store information from step 2.
Make the UI work exactly as you designed in step 3. Don't get fancy.
Focus on Small Goals
There are two keys to the process. The first is to to separate the design of various components. You don't want to be thinking about implementation details when designing the UI, etc. The second key is to iterate. Focus on exactly what you need to add right now and ignore everything else.
Once you're done, you can iterate and tweak, repeat steps 1-4, etc. But don't get stuck in any step for too long. You can always iterate again later if things don't turn out exactly as you like. (I think agile calls the iteration "sprints", but I'm not up on the theory.)
Practical Considerations
It helps if you have a light framework (at minimum) to assist with 4.1 (ORM, like Propel) and 4.2 (JQuery, etc.). You want to keep both the UI and data access as modular and compartmentalized as possible so it's easy to change later.
If you mix everything into one chunk of code, then you'll have to change every part of the program just to (for instance) add a new column to the database or add a new button to your app. You've had some experience, so you should have an idea of pitfalls to avoid.

PHP - Frameworks, ORM, Encapsulation

Programming languages/environments aside, are there many developers who are using a framework in PHP, ORM and still abide by encapsulation for the DAL/BLL? I'm managing a team of a few developers and am finding that most of the frameworks require me to do daily code inspection because my developers are using the built in ORM.
Right now, I've been using a tool to generate the classes and CRUD myself, with an area for them to write additional queries/functions. What's been happening though, is they are creating vulnerabilities by not doing proper checks on data permission, or allowing the key fields to be manipulated in the form.
Any suggestions, other than get a new team and a new language (I've seen Python/Ruby frameworks have the same issues).
Throwing away a team is never an option: improve it instead!
Arrange security workshops to make them more aware of these issues.
Introduce (or even better: ask them to introduce) code guide lines for better handling these problems (a security-aware hungarian notation or usage of prepared statements are two examples)
Address the short-comings in code reviews - don't blame them for ignoring security, just show the problematic snippets you found and explain that security is very important to [choose one: this project/the customer/your company's reputation/you personally]
Let them do security audits on their own or their peer's code. Let them find out how easy it is to exploit such security flaws.
Find other tools/frameworks that better support your security model. But be warned: this option is very expensive! Your programmers will need to maintain code in the old framework and learn a new one (worst case: they will need to learn a new language along with the new framework)
But basically this is an issue that you have to solve collaboratively with your developers. If you declare war on them, you're bound to lose (regardless of the outcome for the developers.)
To me it sounds like you want to improve coding culture. Have a look at the Rules of Extreme Programming. Maybe you can adopt a few techniques.
Basically, I get the impression there is very little communication right now between the developers and you. I might be just reading that into it, but to me it sounds like the devs are locked in the cellar and you are sitting somewhere else and getting frustrated about them. Change that kind of thinking. You are part of the team.
If your developers are not aware of the vulnerabilities they introduce into the code, consider having weekly code reviews. Let the developers talk about the code they wrote. Let them learn from each other. Make the code collectively owned. Foster learning and constructive criticism.
Remember, there is no I in Team.
May I recommend Nepthali? It's not an ORM, but the framework is designed to force security. I.E. all variables are encoded before output to the screen; unless explicitely defined not too.
It's also fairly lean, having no ORM, etc. so you can plug whichever ORM into it you want. It's pretty nice, actually.
If you want to check if the user has access to property it is another layer other than data access layer. But still there are frameworks where you can override default load functionality and insert your logics after/before loading.
The lightest framework I ve ever worked is db.php (http://dbphp.net, https://github.com/hazardland/db.php). But it is code first object rational mapper. You ll have to define classes than databases\tables will be created according to your classes.
Take a look at \db\table::load method. Every class has its own handler instance of \db\table located in database::tables array. You can override table::load or create individual handlers for tables derived from \db\table class and place them in database::tables.
The only problem is that framework is not fully documented but has very light intuitive code structure and samples.
Another option is to make dal framework by yourself it will take up to 3-4 months for 1 person to make it full functional and powerfull.

Simple DB Model

I do not have much experience using frameworks or anything so that leaves me with little experience using Models (MVC). I have no interest whatsoever in using a framework at the moment. I am working on a website and I am trying to model some objects but I'm not sure exactly how I should be designing the class.
For instance, right now I have a class with a few public members which can be accessed directly. I have started prototyping some functions (select, delete, update) but I am not sure
If these functions should be static
If these functions should accept parameters or use the class members instead
If these functions should even exist how they do currently
If the entire concept I'm going for is the right thing to do
I can't seem to find any sort of hints on the interwebs as to how to create a model class.
If you're using a factory class then all verbs are usually instance methods and the factory is instantiated with some sort of DB session.
If the verbs are member's of the entity's class select is usually a static method while update is usually an instance method and delete is usually defined both ways (IE: delete(recordID) and entity.delete())
The entire concept is the right thing to do but you're going to do it wrong. Period. Making a scalable model like this takes a lot more time and effort than people have at their disposal. I know you have no interest in using a framework but you should.
My inference from your question is that this is a low profile project, and you have enough flexibility from your boss/client/teacher that you can build it however you want. That in mind, here is what I would think about when working on this.
If MVC is a new concept to you, then Test-Driven Development is almost certainly and alien one as well. However, I first cracked into a real understanding of OOP while doing it, so I suggest you give it a try. Writing some simple unit tests first against your model classes will take you through the exercise of figuring out how those model classes are going to be used. You'll be working with the external API of each of those objects (or groups of objects if you're not a TDD purist), and that will help guide the design of the internals. Check out PHPUnit for getting started, as the documentation has some great examples as well.
I think the TDD approach will lead you to the following conclusions:
Probably not. Static data/methods are usually only useful when you absolutely need one copy of something. I find in web apps that aside from maybe a resource connection like the DB this is rarely the case.
This depends on what the function does. Keep in mind that using local variables implies side-effects, or changes in the state of the object. If the data you need to operate on should not change the state of the entire object, use a parameter and return a value. It's also easier to test these kinds of methods.
Again, writing tests for these functions that illustrate how you'll use them in the application will lead you to a conclusion one way or another about whether you need them or whether they are designed correctly. Don't be afraid to change them.
Absolutely. How else are you going to become comfortable with MVC if you don't roll your own implementation at least once? In fact, it's probably better to grasp the concepts with real experience before you move to a more professional framework. That way, you'll understand why the concepts and conventions of the framework are the way they are.
Oh, and the lack of clarity that you're finding on what a model class is, is probably due to the fact that it's the part of your application that is most customized. This is your data model and domain logic, so a lot of it is case-specific. The best resource, though, IMHO is Martin Fowler, whose excellent book Patterns of Enterprise Application Architecture goes into a lot of detail on how and why to design a particular set of "model" classes with one pattern or another. Here is the online pattern library--obviously the book is more detailed.
Hope that helps somewhat.
When using PHP, I think designing object oriented model adds extra work with little benefits - even when looking on large frameworks, it's common to just use assoc-arrays that you can get from resultsets (see f.ex. the multiparadigm approach of Zend MVC).
While Object-Relational mapping is much more established among strongly typed languages like Java, there are already tools for PHP as well (f.ex. Doctrine). You may check it out if having OO-oriented model is what you want, but be aware that OR-mapping has severe issues of it's own and might be of little use in PHP (haven't tried it myself in a dynamic language yet).
For most newly started project, picking a good framework is usually a way to go - it can save you time and promote best practices (of course after some learning time that's different for every tool out there). When using some framework, you should always try to find out the framework's / community approach to solving specific problems (like model design & data access) before experimenting on your own.
The "correct" way to abstract away data access using object-oriented concepts is a hot-button topic for a lot of people. Put another way, there are several ways to do it and there is no "one right" way.
Rolling your own works best if you are seriously upgrading an existing application. This is because you have a heap of code that is already database dependant and you have some bounds for the necessary refactoring. It also teaches you about abstracting code because a lot of refactoring involves removing (or reducing) code duplication. Once you've done this to completion, you will have a much better idea of how a data model layer should work. Or at least, should work for the way you program. And you will know what not to do next time you build one. :-)
If you're starting a new codebase and haven't worked with a framework or object layer but know you need to build one, then the best advice I can give is to be willing to build one later, and refactor the code to suit when that does happen. Yes, it will likely mean your application will get 90% rewritten a few times.
Writing an object abstraction layer is difficult and you will end up with dense code that is fairly defensive about things, and doesn't take chances. But once you've got it working, you will also know how to build robust code, because it will probably be debugged fairly thoroughly.
No because, static methods are hard to test
It depends of the parameter, life cycle, etc. Impossible to answer without seeing some code.
?
No
OOP requires at least 10 years of experience to have a better view on what is wrong/right/better/worse.
So, if you are not a OOP expert, instead of losing too much time reinventing the wheel, I would suggest:
Use a well-known framework for the technical part
Create your classes/framework for the business/functional part.
(1) Will help you be ready in no time for the classic technical part (Session, database interaction, etc.). Will avoid you to make errors others already did.
(2) This is your core business, it should be "your DNA".
Also, using a well-known/good technical framework will make you read quality code and help you progress. (Be carefull some frameworks are really of poor quality)
When you will have enough experience, you will be able to skip the technical framework part and build/customize your own... because technical framework are usually evil (They serve too many purposes). :)

Fully Object Oriented framework in PHP

I want to create a 100% object oriented framework in PHP with no procedural programming at all, and where everything is an object. Much like Java except it will be done in PHP.
Any pointers at what features this thing should have, should it use any of the existing design patterns such as MVC? How creating objects for every table in the database would be possible, and how displaying of HTML templates etc would be done?
Please don't link to an existing framework because I want to do this on my own mainly as a learning excercise. You will be downvoted for linking to an existing framework as your answer and saying 'this does what you want'.
Some features I'd like to have are:
Very easy CRUD page generation
AJAX based pagination
Ajax based form validation if possible, or very easy form validation
Sortable tables
Ability to edit HTML templates using PHP
I've gone through many of problems on your list, so let me spec out how I handle it. I am also OOP addict and find object techniques extremely flexible and powerful yet elegant (if done correctly).
MVC - yes, hands down, MVC is a standard for web applications. It is well documented and understandable model. Furthermore, it does on application level what OOP does on class level, that is, it keeps things separated. Nice addition to MVC is Intercepting Filter pattern. It helps to attach filters for pre- and post-processing request and response. Common use is logging requests, benchmarking, access checking, caching, etc.
OOP representation of database tables/rows is also possible. I use DAO or ActiveRecord on daily basis. Another approach to ORM issues is Row Data Gateway and Table Data Gateway. Here's example implementation of TDG utilising ArrayAccess interface.
HTML templates also can be represented as objects. I use View objects in conjunction with Smarty template engine. I find this technique EXTREMELY flexible, quick, and easy to use. Object representing view should implement __set method so every property gets propagated into Smarty template. Additionally __toString method should be implemented to support views nesting. See example:
$s = new View();
$s->template = 'view/status-bar.tpl';
$s->username = "John Doe";
$page = new View();
$page->template = 'view/page.tpl';
$page->statusBar = $s;
echo $page;
Contents of view/status-bar.tpl:
<div id="status-bar"> Hello {$username} </div>
Contents of view/page.tpl:
<html>
<head>....</head>
<body>
<ul id="main-menu">.....</ul>
{$statusBar}
... rest of the page ...
</body>
</html>
This way you only need to echo $page and inner view (status bar) will be automatically transformed into HTML. Look at complete implementation here. By the way, using one of Intercepting Filters you can wrap the returned view with HTML footer and header, so you don't have to worry about returning complete page from your controller.
The question of whether to use Ajax or not should not be important at time of design. The framework should be flexible enough to support Ajax natively.
Form validation is definitely the thing that could be done in OO manner. Build complex validator object using Composite pattern. Composite validator should iterate through form fields and assigned simple validators and give you Yes/No answer. It also should return error messages so you can update the form (via Ajax or page reload).
Another handy element is automatic translation class for changing data in db to be suitable for user interface. For example, if you have INT(1) field in db representing boolean state and use checkbox in HTML that results in empty string or "on" in _POST or _GET array you cannot just assign one into another. Having translation service that alters the data to be suitable for View or for db is a clean way of sanitizing data. Also, complexity of translation class does not litter your controller code even during very complex transformations (like the one converting Wiki syntax into HTML).
Also i18n problems can be solved using object oriented techniques. I like using __ function (double underscore) to get localised messages. The function instead of performing a lookup and returning message gives me a Proxy object and pre-registers message for later lookup. Once Proxy object is pushed into View AND View is being converted into HTML, i18n backend does look up for all pre-registered messages. This way only one query is run that returns all requested messages.
Access controll issues can be addressed using Business Delegate pattern. I described it in my other Stackoverflow answer.
Finally, if you would like to play with existing code that is fully object oriented, take look at Tigermouse framework. There are some UML diagrams on the page that may help you understand how things work. Please feel free to take over further development of this project, as I have no more time to work on it.
Have a nice hacking!
Now at the risk of being downvoted, whilst at the same time being someone who is developing their own framework, I feel compelled to tell you to at least get some experience using existing frameworks. It doesn't have to be a vast amount of experience maybe do some beginner tutorials for each of the popular ones.
Considering the amount of time it takes to build a good framework, taking the time to look into what you like and loathe about existing solutions will pale in comparison. You don't even need to just look at php frameworks. Rails, Django etc are all popular for a reason.
Building a framework is rewarding, but you need a clear plan and understanding of the task at hand, which is where research comes in.
Some answers to your questions:
Yes, it should probably use MVC as the model view controller paradigm translates well into the world of web applications.
For creating models from records in tables in your database, look into ORM's and the Active Record pattern. Existing implementations to research that I know of include Doctrine, more can be found by searching on here.
For anything AJAX related I suggest using jQuery as a starting point as it makes AJAX very easy to get up and running.
Creating your own framework is a good way to gain an appreciation for some of the things that might be going on under the hood of other frameworks. If you're a perfectionist like me, it gives you a good excuse to agonize over every little detail (e.g. is should that object be called X or Y, should I use a static method or an instance method for this).
I wrote my own (almost completely OO framework a while ago), so here's my advice:
If you've worked with other frameworks before, consider what you liked/didn't like and make sure yours gives you exactly what you want.
I personally love the MVC pattern, I wouldn't dream of doing a project without it. If you like MVC, do it, if you don't don't bother.
If you want to do JavaScript/AJAX stuff, do use a JavaScript library. Coding all your own JavaScript from scratch teaches you a bit about the DOM and JavaScript in general, but ultimately its a waste of time, focus on making your app/framework better instead.
If you don't want to adopt another framework wholesale, take a look at whether there are other open source components you like and might want to use, such as Propel, Smarty, ADOdb, or PEAR components. Writing your own framework doesn't necessarily mean writing everything from scratch.
Use design patterns where they make sense (e.g. singletons for database access perhaps), but don't obsess over them. Ultimately do whatever you think produces the neatest code.
Lastly, I learned a lot by delving into a bit of Ruby on Rails philosophy, You may never use RoR (I didn't), but some of the concepts (especially Convention over Configuration) really resonated with me and really influenced my thinking.
Ultimately, unless your needs are special most people will be more productive if they adopt an existing framework. But reinventing the wheel does teach you more about wheels.
At the risk of sounding glib, this seems to me like any other software project, in this sense:
You need to define your requirements clearly, including motivation and priorities:
WHY do this? What are the key benefits you hope to realize? If the answer is "speed" you might do one thing, if it's "ease of coding" you might do another, if it's "learning experience" you might do a thid
what are the main problems you're trying to solve? And which are most important? Security? Easy UI generation? Scalability?
The answer to "what features it should have" really depends on answers to questions like those above.
Here are my suggestions:
Stop what you're doing.
It's already been done to death.
Click this Zend Framework or that CakePHP or maybe even this Recess Framework.
Now, my reasons:
... if you've worked with developers at all, you've worked with developers that love reinventing the wheel for no good reason. This is a very, very common failure pattern.
... they would go off and write hundreds and thousands of the crappiest languages you could possibly imagine ...
... "Oh, I'm gonna create my own framework, create my own everything," and it's all gonna be crappier than stuff you could just go out and get ...
from StackOverflow Podcast # 3.
So, save yourself some time, and work on something that solves a problem for people like a web app that lets people automatically update Twitter when their cat's litter box needs cleaning. The problem of "Object Oriented PHP Framework" is done. Whatever framework you slap together will never be as reliable or useful or feature rich as any of the freely available, fully supported frameworks available TODAY.
This doesn't mean you can't have a learning experience, but why do it in the dark, creating a framework that will grow into a useless blob of code, leaving you without anything to show for your time? Develop a web app, something for people to use and enjoy, I think you'll find the experience incredibly rewarding and EDUCATIONAL.
Like Jim OHalloran said, writing your own framework gives you a very good insight into how other frameworks do things.
That said, I've written a data-access layer before that almost completely abstracted away any SQL. Application code could request the relevant object and the abstraction layer did lots of magic to fetch the data only when it was needed, didn't needlessly re-fetch, saved only when it was changed, and supported putting some objects on different databases. It also supported replicated databases, and respected replication lag, and had an intelligent collection object. It was also highly extensible: the core was parameter driven and I could add a whole new object with about 15 lines of code - and got all the magic for free.
I've also written a CRUD layout engine which was used for a considerable percentage of a site. The core was parameter driven so it could run list and edit pages for anything, once you wrote a parameter list. It automatically did pagination, save-new-delete support etc etc, leveraging the object layer above. It wasn't object-oriented in and of itself, but it could have been made so.
In other words, a object-oriented framework in PHP is not only possible, it can be very efficient. This was all in PHP 4, BTW, and I bumped up against what was possible with PHP 4 objects a couple of times. :-)
I never got as far as a central dispatch that called objects, but I wasn't far away. I've worked with several frameworks that do that, though, and the file layout can get hairy quickly. For that reason, I would go for a dispatch system that is only as complex as it needs to be and no more. A simple action/view (which is almost MVC anyway) should get you more than far enough.
I initially started creating my own framework with similar ideals to your own. However, after a couple of months I realised I was re-creating work that had been done many times over. In the end I found an open source framework which was easily extendable and used it as a basis for my own development.
The features I implemented myself:
MVC Architecture
Authentication object
Database access class
URL rewriting config
Pagination class
Email class
Encryption
The features I looked at and thought, forget it! I'll build on top of someone elses:
Caching class
Form validation class
FTP class
Plugin-ability classes
Of course, writing a framework that outperforms the open source options is possible, but why would you bother?
It's true that some developers reinvent the wheel for no good reason. But because there are already good frameworks around doesn't mean that it's a waste of time doing one yourself. I started on one a while ago with no intention of using it for anything more than an exercise. I highly recommend doing it.
I've got the perfect link for you my friend: http://nettuts.com/tutorials/php/creating-a-php5-framework-part-1/. This is an awesome tutorial I have looked at, and its not too overwhelming. Plus look around the PHP section of that site I saw an article on CRUD. As for the AJAX look elsewhere, but you have to start somewhere, and this tutorial is awesome.
Note: this tutorial has 3 parts and I think it brings up MVC in the second instalment, but starts the first part using other methods.
The one, huge selling point I would look for in a new framework is that it would make writing testable code easy.
We typically work with Zend Framework, and it's mostly awesome, but trying to unit test/test drive ZF-based code is not far short of masochism.
If you could provide a framework that replaces the MVC parts of ZF with something that allows us to write testable code, whilst still allowing us to use the library parts of ZF, I will - quite literally - buy you a beer.
I'll buy you two beers if you ditch the AJAX. There's a huge gulf between an OO PHP framework and a JavaScript framework.
Please don't link to an existing framework
I will not, I started writing my own for learning purposes, and took a peek into some of the mainstream frameworks, and even with my limited knowledge see so many mistakes and bad ideas in them.
They're built by hardcore developers, not end users.
I'm in no way saying I could write better than the "big boys" but I (along with most of you I imagine) could point out why some things they do are bad, even if just because they're not end user/non-developer friendly...
I wonder how your framework is doing, some 6 years on?
Are you still working on it? Did you stop?
Should You Write Your Own Framework
This is probably a little late for you, but for anyone else, writing your own framework is a fantastic thing to do for learning purposes.
If, however, you are wanting to write one other than learning purposes, because you cannot work out the one you are using, or because it's too bloated, then do not!
Believe me, and don't be insulted, you would not be here contemplating it if you are a knowledgeable enough developer to do so successfully!
Last year I wanted to learn OOP/classes, and more advanced PHP.
And writing my own framework was the best thing I did (am actually still doing), as I have learned so much more than I anticipated.
Along the way I've learned (to name a few):
OOP/Classes many best practices which come with it - such as
Dependency Injection, SRP
Design patterns, which help you write code and structure your system
in such a way that it makes many things logical and easy. For an
example see Wiki - SOLID
Namespaces
PHP Error Handling and all of the functionality which that provides
A more robust (and better) understanding of MVC, and how to apply it
appropriately (as there is no clear cut way to use it, just guides
and best practices).
Autoloading (of classes for OOP)
Better code writing style and more structured layout, and better
commenting skills
Naming conventions (it's fun making your own, even if based on
common practices).
And many other basic PHP things which you invariably come across accidentally from reading something.
All of this not only vastly improved my grasp of PHP and things which come with it, to a more advanced level, but also some of the commercially/widely used methods and principles.
And this all boosted my confidence in using PHP in general, which in turns makes it easier to learn.
Why Write a Framework To Learn All of This
When you start out, you learn the basics - A (variables), then B (how to write a basic function), etc.
But it doesn't take long when you're trying to learn more advanced things, that to learn and use D and E, you also have to learn and understand F, G, H, and J, and to know those you have to know K, L, and M, and to know parts of L and M you first need to understand N and O...
It becomes a minefield as trying to learn one thing brings the need to first learn a few other things, and those other things often bring a need to understand various other things.
And you end up a mile away from where you started, your mind tingling and shooting sparks from it, and about 20 tabs open all with various advanced PHP things, none of which you are 100% comfortable with.
But over time, with practice and most certainly dedication, it will all fit into place, and you'll look back at code, even a collection of files/classes, and think "Did I write that.."?
Writing a framework helped greatly with this "minefield" because:
I had specific tasks to do, which brought about the need to learn and
implement other things, but specific things. This allowed me to focus
on less things at once, and even when something branches off to
various other things, you can reel it back in to where you started
because you are working on something specific. You can do this with
any learning, but if you do not have some goal, or specific task you
are focusing on, you can easily get distracted and lost in the ether
of things to learn.
I had something practical to work with. Often reading tutorials about
an animal class, and how cat and dog classes extend animal etc,
can be confusing. When you have a real life task in your own
framework, such as how do I manage XYZ, then you can learn how
classes work easier because you have trial and error and a solid
requirement which you understand, because you created the
requirement! Not just theory-like reading which means nothing
usually.
I could put it down when my mind was blown, although as it was my
framework (my Frankenstein's monster in the beginning :P) I wanted to
press on, because it was interesting, and a personal goal to learn
and sort the next stage, to resolve an issue I was stuck with, etc.
You can do it how you want. It might not be best practice, but as long as you are trying to learn best practice, over time you will improve, and likely easier than just reading tutorials, because you are in control of what and how you do something.
Wait, I Shouldn't Re-invent the Wheel Though
Well, firstly, you cannot reinvent the wheel, it is impossible, as you will just make a wheel.
When people say "Don't reinvent the wheel", they of course mean "there are already frameworks out there", and to be fair, they are written by skilled developers.
That's not to say the frameworks don't have problems or issues, but in general they are pretty solid, secure and well written.
But the statement is nonsensical in relation to writing your own framework!
Writing your own framework for learning purposes is really useful.
Even if you plan to use it commercially, or for your own website, you haven't just "re-invented the wheel", you've made something else.
Your framework won't be like the others, it won't have many features and functionality, which might be a major advantage to you!
As long as you understand about best security practices etc, because you can think you are writing a great system, which is super fast and without all the bloat other frameworks have, but in fact you have holes in places which someone could crawl into...
But a project for learning which you don't use on the internet is ideal - or use it, eventually, when you are advanced enough to know it's secure!
With all that said, you should write your own framework IF:
You are not needing it any time soon! It takes a lot of time as
there are so many aspects to consider, learn, and trial and error
leads to refactoring (a lot at first!)
You are willing to read, code, test, change, read, code, and read
some more. There is a lot of good advice on the internet for advanced
PHP, most of it mind blowing at first, like reading all the design
patterns. But they eventually make sense, and end up helping you
resolve problems you face, and how to do things within your
framework.
Willing to put the time in, and keep trying to improve, and head
towards best practice, especially with security. Speed issues shouldn't be an issue with a small framework, and besides, if you have a fairly decent system, you can usually refactor and make speed improvements. usually if you have significant speed issues it means you've chosen intensive operations, which can usually be addressed by doing it a different way.
.
Without previous experience, or an advanced knowledge of PHP, you will likely spend some time writing a framework, further reading and knowledge will show you that your approach is skewed, and so you might delete everything and start again.
Don't be disheartened by this.
I did exactly that, as I learned so much advanced patterns and ways of doing things along the way in the first month, I ended up where refactoring was no good, and a blank canvas with a whole new approach was the only option.
However, this was quite pleasing, as I saw a much better structure take form, and I could see not only a better framework foundation start to take place, but realised it was because I had a better understanding of advanced PHP.
Just do it! Just make sure you have a plan of what you want it to do before you even write some code.
Seriously, write down on paper how you are going to load error checking, are you going to have auto loading, or include files when needed? Are you going to have a centralised loading mechanism, which instantiates classes when you need them, or some other method?
Whatever you do, and whatever stage you are at, if you are heading into new territory, plan it first. You'll be glad of it when you hit a brick wall, can go back to your plans, and realise a slight deviation to your plans will resolve it.
Otherwise you just end up with a mess and no plan or way to re-deign it to resolve the current problem or requirement you face.
You are looking to build exactly same thing I've worked on for a few years and the result is Agile Toolkit.
Very easy CRUD page generation
$page->add('CRUD')->setModel('User');
AJAX based pagination
All pagination and many other things are implemented through a native support for AJAX and Object Reloading. Below code shows a themed button with random label. Button is reloaded if clicked showing new number.
$b=$page->add('Button')->setLabel(rand(1,50));
$b->js('click')->reload();
Ajax based form validation if possible, or very easy form validation
All form validations is AJAX based. Response from server is a JavaScript chain which instructs browser to either highlight and display error message or to redirect to a next page or perform any other javascript action.
Sortable tables
Table sorting and pagination has a very intuitive and simple implementation when you can really on object reloading.
Ability to edit HTML templates using PHP
This seems out of place and a wrong thing to do. Templates are better of in the VCS.

Categories