Class 'User' not found in UserProvider.php

Hola, estoy aprendiendo a programar y es la primera vez que utilizo Silex. Tengo un problema que no entiendo que puede pasar. Os dejo el código para que me digáis que puede fallar. El error es:

Fatal error: Class 'Evi\User' not found in Evi/UserProvider.php
<?php
 
namespace Evi;
 
use Symfony\Component\Security\Core\User\UserInterface;
 
class User implements UserInterface
{
    private $id;
    private $username;
    private $name;
    private $password;
    private $surname;
    private $email;
    private $activate;
    private $description;
    private $status;
    private $confirmed;
    private $roles;
 
    public function __construct($id,$username, $password, $name, $surname, $description,array $roles = array(), $email, $status, $activate,$confirmed)
    {
        if ('' === $username || null === $username) {
            throw new \InvalidArgumentException('The username cannot be empty.');
        }
        $this->id= $id;
        $this->username = $username;
        $this->password = $password;
        $this->name = $name;
        $this->surname=$surname;
        $this->email=$email;
        $this->activate=$activate;
        $this->description= $description;
        $this->status = $status;
        $this->roles = $roles;
        $this->confirmed=$confirmed;
    }
    public function getId()
    {
        return $this->id;
    }
    public function getConfirmed()
    {
        return $this->confirmed;
    }
    public function getStatus()
    {
        return $this->status;
    }
    public function getActivate()
    {
        return $this->activate;
    }
    public function getEmail()
    {
        return $this->email;
    }
    public function getName()
    {
        return $this->name;
    }
    public function getSurname()
    {
        return $this->surname;
    }
    public function getDescription()
    {
        return $this->description;
    }
    public function __toString()
    {
        return $this->getUsername();
    }
 
    public function getRoles()
    {
        return $this->roles;
    }
 
    public function getPassword()
    {
        return $this->password;
    }
    public function getSalt()
    {
    }
 
    public function getUsername()
    {
        return $this->username;
    }
    public function eraseCredentials()
    {
    }
}
<?php
namespace Evi;
error_reporting(E_ALL);
ini_set('display_errors', 1);
 
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use \Evi\User;
//use Symfony\Component\Security\Core\User\User;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Doctrine\DBAL\Connection;
 
class UserProvider implements UserProviderInterface
{
    private $conn;
 
    public function __construct(Connection $conn) {
        $this->conn = $conn;
    }
 
    public function loadUserByUsername($username) {
        $stmt = $this->conn->executeQuery('SELECT * FROM users WHERE username = ?', array(strtolower($username)));
        if (!$user = $stmt->fetch()) {
            throw new UsernameNotFoundException(sprintf('Username "%s" does not exist.', $username));
        }
 
        return new \Evi\User($user['username'], $user['password'], $user['name'], $user['surname'], $user['description'], explode(',', $user['roles']),$user['email'] , $user['status'],$user['activate'],$user['confirmed']);
    }
 
    public function refreshUser(UserInterface $user) {
        if (!$user instanceof \Evi\User) {
            throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));
        }
 
        return $this->loadUserByUsername($user->getUsername());
    }
 
    public function supportsClass($class) {
        return $class === '\Evi\User';
    }
    ....
}

Gracias, ayudarme por favor no entiendo que falla.

Respuestas

#1

El problema está relacionado con los "namespaces" que, explicado de forma sencilla, sería como el directorio donde se encuentra la clase (¡esto no es exacto del todo, pero para este ejemplo sencillo nos basta!)

La clase User la tienes perfectamente definida:

namespace Evi;
 
use Symfony\Component\Security\Core\User\UserInterface;
 
class User implements UserInterface { ... }

El problema está en la clase UserProvider. Debes hacer estos cambios:

1) El use \Evi\User; debería ser use Evi\User; Si de nuevo simplificamos mucho la explicación: la barra por delante es solo para las clases propias de PHP, no para las tuyas. Así por ejemplo verás habitualmente cosas como \DateTime o \PDO. Importante: cambia esto también en el código de la clase UserProvider en esta línea: return $class === '\Evi\User';

2) Cuando añades un use ... en una clase, estás importando esa clase, por lo que en el código no tienes que volver a usar la ruta completa a la clase. Así que reemplaza en el código de la clase UserProvider cosas como return new \Evi\User por return new User y if (!$user instanceof \Evi\User) { por if (!$user instanceof User) {

3) Por último, cuando las clases que usas están en el mismo "namespace", no hace falta que las importes. Así que como User y UserProvider están bajo el "namespace" Evi, podrías usar cualquier de las dos clases en la otra sin tener que importarla (sin tener que añadir el use ... al principio de la clase).

#2

Muchas gracias he aprendido un poco más de namespace. Lo puse como me dijiste pero me daba el mismo fallo y era porque tenia mal un directorio. Muchas gracias !!! :)