How to extend this simple DataMapper? - php

Can someone please derive a concrete example from the following:
http://www.urdalen.com/blog/?p=210
..that shows how to deal with one-to-many and many-to-many relationships?
I've emailed the author some time ago but received no reply. I like his idea, but can't figure out how to implement it beyond simple single table relations.
Note: I don't want to use a full-blown ORM. I like doing my SQL by hand. I would like to improve the design of my app code though. Right now each domain object has its own class full of queries wrapped in static methods. They just return scalar, 1d-array (record) or 2d-array (recordset) depending on the query.

The problem of ORM's (The impedance mismatch, as it's called) is precisely with relations. In an object graph (In-memory objects), relationships are pointers to other objects. In a relational database, relationships are reversed; This makes it impossible to do a simple mapping between the two models, and that is why ORM's are so complex.
If you want to stay close to the database (avoiding an ORM), then you shouldn't try to abstract relationships away. The way I write datamappers is something like the following:
$car42 = $car_gateway->fetch(42);
$wheels = $wheel_gateway->selectByCar($car42);
In contrast to the ORM way:
$car42 = $car_gateway->fetch(42);
$wheels = $car42->selectWheels();
This does mean that the gateways end up in your client-code, but it also keeps things very transparent and close to the database.

If you're looking for a simple and portable DataMapper ORM, have a look at phpDataMapper. It's only dependencies are PHP5 and PDO, and it's very small and lightweight. It supports table relations and some other very nice features as well.

Given your response to Tom's answer, I would recommend that you look at something like Zend Framework. Its ORM has a take it or leave it architecture that can be implemented in stages.
When I came to my present employer, they had an application that had just been completed months previously but had been through one or two prior versions and the current version had been in development six months longer than it was supposed to have been. However, the code base was mess. For example there was no abstraction between the database access logic and the business logic. And, they wanted me to move the site forward building new functionality, extending existing features, and fixing existing bugs in the code. To further complicate things they weren't using any form of sanitation on data inputs or outputs.
As I started to wade into the problem, I realized that I would need a solution to abstract concerns that could be implemented in steps because they obviously weren't going to go for a complete rewrite. My initial approach was to write a custom ORM and DAL that would do the heavy lifting for me. It worked great because it didn't intrude on the existing code base, and so it allowed me to move entire portions of the application to the new architecture in an unobtrusive manner.
However, after having ported a large portion of the user's area of our site to this new structure and having built an entire application on my custom framework (which has come to also include a custom front-end controller and mvc implementation), I am switching to Zend Framework (this is my choice though I am certain that some of the other frameworks would also work in this situation).
In switching to the Zend Framework I have absolutely no concerns about the legacy code base because:
I can build new models and refactor
old models (built on my custom
framework) unobtrusively.
I can refactor the existing
controllers (such as they are) to be
wrapped within a class that behaves
in a manner consistent with Zend's
MVC framework so that it becomes a
minor issue to actually begin using
Zend's Front-End Controller.
Our views are already built in
Smarty so I don't have to worry
about separating controller and view
logic, but I will be able to extend
the Zend Framework so that I can
render existing templates in Smarty
while building new templates in
straight PHP.
Basically, Zend Framework has a take it or leave architecture that makes its a joy to use within existing projects because new code and refactored code doesn't need to intrude on existing code.

Related

Does MVC design means you have to separate mysql from php code?

Does MVC really means you have to separate => View aka design (html css) => controler (php code), model (mysql code into classes etc.)???
Are there not alternatives? Wondering because I would really like to avoid separating php code and mysqli as right now it's sooo easy to work on it (got used to it).
Yes, you definitely want to separate HTML and CSS from business logic.
Most frameworks use an ORM or something similar to abstract building queries but still give you the option to write plain SQL. I would recommend to use an ORM like doctrine2 for example over plain SQL. If you use any SQL directly the model would most likely the right place to put it into.
MVC exists for a reason, separation of concerns. This makes sure that your application becomes easy to maintain because every part of it should be easy to replace and not depend on each other to much. You want to avoid strong coupling. MVC is a pattern that helps you with that.
And like tttpapi said, there other ways to do it, but honestly, I personally think that specially Wordpress for example is a horrible clutter. I don't like Drupal or Joomla as well. The code base feels like working with 10 year old clutter compared to a modern well written application following the MVC pattern.
This is a little about discipline es well, I've seen totally messed up applications as well because people did not pay attention to separation of concerns and didn't follow the MVC pattern.
Does MVC really means you have to separate => View aka design (html
css) => controler (php code), model (mysql code into classes etc.)???
No.
MVC is about separation pf concerns. It separates presentation layer from model layer. And within presentation layer - it separates handling of input (controllers) from handling of output (views).
The model in MVC is not a databases abstraction or collection of queries. Instead it is a layer that contains several groups of classes. The major groups are domain objects, data mappers and services. The model in MVC is all these things taken together.
Longer explanation: here
Note: do not confuse MVC's model with domain model, which is the accumulated knowledge and vocabulary for specifica application. The part of domain model, that can be encompassed in code, is implemented using domain objects.
View is not html and css. Views in MVC are classes that contain the UI logic for the application. THey acquire data from model layer and then, based in this information, choose which templates to use for producing a response.
Longer explanation: here
Controllers are not some mystical "php code". They are part of application that takes user input, and based on that alter the state of model layer and (in rare cases) state of current view.
Are there not alternatives? Wondering because I would really like to
avoid separating php code and mysqli as right now it's sooo easy to
work on it (got used to it).
The point is NOT separating SQL from PHP.
The separation of concerns principle simply means that each part of your application should be dealing with one specific aspect.
And, if you try to implement MVC architecture, it will NOT mean that you separate sql from php, but that you separate business logic from persistence logic. Both of those would be written in PHP. But the trick is - MySQL is not the only form of storage. Data can also be stored in session, in cache, in noSQL, in files, in SOAP, etc. If you have separated business logic from persistence logic, then you can add caching to your existing application without rewriting the whole thing.
Also ...
There are more architectures then just MVC and Big Ball of Mud (which was advertised by people who talked about Drupal and Joomla).
You have MVP, MVVM, n-Tier, DCI, EDA and many others. And all these will be adhering to SoC principle .. but the result that they come up with will be different.
P.S.: If you actually want to learn about MVC, I would recommend for you to start going through materials from this list. It will start by introduction to simple concepts and gradually build up to ideas that you have to grasp to actually start working with MVC.
It is always up to you.
You always can find way how to use MVC as nonMVC. (example is Joomla here you can use just view with all code in it)
Or you can use systems that are not MVC bases such as Drupal.
But the MVC is here for some reasons.
To directly answer your question, yes MVC means exactly that.
However MVC is just a design pattern, and not a holy writ.
There are many variations available to you. I myself initially thought MVC to be restrictive and confusing, but in fact it was the particular MVC based framework i choose that had these failings.
There are many lightweight, flexable frameworks available. Take a look at https://github.com/bcosca/fatfree as a nice example, in particular the database section. You wont think mysqli is simple in comparison

Is there a (simple) way to separate models in pure PHP, and what is a good way of doing it?

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.

Migrating pure PHP project to Yii framework

I have almost completed a PHP project, using MVC, jQuery and Ajax. It is pure PHP project. I don't use any frameworks in the code right know. I would like to change that.
Doing some research, I found, that Yii turns out to be one of the best frameworks out there.
Is it possible to somehow migrate pure PHP project to Yii?
If so, then how to do this? Which steps should I follow in order to reduce the workload and enjoy the benefits the Yii framework presents?
I'm a total Yii newbie, any insights appreciated.
TL;DR : Don't do it. It's a really horrible idea.
The Rant ..
"Framework" is not a magic sauce, that you add to a project, to make it better and shinier.
Doing some research i found Yii turns out to be one of the best frameworks out there.
What a strange research you have done .. I would love to see the materials. Especially, since I would rank it as 3rd worst PHP framework. Only surpassed in it's awfulness by CodeIgniter and CakePHP.
And the reason for it is the extremely bad quality of code, that this framework displays, combined with the bad practices, that it perpetuates.
Why avoid migration?
From your description is obvious, that you are NOT familiar with this framework and have no previous experience with it.
In management of projects there a subject: risk management. And in this case, adding a previously unused framework in final stages of project would constitute a high probability an high impact risk which also, due to the sage of project, is completely unmitigated.
It means that there is a really good chance that something will go wrong. And when it does, it most likely will sink the project. Or at least push back the release data by significant length of time.
In a perfect world frameworks are used to simplify the repetitive tasks of development, at the cost of some performance. Those are the tasks you do at the start of the project. You are not at the start of a project. This means that you will gain no benefits from this "maneuver".
Why not Yii?
As I noted before, there are also reasons not only for avoiding adding framework to an existing project, but also reasons why to avoid Yii in particular.
The inheritance nightmare
All your controller will extend class CController, which extends CBaseController, which extends CComponent
All your "models" will extend ether CActiveRecord or CFormModel, which extends CModel, which extends CComponent.
Both of there chains contain static variables and execute static methods on multitude of different other classes. Combination of these factors will make debugging extremely difficult and tedious.
Global state
There are several forms of global state. One that people in PHP usually know are global variables. But that is not the only form. Every time you have a class that contains a static variable, it also creates a global state, that can (and almost always - will) cause seemingly unrelated instance mysteriously interact.
Use of global state is a core mechanic. You will see static calls all over the codebase, and the Yii's configuration file would not function without global state.
And every time you call Yii::app() you are accessing and/or changing it.
This makes unittesting impossible for Yii applications. And debugging turns into exercise of using grep on your whole project.
Tight coupling
When you create an application in Yii. It becomes bound to it. You cannot execute parts of your application without launching the full framework. Mostly it is due to the static call, that you end up adding to your code.
Every time you add a static call in your own code, that piece of code becomes tied to the name of the class. That essentially is tight coupling.
As you might have noticed (hopefully), there is another way how to achieve the same effect - the use of new operator. That is another way of coupling some code of yours to a specific name of a class.
No interfaces .. none .. whatsoever
No matter how horrible the configuration of a Yii project is, the configuration file was a well intended gesture. The least harmful way to introduce external code and replace existing components in so messed up codebase.
But unfortunately it brings in the focus the problems caused by lack of interfaces and the existing coupling.
One of the component that developers will try to replace is the CUrlManager. Mostly due to way how you can pass additional parameters.
An interface in OOP specifies the contract between two instances. It lets you define the capabilities of an instance, the methods that can be used by others. When it's not there, in a large codebase, you are left guessing, which methods are required and which are not.
In case of Yii components the problem is compounded even further due to static call and deep inheritance. The above mentioned CUrlManager extends CApplicationComponent, which extends CComponent. Also the same file defines CUrlRule and CBaseUrlRule classes.
When you are writing a replacement, you have to write some code, plug it in the configuration and then test it by running your applications. That way you know which method (or parameter) next you need to add.
Basically, it's the "save-an-see-what-blows-up" method of development.
That's not MVC!
Yii does not implement MVC or any of MVC-inspired design patterns. What it calls "MVC" could be described as ActiveRecord-Template-Logic pattern.
Instead of having proper model layer (yes, it should be a layer), the creator(s) of Yii opted for collection of active record and form wrappers. This forces the application logic to be forced in the "controllers".
On the other hand you have glorified templates, instead of proper view instances for containing presentation logic. It is somewhat mitigated by use of widgets, but those instead suffer from SRP violations, because widgets are forced to contain bits of presentation logic and perform partial rendering. The rest of presentation logic ends up again in the controllers.
And to make it all worse, the "controllers" also have to deal with authorization. This usually will mean, that whenever you change the access scheme, you will have to go through every single instance of CController to check whether it needs to be changed too.
It's not MVC. It's a mess with names taken from MVC design pattern and slapped on some components.
All the small things ..
The framework also comes with few minor issue, that do not deserve a separate section:
Defining more then one class per file:
This will get annoying quite fast, because there will be classes that are shoehorned at the class files with completely unrelated filenames. This will mean, that debugging will quite often require use of search.
Slapped on "modules":
By the looks of it, the modules where added to the framework after the fact. Which is why, when you need to set default module, you will have to set it in the configuration files parameter, that is called 'defaultController'.
I actually recently converted a MVC pattern website I had built from the ground up into Yii. It did take some time to set it all up but in all honesty it was well worth it. I was able to throw away a lot of code because there were already Yii extensions doing what I needed. I would also suggest that you keep your database because you can create the controllers and Models using Gii which will save you a ton of time.
I don't know of any quick solutions to this. It depends upon how the code was written. You have the database and your views so it is not really a complete new project when you take into yii. Yii will generate the database models for you. You already have the views from the existing project. Write the controller and actions and modify the views if necessary.
try these links as they refer to the same problem.
How do you convert an old oop project into Yii
tips on migrating an existing site to Yii
Drupal to Yii Migration
Since you already have a code in mvc, things will be much easier for you to migrate. However, while migrating to Yii, since it can generate controller and model very easily using gii, you can take the advantage of it.
So, first generate controller and model using gii, then you can replace your existing code (by replace I mean, substitute your code to the specific function in the controller and model) to the built in controller and model so that the functionality of your site still works. You can modify your view accordingly. But that won't be much of a work.
You can simply register your script for ajax, jquery and css. Those will work as well.
And yes, Yii is the best framework out there so take as much benefit as you can.
Thanks,
Ujjwal
In this project you converted php to yii framework. Its really easy for you if you do following step.
Since you already have a code in mvc, things will be much easier for you to migrate. However, while migrating to Yii, since it can generate controller and model very easily using gii, you can take the advantage of it.
second, If your database is accurate then 50% work complete.when you create CRUD operation using gii then automatically model-view-controller create.if you create mvc in php then it benifit for you.
third,You can simply include your script for ajax, jquery and css. Those will work as well you create a folder in themes(CSS,JS,AZAX,BOOTSTRAP).
four-Protected->view->layout, where you can change your theme..thats all
you also help www.yiiframework.com/doc-2.0/guide-intro-yii.html
if you think my answer is help you then rating me...thank you.

Lithium apps that go beyond CRUD

This is more or less a framework-centric version of a past Stack Overflow question, which is about how most introductory material on MVC applications tends to present a tight coupling between models, views, and controllers. For example, you'll have a User table that is modified by a User controller which in turn pushes filtered data to a User view. It's my impression that a lot of MVC frameworks tend to reflect this pattern as well. This is all fine and well for what it is, but it never really leads me to anything beyond building and displaying monotonous lists of things with an HTML form.
The MVC framework that looking at right now is Lithium, which seems quite interesting as a case study of clever PHP5.3 coding techniques. On one end, Lithium has a Model class that offers wrapper objects around a individual tables, and abstracts away some simple queries. On the other end, it's got a nifty convention of routing URLs to method calls on controller objects, which then render to display templates.
But in the midst of this, I find myself at a loss as to where to place all of the interesting logic that relates data in table A to data in tables B through Z. Or at least, I'm not sure where to place such logic in a manner that's consistent with the design of the framework. To my understanding, Lithium's Model abstraction doesn't do much more than eliminate some row-level insert/update/delete boilerplate, and the controller/view architecture seems mostly about user interface. I wouldn't want to put a lot of business logic in the same Controller class that is receiving routed function calls from URL requests.
My instinct would be to fill the gap with a bunch of my own code that exists more or less entirely outside of the framework. I'm not sure if I ought to expect more than that, but given how rigidly structured everything else is in Lithium, it feels somehow unsatisfying, like I could have just rolled my own boilerplate-reduction code without the overhead of grokking the source of a big framework.
What am I missing here? Is there a recommended architecture or philosophy to using this type of framework?
One thing you have to remember with Lithium is that theres no production ready release yet (although some sites are using it in production).
The main missing feature right now is model relations. With relations in place i assume your question would be partially answered as that is an important brick in the big picture of creating more complex applications.
You could check out the x-data branch where the work on relations should be ongoing.
For the second part of writing domain logic the simple answer is "in the model".
See this (rather useless) example of extending model functionality for example.
Another example to look at is the open source mini application Analogue that is one of the few working open examples of Lithium in use. The Analogue model class shows a slightly more meaty model.
And finally its a matter of connecting the dots between M, V and C.
A Lithium controller should mainly delegate jobs over to models, and perhaps restructure the input data if needed.
The simple examples of having a Post model, PostsController and views/posts/add,index,etc doesn't mean that you have to merely have Post::all() in there.
PostsController::view need to load a set of Comment models probably.
So you will toss a lot of your own code in there, of course! Else it would not be much of an application. But keep the domain logic tied to the model where it is natural.
Need to verify that blog post has a
unique title? Write a validator.
Need to ensure the user has write access to the post? Override the save method and verify it, or filter it.
But I think we need to wait for relations to land and a 1.0 release before we can fully judge how structuring applications in Lithium can be solved best.

activerecord as model, is this a good idea?

Recently thanks to rails' popularity, many people start using activerecord as model. however, before I heard of rails (my peer group was not a fan of open source stuff, we were taught in a .NET school...) and while I was doing my final year project, i found this definition for a model
The model represents enterprise data and the business rules that govern access to and updates of this data. Often the model serves as a software approximation to a real-world process, so simple real-world modeling techniques apply when defining the model.
it doesn't say the model should represent one table as what activerecord does. And normally within a transaction, one may have to query a few unrelated tables and then manipulate data from different tables... so if activerecord is used as model, then either one would have to cram all the logic code into the controller (which is kinda popular in some php frameworks) that makes it difficult to test or hack the activerecord model so that it performs database operation on not only the table it maps to, but also other related tables as well...
so, what is so great about abusing (IMHO) activerecord as the model in a MVC architectural pattern?
Martin Fowler described this pattern in Patterns of Enterprise Application Architecture together with two other patterns or architectures. These patterns are good for different situations and different amounts of complexity.
If you want to so only simple stuff you can use Transaction Script. This is an architecture you saw in lot's of old ASP and PHP pages where a single script contained the business logic, data-access logic and presentation logic. This falls apart fast when things get more complicated.
The next thing you can do is add some separation between presentation and model. This is activerecord. The model is still tied to the database but you've a bit more flexibility because you can reuse your model/dataccess between views/pages/whatever. It's not as flexible as it could be but depending on your data-access solution it can be flexible enough. Frameworks like CSLA in .Net have a lot of aspects from this patterm (I think Entity Framework looks a bit too much like this too). It can still handle a lot of complexity without becoming unmaintainable.
The next step is separating your data-access layer and your model. This usually requires a good OR mapper or a lot of work. So not everyone wants to go this way. Lot's of methodologies like domain driven design perscribe this approach.
So it's all a matter of context. What do you need and what is the best solution. I even still use transaction-script sometimes for simple single use code.
I've said many times that using Active Record (or ORM which is almost the same) as Business Models is not a good idea. Let me explain:
The fact that PHP is Open Source, Free (and all that long story...) provides it with a vast community of developers pouring code into forums, sites like GitHub, Google code and so on. You might see this as a good thing, but sometimes it tends not to be "so good". For instance, suppose you are facing a project and you wish to use a ORM framework for facing your problem written in PHP, well... you'll have a lot of options to choose for:
Doctrine
Propel
QCodo
Torpor
RedBean
And the list goes on and on. New projects are created regularly. So imagine that you've built a full blown framework and even a source code generator based on that framework. But you didn't placed business classes because, after all, "why writing the same classes again?". Time goes by and a new ORM framework is released and you want to switch to the new ORM, but you'll have to modify almost every client application using direct reference to your data model.
Bottom line, Active Record and ORM are meant to be in the Data Layer of your application, if you mix them with your Presentation Layer, you can experience problems like this example I've just laid.
Hear #Mendelt's wise words: Read Martin Fowler. He's put many books and articles on OO design and published some good material on the subject. Also, you might want to look into Anti-Patterns, more specifically into Vendor Lock In, which is what happens when we make our application dependent on 3rd party tools. Finally, I wrote this blog post speaking about the same issue, so if you want to, check it out.
Hope my answer has been of any use.
The great thing about using the Rails ActiveRecord as a model in MVC is that it gives you an automatic ORM (Object Relational Mapper) and easy way to create associations between models. As you have pointed out, MVC can sometimes be lacking.
Therefore, for some complex transaction involving many models, I'd suggest to use a Presenter in between your controller and your models (Rails Presenter Pattern). The Presenter would aggregate your models and transactional logic and would remain easily testable. You definitely want to strive to keep all of your business logic in your models or presenters, and out of your controllers (Skinny Controller, Fat Model).

Categories