Bonjour,
Voilà je vous explique je suis en train de mettre en place le module utilisateur. Et sur la class Auth j'ai une erreur que je ne m'explique pas. (nb: j'ai remplacé l'adresse mail par des * pour des raisons de confidentialité)
( ! ) Fatal error: Uncaught PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 Erreur de syntaxe près de '@******.***' à la ligne 2 in E:\web\blog\src\user\Auth.php on line 42
( ! ) PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 Erreur de syntaxe près de '@******.***' à la ligne 2 in E:\web\blog\src\user\Auth.php on line 42
Call Stack
# Time Memory Function Location
1 0.0000 410536 {main}( ) ...\index.php:0
2 0.0005 440184 require_once( 'E:\web\blog\utils\user\login.php' ) ...\index.php:27
3 0.0012 490032 App\user\Auth->authUser( ) ...\login.php:13
4 0.0015 513832 execute ( ) ...\Auth.php:42
Quand je regarde le code je ne vois pas le problème et quand je commente la partie lié à l'update du last_login, pas de problème à me connecter.
<?php
namespace App\user;
use App\Crud;
use \PDO;
class Auth extends Crud{
protected $table = 'users';
protected $selector = ['email', 'pass', 'last_login'];
public function authUser(array $datas) :bool
{
if(session_status() === PHP_SESSION_NONE):
session_start();
endif;
$table = $this->table;
$selector = $this->selector;
date_default_timezone_set('Europe/Paris');
$date = date("Y-m-d H:i:s");
$email = $datas[0];
$pass = $datas[1];
$req = parent::getPDO()->prepare(
"SELECT $selector[0], $selector[1], $selector[2] FROM $table
WHERE email = :email AND pass = :pass");
$req->execute(array(
'email' => $email,
'pass' => $pass
));
$finduser = $req->fetch();
if(!empty($finduser)){
$_SESSION['user_connected'] = true;
$req_update = parent::getPDO()->prepare(
"UPDATE $table SET $selector[2] = :last_login
WHERE email = $email");
$req_update->bindParam('last_login', $date, PDO::PARAM_STR);
$req_update->execute();
return true;
}else{
return false;
}
}
}
<?php
namespace App;
use \PDO;
use \PDOException;
class Crud {
protected $pdo;
public function __construct()
{
try{
$this->pdo = new PDO('mysql:host=blog;dbname=blog;port=3307;charset=utf8', 'root', '', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]);
}catch (PDOException $error){
throw new PDOException($error->getMessage(), (int)$error->getCode());
}
}
protected function getPDO()
{
if ($this->pdo instanceof PDO) {
return $this->pdo;
}
}
public function createElement(array $datas)
{
}
protected function searchElement()
{
}
protected function updateElement()
{
}
protected function deleteElement()
{
}
}
<?php
use App\user\Auth;
if(!isset ($_POST['email']) && !isset ($_POST['pass'])){
require_once '../templates/user/login.html.php';
}else{
$user_log = htmlentities($_POST['email']);
$user_pass = htmlentities(hash('sha256', $_POST['pass']));
$user= [$user_log, $user_pass];
$loginuser = new Auth();
$user_login= $loginuser->authUser($user);
if($user_login === true){
$route= $router->generate('home');
header('Location:' .$route);
exit;
}else{
require_once '../templates/user/login.html.php';
};
};
<div class="container">
<?php if(isset($_POST['pass'])): ?>
<div class="alert">
<span class="closebtn" onclick="this.parentElement.style.display='none';">×</span>
Identifiant ou mot de passe incorrect.
</div>
<?php
endif;
?>
<div class="form-group">
<h1>Se connecter:</h1>
<form action="" method='POST'>
<div class="required">
<label for="email">Identifiant</label>
<input type="email" name="email" placeholder="Votre email" value="<?= htmlentities($_POST['email'] ?? null)?>" required/>
</div>
<div class="required">
<label for="pass">Mot de passe</label>
<input type="password" name="pass" placeholder="Votre mot de passe" required/>
</div>
<div class="form-submit">
<button class="btn-submit click-animation" type="submit" value="S'inscrire" >S'inscrire</button>
</div>
</form>
<a href="passwordChange.php">Mot de passe oublié?</a>
</div>
</div>
Je tiens à rappeler que tout fonctionne si j'enlève la partie update du last_login.
Merci par avance de votre aide.
Et si tu bindParam
l'email ?
Au lieu de faire parent::getPDO()
tu peux faire $this->getPDO()
Tu peux te créer une propriété entity = User::class
et te créer un modèle afin de récupérer ton user sous forme d'objet avec PDO::FETCH_CLASS
Je te remercie pour l'aide Curvata, mais l'update se fait sur le last_login
et non l'email. Je ne comprends pas pourquoi tu veux que je fasses ta dernière phrase, ni même à quoi ça servira.
Mon problème était bien plus simple que ça, j'avais oublié les quotes sur la variable $email
Tu te fais une classe qui va représenter ton user.
<?php
class user
{
private $email;
private $pass;
private $last_login;
public function getEmail()
{
return $this->email;
}
public function getPass()
{
return $this->pass;
}
public function getLastLogin()
{
return $this->last_login;
}
public function setEmail(string $email)
{
$this->email = $email;
}
public function setPass(string $pass)
{
$this->pass = $pass;
}
public function setLastLogin(string $date)
{
$this->last_login = new DateTime($date);
}
}
Dans ton CRUD tu rajoutes une propriété entity
Dans ta classe auth tu redéfini la propriété entity
entity = user::class
Quand tu veux récupérer des users tu fais
->fetchAll(PDO::FETCH_CLASS, $this-entity)
C'est plus sympa d'avoir un objet qu'un tableau..
$user->getName()
$user->getPass()
Par la suite, tu créeras des classes afin de représenter un article, un produit, une catégorie,... Tu auras cas changer la propriété
entity
Je te remercie Curvata tu viens de me donner ce qui me manquait, la logique derrière un CRUD. Donc je comprends la logique de faire un objet par module, les appels à la BDD sont simplifiés. La seule chose que je ne déchiffre pas, que je ne comprends pas c'est ce que fait exactement entity. J'imagine que c'est une variable, mais le user::class je ne trouve rien de tel dans la doc php.
Je vais me baser sur ce que tu m'as donné pour faire des tests.
constante spéciale
La constante spéciale ::class permet une résolution de nom de classe pleinement qualifié au moment de la compilation, cela est utile pour les classes dans un espace de nom.
Par exemple, depuis ta classe "auth" tu veux utiliser ta méthode "searchElement" de ta classe Crud, tu fais $auth->searchElement()
et dans celle-ci tu définis ton fetch (PDO::FETCH_CLASS, $this-entity)
.
Comme le entity
de "auth" c'est "user::class" tu auras un objet pour modèle ta classe "User", si tu as par la suite une classe "PostCrud", tu n'auras cas redéfinir "entity" entity = post::class
et faire ton $postCrud->searchElement()
en ayant bien entendu changé également ta propriété "table".
Tu devrais te faire une classe "userCrud" avec tes deux méthodes "update" et "select" et dans "auth" tu fais ta logique.
Un truc dans le genre
class Auth
{
private $userCrud;
public function __construct(UserCrud $userCrud)
{
$this->userCrud = $userCrud;
}
public function authUser(array $datas) :bool
{
if(session_status() === PHP_SESSION_NONE):
session_start();
endif;
$user = $this->userCrud->findUser($datas)
if(!empty($user)){
$_SESSION['user_connected'] = true;
$this->userCrud->update($user->getEmail());
return true;
}else{
return false;
}
}
}
Je te remercie, je me creuse le cerveau, mais comme je ne suis pas sur un framework certaines choses ne fonctionne peut-être pas.
La propriété Entity n'existe pas sur PHP 7.2, du coup j'essaie de décortiquer la logique derrière ce que tu m'as écris. De ce que j'ai compris:
1 - Le user (ou articles ....) j'en fais des objets avec les getter
et les setter
2 - Dans le crud j'initie les entités (donc objets)
3 - J'appelle ces objets soit dans les méthodes style updateElement
ou searchElement
ou dans des classes style Auth
4 - Je get ou set ces objets à partir de ses méthodes ou classes
Maintenant j'ai du mal à comprendres dans mon Crud
comment un $user = user::class
fera appelle à la classe User. Est-ce que ça veut dire que c'est équivalent à un $user= new User()
?
Je pense que j'ai du mal à definir ce qu'est entity étant donné qu'à part une référence à Symfony, j'ai rien trouvé.
Encore merci pour ton aide.