Accéder à une propriété sur un élément qui n'est pas un objet

Default
,

Bonjour,

Voilà je rencontre un petit problème avec mon code, (je suis débutant en PHP) apres avoir suivi le tuto sur la création d'un espace membre, j'ai téléchargé les codes sources, et après avoir créé mon compte, j'ai voulu m'y connecter mais à chaque fois mes identifiants sont incorrects, aussi le message d'erreur " Notice: Trying to get property of non-object in C:\UwAmp\www\demo\class\Auth.php on line 82" apparait.

<?php
class Auth{

    private $options = [
        'restriction_msg' => "Vous n'avez pas le droit d'accéder à cette page"
    ];
    private $session;

    public function __construct($session, $options = []){
        $this->options = array_merge($this->options, $options);
        $this->session = $session;
    }

    public function hashPassword($password){
        return password_hash($password, PASSWORD_BCRYPT);
    }

    public function register($db, $username, $password, $email){
        $password = $this->hashPassword($password);
        $token = Str::random(60);
        $db->query("INSERT INTO users SET username = ?, password = ?, email = ?, confirmation_token = ?", [
            $username,
            $password,
            $email,
            $token
        ]);
        $user_id = $db->lastInsertId();
        mail($email, 'Confirmation de votre compte', "Afin de valider votre compte merci de cliquer sur ce lien\n\nhttp://local.dev/Lab/Comptes/confirm.php?id=$user_id&token=$token");
    }

    public function confirm($db, $user_id, $token){
        $user = $db->query('SELECT * FROM users WHERE id = ?', [$user_id])->fetch();
        if($user && $user->confirmation_token == $token ){
            $db->query('UPDATE users SET confirmation_token = NULL, confirmed_at = NOW() WHERE id = ?', [$user_id]);
            $this->session->write('auth', $user);
            return true;
        }
        return false;
    }

    public function restrict(){
        if(!$this->session->read('auth')){
            $this->session->setFlash('danger', $this->options['restriction_msg']);
            header('Location: login.php');
            exit();
        }
    }

    public function user(){
        if(!$this->session->read('auth')){
            return false;
        }
        return $this->session->read('auth');
    }

    public function connect($user){
        $this->session->write('auth', $user);
    }

    public function connectFromCookie($db){
        if(isset($_COOKIE['remember']) && !$this->user()){
            $remember_token = $_COOKIE['remember'];
            $parts = explode('==', $remember_token);
            $user_id = $parts[0];
            $user = $db->query('SELECT * FROM users WHERE id = ?', [$user_id])->fetch();
            if($user){
                $expected = $user_id . '==' . $user->remember_token . sha1($user_id . 'ratonlaveurs');
                if($expected == $remember_token){
                    $this->connect($user);
                    setcookie('remember', $remember_token, time() + 60 * 60 * 24 * 7);
                } else{
                    setcookie('remember', null, -1);
                }
            }else{
                setcookie('remember', null, -1);
            }
        }
    }

    public function login($db, $username, $password, $remember = false){
        $user = $db->query('SELECT * FROM users WHERE (username = :username OR email = :username) AND confirmed_at IS NOT NULL', ['username' => $username])->fetch();
        if(password_verify($password, $user->password)){
            $this->connect($user);
            if($remember){
                $this->remember($db, $user->id);
            }
            return $user;
        }else{
            return false;
        }
    }

    public function remember($db, $user_id){
        $remember_token = Str::random(250);
        $db->query('UPDATE users SET remember_token = ? WHERE id = ?', [$remember_token, $user_id]);
        setcookie('remember', $user_id . '==' . $remember_token . sha1($user_id . 'ratonlaveurs'), time() + 60 * 60 * 24 * 7);

    }

    public function logout(){
        setcookie('remember', NULL, -1);
        $this->session->delete('auth');
    }

    public function resetPassword($db, $email){
        $user = $db->query('SELECT * FROM users WHERE email = ? AND confirmed_at IS NOT NULL', [$email])->fetch();
        if($user){
            $reset_token = Str::random(60);
            $db->query('UPDATE users SET reset_token = ?, reset_at = NOW() WHERE id = ?', [$reset_token, $user->id]);
            mail($_POST['email'], 'Réinitiatilisation de votre mot de passe', "Afin de réinitialiser votre mot de passe merci de cliquer sur ce lien\n\nhttp://local.dev/Lab/Comptes/reset.php?id={$user->id}&token=$reset_token");
            return $user;
        }
        return false;
    }

    public function checkResetToken($db, $user_id, $token){
        return $db->query('SELECT * FROM users WHERE id = ? AND reset_token IS NOT NULL AND reset_token = ? AND reset_at > DATE_SUB(NOW(), INTERVAL 30 MINUTE)', [$user_id, $token])->fetch();
    }

}

Comme je vous l'ai dit je suis débutant en php et je ne comprend pas d'ou vient l'erreur. Si vous pouviez m'aider ce serait top ;)

Merci à vous .

6 Réponse

17162
,

Bonsoir.

j'ai téléchargé les codes sources, et après avoir créé mon compte, j'ai voulu m'y connecter mais à chaque fois mes identifiants sont incorrects

Est-ce que tu as bien confirmé le compte via le lien qui est envoyé par mail ?
Car si ce n'est pas le cas, c'est tout à fait normal étant donné que pour récupérer l'utilisateur, il n'y a pas que le nom d'utilisateur ou son email qui sont utilisé dans la requête, il y a aussi le fait que le champ confirmed_at doit être NULL.

aussi le message d'erreur " Notice: Trying to get property of non-object in C:\UwAmp\www\demo\class\Auth.php on line 82" apparait.

Cette erreur rejoint le premier problème, car si aucun enregistrement n'est retourné par la requête SQL, la variable qui stocke le retour vaudra false et étant donné que la variable du coup n'est pas un objet, tu tentes d'accéder à une propriété inexistante, donc pour éviter cette erreur, tu peux ajouter un argument dans la condition, soit par exemple :

if ($user && password_verify($password, $user->password)) {
    // code ...
} else {
    return false;
}
Default
,

Non en effet je n'ai pas confirmé, mais le souci c'est que je reçois pas le lien de confirmation.

35773
,

"le souci c'est que je reçois pas le lien de confirmation"

Est-ce que la fonction "mail" utilisée dans la méthode "register" retourne bien TRUE ??
Si ce n'est pas le cas, il faut vérifier les paramètres passés.
https://www.php.net/manual/fr/function.mail.php

Après, comme dit la documentation : "Il est important de noter que ce n'est pas parce que le mail a été accepté pour livraison qu'il arrivera à destination. "

Si mail() retourne TRUE, il faut vérifier si l'environnement est bien configuré pour envoyer des mails, et si oui, vérifier si ce n'est pas la boite mail qui les bloque.

Default
,

Si c'est bien ça, a priori oui elle retourne bien true.

public function isEmail($field, $errorMsg)
    {
        if (!filter_var($this->getField($field), FILTER_VALIDATE_EMAIL)) {
            $this->errors[$field] = $errorMsg;
            return false;
        }
        return true;
    }

Je cherche dans les paramètres de ma boîte mail (mail) au cas il y aurait quelque chose qui peut bloquer, j'ai même essayé avec d'autres boîtes mail mais rien n'y fait.

35773
,

Non, ce n'est pas çà, reprend mon post : "...la fonction "mail" utilisée dans la méthode "register"...", elle est à la fin de la méthode...

"Je cherche dans les paramètres de ma boîte mail (mail) au cas il y aurait quelque chose qui peut bloquer, j'ai même essayé avec d'autres boîtes mail mais rien n'y fait."

Comme je t'ai les préconisé, assure toi d'abord que les mails peuvent être envoyés par le serveur.

Default
,

Bonjour,
Désolé de cette réponse tardive, en effet c'est bien l'envoi de mail en local qui posait problème. Merci beaucoup pour votre en tout cas.