PHP OO - how to initialize your business objects? - php

By business model, or business objects, I mean plain old objects like a "User" with all their properties name, adress, ...; in addition to all the user properties let's say each user would have an "AppointmentBook" object, each book has a set of "TimeSlot" objects, etc.
The business model has objects with references between them, at least that's how I code a business model in Java.
Here comes the question:
To intialize my business objects, in Java, I would
fetch all of the data from DB only once during application
initialization,
map data from my DB to my business objects
store in memory (maps) and they would be shared across all the requests.
PHP's Share-Nothing-Architecture is confusing me for proper OO programming:
If I use the same logic, I would have to fetch all the objects from DB, for every request (I know I could still cache, but you don't cache all of your DB, it's not a question about caching but rather about the way of programming in PHP and its architecture).
So let's say that for one HTTP request, I just need the User properties and I don't need to access his appointment book. It would be a pitty to fetch all the data from the DB for all the objects the User makes reference to, as I just need his properties. This means that I will initialize PHP objects from my model with a lot of NULL values (NULL because of the objects contained in User that I won't load) which can later on lead to errors.
I was wondering how professional PHP developers usually use their business objects?
(I'm coming from Java)
UPDATE: It was kind of stupid to say that I would load the whole database into memory during application init in Java. What I rather meant is that, if I need to fetch a specific user, I could just load all of its data and that would be accessible through all the requests.

In PHP you do not keep all the data of your domain business model in the memory. Instead you only request from DB ( though cache, if needed ), the data you want.
Model layer in php should be built from multiple domain object and data mappers ( i assume, that part is not so different from Java ). If you need User details, then you fetch only that information from database/cache. You most likely will have a separate mapper just for dealing with user(s).
You display the information about that user, and forget about the query. Next request (when and if it comes) will require different information. Maybe you will want ContactList for that User ... then you really do not need user itself, only his user_id. Again, you let you mapper to fetch data into the domain object responsible for handling contact list, and if contact list contains User instances, then just create them, but leave in "unfetched" state (object knows only own user_id). Fetch them only if you really need to, and only the parts which you will use ins that "view".
P.S. you might have notices, I told that model later should be segmented, but quite often php developers just create single class of each DB table (which implements ActiveRecord) and call it "model". This is a result caused by Ruby on Rails influence on php framework developers, which, IMHO, is one of the worst things that has happened to PHP in past 5 years.

Your Java example implies your storing your entire databases content in memory. If your doing that, what's the point of the database? Why not just create all those object and memdump them for persistence.
If I use the same logic, I would have to fetch all the objects from DB, for every request
That's simply madness, you don't need to fetch anything, you create new instances when you need them and destroy them when you no longer need them.
So let's say that for one HTTP request, I just need the User properties and I don't need to access his appointment book.
That's easy, redesign your user. Your user needs it's properties and a property called appointmentBook which is simply an array of appointment book ids.
If you actually need those appointments you can fetch them from the database later.
This means that I will initialize PHP objects from my model with a lot of NULL values (NULL because of the objects contained in User that I won't load) which can later on lead to errors.
Not really, if this is the case your User object is too big. Make it smaller, you should load the entire user. Except of course the user has to be small enough for you to sensible load it.
If you don't want that then you can always create a UserProperties class and let every User have one. When you load the User you load the properties, but you also have an option to create the properties seperately.

Even in Java you would not load all data from the database into memory. You can however - as you write - often load more compared to short Transaction Scripts you normally have in PHP.
You models should be "clever" then to only load the data from the persistence storage that is needed to perform the requested action. This requires the object to be "clever" enough to lazy-load data probably.
This can be achieved with a Domain Model that knows enough about itself and a Data Mapper that knows enough about the storage for example.
There are other patterns as well which might suit your needs depending on the type of application, however a Domain Model together with Data Mapper is quite flexible.
An exemplary data mapper in the PHP world is Doctrine.

Related

Active Record must have domain logic?

I started some time working with the Yii Framework and I saw some things "do not let me sleep." Here I talk about my doubts about how Yii users use the Active Record.
I saw many people add business rules of the application directly in Active Record, the same generated by Gii. I deeply believe that this is a misinterpretation of what is Active Record and a violation of SRP.
Early on, SRP is easier to apply. ActiveRecord classes handle persistence, associations and not much else. But bit-by-bit, they grow. Objects that are inherently responsible for persistence become the de facto owner of all business logic as well. And a year or two later you have a User class with over 500 lines of code, and hundreds of methods in it’s public interface. Callback hell ensues.
When I talked about it with some people and my view was criticized. But when asked:
And when you need to regenerate your Active Record full of business rules through Gii what do you do? Rewrite? Copy and Paste? That's great, congratulations!
Got an answer, only the silence.
So, I:
What I am currently doing in order to reach a little better architecture is to generate the Active Records in a folder /ar. And inside the /models folder add the Domain Model.
By the way, is the Domain Model who owns the business rules, and is the Domain Model that uses the Active Records to persist and retrieve data, and this is the Data Model.
What do you think of this approach?
If I'm wrong somewhere, please tell me why before criticizing harshly.
Some of the comments on this article are quite helpful:
http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/
In particular, the idea that your models should grow out of a strictly 'fat model' setup as you need more seems quite wise.
Are you having issues now or mainly trying to plan ahead? This may be hard to plan ahead for and may just need refactoring as you go ...
Edit:
Regarding moveUserToGroup (in your comment below), I could see how having that might bother you. Found this as I was thinking about your question: https://gist.github.com/justinko/2838490 An equivalent setup that you might use for your moveUserToGroup would be a CFormModel subclass. It'll give you the ability to do validations, etc, but could then be more specific to what you're trying to handle (and use multiple AR objects to achieve your objectives instead of just one).
I often use CFormModel to handle forms that have multiple AR objects or forms where I want to do other things.
Sounds like that may be what you're after. More details available here:
http://www.yiiframework.com/doc/guide/1.1/en/form.overview
The definition of Active Record, according to Martin Fowler:
An object carries both data and behavior. Much of this data is persistent and needs to be stored in a database. Active Record uses the most obvious approach, putting data access logic in the domain object. This way all people know how to read and write their data to and from the database.
When you segregate data and behavior you no longer have an Active Record. Two common related patterns are Data Mapper and Table/Row Gateway (this one more related to RDBMS's).
Again, Fowler says:
The Data Mapper is a layer of software that separates the in-memory objects from the database. Its responsibility is to transfer data between the two and also to isolate them from each other. With Data Mapper the in-memory objects needn't know even that there's a database present; they need no SQL interface code, and certainly no knowledge of the database schema.
And again:
A Table Data Gateway holds all the SQL for accessing a single table or view: selects, inserts, updates, and deletes. Other code calls its methods for all interaction with the database.
A Row Data Gateway gives you objects that look exactly like the record in your record structure but can be accessed with the regular mechanisms of your programming language. All details of data source access are hidden behind this interface.
A Data Mapper is usualy storage independent, the mapper recovers data from the storage and creates mapped objects (Plain-old objects). The mapped object knows absolutely nothing about being stored somewhere else.
As I said, TDG/RDG are more inwardly related to a relational table. TDG object represents the structure of the table and implements all common operations. RGD object contains data related to one single row of the table. Unlike mapped object of Data Mapper, the RDG object has conscience that it is part of a whole, because it references its container TDG.

Use of models in FuelPHP?

I'm new to PHP frameworks and to start my venture I went to try FuelPHP. After a few days of testing around I understood how things work. Controllers control the actions, views control the $content and the template controls the layout. But what about models, What are they for?
Models are abstractions over data stored elsewhere, they encapsulate the data access through standard object creation, method calls, property access, etc. just like ordinary objects. The main idea here is that the controller (or whatever object that requires the data) doesn't need to know how to get the data or how it's stored. It could be stored in files, web (via webservice), database, whatever thing that could persist data. The data could be retrieved with webservice request, database query, file reading, etc.
For instance, "gimme student record with id 1" could be as simple as student := new student(1); and after that you have access to the student's name, address, etc. But how does the student retrieve its data? Where does it store the data? It's out of concern and could be tuned (or should be tunable) as needed.
models controle your data and have a direct contact with your db have a read here
You might have say
Contact With ID,Name,Detail and ContactType properties.
The idea is to keep it minimal it's basically something to cart around all the useful properties of an entity.
This is the current definition of MVC. Nothing about the backend in it. That would be some seperate library / dll that only knows about model, and how the underlying data is stored in the DB.

What does a Data Mapper typically look like?

I have a table called Cat, and an PHP class called Cat. Now I want to make a CatDataMapper class, so that Cat extends CatDataMapper.
I want that Data Mapper class to provide basic functionality for doing ORM, and for creating, editing and deleting Cat.
For that purpose, maybe someone who knows this pattern very well could give me some helpful advice? I feel it would be a little bit too simple to just provide some functions like update(), delete(), save().
I realize a Data Mapper has this problem: First you create the instance of Cat, then initialize all the variables like name, furColor, eyeColor, purrSound, meowSound, attendants, etc.. and after everything is set up, you call the save() function which is inherited from CatDataMapper. This was simple ;)
But now, the real problem: You query the database for cats and get back a plain boring result set with lots of cats data.
PDO features some ORM capability to create Cat instances. Lets say I use that, or lets even say I have a mapDataset() function that takes an associative array. However, as soon as I got my Cat object from a data set, I have redundant data. At the same time, twenty users could pick up the same cat data from the database and edit the cat object, i.e. rename the cat, and save() it, while another user still things about setting another furColor. When all of them save their edits, everything is messed up.
Err... ok, to keep this question really short: What's good practice here?
From DataMapper in PoEA
The Data Mapper is a layer of software
that separates the in-memory objects
from the database. Its responsibility
is to transfer data between the two
and also to isolate them from each
other. With Data Mapper the in-memory
objects needn't know even that there's
a database present; they need no SQL
interface code, and certainly no
knowledge of the database schema. (The
database schema is always ignorant of
the objects that use it.) Since it's a
form of Mapper (473), Data Mapper
itself is even unknown to the domain
layer.
Thus, a Cat should not extend CatDataMapper because that would create an is-a relationship and tie the Cat to the Persistence layer. If you want to be able to handle persistence from your Cats in this way, look into ActiveRecord or any of the other Data Source Architectural Patterns.
You usually use a DataMapper when using a Domain Model. A simple DataMapper would just map a database table to an equivalent in-memory class on a field-to-field basis. However, when the need for a DataMapper arises, you usually won't have such simple relationships. Tables will not map 1:1 to your objects. Instead multiple tables could form into one Object Aggregate and viceversa. Consequently, implementing just CRUD methods, can easily become quite a challenge.
Apart from that, it is one of the more complicated patterns (covers 15 pages in PoEA), often used in combination with the Repository pattern among others. Look into the related questions column on the right side of this page for similar questions.
As for your question about multiple users editing the same Cat, that's a common problem called Concurrency. One solution to that would be locking the row, while someone edits it. But like everything, this can lead to other issues.
If you rely on ORM's like Doctrine or Propel, the basic principle is to create a static class that would get the actual data from the database, (for instance Propel would create CatPeer), and the results retrieved by the Peer class would then be "hydrated" into Cat objects.
The hydration process is the process of converting a "plain boring" MySQL result set into nice objects having getters and setters.
So for a retrieve you'd use something like CatPeer::doSelect(). Then for a new object you'd first instantiate it (or retrieve and instance from the DB):
$cat = new Cat();
The insertion would be as simple as doing: $cat->save(); That'd be equivalent to an insert (or an update if the object already exists in the db... The ORM should know how to do the difference between new and existing objects by using, for instance, the presence ort absence of a primary key).
Implementing a Data Mapper is very hard in PHP < 5.3, since you cannot read/write protected/private fields. You have a few choices when loading and saving the objects:
Use some kind of workaround, like serializing the object, modifying it's string representation, and bringing it back with unserialize
Make all the fields public
Keep them private/protected, and write mutators/accessors for each of them
The first method has the possibility of breaking with a new release, and is very crude hack, the second one is considered a (very) bad practice.
The third option is also considered bad practice, since you should not provide getters/setters for all of your fields, only the ones that need it. Your model gets "damaged" from a pure DDD (domain driven design) perspective, since it contains methods that are only needed because of the persistence mechanism.
It also means that now you have to describe another mapping for the fields -> setter methods, next to the fields -> table columns.
PHP 5.3 introduces the ability to access/change all types of fields, by using reflection:
http://hu2.php.net/manual/en/reflectionproperty.setaccessible.php
With this, you can achieve a true data mapper, because the need to provide mutators for all of the fields has ceased.
PDO features some ORM capability to
create Cat instances. Lets say I use
that, or lets even say I have a
mapDataset() function that takes an
associative array. However, as soon as
I got my Cat object from a data set, I
have redundant data. At the same time,
twenty users could pick up the same
cat data from the database and edit
the cat object, i.e. rename the cat,
and save() it, while another user
still things about setting another
furColor. When all of them save their
edits, everything is messed up.
In order to keep track of the state of data typically and IdentityMap and/or a UnitOfWork would be used keep track of all teh different operations on mapped entities... and the end of the request cycle al the operations would then be performed.
keep the answer short:
You have an instance of Cat. (Maybe it extends CatDbMapper, or Cat3rdpartycatstoreMapper)
You call:
$cats = $cat_model->getBlueEyedCats();
//then you get an array of Cat objects, in the $cats array
Don't know what do you use, you might take a look at some php framework to the better understanding.

Why make Objects when you can just use a MySQL database?

So I am a little confused on the object oriented part of PHP. Right away I will apologize for the fact I know very little about PHP and databases.
My question is when you are making, say, a database to hold users in it, why would you want to make a class/object for that user when you can just pull info from the database?
Also, if you were to make a object/class where is the data for the objects stored? For example, if I have a class with a username and email, and I make that object, were does it get stored?
Thanks for taking your time to help a learning noob!
My question is when your making per
say a database to hold users in it,
why would you want to make a
class/object for that user when you
can just pull info from the database.
You make objects to abstract away specific functionality. What happens if you move to, say, Microsoft SQL Server (hypothetically speaking)? Rather than update your entire site, you just edit the implementation of the object.
Also if you were to make a
object/class where is the data for the
objects stored? Like a class with a
username and email, and I make that
object, were does it get stored.
The same place as any other variable.
There are a LOT of reasons why you want to use some abstraction on top of just raw database access in any reasonably large software system. If you're looking at an Object Oriented approach you should consider that one of the core ideas of the Object Oriented paradigm is that an object encapsulates both data and logic that acts on that data.
Let's take a concrete example. Say that a part of your application (the UI) needs to display user information, including a nicely formatted user name. In an OO world you could have a User object which would store a local copy of the data in the database, and expose methods like getFormattedName(), or something similar. Now the rest of your application can use that code without needing to know about the database, or even how the name is formatted. On the other hand if you were just pulling data directly from the database then the UI part of the application (which doesn't really care about databases) still has to know itself how to get information about the user from the database, and how to format the users name nicely.
To put it simply, there are logic not captured in a database table but related to the entry. The database only stores the raw data. How the data is used and how it interacts with the rest of your application should be captured in your object methods.
You're missing a fundamental of object-oriented design. Ignoring inheritence entirely, Objects combine information/data and functions/procedures/operations into a single unit called an object. This object performs operations (methods/behaviors/functions/procedures) and has attributes. A database will not have the entire set of operational/procedural information. By design, a database will only contain data, and know nothing of how the data can be used or what the data does.
Databases store data in a tabular fashion which is designed to be speedy. Objects are so much more flexible; they can be trees, they can be lists, they can be widgets, or anything else out of a million things. They can represent presentation, data, or structure. And sometimes they are even faster (when it's easier to calculate a value on the fly rather than retrieve it from a database). Databases are very powerful and important but are only appropriate for a small subset of the tasks that a web application performs. The rest are made easier by objects.

PHP MVC & SQL minus Model

I've been reading several articles on MVC and had a few questions I was hoping someone could possibly assist me in answering.
Firstly if MODEL is a representation of the data and a means in which to manipulate that data, then a Data Access Object (DAO) with a certain level of abstraction using a common interface should be sufficient for most task should it not?
To further elaborate on this point, say most of my development is done with MySQL as the underlying storage mechanism for my data, if I avoided vendor specific functions -- (i.e. UNIX_TIMESTAMP) -- in the construction of my SQL statements and used a abstract DB object that has a common interface moving between MySQL and maybe PostgreSQL, or MySQL and SQLite should be a simple process.
Here's what I'm getting at some task, are handled by a single CONTROLLER -- (i.e. UserRegistration) and rather that creating a MODEL for that task, I can get an instance of the db object -- (i.e. DB::getInstance()) -- then make the necessary db calls to INSERT a new user. Why with such a simple task would I create a new MODEL?
In some of the examples I've seen a MODEL is created, and within that MODEL there's a SELECT statement that fetches x number of orders from the order table and returns an array. Why do this, if in your CONTROLLER your creating another loop to iterate over that array and assign it to the VIEW; ex. 1?
ex. 1: foreach ($list as $order) { $this->view->set('order', $order); }
I guess one could modify the return so something like this is possibly; ex. 2.
ex. 2: while ($order = $this->model->getOrders(10)) { $this->view->set('order', $order); }
I guess my argument is that why create a model when you can simply make the necessary db calls from within your CONTROLLER, assuming your using a DB object with common interface to access your data, as I suspect most of websites are using. Yes I don't expect this is practical for all task, but again when most of what's being done is simple enough to not necessarily warrant a separate MODEL.
As it stands right now a user makes a request 'www.mysite.com/Controller/action/args1/args2', the front controller (I call it router) passes off to Controller (class) and within that controller a certain action (method) is called and from there the appropriate VIEW is created and then output.
So I guess you're wondering whether the added complexity of a model layer -on top- of a Database Access Object is the way you want to go. In my experience, simplicity trumps any other concern, so I would suggest that if you see a clear situation where it's simpler to completely go without a Model and have the data access occur in the equivalent of a controller, then you should go with that.
However, there are still other potential benefits to having an MVC separation:
No SQL at all in the controller: Maybe you decide to gather your data from a source other than a database (an array in the session? A mock object for testing? a file? just something else), or your database schema changes and you have to look for all the places that your code has to change, you could look through just the models.
Seperation of skillsets: Maybe someone on your team is great at complex SQL queries, but not great at dealing with the php side. Then the more separated the code is, the more people can play to their strengths (even more so when it comes to the html/css/javascript side of things).
Conceptual object that represents a block of data: As Steven said, there's a difference in the benefits you get from being database agnostic (so you can switch between mysql and postgresql if need be) and being schema agnostic (so you have an object full of data that fits together well, even if it came from different relational tables). When you have a model that represents a good block of data, you should be able to reuse that model in more than one place (e.g. a person model could be used in logins and when displaying a personnel list).
I certainly think that the ideals of separation of the tasks of MVC are very useful. But over time I've come to think that alternate styles, like keeping that MVC-like separation with a functional programming style, may be easier to deal with in php than a full blown OOP MVC system.
I found this great article that addressed most of my questions. In case anyone else had similar questions or is interested in reading this article. You can find it here http://blog.astrumfutura.com/archives/373-The-M-in-MVC-Why-Models-are-Misunderstood-and-Unappreciated.html.
The idea behind MVC is to have a clean separation between your logic. So your view is just your output, and your controller is a way of interacting with your models and using your models to get the necessary data to give to the necessary views. But all the work of actually getting data will go on your model.
If you think of your User model as an actual person and not a piece of data. If you want to know that persons name is it easier to call up a central office on the phone (the database) and request the name or to just ask the person, "what is your name?" That's one of the ideas behind the model. In a most simplistic way you can view your models as real living things and the methods you attach to them allow your controllers to ask those living things a series of questions (IE - can you view this page? are you logged in? what type of image are you? are you published? when were you last modified?). Your controller should be dumb and your model should be smart.
The other idea is to keep your SQL work in one central location, in this case your models. So that you don't have errant SQL floating around your controllers and (worst case scenario) your views.

Categories