Attempting to utilize OOP with a user-management class
No, this design is not object-oriented, nor would I recommend you follow your friend's advice. I also would not recommend your original design either. Neither one adheres very well to object-oriented design principles, namely the SOLID principles.

In your friend's rendition, he is proposing a structure that is very active record-like, where a domain object also knows how to persist and retrieve itself. While this pattern is used in many places (Ruby on Rails, CakePHP, etc), it can make testing very difficult, it can cause dependency problems, and it is not single responsibility.

It is difficult to test (especially your rendition) because the object is dependent on the database. Since you instantiate the database object in your method, there is no easy way to mock it or stub it out either.

Nor is there an easy way to substitute different implementations. Your class is tied to the concrete database implementation. It has a dependency that cannot be isolated.

The class has numerous responsibilities that are completely unrelated to representing a user. For example, in the getUser method, we are responsible for:


Getting a database connection object,
Building a query,
Running that query,
Fetching the results,
Translating the results into object properties.


This code has a lot of fingers in a lot of pies, and depends on the specific functionality of a lot of other parts.

Your proposal of simply having a data object, and a separate object to manage persistence is more on track. It falls down a bit in the details, though. To be truly object-oriented, you want to encapsulate your data. Having all public members does not encapsulate anything. The most basic way to make this more object-oriented is to have getters and setters (some may debate this, and there are other routes that can be taken, but this is a good start). This way, if the internal structure of your class changes, you can hide it by adjusting the implementations of the encapsulating methods while preserving the public API.

The pattern you are looking for is the Repository pattern. It allows you to isolate and encapsulate mapping between a persistence layer and domain objects, and allows the domain objects to focus on the single responsibility of representing the business concept they represent.

I would also recommend you learn about dependency injection to help you to understand why instantiating objects inline can cause problems, and what one potential solution is.