Object-oriented – OOP implementation doubts with databases

classdatabaseobject-orientedPHP

I was starting a project today and after designing the database structure and how the data would be stored etc, I started the implementation. I am doing this on php, but the language isn't really relevant here, since my doubts are more architectured related or I guess, since I'm struggling more than I thought by implenting stuff in OOP on PHP. (Recently jumped on php, I've been coding in c++ and java before).

So, I started by creating my "User" class, simple as that, few attributes, and __construct, insert, update and delete methods. Those last 3, queries to the db.

Then this doubt came to my head, and I probably know the answer myself but I just don't find out.

I can now create instances and create new Users: $user = new User("John", 34) but, what if I want to edit the user "Dave"? Or I want to show all users. That method, for example, getAllUsers() which would return all users where would be implemented? Because it doesn't really belong to the class User right? If it did, then how I would instance that method if I don't have any User instance?

I guess, I would need a class Users, or UserCollection which would be a collection of all the users, with the methods ´getCertainUser(id)´ and ´getAllUsers()´ which would return certain User or All of them, now then I would have a User I would be able to edit.
That is the way I've did in both Java and C++, since I didn't use a database to store the data, it was stored on a Set/Map or whatever the structure, and then saved on files.

That being said, my questions is, how this problem should be addressed as the way to go, Am I complicating things too much? How this should be solved 'the correct way' in OOP. The times I've handled similar problems I've never used a database, so having a collection of users was the only way to store them, but having the database which stores the users feels redundant to have that collection of users.

Thanks in advance.

Best Answer

The problem should be addressed by separating concerns

Here is what I mean.

The reason why you have a bad feeling about adding the getAllUsers() to the User class is because it is too much responsibility for that class. This could convolute things down the line - especially when trying to test things.

My suggesting would be to rethink the way you are doing it.

Instead of making the User class know about all of those things such as inserting itself, updating itself and maybe returning all of the users - make it instead a DTO object that doesn't know about anything.

Then have a UserManager that takes in that DTO which can insert it into the database, update it, delete it and have a UserReader or UserRetriever (or some other name that gets the point across) that either returns back all users as a list of DTOs or a specific user based on the id.

This way it makes testing easier and makes sense conceptually which is key when - you want others to contribute to the project or just maintain it yourself.