[RESOLU] Comment différencier plusieurs persos/id?

Eléphant du PHP | 345 Messages

20 août 2021, 16:24

:oops:
J'essaie de tester pour ne récupérer et afficher que l'avatar souhaité.

j'ai aussi essayé sur la fin du SELECT mais sans résultat valable.
je pense que c'est dans cette partie de "action_perso_id.php" qu'il faut récupérer le $_GET['id'] mais je ne vois pas comment.
$sql = "SELECT avatar FROM membres WHERE (pos_x=$pos_x AND pos_y=$pos_y) AND id!=id";
$pdostat = $bdd->prepare($sql);
$pdostat->bindvalue(':id',$id ,PDO::PARAM_INT);
$pdostat->execute();
while ($resultat = $pdostat->fetch())
{
$avatar = $resultat['avatar'];


ynx
Mammouth du PHP | 586 Messages

21 août 2021, 18:21

Quelques conseils et exemples :

dans le fichier map.php :
<?php
// [...] 

// id du membre connecté en session
$idMembreSession = !empty($_SESSION['id']) ? $_SESSION['id'] : NULL;

// récupération en bdd du membre connecté en session
$pdostat = $bdd->prepare('SELECT * FROM membres WHERE id = :id');
$pdostat->bindvalue(':id', $idMembreSession, PDO::PARAM_INT);
$pdostat->execute();

$membreSession = $pdostat->fetch();

if (!empty($membreSession)) {
    // récupération en bdd des membres à la même position que le membre connecté en session
    $pdostat = $bdd->prepare("SELECT * FROM membres WHERE (pos_x = :pos_x AND pos_y = :pos_y) AND id != :id AND vacance = 'OFF'");
    $pdostat->bindvalue(':id', $idMembreSession, PDO::PARAM_INT);
    $pdostat->bindvalue(':pos_x', $membreSession['pos_x'], PDO::PARAM_INT);
    $pdostat->bindvalue(':pos_y', $membreSession['pos_y'], PDO::PARAM_INT);
    $pdostat->execute();

    while ($membreVoisin = $pdostat->fetch()) {
        echo '<a href="/action_perso_id.php?id=' . intval($membreVoisin['id']) . '"><img src="' . htmlentities($membreVoisin['avatar']) . '"></a>';
    }
}
?>
- // [...] : l'exemple n'est pas complet, il doit notamment avoir une instruction session_start() au début du fichier et une redirection si le l'utilisateur n'est pas connecté en session (voir sur le 2e exemple).

- Nommer plus précisément les variables par rapport à ce qu'elles représentent : $idMembreSession au lieu de $id, $membreSession au lieu du premier $resultat et $membreVoisin au lieu du deuxième $resultat

- Ne pas abuser des variables intermédiaires : les variables $sql ne sont pas utiles pour le moment, autant saisir directement la requête sql dans la méthode prepare().
Même chose pour $pos_x, $pos_y et $avatar, autant utiliser directement l'objet retourné par PDO avec $resultat['pox_x'], $resultat['pox_y'] et $resultat['avatar']. Ou après avoir renommé la variable $resultat : $membreSession['pos_x'] (la position x du membre connecté) ou $membreVoisin['avatar'] (l'avatar d'un membre voisin dans la boucle).

- Il ne faut pas injecter les variables php $pos_x et $pox_y dans la requête sql préparée. Il faut les passer en paramètre avec la méthode bindvalue() comme pour le paramètre :id.
Dans l'exemple au dessus, si les colonnes pox_x et pox_y dans la base de données ne sont pas des entiers, il faut corriger le 3e paramètre PDO::PARAM_INT.

Fichier action_perso_id.php :
<?php
session_start();
require_once 'config.php';

// id du membre connecté en session
$idMembreSession = !empty($_SESSION['id']) ? $_SESSION['id'] : NULL;

// récupération en bdd du membre connecté en session
$pdostat = $bdd->prepare('SELECT * FROM membres WHERE id = :id');
$pdostat->bindvalue(':id', $idMembreSession, PDO::PARAM_INT);
$pdostat->execute();

$membreSession = $pdostat->fetch();

if (empty($membreSession)) {
    // le membre n'est pas connecté ou n'existe plus, on redirige vers la page de connexion
    header('Location: /connexion.php');
    exit();
}

// identifiant du membre sélectionné dans l'url
$idMembreSelect = !empty($_GET['id']) ? $_GET['id'] : NULL;

// récupération en bdd du membre sélectionné dans l'url (si il est toujours à proximité du membre connecté en session et pas en vacances)
$pdostat = $bdd->prepare("SELECT * FROM membres WHERE id = :id AND (pos_x = :pos_x AND pos_y = :pos_y) AND vacance = 'OFF'");
$pdostat->bindvalue(':id', $idMembreSelect, PDO::PARAM_INT);
$pdostat->bindvalue(':pos_x', $membreSession['pos_x'], PDO::PARAM_INT);
$pdostat->bindvalue(':pos_y', $membreSession['pos_y'], PDO::PARAM_INT);
$pdostat->execute();

$membreSelect = $pdostat->fetch();
?>
<h1>ACTIONS SUR LE PERSO</h1>

<?php if (!$membreSelect) : ?>

    <p>Ce perso n'existe pas ou n'est plus à proximité.<p>
    
    <a href="/map.php">Vers la carte de jeu</a>

<?php else : ?>
    
    <h2>INTERACTIONS</h2>

    <a href="/voler.php?id=<?php echo intval($membreSelect['id']) ?>" title="VOL">VOLER</a>
    <a href="/attaquer.php?id=<?php echo intval($membreSelect['id']) ?>" title="ATTAQUE">ATTAQUER</a>
    <a href="/capturer.php?id=<?php echo intval($membreSelect['id']) ?>" title="CAPTURE">CAPTURER</a>

    <a href="/map.php">Vers la carte de jeu</a>

<?php endif; ?>
- Comme dans le précédent exemple, on récupère dans la bdd le membre connecté en session. Puis on redirige vers la page de connexion si l'utilisateur n'est pas connecté ou que le membre n'existe pas (l’exécution du script s'arrête ici dans ce cas).
Il faut corriger l'url dans l'instruction header() si la page de connexion n'est pas /connexion.php

- Avec la deuxième requête sql, on récupère en bdd le membre sélectionné dont l'identifiant est indiqué dans l'url (WHERE id = :id avec le paramètre :id auquel on bind la valeur de $idMembreSelect qui correspond à $_GET['id']).
On vérifie aussi que le membre sélectionné est bien à la même position que le membre connecté en session (AND (pos_x = :pos_x AND pos_y = :pos_y) avec les mêmes bind que le premier exemple) car l'internaute peut saisir n'importe quel identifiant dans l'url de son navigateur.

- Pour la partie html, l'exemple est très simplifié pour rendre le code plus clair (il manque notamment le doctype et les balises <html>, <head>, <body>, ect pour un exemple complet).
Tes balises <span> n'étaient pas fermés dans tes liens. Tu peux supprimer cette balise et mettre l'attribut title directement sur la balise <a> si les balises <span> n'ont pas d'autres utilités.
Tes balises <img> devraient avoir un attribut alt. Tu pourrais y renseigner le pseudo du membre lorsque tu affiche l'avatar par exemple.
Les balises <font> et <center> ne devraient plus être utilisées. Même chose pour pour les répétitions de <br> ou pour l'utilisation des balises <table> si celles-ci sont utilisées pour de la mise en page. Tu devrais utiliser une feuille de style css rendre ton code html plus simple et personnaliser l'affichage de ton site plus facilement.

Enfin, il serait plus simple pour ton projet (mais aussi pour l'utilisateur d'un point de vue ergonomie) de suivre le conseil de or1 et de proposer les actions pour chaque membre à proximité directement dans le fichier map.php.
Pour cela il faudra donc modifier la boucle qui parcours les membres à proximité (while ($membreVoisin ... dans mon premier exemple) afin d'afficher les liens qui devront désormais pointer vers /voler.php, /attaquer.php et /capturer.php à la place du lien qui pointe vers /action_perso_id.php.

Eléphant du PHP | 345 Messages

29 août 2021, 11:31

Merci pour tous ces conseils. je vais m'atteler à tout réécrire.
Un seul point que je dois éclairer: faut il modifier en table le id en idMembreSession?

Eléphant du PHP | 345 Messages

30 août 2021, 11:33

Merci pour tous ces conseils ainsi que les explications claires. je vais m'atteler à tout réécrire.

ynx
Mammouth du PHP | 586 Messages

30 août 2021, 11:40

Non il n'est pas nécessaire de renommer la colonne dans la bdd. La colonne id étant dans la table membres, on devine donc implicitement qu'il s'agit de l'identifiant d'un membre.

Eléphant du PHP | 345 Messages

31 août 2021, 23:04

Je cloture ce topic car l'affichage des avatars sur la map est OK.
Mille mercis pour les explications claires et bien expliquées.
je m'attelle maintenant aux fameuses interactions en espérant que cela ne coince pas trop.

Eléphant du PHP | 345 Messages

20 nov. 2021, 16:57

Je réouvre ce post car si le script d'origine est OK, il ne fonctionne plus sur la map "ville".
$idMembreSession = !empty($_SESSION['id']) ? $_SESSION['id'] : NULL;

$pdostat = $bdd->prepare('SELECT * FROM membres WHERE id = :id');
$pdostat->bindvalue(':id', $idMembreSession, PDO::PARAM_INT);
$pdostat->execute();
$membreSession = $pdostat->fetch();

$idMembreSelect = !empty($_GET['id']) ? $_GET['id'] : NULL;

$pdostat = $bdd->prepare("SELECT nom_ville FROM villes LEFT JOIN membres ON villes.pos_x_map = membres.pos_x_enter_ville AND villes.pos_y_map = membres.pos_y_enter_ville WHERE membres.id=:id");
$pdostat->bindvalue(':id',$idMembreSession, PDO::PARAM_INT);
$pdostat->execute();
$membreSession = $pdostat->fetch();    
if (!empty($membreSession)) { 
$nom_ville = $membreSession['nom_ville'];
}
// récupération en bdd du membre sélectionné dans l'url (si il est toujours à proximité du membre connecté en session et pas en vacances)
$pdostat = $bdd->prepare("SELECT * FROM membres WHERE id = :id AND (pos_x_ville =:pos_x_ville AND pos_y_ville =:pos_y_ville) AND vacance = 'OFF' AND situation='$nom_ville'");
$pdostat->bindvalue(':id', $idMembreSelect, PDO::PARAM_INT);
$pdostat->bindvalue(':pos_x_ville', $membreSession['pos_x_ville'], PDO::PARAM_INT);
$pdostat->bindvalue(':pos_y_ville', $membreSession['pos_y_ville'], PDO::PARAM_INT);
$pdostat->execute();
$membreSelect = $pdostat->fetch();
Les variables pos_x_ville et pos_y_ville ne passent pas.
Undefined index: pos_x_ville in C:\wamp64\www\action_ville_perso_id.php on line 24
( ! ) Notice: Undefined index: pos_y_ville in C:\wamp64\www\action_ville_perso_id.php on line 25

echo et var_dump donnent NULL...