I am playing around with OOP programming, and have hit a hurdle I could use advice with.
I have a situation where I have nested classes. I have a "Company" class, which contains an array called people. This array contains many instances of a "Person" class.
The data for both 'company' and 'person', are stored within a database, and the relevant class retrieves the information from that database as and when it is needed.
My question quite simply is this: "At what point do I connect to the database?" Do I:-
a) Connect first in my PHP page, then pass the connection to the instance of "Company" for it to use.
b) Put the username, password etc directly in the "Company" class and connect there.
I would have thought that the latter would create multiple connections to the database - one for each instance of "Company" - so probably the answer is "A". But then, if I were to pass the class to another developer (this is only a learning exercise, so not something I plan to do), he would have to connect to the database himself, and not allow my class to do it for him.
In either case, would the connection be passed to each instance of the "Person" class automatically, or would I have to pass the connection each time I create a new instance?
I have done some research on this, and I think the answer is "A" (connect to the database in my PHP page, and pass the connection to each instance of the Company class), but just thought I should double check before I get too far.
Thanks for any advice you are able to offer.
You solution A) sounds familiar to me. That way you can just pass the database connection to the object or maintain a global registry to store the connection object (e.g. PDO) into.
I think you're on the right track.
What you're describing is known as dependency injection and using it is generally a good idea.
When you're dealing with a more complex project, it might be a good idea to abstract the retrieval of data completely. Create an interface, i.e. "PersonFinder" or "CompanyFinder" that deals only with the lookup and retrieval of its associated records. Concrete implementations of this interface might include database lookups, or CSV file lookups, or even some sort of web-based service lookup. Pass your Finder into your Company or Person objects when you create them.
This way you can easily change how you find your records without changing the code that deals with them.
Related
I am beginning to get into more OO PHP and also writing tests for that objects. My main question is: if I have a Blog_Post object, and I call $post->setCategory( 'Foo' ), should doing that save to the database directly?
The reason I ask is for unit testing, I often don't want to use the DB for these kind of things because that's not what I am testing.
I have seen people suggest doing something like
function __construct( PDO $db )
to pass in the database object to be used, then use mock when testing. However, I really don't like the idea of having instantiate my database objects all the time by whatever is calling the Blog_Post class.
This is in the scope of WordPress, which does not have an OO approach fundamentally - with my current Blog_Post, the setter method would just call the DB (via a global $wpdb!! (i know!)).
Really I wanted to know, what's the general pattern that is the path of least resistance with something like this. Would Blog_Post just write it's self, or would one maybe put on a "save()" method to actually push all set properties to the DB? Or perhaps set a flag on teh object "setSaveToDB(false)" before calling the setter.
Thanks, hope this make some sense!
Short answer: No. Delegate loading, saving to another layer.
If you're looking to have any kind of performance, then using a ->save() function on the object is preferable to saving whenever a property is set. If you write to the database every time a property is set then an object with 7 properties will write 7 times to the db, if you have a save function then only one write will be used for all 7 properties. Since opening the db connection is the slowest function of a db you will want to minimize the amount of separate read/writes. In general terms, opening the connection to the db and writing one row takes about the same time as opening a connection and writing 100000 rows. SQL is fast when handling large data sets, but opening the connection and finding the right place to read/write is quite slow.
Hope this helps :-)
I'm creating a new PHP application and want to make sure I get the ground work right to save any future problems. I know my application will have more than one class that will need a database connection (PDO) and after a long time scouring the internet i can't find a definitive solution.
I like the singleton design pattern personally, but there are a lot of people out there that say singletons in general should be avoided at all costs. These people, however, don't give a specific solution to this problem.
I understand that an application may need more than one database connection but could i not create a singleton that contained each required DB connection (i.e. DB::getInst('conn1')->query(); )?
Is it a case of having to pass round the PDO (or PDO wrapper) object to every class that may need it? I've done this before found it annoying keeping track of it.
I personally thing a singleton (or a multiton, if you need several DB connections) is fine for such an usage.
But if you do not want to use it, you should then take a look at the Registry pattern.
This way, you can have your database class instance(s) available for all your application's classes, without having to pass an additional parameter each time (which is very ugly, IMHO).
but could i not create a singleton that contained each required DB connection (i.e. DB::getInst('conn1')->query(); )?
you can, it's called multiton pattern
This is going to take a bit to explain. I'm creating my first real-world web application, and I'd to do it properly. I have very little PHP experience, but vast experience in other languages so technical skill isn't a problem, it's more conventions of the language. I'm following the MVC pattern, and I am at the stage where I'm implementing user registration for the application.
To standardise connections to the database, I've created a Config class with a static getConnection method, which creates a mysqli connection object. This isn't a problem, it's the next bit that is.
To make my classes a bit more readable, I have various functions built into them that make database calls. For example, my User class has a getFriends method like so:
class User
{
public $id;
public getFriends()
{
return UserController::getFriends($id);
}
}
But as it stands now, if I implement it that way, it means creating a connection for every query on a page, probably many times in a single script, which is just horrific.
I was thinking about doing the same as above, but pass getFriends a mysqli object, which in turn passes one to UserController::getFriends as well, but that feels messy, and frankly poor form, even though it would guarantee only one connection per script, a much better improvement.
I also thought about scrapping the idea of keeping the methods inside User altogether, and instead making calls like UserController::getFriends($connection, $id) directly in the script, with a single $connection declared at the beginning, in place of user->getFriends(). That seems like the absolute cleanest, nicest solution, but I'm unsure.
So, essentially, how do PHP folks normally do this sort of thing?
What I do in my MVC framework is create a db connection and assign it to the Model base class (in the config):
$db = new database\adapters\MySQL(...);
if ( !$db->connected() ) {
exit('Ewps!');
}
database\Model::dbObject($db);
Then later on, anywhere, I can use:
User::getFriends(13);
because User extends Model and Model has access to $db: self::dbObject()
If I need my raw db connection, I either use Model::dbObject() or $GLOBALS['db'], but I rarely do need the raw connection, because all db logic should be in your Models.
https://github.com/rudiedirkx/Rudie-on-wheels/blob/master/example_app/config/database.php
https://github.com/rudiedirkx/Rudie-on-wheels/blob/master/example_app/models/User.php#L30
Have a look into the Singleton Pattern . It allows you to create a class (a DB object), but where only one of them is ever allowed (so more than one can't be instantiated).
This means that you only have to create one connection to the DB and it's shared.
Check here for a code example
The Situation:
I am using a db class as a wrapper (dbwrapper) to open and close db connections via PHP PDO
I have 3 separate classes which extend this db wrapper
I instantiate 3 objects from said classes and in the course of their existence they each make db queries
MySQL used in this case.
When the methods of the 3 classes require db access they each create PDO objects internally, making use of the dbwrapper which they extended. Each object is storing its PDO object in a member/field for reference by itself.
The Question: My question is this... is each object creating a separate connection to the database, making 3 in total? Is each client of Apache creating only one connection to the database or is each object using the db in a php application creating a connection. (sounds inefficient!)
The Reason: I would like to understand how these connections are handled.
I am trying to decide if it would be better to have each class extend the dbwrapper or if it would be better to initialize the dbwrapper without making an automatic connection the db, handle that when its needed. Instead I would pass the dbwrapper to each objects constructor as they are initialized... letting them use that reference. If multiple db connections are happening then I think this would be the best way to minimize overhead while overcoming issues of object's scope and access.
Thanks in advance!
is each object creating a separate connection to the database, making 3 in total?
Maybe. I don't know, but here's how to find out. While your script is running, connect to MySQL via your client of choice (like the command line) and issue the command SHOW PROCESSLIST; You'll get a list of active connections.
You might need to insert a sleep in your script to keep it alive long enough for you to run the process list command when you've instantiated and are working on all three objects.
You'll see either one connection or three. Then you'll have your answer.
(The answer will vary depending on the underlying driver. Some drivers will reuse the connection if the DSN is identical.)
Instead I would pass the dbwrapper to each objects constructor as they are initialized... letting them use that reference
This is the common practice. Database handles are prime candidates for the Singleton pattern as well.
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.