Comprensión de OOP: cómo usar la conexión PDO en otras clases

Creo que tengo un problema para entender cómo funciona la POO. Ya cambié el código que funciona, pero creo que no es la forma correcta. Siguiente escenario (No, no estoy creando un inicio de sesión de usuario por mí mismo, es realmente solo para que el desarrollador local entienda mejor la POO):

Tengo un archivo database.php:

class Database {

    /* Properties */
    private $conn;
    private $dsn = 'mysql:dbname=test;host=127.0.0.1';
    private $user = 'root';
    private $password = '';

    /* Creates database connection */
    public function __construct() {
        try {
            $this->conn = new PDO($this->dsn, $this->user, $this->password);
        } catch (PDOException $e) {
            print "Error!: " . $e->getMessage() . "";
            die();
        }
        return $this->conn;
    }
}

Entonces, en esta clase, estoy creando una conexión de base de datos y devuelvo la conexión (¿objeto?)

Luego tengo una segunda clase, la famosa clase de usuario (en realidad no estoy usando carga automática, pero lo sé):

include "database.php";

class User {
    /* Properties */
    private $conn;

    /* Get database access */
    public function __construct() {
        $this->conn = new Database();
    }

    /* Login a user */
    public function login() {
        $stmt = $this->conn->prepare("SELECT username, usermail FROM user");
        if($stmt->execute()) {
            while($rows = $stmt->fetch()) {
                $fetch[] = $rows;
            }
            return $fetch;
        }
        else {
            return false;
        }
    }
}

Estas son mis dos clases. Nada grande, como ves. Ahora, no te confundas con el nombre de la funciónlogin - En realidad, solo trato de seleccionar algunos nombres de usuario y correos de usuario de la base de datos y mostrarlos. Intento lograr esto:

$user = new User();
$list = $user->login();

foreach($list as $test) {
    echo $test["username"];
}

Y aquí viene el problema. Cuando ejecuto este código, aparece el siguiente mensaje de error:

Error no detectado: llamada al método indefinido Base de datos :: prepare ()

Y no estoy seguro de entender realmente qué causa este error.

El código funciona bien cuando cambio las siguientes cosas:

Cambio$conn en database.php a public en lugar de private (creo que eso es malo ...? Pero cuando es privado, solo puedo ejecutar consultas dentro de la clase Database, tengo razón? Entonces, ¿debería poner todas estas consultas en la clase Database? "Creo que eso es malo, porque en un gran proyecto se volverá realmente grande ..)

Y el segundo cambio que tengo que hacer es: Cambiar$this->conn->prepare a$this->conn->conn->prepare en el archivo user.php. Y aquí realmente no tengo idea de por qué.

Quiero decir, en el constructor de user.php tengo un$this->conn = new Database() y dado que la nueva Base de datos me devolverá el objeto de conexión de la clase DB, realmente no sé por qué tiene que haber un segundoconn->

Estaría realmente agradecido si alguien puede explicarme esto un poco mejor. Sé sobre la visibilidad de las variables y he leído mucho al respecto, pero creo que no lo entiendo en este momento, de lo contrario no tendría este problema.

Gracias por cada consejo! :)

Respuestas a la pregunta(1)

Su respuesta a la pregunta