requete spéciale?

Eléphant du PHP | 345 Messages

21 nov. 2023, 12:46

Bonjour,

est il possible de trouver un équivalent à ce qui suit ( une jointure sur une SEULE table)?

$sql = "SELECT tile FROM map LEFT JOIN map ON map.pos_x= pos_x AND map.pos_y= pos_y WHERE pays_name= 'xxxx'";


Le but étant de pouvoir afficher mes tiles en fonction de leurs coordonnées réelles (pos_x et pos_y) et d'obtenir ainsi une cartographie exacte

Avatar du membre
Mammouth du PHP | 1609 Messages

21 nov. 2023, 15:38

Salut, je vois pas l'intérêt de faire une jointure...

SELECT tile, pos_x, pos_y FROM map WHERE pays_name = 'xxxx';

En quoi n'est ce pas suffisant ?
Développeur web depuis + de 20 ans

Eléphant du PHP | 345 Messages

21 nov. 2023, 19:00

heu, oui peut-être. :oops:
Mais comment adapter ce script avec les coordonnées correspondantes à chaque tile?
$sql = "SELECT pos_x, pos_y FROM map WHERE pays_name='xxxx'";
$pdostat = $bdd->prepare($sql);
$pdostat->execute();
$resultat= $pdostat->fetch();
if (!empty($resultat)) { 
$tile= $resultat['tile'];
$pos_x= $resultat['pos_x'];
$pos_y= $resultat['pos_y'];
} 
//paramètre
$nb_par_ligne = 10;

//on commence par ouvrir le tableau (1 seule fois ! à pas mettre dans la boucle)
echo '<table><tr>';

//initialisation du compteur
$i = 1;

while($resultat = $pdostat->fetch()){
  
  //afichage de la tile
  echo '<td><img src="' . $resultat['tile'] . '"></td>';
  
  //si le nombre de tile est de 10, on passe à la ligne
  if($i == $nb_par_ligne){
    
    //retour à la ligne
    echo '</tr><tr>';
    $i = 1;
  
  //sinon, on continu l'affichage horizontal
  }else{
    
    //compte le nombre de tile affichées
    $i ++;
    
  }
}

//fermeture du tableau
echo '</tr></table>';$i = 1;
?>


Avatar du membre
Mammouth du PHP | 1564 Messages

21 nov. 2023, 23:57

Il ya la solution avec un tableau multidimensionnel, enregistre les x et les y, puis affiche les en refaisant une boucle avec foreach().

Un exemple :
$tableau = [];

//lors de ta boucle while, ajoute les tiles dans le tableau:

$tableau[coordonnée x ici][coordonnée y ici] = "j'ajoute une title ici";

Eléphant du PHP | 345 Messages

22 nov. 2023, 15:39

Quand tu dis "enregistre les x et y", il faut d'abord que je les rentre la dedans?
$tableau[coordonnée x ici][coordonnée y ici] = "j'ajoute une title ici";
Modifié en dernier par nestor94 le 22 nov. 2023, 15:55, modifié 1 fois.

Avatar du membre
Mammouth du PHP | 1564 Messages

22 nov. 2023, 15:46

Je t'invite à apprendre comment manipuler les tableaux, la documentation officielle où tu pourra trouver pleins d'infos utiles est ici : https://www.php.net/manual/fr/language.types.array.php

Eléphant du PHP | 345 Messages

22 nov. 2023, 16:03

ok, je veux bien tenter d'y comprendre quelque chose mais je réitère ma question principale: dois je d'abord enter manuellement toutes mes coordonnées pos_x et pos_y?

Avatar du membre
Mammouth du PHP | 1564 Messages

22 nov. 2023, 16:24

Non, tu dois le faire dans ta boucle while, comme je l'ai précédemment dit :
//lors de ta boucle while, ajoute les tiles dans le tableau:

$tableau[coordonnée x ici][coordonnée y ici] = "j'ajoute une title ici";
Regarde comment fonctionne les tableaux, tu comprendra mon message. ;)

Eléphant du PHP | 345 Messages

22 nov. 2023, 17:31

ouf, parce que il y aura 2000 coordonnées éventuelles en table :shock:

ynx
Mammouth du PHP | 586 Messages

23 nov. 2023, 19:57

Puisque tu connais les coordonnées de chaque tile (et les dimensions, je suppose), au lieu d'utiliser un tableau html, une alternative pourrait être le positionnement absolu en css.

L'idée est d'afficher toutes les balises html <img> des tiles en position absolute dans un div conteneur en position relative.
Puis pour chaque tile, calculer les propriétés css top et left pour positionner l'image dans le conteneur en fonction de pos_x, pos_y et des dimensions :
- la tile avec pos_x=0 et pos_y=0 sera placée en haut à gauche du conteneur.
- la tile avec pos_x=0 et pos_y=1 sera placée à droite de la première.
- la tile avec pos_x=1 et pos_y=0 sera placée sous de la première, etc.

<?php

const TILE_WIDTH = 150;
const TILE_HEIGHT = 150;

$pays = $_GET['pays'] ?? 'France';

/** @var \PDO $bdd */
$pdostat = $bdd->prepare('SELECT tile, pos_x, pos_y FROM map WHERE pays_name=?');
$pdostat->execute([$pays]);
$tiles = $pdostat->fetchAll();
?>

<h1><?= htmlspecialchars($pays) ?></h1>

<?php if (empty($tiles)) : ?>

    <p>Pas de tiles !</p>

<?php else : ?>

    <div style="position: relative;">

        <?php foreach ($tiles as $tile) : ?>
            <img src="<?= $tile['tile'] ?>" 
                style="position: absolute; top: <?= $tile['pos_x'] * TILE_WIDTH ?>px; left: <?= $tile['pos_y'] * TILE_HEIGHT ?>px;" 
                alt="">
        <?php endforeach; ?>

    </div>

<?php endif; ?>

Eléphant du PHP | 345 Messages

26 nov. 2023, 01:02

Merci ynx, ta solution me parait plus intéressante en terme d'affichage.
Je me suis permis de modifier un peu ton script mais est ce que les coordonnées pos_x et pos_y sont prises en compte?
car rien ne s'affiche excepté le nom du pays.
const TILE_WIDTH = 40;
const TILE_HEIGHT = 40;
/** @var \PDO $bdd */
$pdostat = $bdd->prepare("SELECT situation_pays FROM membres WHERE id=:id");
$pdostat->bindvalue(':id',$idMembreSession ,PDO::PARAM_INT);
$pdostat->execute();
$membreSession = $pdostat->fetch();  
if (!empty($membreSession )) { 
$situation_pays = $membreSession['situation_pays'];
}
$pdostat = $bdd->prepare("SELECT tile, pos_x, pos_y FROM map WHERE pays_name='$situation_pays'");
$pdostat->execute();
$tile = $pdostat->fetchAll();
$pos_x= $pdostat->fetchAll();
$pos_y= $pdostat->fetchAll();
?>
<h1><?= htmlspecialchars($situation_pays) ?></h1>

<?php if (empty($tile)) : ?>

    <p>Pas de tiles !</p>

<?php else : ?>

    <div style="position: relative;">

        <?php foreach ($tile as $tile) : ?>
            <img src="<?= $tile['tile'] ?>" 
                style="position: absolute; top: <?= $tile['pos_x'] * TILE_WIDTH ?>px; left: <?= $tile['pos_y'] * TILE_HEIGHT ?>px;" 
                alt="">
        <?php endforeach; ?>

    </div>

<?php endif; ?>


pour info:

Image

ynx
Mammouth du PHP | 586 Messages

27 nov. 2023, 13:42

Attention au nommage des variables (ne pas confondre le tableau $tiles et chaque élément $tile).
N'hésites pas à ajouter des echo/print_r/var_dump sur les variables dans ton code pour mieux comprendre son éxecution.
<?php

const TILE_WIDTH = 40;
const TILE_HEIGHT = 40;

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

// Si $membreSession est vide, la variable $situation_pays n'est pas définie,
// il faut lui définir une valeur par défaut :
$situation_pays = '';

if (!empty($membreSession)) { 
	$situation_pays = $membreSession['situation_pays'];
}

// Attention aux injections sql : pas de variable php dans une requête sql !
// On utilise bindValue ou le tableau dans execute pour définir les valeurs des paramètres :
$pdostat = $bdd->prepare("SELECT tile, pos_x, pos_y FROM map WHERE pays_name=:pays");
$pdostat->bindvalue(':pays', $situation_pays, PDO::PARAM_STR);
$pdostat->execute();

//$tile = $pdostat->fetchAll();
//$pos_x= $pdostat->fetchAll();
//$pos_y= $pdostat->fetchAll();

// La méthode fetchAll retourne toutes les lignes du résultat de la requête dans un tableau,
// cette méthode ne doit être appelée qu'une seule fois.
// On récupère le retour de la fonction fetchAll dans un tableau nommé $tiles (au pluriel avec un s) :
$tiles = $pdostat->fetchAll();

// pour voir/déboguer le tableau :
//print_r($tiles);
?>
<h1><?= htmlspecialchars($situation_pays) ?></h1>

<?php if (empty($tiles)) : // on vérifie si le tableau $tiles (avec un s) est vide ?>

    <p>Pas de tiles !</p>

<?php else : ?>

    <div style="position: relative;">

        <?php foreach ($tiles as $tile) : // pour chaque "tile" dans le tableau $tiles ?>
            <img src="<?= $tile['tile'] ?>" 
                style="position: absolute; top: <?= $tile['pos_x'] * TILE_WIDTH ?>px; left: <?= $tile['pos_y'] * TILE_HEIGHT ?>px;" 
                alt="">
        <?php endforeach; ?>

    </div>

<?php endif; ?>

Eléphant du PHP | 345 Messages

27 nov. 2023, 16:16

Salut, merci pour le code corrigé et expliqué.
J'ai effectué les quelques vérifs pour chaque step important, mais ça n'affiche toujours rien :cry:

C'est ci-dessous que le soucis doit être, pourtant ? #-o
<?php foreach ($tiles as $tile) : // pour chaque "tile" dans le tableau $tiles ?>
            <img src="<?= $tile['tile'] ?>" 
                style="position: absolute; top: <?= $tile['pos_x'] * TILE_WIDTH ?>px; left: <?= $tile['pos_y'] * TILE_HEIGHT ?>px;" 
                alt="">
        <?php endforeach; ?>


ynx
Mammouth du PHP | 586 Messages

27 nov. 2023, 16:43

Que veux dire "ca n'affiche toujours rien" ?

Tu as une page toute blanche ?

Tu as une page avec uniquement le titre et le message "Pas de tiles !" ?

Tu as une page avec uniquement le titre ? Qu'est-ce qui s'affiche dans le code source de la page depuis le navigateur (clique-droit -> Afficher le code source) ?

As tu essayé de décommenter la ligne //print_r($tiles); pour voir si tableau $tiles contient bien les bonnes données ?

Eléphant du PHP | 345 Messages

27 nov. 2023, 20:15

Alors, à l'affichage je n'ai que le nom du pays.
le "print_r" m'affiche bien le nom des tiles avec leurs coordonnées.

Array ( [0] => Array ( [tile] => /relief/tile_plage.gif [0] => /relief/tile_plage.gif [pos_x] => 60 [1] => 60 [pos_y] => 61 [2] => 61 ) [1] => Array ( [tile] => /relief/tile_peage.gif [0] => /relief/tile_peage.gif [pos_x] => 60 [1] => 60 [pos_y] => 60 [2] => 60 ) [2] => Array ( [tile] => /relief/tile_prairie.gif [0] => /relief/tile_prairie.gif [pos_x] => 61 [1] => 61 [pos_y] => 61 [2] => 61 ) [3] => Array ( [tile] => /relief/tile_prairie.gif [0] => /relief/tile_prairie.gif [pos_x] => 62 [1] => 62 [pos_y] => 60 [2] => 60 ) [4] => Array ( [tile] => /relief/tile_rocher.gif [0] => /relief/tile_rocher.gif [pos_x] => 62 [1] => 62 [pos_y] => 61 [2] => 61 ) [5] => Array ( [tile] => /relief/tile_mer_hiver.gif [0] => /relief/tile_mer_hiver.gif [pos_x] => 59 [1] => 59 [pos_y] => 62 [2] => 62 ) [6] => Array ( [tile] => /relief/tile_mer_hiver.gif [0] => /relief/tile_mer_hiver.gif [pos_x] => 60 [1] => 60 [pos_y] => 62 [2] => 62 ) [7] => Array ( [tile] => /relief/tile_plage.gif [0] => /relief/tile_plage.gif [pos_x] => 59 [1] => 59 [pos_y] => 61 [2] => 61 ) [8] => Array ( [tile] => /relief/tile_poste_frontiere.gif [0] => /relief/tile_poste_frontiere.gif [pos_x] => 58 [1] => 58 [pos_y] => 60 [2] => 60 ) [9] => Array ( [tile] => /relief/tile_chemin.gif [0] => /relief/tile_chemin.gif [pos_x] => 59 [1] => 59 [pos_y] => 60 [2] => 60 ) [10] => Array ( [tile] => /relief/tile_mer_hiver.gif [0] => /relief/tile_mer_hiver.gif [pos_x] => 58 [1] => 58 [pos_y] => 62 [2] => 62 ) [11] => Array ( [tile] => /relief/tile_poste_frontiere.gif [0] => /relief/tile_poste_frontiere.gif [pos_x] => 58 [1] => 58 [pos_y] => 61 [2] => 61 ) [12] => Array ( [tile] => /relief/tile_mer_hiver.gif [0] => /relief/tile_mer_hiver.gif [pos_x] => 62 [1] => 62 [pos_y] => 62 [2] => 62 ) [13] => Array ( [tile] => /relief/tile_grue_chantier.gif [0] => /relief/tile_grue_chantier.gif [pos_x] => 61 [1] => 61 [pos_y] => 62 [2] => 62 ) )


le code source (clic droit sur la page ) affiche ceci....
<h1>JAWHA</h1>


     <div style="position: relative;">

                    <img src="/relief/tile_plage.gif" 
                style="position: absolute; top: 2400px; left: 2440px;" 
                alt="">
                    <img src="/relief/tile_peage.gif" 
                style="position: absolute; top: 2400px; left: 2400px;" 
                alt="">
                    <img src="/relief/tile_prairie.gif" 
                style="position: absolute; top: 2440px; left: 2440px;" 
                alt="">
                    <img src="/relief/tile_prairie.gif" 
                style="position: absolute; top: 2480px; left: 2400px;" 
                alt="">
                    <img src="/relief/tile_rocher.gif" 
                style="position: absolute; top: 2480px; left: 2440px;" 
                alt="">
                    <img src="/relief/tile_mer_hiver.gif" 
                style="position: absolute; top: 2360px; left: 2480px;" 
                alt="">
                    <img src="/relief/tile_mer_hiver.gif" 
                style="position: absolute; top: 2400px; left: 2480px;" 
                alt="">
                    <img src="/relief/tile_plage.gif" 
                style="position: absolute; top: 2360px; left: 2440px;" 
                alt="">
                    <img src="/relief/tile_poste_frontiere.gif" 
                style="position: absolute; top: 2320px; left: 2400px;" 
                alt="">
                    <img src="/relief/tile_chemin.gif" 
                style="position: absolute; top: 2360px; left: 2400px;" 
                alt="">
                    <img src="/relief/tile_mer_hiver.gif" 
                style="position: absolute; top: 2320px; left: 2480px;" 
                alt="">
                    <img src="/relief/tile_poste_frontiere.gif" 
                style="position: absolute; top: 2320px; left: 2440px;" 
                alt="">
                    <img src="/relief/tile_mer_hiver.gif" 
                style="position: absolute; top: 2480px; left: 2480px;" 
                alt="">
                    <img src="/relief/tile_grue_chantier.gif" 
                style="position: absolute; top: 2440px; left: 2480px;" 
                alt="">
        
    </div>
les 2440px ou 2480px 8-|