Creation of db abstraction layer using php - php

I am trying to create simple database abstraction layer. I read a lot of articles about Active Record and Table Data Gateway and right now I am very confused.
I think that I understand some theory (small) about them but not how exactly to implement them. I have choosed to implement Data Table Gateway. I will try to explain what I did and if you give me some advices I will be glad. I am not sure why (for example in ZF2) every time I have to use Table Data Gateway like DI in the models.
In my case my AbstractModel just get DbAdapter in the constrictor by IoC container but I am not sure that this is ok.
Ok I will describe my situation.
I have following classes:
DbAdapter -> it creates db connection (using PDO)
IoC (Inversion of Control Container)
AbstractModel -> in constructor I get DbAdapter using IoC. This means that it hold only one instance of DbAdapter. In this class I also have CRUD methods.
Another classes represent the tables in db. For example class User extends AbstractModel and has method getTable which return the name of the table. Another sql queries will be in this classes which represent the tables. These classes have access to DbAdapter.
Is it ok this scheme and how can I improve it?

Related

How to query database from a OOP point-of-view

Hey Guys
I know Stackoverflow is may not the right place to ask, if there's another Stackexchange group where
this question fits better, then please tell me.
So, I'm trying to learn OOP. I think I understand it quite good, but there's one thing I really can't figure
out what the right way is, and thats the handling of database.
So, I'm confused a bit of what should go in which class.
Lets say I've a db class. Inside of this class I'm connecting to the database in a constructor. And now lets say
I've got a user class.
So now the question:
Where should I put in the query for example creating a new user? Should i create a method in the user class,
or should I create a method in the DB class? If in DB class, should it really be a method like create_user()
or should it more be something globally like query where I can pass in whatever query I want.
Here, for example a project from Github:
https://github.com/christran/PHP-OOP-Login-Register-System/blob/master/classes/user.php
As you can see, all query methods are in db.php and from user.php he's just calling this methods. So is this the right way to go?
Or doesn't it matter at all? May, any of those approches is "more" OOP than the other?
It's actually just really confusing me and I don't understand whats the better way. I've searched a lot, but never
found an article to this specific question.
So what I did, I looked for projects on Github and looked at their code, how they've solved the problem...
But with this method I just got confused even more, because you see both.
Is it just a preference of the coder?
I am really thankful for all your help. Have a nice day! :)
Here a little example of what I mean:
Query inside user class:
class user {
private function createUser() {
//SQL Query here (prepared statements etc...)
}
}
OR:
class user {
private function createUser() {
// Call to db.class to insert_method() ...
}
}
Basically, you are looking into ORM.
To answer your question specifically,
Should i create a method in the user class
This is possible, and is called Active record pattern, where an entity contains not only methods related to itself (like $user->getBirthday()) but also methods that related to database interaction (like $user->save()).
or should I create a method in the DB class?
This is impossible, as this class will become enormously big.
However, you can create a sister class for the every entity, that will be responsible for the database interaction. This approach is called Data Mapper pattern. For example, there is a User class that contains methods related to the user, and also a UserMapper class, that is inherited from abstract mapper class with generic methods $userMapper->save(), $userMapper->find() and such.
The createUser method that contains the query shouldn't be part of the User object, but neither of the database object. The first one is for business logic. The latter one is for managing the database method and providing generic functionality for executing statements. A different object inbetween those objects should be the one that takes the data from the user object and generate the queries for storing it in the database.
The term I think you're looking for here is ORM (Object-relational mapping).
This concept is about mapping objects to a different, incompatible structure, like a database.
There are ORM libraries/frameworks available for PHP which can do much of the work for you, and some of them are part of, or can be used with, popular MVC frameworks like Eloquent ORM in Laravel. For example, they will often provide the basic CRUD operations by implementing the SQL statements needed after you just configure the right database table.
In terms of OOP, you will often have an extra layer on top of it. So you got a business object User, which contains the rules for users, for instance rules it has to follow for a user name. The business object will enforce those rules and contain the general behaviour of a User object. For saving you make use of an ORM to save a user object to a specific database. The database logic is not in the User object itself. It shouldn't have to know about the specific queries to save itself, and maybe it shouldn't even be aware of concepts like loading and saving. It just contains logic and data, and other parts of the implementation are responsible for persisting that data (optionally using an ORM framework to make things easier).

Symfony2 Database separation

I was trying to setup a UserModel Class and very unhappy with the separation of database and Models.
For example I want to check if Username already exists or generate a new User. But all these actions require a database connection, which is only available in a controller. Of course i can always inject the DB Object, but it just feels wrong. What is the right way to handle these things?
You can use the UniqueEntity validator, the docs are here
http://symfony.com/doc/current/reference/constraints/UniqueEntity.html
About the db connection, you can easily inject specific repositories or the entity manager itself in your services where needed.

PHP OOP - Php objects extends Mysql Object = Multiple Mysql Connection?

I'm currently working on a Shopping Cart in which I use a custom Mysql Class to send query to the db.
On this project, I plan to extends this Mysql Class for each Object that I will use : Category, Product, Shopping Cart.
If I create a class like this one:
class Catalog_Categories extends Mysql{}
And then another one like this:
class Catalog_Products extends Mysql{}
Are those classes using the same Mysql Object to connect on DB or are they using 2 separate connections?
I'm a little bit lost.
Thanks!
Carl.
That depends on how your Mysql class is written. If you write it using a Singleton pattern, it will maintain one database instance. You could write it as a Factory pattern and have it generate a new instance for each object that uses it. There are many other patterns and possibilities available so it all just depends on how you want it to work and how you wrote the custom Mysql class.
Assuming that you are creating a database connection in your Mysql class, every object your create of any of the extending classes, will create a new DB connection.
There are several ways to avoid this, for example, you can create one global connection to your database and pass that connection to the constructor of your class so that they all will use that same connection.
Are those classes using the same Mysql Object to connect on DB or are they using 2 separate connections?
We cannot answer this question until we see the complete code.
But extending in this case looks like a bad idea. If you cannot say that class A is a class B - then you should prefer composition over inheritance. This means that Catalog_Products should have a reference to mysql object, but shouldn't extend it.
To get you idea when inheritance is justified is class mysql extends database. In this case you can say "mysql is a database", so extension here looks reasonable as long as database class encapsulates the common logic, and mysql class represents more detailed specifics.

How does an implementation of Table Data Gateway differs from Active Record?

Put simply about Table Data Gateway (TDG) implementation: you create separate TDG class that contains SQL for CRUD operations with concrete table. So, your models communicate not directly with a datasource (for example database) but via those abstracted ones - TDG classes. So, it's just an approach for making another level of abstraction and it's just a wrapper for communicating with database - get and modify the data. IMHO TDG classes should not contain members, only methods. Here's a good schema that visualizes the use TDG pattern. When using TDG approach, SQL should be moved from model classes to datasource (TDG) classes. And all data that I retrieve from DB through TDG classes are stored in my model members.
Now, what about active record implementation? If I would merge data access and my model class into one model class then would I implement active record? I was unable to find a clear distinction or how those patterns look in PHP and differ from each other.
Often, I'm having one singleton database class and then separate model class for each database table. Each model class has CRUD + several custom (count, avg and etc.) operations. Some classes have members for persisting results from CRUD or custom operations - thats's done upon the need. Could this approach be identified as active record? Also, if I would move SQL from my model classes to TDG classes would this be Table Data Gateway?
From http://martinfowler.com/eaaCatalog/index.html
Table Data Gateway: An object that acts as a Gateway (466) to a database table. One instance handles all the rows in the table.
Active Record: An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data.
The obvious main difference is that TDGs wrap access to a table and only returns row data, while ARs wrap access to a row in the table and adds business logic to it.
Unless you have very low impedance mismatch, having a TDG is preferred because with AR your business/domain objects follow the structure in the database, which us usually not how your domain objects should be modeled. A Row may know how to persist itself, but a Person should not know. It is more maintainable in the long run to to separate persistence logic and domain logic.
Regarding your Singleton DB object have a look at Is there a use-case for singletons with database access in PHP?.

Should I be making this a model?

I have a family of complex select queries which I need to call from different parts of the application. I think I should group them all into a model class, but would like to verify this.
The queries all work off the same set of 5 tables. Each of these tables has its own Table Data Gateway class and Row Data Gateway class, but my new class for the queries would not be implementing any such pattern (since it doesn't wrap a table or row). My new class would be calling on the Table and Row Data Gateways already established.
In addition, the values that come from users can't be susbstituted into the queries directly, so I plan to do some pre-processing in the new class as well. This pre-processing includes accessing the DB for lookup values, etc.
Does this sound fair? I think it's exactly how models should be used, but I can be spectacularly wrong about such things so would appreciate any comments or advice. (FYI, I'm using Zend Framework).
Queries don't go in the Model part. They are persistence related (the model doesn't handle persistence).
These complex queries should be in the Persistence layer, which is here the Table Data Gateway classes.
I would name the Table Data Gateway classes "DAO" (Data Access Object). A Table Data Gateway is a kind of DAO, since you can have a DAO that help you get things from files, webservices...
So you can keep your actual classes, and add a DAO to manage these complex queries. This DAO is not providing you access to a specific DB table, but it is still providing you access to a data source (composed by several DB tables).
Edit :
I suggest you to create a DAO interface (it may be empty). You DB Tables will implement this interface. Your new class will also implement this interface, but not extend Zend_Db_Table.
In short, you are redefining/renaming your persistence layer, from "Zend Db Table" to "DAO" (which makes it more generic). Zend Db Table is a kind of DAO.

Categories