Photobase, php, mysql

Exemple de site avec base de données

[Mise à jour, 3 octobre 2012 : le site exemple n'est momentanément plus accessible.  Je vais essayer d'y remédier]

Les tables

Fichier photobase-create.sql

DROP TABLE IF EXISTS photobase_users;
CREATE TABLE IF NOT EXISTS photobase_users (
  id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(256) NOT NULL DEFAULT ''
) DEFAULT CHARSET=utf8;

DROP TABLE IF EXISTS photobase_photos;
CREATE TABLE IF NOT EXISTS photobase_photos (
  id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  upload TIMESTAMP,
  owner INT(4)
) DEFAULT CHARSET=utf8;

DROP TABLE IF EXISTS photobase_comments;
CREATE TABLE IF NOT EXISTS photobase_comments (
  id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  photo INT(4),
  author INT(4),
  comment TEXT
) DEFAULT CHARSET=utf8;

Fichier photobase-insert.sql

INSERT INTO photobase_users (name) VALUES
  ('alain b'),
  ('hbl'),
  ('binto'),
  ('iciautrement'),
  ('donkeykong donkeypix'),
  ('stok'),
  ('philippineroyer'),
  ('artyu'),
  ('mister blast7'),
  ('bcommebenedicte'),
  ('or2k'),
  ('zespinal'),
  ('ouranos'),
  ('miloo phototruc'),
  ('lomosapiens'),
  ('leprive')
;

INSERT INTO photobase_photos (upload, owner)
VALUES
  (20100314, 1),
  (20100315, 1),
  (20100316193210, 1),
  (20100316201403, 1),
  (20100401102002, 2),
  (20100401102132, 2),
  (20100401102345, 2),
  (20100401, 3),
  (20100401, 3),
  (20100401, 3),
  (20100402, 3),
  (20100403, 3),
  (20100310, 4),
  (20100313, 4),
  (20100322, 4),
  (20100322, 4),
  (20100403, 4)
;

INSERT INTO photobase_comments (photo, author, comment)
VALUES
  (1, 2, 'très jolie photo !'),
  (1, 1, 'merci binto lol'),
  (5, 1, 'lol'),
  (5, 3, 'mdrrrrrrr')
;

La page d’accueil (index.php)

A retenir : mysql_query,  mysql_fetch_assoc.

  ...
  <body>
    <?php include 'photobase-menus.php'; ?>
   <h1>Bienvenue sur photobase</h1>
   <h2>Utilisateurs du service</h2>
   <?php affiche_utilisateurs(); ?>
   </ul>
  </body>

La fonction se fait en trois temps.

1. Récupération des utilisateurs dans la base.


   function get_users()
   {
     global $connexion; // on verra plus tard où est définie cette variable
     $request = 'SELECT * FROM photobase_users';
     return mysql_query($request, $connexion);
   }

La chaîne SELECT * FROM photobase_users est une requête mysql, en langage sql, donc pas en php. Elle est envoyée à la base par la fonction php mysql_query.

2. Récupération des entrées renvoyées par la base

 function affiche_utilisateurs()
  {
    $users = get_users();
    echo '<ul id="users">';
    while($user = mysql_fetch_assoc($users))
      affiche_utilisateur($user);
    echo '</ul>';
  }

Chaque appel à la fonction php mysql_fetch_assoc extrait une nouvelle entrée dans le résultat renvoyé par la fonction mysql_query, et est évalué à faux quand il n’y a plus d’entrée à lire.
Il ne nous reste plus qu’à écrire la fonction d’affichage d’un utilisateur.

3. Affichage d’un utilisateur


   function url_user($user)
   {     return "user.php?id=" . $user['id'];    }

   function affiche_utilisateur($user)
   {
      echo '<li>'
       . '<a href="' . url_user($user) . '">'
       . $user['name']
       . '</a>'
       . "</li>\n";
   }

La page d’un utilisateur (user.php)

Le début du fichier (avant d’écrire quoi que ce soit, y compris le doctype).
Encore mysql_fetch_assoc.

<?php
require_once 'connect-photobase.php';
if(!isSet($_GET['id']))
  header('Location: index.php'); // redirige sur la page d'accueil
else
{
  $user_id = $_GET['id'];
  $request = "SELECT name FROM photobase_users WHERE id=$user_id";
  $res = mysql_query($request, $connexion);
  $tab = mysql_fetch_assoc($res);
  $name = $tab['name'];
}
?>

Les fonctions pour l’affichage des photos vignettes :

function photo_id_to_tiny_filename($id)
{
  return "Img/tiny-$id.jpg";
}

function photolink($id)
{
  return
    '<a href="photo.php?id='
    . $id
    . '">'
    . '<img src="'
    . photo_id_to_tiny_filename($id)
    . '" alt="'
    . $id
    . '"/>'
    . '</a>'
    ;
}

La page elle-même.
A retenir : mysql_num_row

  <?php include 'photobase-menus.php'; ?>

  <h1>Bienvenue sur la photobase de
  <?php
  echo $name;
  ?>
  </h1>

<?php
$request = 'SELECT id FROM photobase_photos '
  . " WHERE owner=$user_id ORDER BY upload DESC";
// attention à l'espace quand on coupe la chaîne !!

$photos = mysql_query($request, $connexion);
$nb = mysql_num_rows($photos);
echo "<p>$name a $nb photos.</p>\n";
if($nb > 0)
{
  echo '<table class="vignettes">';
  $done = 0;
  while($photo = mysql_fetch_assoc($photos))
    {
      if($done % 2 == 0) echo '<tr>';
      echo '<td>' . photolink($photo['id']) . "</td>\n";
      if($done % 2 == 1) echo "</tr>\n";
      $done++;
    }
  echo "</table>\n";
}
?>

Connexion à la base

La variable $connexion est définie dans le fichier connect-photobase ci-dessous (j’ai bien entendu supprimé les paramètres de ma base). Il doit donc être inclus avant les fonctions qui l’utilisent (par exemple au tout début du fichier, pour pouvoir rediriger sur une autre page en cas d’erreur de connexion).

<?php
define('SERVER', '...');
define('USER', '...');
define('PSSWD', '...');
define('BASE', '...');

$connexion = mysql_pconnect(SERVER, USER, PSSWD);

if (!$connexion) {
    echo 'Pas de connexion au serveur.';
    exit;
}

if (!mysql_select_db(BASE, $connexion)) {
    echo 'Pas d\'accès à la base.';
    exit;
}

?>

[Mise à jour, 3 octobre 2012 : j'ai modifié les pseudos de sorte qu'ils ne soient pas directement les pseudos des utilisateurs de Flickr que j'ai pris comme base de départ pour le site]

Cette entrée a été publiée dans Cours, avec comme mot(s)-clef(s) , , , , , , . Vous pouvez la mettre en favoris avec ce permalien.

4 réponses à Photobase, php, mysql

  1. Sophie dit :

    J’aime assez l’idée du concours de hack (même si c’est pas du tout mon truc…), du coup on va être obligés de lire vos exemples encore plus attentivement^^
    Première tentative : c’est pas dangereux de mettre un mot de passe en constante? Ou de le mettre directement dans le fichier d’ailleurs. Quelle est la différence entre cette méthode et le fait de les mettre dans un autre fichier en tant que variables puis de les inclure? Et surtout une telle constante est définie jusqu’à quand? sur tout le fichier? jusqu’à la fermeture de la balise php?
    Bon week end

  2. Christophe dit :

    la constante est définie sur tout le fichier.
    Qu’on la définisse par inclusion d’un autre fichier ou directement, c’est identique. Et variable ou constance, ça ne change rien.

    Mais bien entendu, mettre le mot de passe en dur dans le fichier n’est valable que dans l’hypothèse où l’hébergement sur le serveur est fiable.

  3. FlickUSR dit :

    Chaud de trouver son Pseudo Flickr dans une page qui n’a rien à voir ! Mais bon , c’est leu jeu d’être sur internet…Ce qui est plus chaud, c’est de trouver celui d’une personne décédée au moment où cette article a été écrit…
    « hughesleglise »
    http://culturevisuelle.org/icones/1479

    Ah le fameux droit à l’oubli toussa toussa…

    • Christophe dit :

      Ah mince, bienvenue quand même. :)
      Et désolé pour cette mauvaise surprise, qui est surtout une maladresse de ma part, avec une série d’explications et de produits dérivés :

      - au départ, il y avait un projet de recherche sur les usages de Flickr
      - puis, sans lien (si ce n’est l’auteur), un site-jouet pour apprendre à programmer des sites web, qui puisait sur une dizaine de comptes Flickr existants, juste pour que ce soit plus réaliste et attractif. Le site jouet respectait toutes les règles de bonne conduite : il renvoyait vers les pages originales sur le site Flickr, sans jamais citer d’autres noms que les pseudos Flickr
      - à partir de ce site-jouet, un billet sur ce blog, en appui du cours qui présentait le site jouet. Et du coup, le contenu de la base de données, à savoir la liste des pseudos Flickr utilisés et des numéros de photos.

      Malheureusement, je découvre à l’instant avec agacement, que pour une raison que j’ignore, le site-jouet n’est plus accessible, donc le lien entre les pseudos et leur site d’origine est rompu, ce qui donne sans doute l’effet désagréable d’être pisté par des hackers sans vergogne ni morale (ce qui est peut-être quand même le cas, je te laisse apprécier).

      Quoi qu’il en soit, je voyais mon site-jouet plus comme un hommage qu’une atteinte à la vie privée de quiconque. Je suis attristé d’apprendre le décès d’Hughes Bataille-Léglise, dont j’avais beaucoup entendu parler il y a quelques années. En revanche, pour ce qui est du droit à l’oubli, l’expression est assez mal choisie accolée à un article intitulé In memoriam. La présence sur le web sous toutes ses formes participe de la postérité.

      Enfin pour être pragmatique, je vais retirer les pseudos de l’article pour éviter de chatouiller Google, et ajouter un hommage explicite à la mémoire du défunt dans le site-jouet. Si tu préfères que je retire ton nom du site-jouet lui-même, je le ferai bien entendu (je te ferai signe de toute façon quand il sera de nouveau accessible, pour te montrer son innocuité).

      N’hésite pas à m’écrire directement, prieur à didiode point france, ou krytofr sur Flickr ;)

Répondre à Christophe Annuler la réponse.

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Merci de répondre à cette question pour prouver que vous n'êtes pas un robot :

quel est le premier mot qui commence par un m dans cette phrase ?