IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

Revision d'un vieux site en PHP/MySQL avec le format actuel


Sujet :

PHP & Base de données

  1. #1
    Membre confirmé Avatar de RinaBK
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2021
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 49
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2021
    Messages : 92
    Par défaut Revision d'un vieux site en PHP/MySQL avec le format actuel
    Bonjour tout le monde,

    Comme je l'avais expliqué dans un autre sujet, je me suis rendue compte que ma manière de coder n'est plus du tout adapté à ce qui se fait de nos jours. Hé oui, avec des années d'absences, la programmation ne va pas m'attendre Donc, je vais avoir besoin d'aide pour transformer certaines lignes de codes dans un format plus correct et je me dis qu'il serait aussi bien d'opter pour une manière plus aérée et plus lisible que mes gros pâtés de codes qui ne veulent plus rien dire. Donc, je vais devoir refaire intégralement mon site principal (www.gwanda.ch). Donc, si vous voulez m'aider, c'est avec grand plaisir de recevoir vos remarques et vos corrections


    Pour commencer depuis le départ, j'ai une partie ADMIN qui gère la totalité de mes sites web. Pour simplifier les choses, je fais appel à des "préfixes" qui vont différencier chaque site web.
    Voici l'intégral de ma page sites.php :
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
     
    <?
    session_start();
     
    if (!isSet($_SESSION['site'])) {
    	$siteID = '';
    	$sitePrefixe = '';
    	$siteName = '';
    } else {
    	$siteID = $_SESSION['site']['id'];
    	$sitePrefixe = $_SESSION['site']['prefixe'];
    	$siteName = $_SESSION['site']['nom'];
    }
     
     
     
     
    /***************************************************************************************************
    **********				CONTRÔL DES FICHIERS À INCLURE POUR L'AFFICHAGE DES PAGES
    *********/
    $include_files = array();
    $include_files[] = array('pheader','includes/header.php');
    $include_files[] = array('pfooter','includes/footer.php');
    $include_files[] = array('variables','includes/variables.php');
    $include_files[] = array('fonctions','includes/fonctions.php');
     
     
    $fichiers_inclus = array();
    if (count($include_files) > 0) {
    	for ($i = 0; $i < count($include_files); $i++) {
    		if (!file_exists($include_files[$i][1])) { header('Location: alerte.php?warning=500'); }
    		else { $files_includes[$include_files[$i][0]] = $include_files[$i][1]; }
    	}
    }
    include($files_includes['variables']);
    include($files_includes['fonctions']);
     
     
     
     
    /*
    CREATE TABLE adm_sites (
    	id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    	prefixe VARCHAR(200) NULL,
    	nom VARCHAR(200) NOT NULL,
    	infos TEXT NULL,
    	PRIMARY KEY (id),
    	UNIQUE (prefixe)
    );
    */
     
    //	Initialisations des valiables
    $id = 0;
    $prefixe = '';
    $nom = '';
    $infos = '';
     
     
    if ((isSet($_POST['gestion'])) || (isSet($_GET['gestion']))) {
     
    	if (($_GET['gestion'] == 'delete') && ($_GET['id'] > 0)) {
    		if (mySqli_query(db(),'DELETE FROM adm_sites WHERE id='.$_GET['id'])) {
    			header('Location: sites.php?alerte=valide');
    		} else { header('Location: sites.php?alerte=error'); }
    	}
    	else {
    		if ($_POST['prefixe'] == '') { $alerte[] = array('error','ATTENTION&nbsp;! Vous n&rsquo;avez pas sp&eacute;cifi&eacute; le pr&eacute;fixe du site'); }
    		if ($_POST['nom'] == '') { $alerte[] = array('error','ATTENTION&nbsp;! Vous n&rsquo;avez pas sp&eacute;cifi&eacute; le nom du site'); }
     
    		$prefixe = $_POST['prefixe'];
     
    		$nom = $_POST['nom'];
    		$nom = stripSlashes($nom);
    		$nom = trim($nom);
    		$nom = htmlEntities($nom);
    		$nom = str_replace('\'','&rsquo;',$nom);
     
    		$infos = $_POST['infos'];
    		$infos = stripSlashes($infos);
    		$infos = trim($infos);
    		$infos = htmlEntities($infos);
    		$infos = str_replace('\'','&rsquo;',$infos);
     
    	}
     
    	if (count($alerte) == 0) {
    		if (($_POST['gestion'] == $bt['update']) && ($_POST['id'] > 0)) {
    			if (mySqli_query(db(),'UPDATE adm_sites SET prefixe="'.$prefixe.'", nom="'.$nom.'", infos="'.$infos.'" WHERE id='.$_POST['id'])) {
    				header('Location: sites.php?alerte=valide');
    			} else { header('Location: sites.php?alerte=error'); }
    		}
     
    		if ($_POST['gestion'] == $bt['register']) {
    			if (mySqli_query(db(),'INSERT INTO adm_sites VALUES (NULL, "'.$prefixe.'", "'.$nom.'", "'.$infos.'")')) {
    				header('Location: sites.php?alerte=valide');
    			} else { header('Location: sites.php?alerte=error'); }
    		}
    	}
     
    }
    ?>
     
    <!DOCTYPE html>
    <html lang="fr-CH">
    <head>
    	<title>Administrations</title>
    	<link rel="stylesheet" href="images/designs/styles.css">
    	<script src="https://kit.fontawesome.com/2e9b34a81e.js"></script>
    </head>
     
     
    <body>
    <? include($files_includes['pheader']); ?>
     
     
    <h1>Gestion des Sites</h1>
    <div align="justify"  style="width: 600px;">
    	Concernant le nom du site ainsi que son pr&eacute;fixe, il serait important de ne pas mettre d&rsquo;accents, 
    	de caract&egrave;res sp&eacute;ciaux ou d&rsquo;espace. Il faudrait plut&ocirc;t jouer entre les majuscules 
    	et les minuscules pour diff&eacute;rencier les mots. En revanche pour les infos, aucun soucis, tous les 
    	caract&egrave;res sont accept&eacute;s et pr&eacute;senteront aucun danger niveau codage.
    </div>
    <br />
    <a href="sites.php?manage=insert" target="_parent" title="Ajouter une entr&eacute;e"><i class="fas fa-folder-plus" style="font-size: 30px;"></i></a>
    <br />
     
     
    <?
    if (isSet($_GET['alerte'])) {
    	if ($_GET['alerte'] == 'error') { $alerte[] = array('error','Op&eacute;ration impossible&nbsp;!'); }
    	if ($_GET['alerte'] == 'valide') { $alerte[] = array('valide','Op&eacute;ration r&eacute;ussi&nbsp;!'); }
    }
    if (count($alerte) > 0) { echo '<br />';
    	for($i = 0; $i < count($alerte); $i++) { echo '<div align="left" class="'.$alerte[$i][0].'">'.$alerte[$i][1].'</div>'; } echo '<br />';
    }
    ?>
     
     
    <br />
    <?
    if (isSet($_GET['manage']) && ($_GET['manage'] == 'insert')) {
    	?>
    	<br />
    	<table border="0" cellpadding="5" cellspacing="0">
    		<form method="POST">
    			<tr>
    				<td align="left" valign="top">Nom&nbsp;:</td>
    				<td align="left" valign="top"><input type="text" name="nom" value="<? if (isSet($_POST['nom'])) { echo $_POST['nom']; }?>" required style="width: 400px;"></td>
    			</tr>
    			<tr>
    				<td align="left" valign="top">Pr&eacute;fixe&nbsp;:</td>
    				<td align="left" valign="top"><input type="text" name="prefixe" value="<? if (isSet($_POST['prefixe'])) { echo $_POST['prefixe']; }?>" required style="width: 400px;"></td>
    			</tr>
    			<tr>
    				<td align="left" valign="top">Infos&nbsp;:</td>
    				<td align="left" valign="top"><textarea name="infos" cols="" rows="" style="width: 400px;"><? if (isSet($_POST['infos'])) { echo stripSlashes($_POST['infos']); }?></textarea></td>
    			</tr>
    			<tr>
    				<td align="left" valign="top">&nbsp;</td>
    				<td align="left" valign="top"><input type="submit" name="gestion" value="<?=$bt['register'];?>" style="width: 405px;"></td>
    			</tr>
    		</form>
    	</table>
    	<?
    }
    ?>
     
     
    <br />
    <br />
    <br />
     
     
    <?
    $sql = $bdd1->query('SELECT * FROM adm_sites');
    echo '<table border="0" cellpadding="2" cellspacing="0">';
    while ($data = $sql->fetch()) {
    	?>
    	<form method="POST">
    		<input type="hidden" name="id" value="<?=$data['id'];?>">
    		<tr>
    			<td align="left" valign="top"><div style="font-weight: bold; font-size: 16px;"><?=$data['id'];?></div></td>
    			<td align="right" valign="top"><a href="sites.php?gestion=delete&id=<?=$data['id'];?>" target="_parent"><i class="fas fa-trash-alt"></i></a></td>
    		</tr>
    		<tr><td colspan="2" align="left" valign="top"><input type="text" name="nom" value="<?=$data['nom'];?>" maxlength="" style="width: 400px;"></td></tr>
    		<tr><td colspan="2" align="left" valign="top"><input type="text" name="prefixe" value="<?=$data['prefixe'];?>" maxlength="" style="width: 400px;"></td></tr>
    		<tr><td colspan="2" align="left" valign="top"><textarea name="infos" cols="" rows="3" style="width: 400px;"><?=$data['infos'];?></textarea></td></tr>
    		<tr><td colspan="2" align="left" valign="top"><input type="submit" name="gestion" value="<?=$bt['update'];?>"></td></tr>
    		<tr><td colspan="2" align="left" valign="top">&nbsp;</td></tr>
    	</form>
    	<?
    }
    echo '</table>';
    $sql->closeCursor();
    ?>
     
     
    <? include($files_includes['pfooter']); ?>
    </body>
    </html>
    Pour vous expliquer un peu mes lignes de codes, je commence par initialiser ma variable session(); car une fois un site sélectionné (dans une autre page), cela me permet de naviguer sur la partie ADMIN en gardant les infos principale du site sélectionné.

    Ensuite, j'inclus différents fichiers tel que le fichier comportant mes fonctions globales, variables globales, header, footer, etc. qui sont les même pour chaque page de la partie ADMIN.

    Ensuite, il y a les codes de contrôles et les requêtes pour l'enregistrement, la modification et la suppression des données sur la BDD.

    Après, on arrive sur le corps de la page, avec une gestion d'erreur, un formulaire pour l'ajout d'une entrée, et l'affichage des entrées qui offre la possibilité de modifier directement chaque enregistrement.

    Vu que je débute en PDO, j'ai déjà modifié l'affichage et la modification de chaque entrée déjà existante.


    Je suis en ce moment, en train de refaire la gestion de contrôle sur les champs envoyé depuis le formulaire afin de les enregistrer, modifier ou effacer les données. Mais voilà, en regardant mon code, je me dis qu'il doit bien y avoir une manière de simplifier les lignes de codes afin de les rendre plus aérée et plus adapté !!?
    Qu'en pensez-vous? Avez-vous des suggestion à me donner pour rendre ma page moins bordélique et plus simplifiée ??

  2. #2
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 496
    Par défaut
    Bonjour,

    D'après ce que je vois, il n'y a pas beaucoup de choses à modifier, seulement qu'il faut bien préparer tes requêtes quand elles utilises des variables $_POST ou $_GET.

    Et vu que tu veux utiliser PDO au lieu de mysqli (ce qui est un choix judicieux), il ne faut jamais écrire ce genre de requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    'UPDATE adm_sites SET prefixe="'.$prefixe.'", nom="'.$nom.'", infos="'.$infos.'" WHERE id='.$_POST['id']
    Mais plutôt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    $db=db();//récupérer l'objet de connexion 
    $stmt=$db->prepare("update adm_sites set prefix=:prefix, nom=:nom, infos=:infos where id=:id");
    $stmt->execute(array(":prefix"=>$prefix,":nom"=>$nom,":infos"=>$infos,":id"=>$_POST["id"]));
    if($stmt->rowCount()>0){
       echo "modification effectuée avec succès";.
    }
    else echo "Aucune modification n'a été effectuée !";
    La même chose pour les autres requêtes utilisant des variables...

  3. #3
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 505
    Par défaut
    Bonjour,

    Une autre façon de faire est d'utiliser des '?' en lieu et place de système nommé, c'est une question de goût

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    $db=db();//récupérer l'objet de connexion 
    $stmt=$db->prepare("update adm_sites set prefix=?, nom=?, infos=? where id=?");
    $stmt->execute(["$prefix,$nom,$infos,$_POST["id"]]);
    if($stmt->rowCount()>0){
       echo "modification effectuée avec succès";.
    }
    else echo "Aucune modification n'a été effectuée !";
    Les deux fonctionne bien.

    Par contre, je vois que dans vos fonctions native vous utilsez le camelCase "isSet", "mySqli_query"..... en fait, si votre serveur est un linux, vous risquez des erreurs, car la norme est "isset", "mysqli_", stripslash ......

  4. #4
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 505
    Par défaut
    Après, vous êtes dans un système from scratch, qui fonctionne, mais ne respecte plus effectivement les standards.
    On essaye actuellement de séparer les couche, de ne plus avoir les requêtes de DB dans la même page, mais externaliser et l'injecter.
    Si votre projet est pour le long terme, apprendre un petit framework pour votre aprtie admin pourrais-être intéressant pour vous, genre Slim, Mezzio ou autre.

  5. #5
    Membre confirmé Avatar de RinaBK
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2021
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 49
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2021
    Messages : 92
    Par défaut
    Avant tout chose, un grand merci pour votre aide, elle m'est très précieuse !

    J'ai donc repris vos exemples, mais je me suis rendue compte que je n'arrive pas à utiliser les '?', car cela me donne à chaque fois une erreur... J'ai donc utilisé la version de Toufik83 qui fonctionne sans problème.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
     
    <?
    define('MAJ','25.01.2021 19:53:21');
     
     
     
    session_start();
     
    if (!isSet($_SESSION['site'])) {
    	$siteID = '';
    	$sitePrefixe = '';
    	$siteName = '';
    } else {
    	$siteID = $_SESSION['site']['id'];
    	$sitePrefixe = $_SESSION['site']['prefixe'];
    	$siteName = $_SESSION['site']['nom'];
    }
     
     
     
     
    /***************************************************************************************************
    **********				CONTRÔL DES FICHIERS À INCLURE POUR L'AFFICHAGE DES PAGES
    *********/
    $include_files = array();
    $include_files[] = array('pheader','includes/header.php');
    $include_files[] = array('pfooter','includes/footer.php');
    $include_files[] = array('variables','includes/variables.php');
    $include_files[] = array('fonctions','includes/fonctions.php');
     
     
    $fichiers_inclus = array();
    if (count($include_files) > 0) {
    	for ($i = 0; $i < count($include_files); $i++) {
    		if (!file_exists($include_files[$i][1])) { header('Location: alerte.php?warning=500'); }
    		else { $files_includes[$include_files[$i][0]] = $include_files[$i][1]; }
    	}
    }
    include($files_includes['variables']);
    include($files_includes['fonctions']);
     
     
     
     
    /*
    CREATE TABLE adm_sites (
    	id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    	prefixe VARCHAR(200) NULL,
    	nom VARCHAR(200) NOT NULL,
    	infos TEXT NULL,
    	PRIMARY KEY (id),
    	UNIQUE (prefixe)
    );
    */
     
     
     
     
    //	Initialisations des variables
    $id = 0;
    $prefixe = '';
    $nom = '';
    $infos = '';
     
     
    if ((!empty($_POST['gestion'])) || (!empty($_GET['gestion']))) {
     
    	if (($_GET['gestion'] == 'delete') && ($_GET['id'] > 0)) {
     
    		$db=db();
    		$sql = "DELETE FROM adm_sites WHERE id=:id";
    		$stmt = $db->prepare($sql);
    		$req = array('id' => $_GET['id']);
    		$stmt->execute($req);
     
    		if($stmt->rowCount()>0){ header('Location: sites.php?alerte=valide'); }
    		else { header('Location: sites.php?alerte=error'); }
    		$sql->closeCursor();
     
    	}
    	else {
    		if ($_POST['prefixe'] == '') { $alerte[] = array('error','ATTENTION&nbsp;! Vous n&rsquo;avez pas sp&eacute;cifi&eacute; le pr&eacute;fixe du site'); }
    		if ($_POST['nom'] == '') { $alerte[] = array('error','ATTENTION&nbsp;! Vous n&rsquo;avez pas sp&eacute;cifi&eacute; le nom du site'); }
     
    		$prefixe = $_POST['prefixe'];
     
    		$nom = $_POST['nom'];
    		$nom = stripSlashes($nom);
    		$nom = trim($nom);
    		$nom = htmlEntities($nom);
    		$nom = str_replace('\'','&rsquo;',$nom);
     
    		$infos = $_POST['infos'];
    		$infos = stripSlashes($infos);
    		$infos = trim($infos);
    		$infos = htmlEntities($infos);
    		$infos = str_replace('\'','&rsquo;',$infos);
     
    	}
     
    	if (count($alerte) == 0) {
     
    		if (($_POST['gestion'] == $bt['update']) && ($_POST['id'] > 0)) {
    			$db=db();
    			$stmt=$db->prepare('UPDATE adm_sites SET prefixe=:prefixe, nom=:nom, infos=:infos WHERE id=:id');
    			$stmt->execute(array(':prefixe' => $prefixe,':nom' => $nom,':infos' => $infos,':id' => $_POST['id']));
    			if($stmt->rowCount()>0){ header('Location: sites.php?alerte=valide'); }
    			else { header('Location: sites.php?alerte=error'); }
    			$stmt->closeCursor();
    		}
     
    		if ($_POST['gestion'] == $bt['register']) {
    			$db=db();
    			$stmt = $db->prepare('INSERT INTO adm_sites (prefixe, nom, infos) VALUES(:prefixe, :nom, :infos)');
    			$stmt->execute(array('prefixe' => $prefixe,'nom' => $nom,'infos' => $infos));
    			if($stmt->rowCount()>0){ header('Location: sites.php?alerte=valide'); }
    			else { header('Location: sites.php?alerte=error'); }
    			$stmt->closeCursor();
     
    		}
    	}
     
    }
     
    ?>
     
    <!DOCTYPE html>
    <html lang="fr-CH">
    <head>
    	<title>Administrations</title>
    	<link rel="stylesheet" href="images/designs/styles.css">
    	<script src="https://kit.fontawesome.com/2e9b34a81e.js"></script>
    </head>
     
     
    <body>
    <? include($files_includes['pheader']); ?>
     
     
    <h1>Gestion des Sites</h1>
    <div align="justify"  style="width: 600px;">
    	Concernant le nom du site ainsi que son pr&eacute;fixe, il serait important de ne pas mettre d&rsquo;accents, 
    	de caract&egrave;res sp&eacute;ciaux ou d&rsquo;espace. Il faudrait plut&ocirc;t jouer entre les majuscules 
    	et les minuscules pour diff&eacute;rencier les mots. En revanche pour les infos, aucun soucis, tous les 
    	caract&egrave;res sont accept&eacute;s et pr&eacute;senteront aucun danger niveau codage.
    </div>
    <br />
    <a href="sites.php?manage=insert" target="_parent" title="Ajouter une entr&eacute;e"><i class="fas fa-folder-plus" style="font-size: 30px;"></i></a>
    <br />
     
     
    <?
    if (isSet($_GET['alerte'])) {
    	if ($_GET['alerte'] == 'error') { $alerte[] = array('error','Op&eacute;ration impossible&nbsp;!'); }
    	if ($_GET['alerte'] == 'valide') { $alerte[] = array('valide','Op&eacute;ration r&eacute;ussi&nbsp;!'); }
    }
    if (count($alerte) > 0) { echo '<br />';
    	for($i = 0; $i < count($alerte); $i++) { echo '<div align="left" class="'.$alerte[$i][0].'">'.$alerte[$i][1].'</div>'; } echo '<br />';
    }
    ?>
     
     
    <br />
    <?
    if (isSet($_GET['manage']) && ($_GET['manage'] == 'insert')) {
    	?>
    	<br />
    	<table border="0" cellpadding="5" cellspacing="0">
    		<form method="POST">
    			<tr>
    				<td align="left" valign="top">Nom&nbsp;:</td>
    				<td align="left" valign="top"><input type="text" name="nom" value="<? if (isSet($_POST['nom'])) { echo $_POST['nom']; }?>" required style="width: 400px;"></td>
    			</tr>
    			<tr>
    				<td align="left" valign="top">Pr&eacute;fixe&nbsp;:</td>
    				<td align="left" valign="top"><input type="text" name="prefixe" value="<? if (isSet($_POST['prefixe'])) { echo $_POST['prefixe']; }?>" required style="width: 400px;"></td>
    			</tr>
    			<tr>
    				<td align="left" valign="top">Infos&nbsp;:</td>
    				<td align="left" valign="top"><textarea name="infos" cols="" rows="" style="width: 400px;"><? if (isSet($_POST['infos'])) { echo stripSlashes($_POST['infos']); }?></textarea></td>
    			</tr>
    			<tr>
    				<td align="left" valign="top">&nbsp;</td>
    				<td align="left" valign="top"><input type="submit" name="gestion" value="<?=$bt['register'];?>" style="width: 405px;"></td>
    			</tr>
    		</form>
    	</table>
    	<?
    }
    ?>
     
     
    <br />
    <br />
    <br />
     
     
    <?
    $db=db();
    $sql = $db->query('SELECT * FROM adm_sites');
    echo '<table border="0" cellpadding="2" cellspacing="0">';
    while ($data = $sql->fetch()) {
    	?>
    	<form method="POST">
    		<input type="hidden" name="id" value="<?=$data['id'];?>">
    		<tr>
    			<td align="left" valign="top"><div style="font-weight: bold; font-size: 16px;"><?=$data['id'];?></div></td>
    			<td align="right" valign="top"><a href="sites.php?gestion=delete&id=<?=$data['id'];?>" target="_parent"><i class="fas fa-trash-alt"></i></a></td>
    		</tr>
    		<tr><td colspan="2" align="left" valign="top"><input type="text" name="nom" value="<?=$data['nom'];?>" maxlength="" style="width: 400px;"></td></tr>
    		<tr><td colspan="2" align="left" valign="top"><input type="text" name="prefixe" value="<?=$data['prefixe'];?>" maxlength="" style="width: 400px;"></td></tr>
    		<tr><td colspan="2" align="left" valign="top"><textarea name="infos" cols="" rows="3" style="width: 400px;"><?=$data['infos'];?></textarea></td></tr>
    		<tr><td colspan="2" align="left" valign="top"><input type="submit" name="gestion" value="<?=$bt['update'];?>"></td></tr>
    		<tr><td colspan="2" align="left" valign="top">&nbsp;</td></tr>
    	</form>
    	<?
    }
    echo '</table>';
    $sql->closeCursor();
    ?>
     
     
    <? include($files_includes['pfooter']); ?>
    </body>
    </html>
    Maintenant, je me demande comment on peut encore améliorer cette page pour la rendre un peu plus au gout du jour?



    Citation Envoyé par MaitrePylos Voir le message
    Par contre, je vois que dans vos fonctions native vous utilsez le camelCase "isSet", "mySqli_query"..... en fait, si votre serveur est un linux, vous risquez des erreurs, car la norme est "isset", "mysqli_", stripslash ......
    A l'époque, l'on m'avait conseillé de coder en séparant les mots par des majuscule afin de rendre les codes plus clair lisiblement. Mais jamais je n'aurais pensé que cela pouvais causer des erreurs, bien au contraire! Bon.. Alors dans ce cas, si je veux coder correctement, je vais cesser de coder en camelCase




    Citation Envoyé par MaitrePylos Voir le message
    Après, vous êtes dans un système from scratch, qui fonctionne, mais ne respecte plus effectivement les standards.
    On essaye actuellement de séparer les couche, de ne plus avoir les requêtes de DB dans la même page, mais externaliser et l'injecter.
    Si votre projet est pour le long terme, apprendre un petit framework pour votre aprtie admin pourrais-être intéressant pour vous, genre Slim, Mezzio ou autre.
    Non, mon site personnel est surtout utilisé pour tester mes découvertes et apprendre de nouvelles combines en matière de programmations web. Cela me permet de rendre l'utile à l'agréable, car j'optimise mon site en apprenant et testant de nouvelles combines. Se serait un site professionnel avec une forte audiance, se serait différent, mais pour mon site perso, il est continuellement en transformation.

    Mais, histoire de me mette un peu à jour... Ces framework que tu me propose, c'est un genre de base pour templates? J'avais réalisé, il y a fort longtemps un site totalement sous templates. Le principe de séparer le HTML des codes de programmation est clairement bien lorsque l'on code professionnelement. Je ne dis pas que je ne veux pas me lancer à nouveau là-dedant, mais je pense que dans un premeir temps, je dois me remètre à jours sur le point de vue code. Après, pourquoi pas me lancer dans un site sous templates histoire de voir comment tout cela a évoluer

  6. #6
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 496
    Par défaut
    Bonjour,

    La ligne 73 array('id' => $_GET['id']);, tu as oublié les deux points avant le marqueur de l'id array(':id' =>...);, ça peut passer sans erreur oui, mais la bonne syntaxe est avec les deux points.

    La ligne 78 $sql->closeCursor();, ce n'est pas $sql mais $stmt, ça devrait te retourner une erreur ou avertissement je suppose... , à moins que tu n'as pas activé l'affichage des erreurs/avertissement.

  7. #7
    Membre confirmé Avatar de RinaBK
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2021
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 49
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2021
    Messages : 92
    Par défaut
    @Toufik83 merci beaucoup pour les corrections !!
    Pour la ligne 78, cela ne m'a pas affiché d'erreur en effet, mais c'est parce que la page est directement redirigée avec header('Location:'); J'aurais du mettre la redirection en commentaire pour tester correctement. Je l'avais fait pour les requêtes INSERT et UPDATE, mais j'ai du oublier sur le DELETE, tête de linotte que je suis

    Merci Toufik83

  8. #8
    Expert confirmé

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 416
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 416
    Par défaut
    Salut,

    1/ Le système avec marqueurs indiqué par MaitrePylos est très pratique et de plus dans certaines circonstances il te sera difficile de faire autrement sans complexifier ton code. Tu devrais t'entrainer à l'utiliser un peu même si tu préfères utiliser plus volontiers les paramètres nommées. C'est vrai que les paramètres nommés sont plus clairs, car avec l'autre syntaxe il faut faire attention à l'ordre des marqueurs mais le gros avantage est que cela te permet d'envoyer un tableau basique. Enfin bon choisis la méthode que tu veux mais ne négliges pas les marqueurs, cela te rendras parfois des services beaucoup plus difficiles à obtenir autrement.

    Pour gérer les erreurs et/ou savoir pourquoi cela ne fonctionne pas, utilises des blocs try/catch

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    try {
     
    $requete = ...
    //...
    $resultat = ...
    }
    catch(PDOException $e)
    {
    	exit($e->getMessage());
    }
    Mais pour que ça fonctionne il faut activer les exceptions, j'en viens donc au point numéro 2

    2/ Tu utilises plusieurs fois $db=db();. Si c'est une connexion dans une fonction standard tu tentes d'ouvrir inutilement plusieurs connexions. Plutôt que d'espérer que le serveur se débrouille pour le mieux il y a la méthode de connexion statique qui t'assures de n'ouvrir qu'une seule connexion que tu pourras réutiliser partout dans ton script. J'en donne un exemple ici avec la classe C_PDO. Cette classe est configurée pour gérer les exceptions donc ton bloc try/catch fonctionnera et tu pourras mieux connaître l'origine de tes erreurs. Par ailleurs dans ce script tu as un exemple de CRUD (création, read, update, delete) complet avec PDO.

    3/ On utilise jamais htmlentities ni htmlspecialchars pour rentrer des données en BDD, ces fonctions doivent être utilisées uniquement pour l'affichage. Et avec utf-8 on utilise uniquement htmlspecialchars pour l'affichage (non pas htmlentities). On utilise pas non plus "stripSlashes" puisque magic_qote_gpc est désactivée depuis php 5.4. Donc au final le code utile est le trim et le str_replace, le reste tu l'enlèves. Et à chaque fois que tu affiches une variable php dans le html tu ne te poses pas de question et tu utilises htmlspecialchars.

    4/ Quel est l'intérêt de $include_files[] = array('pheader','includes/header.php');, pourquoi pas $include_files['pheader'] = 'includes/header.php'; ? Et puis si ce sont des variables qui ne sont définies qu'une fois dans le site on utilise plutôt des constantes, c'est étudié pour. En plus elles acceptent des tableaux dynamiques avec php 7 donc il n'y a plus de contraintes. Mais bon si tu utilises des variables je ne comprends pas pourquoi tu n'utilises pas l'index du tableau. Et comme déjà dit il faudra te documenter sur la fonction foreach pour lister tes tableaux.

    5/ On ne fait pas (sauf exception quand on ne peut pas faire autrement) de requêtes dans le html pour une meilleure organisation/séparation du code. Tu fais ta requête en haut dans le code php et tu listes le tableau des résultats dans le html. Tu peux regarder l'exemple de CRUD dans le lien que j'ai donné plus haut pour exemple.

    6/ Depuis php 5.6 c'est utf-8 par défaut, donc tu peux écrire "Vous n'avez pas spécifier le préfixe du site" plutôt que "Vous n&rsquo;avez pas sp&eacute;cifi&eacute; le pr&eacute;fixe du site". Attention quand même que ton fichier soit encodé en utf-8 (sans signature BOM si tu vois cette option dans ton éditeur de texte). Sinon le plus simple pour le convertir (qui marche à tous les coups) est de créer un nouveau fichier au format UTF-8 et d'y recopier le code (toute la page) de ton ancien fichier.

  9. #9
    Membre confirmé Avatar de RinaBK
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2021
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 49
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2021
    Messages : 92
    Par défaut
    Bonjour ABCIWEB
    Tout d'abord, merci beaucoup pour ta réponse !


    Citation Envoyé par ABCIWEB Voir le message
    1/ Le système avec marqueurs indiqué par MaitrePylos est très pratique et de plus dans certaines circonstances il te sera difficile de faire autrement sans complexifier ton code. Tu devrais t'entrainer à l'utiliser un peu même si tu préfères utiliser plus volontiers les paramètres nommées. C'est vrai que les paramètre nommés sont plus clairs, car avec l'autre syntaxe il faut faire attention à l'ordre des marqueurs mais le gros avantage est que cela te permet d'envoyer un tableau basique. Enfin bon choisi la méthode que tu veux mais ne néglige pas les marqueurs, cela te rendra parfois des services beaucoup plus difficiles à obtenir autrement.
    A ma lecture du système proposé par MaitrePylos m'a tout de suite intéressé, car je le trouvais très intéressant. Après mes nombreux test pour trouver pourquoi cela ne fonctionnait pas, et par mon manque d'expérience dans ce système, je me sus bêtement dis que peut-être mon serveur ne l’acceptait pas et j'ai testé avec les variables et là, tout à tout de suite fonctionné. Mais je vais prendre le temps aujourd'hui de voir tout cela plus en détail! Je dois avouer que hier, j'avais fait nuit blanche et je n'étais plus vraiment apte à réfléchir correctement.



    Citation Envoyé par ABCIWEB Voir le message
    Pour gérer les erreurs et/ou savoir pourquoi cela ne fonctionne pas, utilises des blocs try/catch
    Voici la fonction que j'ai réalisée pour me connecter à ma BDD :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function db() {
    	try { $bdd = new PDO('mysql:host=gwandach.mysql.db;dbname=gwandach;charset=utf8', 'gwandach', 'monmotdepasse', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)); }
    	catch (Exception $e) { die('Erreur : ' . $e->getMessage()); }
    	return $bdd;
    }
    J'ai pris l'habitude de mettre ma connexion pour ma base de données via une fonction, car il me semble que pour protéger l'accès à mes données cela me semble plus sécuritaire. Maintenant, je ne suis plus trop certaine que mon raisonnement soit correct. Mais pour moi, du moins c'est ce que j'ai toujours pensé, c'est que de mettre son mot de passe dans une variable, cela ne me semble pas très prudent pour la sécurité. Après pour l'affichage des erreurs, j'ai bien mis l'affichage. Seulement, encore une fois, par mon manque d'expérience sur ce sujet, j'ai encore un peu de mal à identifier correctement les erreurs envoyées.



    Citation Envoyé par ABCIWEB Voir le message
    2/ Tu utilises plusieurs fois $db=db();. J'espère que c'est une connexion statique, sinon tu ouvres des connexions inutiles. Plutôt que d'espérer que le serveur se débrouille pour le mieux il y a la méthode de connexion statique qui t'assures de n'ouvrir qu'une seule connexion que tu pourras réutiliser partout dans ton script. J'en donne un exemple ici avec la classe C_PDO. Cette classe est configurée pour gérer les exceptions donc ton bloc try/catch fonctionnera et tu pourras mieux connaître l'origine de tes erreurs. Par ailleurs dans ce script tu as un exemple de CRUD (création, read, update, delete) complet avec PDO.
    Je suis très heureuse de pouvoir enfin utiliser des class, car c'est l'une de mes plus grosses lacunes en matière de programmation et pourtant c'est une base très importante! J'ai donc remplacé ma fonction de connexion pour ma base de données avec la class C_PDO. Je ne connaissais pas la possibilité de faire une connexion statique pour ma base de données et c'est vraiment génial !!! J'adore tout simplement !!! ...Et j'ai intégré le système de fonctions pour INSERT, UPDATE et DELETE dans ma page et je suis époustouflée ! Encore une fois, j'adore vraiment !!! Et je m'ennuyait tout le temps à utiliser des tableaux HTML, et lorsque j'ai vu que tu utilisais le CSS pour remplacer les tableaux, je me suis dit, mais quel bonne idée. Bref, tu as fait une heureuse aujourd'hui et pas qu'un peu, j'ai le sourire croché et des étoiles pleins les yeux !


    Citation Envoyé par ABCIWEB Voir le message
    3/ On utilise jamais htmlentities ni htmlspecialchars pour rentrer des données en BDD, ces fonctions doivent être utilisées uniquement pour l'affichage. Et avec utf-8 on utilise uniquement htmlspecialchars pour l'affichage (non pas htmlentities). On utilise pas non plus "stripSlashes" dans les requêtes préparées. Donc au final le code utile est le trim et le str_replace, le reste tu l'enlèves.
    Ah bon, je ne savais pas Je pensais que par sécurité, il était préférable de convertir tous les caractères spéciaux avant l'enregistrement dans la DDB afin d'éviter que par exemple un utilisateur hack la base de données. Et j'utilisais d'office htmlentities car d'après la bible PHP de 2002, htmlentities convertit les caractères accentués contrairement à htmlspecialchars. Après, la bible PHP n'est plus d'actualité vu qu'elle est sortie en 2002 Mais j'avoue encore beaucoup l'utiliser, car elle est sacrément bien faite.

    Concernant le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $valeur = str_replace('\'','&rsquo;',$valeur);
    Est-il encore bien nécessaire, vu qu'il n'est plus question de convertir les caractères spéciaux avec htmlentities ?



    Citation Envoyé par ABCIWEB Voir le message
    4/ Quel est l'intérêt de $include_files[] = array('pheader','includes/header.php');, pourquoi pas $include_files['pheader'] = 'includes/header.php'; ? Et puis si ce sont des variables qui ne sont définies qu'une fois dans le site on utilise plutôt des constantes, c'est étudié pour. En plus elles acceptent des tableaux dynamiques avec php 7 donc il n'y a plus de contraintes. Mais bon si tu utilises des variables je ne comprends pas pourquoi tu n'utilises pas l'index du tableau. Et comme déjà dit il faudra te documenter sur la fonction foreach pour lister tes tableaux.
    C'est une très bonne remarque! En effet, cette portion de code, je l'avais réalisée il y a des lustres et je n'ai jamais pris la peine de la contrôler ou de chercher à la faire mieux. Je faisais bêtement des copier/coller... Bon, il y a aussi que j'ai toujours eu du mal à utiliser la boucle foreach car je dois avouer que la boucle for est bien plus ancrée dans ma tête. Mais comme on me l'a souvent répété ces derniers temps, il est temps que je l'utilise pour mes tableaux, d'autant plus qu'elle est faite pour ça. Ceci-dit, si j'avais choisi d'utiliser des variables, il me semble que c'était pour le contrôle de l'existence des fichiers.

    Je vais suivre ton conseil et mettre le nom de mes fichiers en constantes. Ceci-dit, je n’ai jamais utilisé de tableau avec les constantes et bien que mon code ne m’affiche aucune erreur, je ne sais pas si je les ai utilisées correctement.


    Citation Envoyé par ABCIWEB Voir le message
    5/ On ne fait pas (sauf exception quand on ne peut pas faire autrement) de requêtes dans le html pour une meilleure organisation/séparation du code. Tu fais ta requête en haut dans le code php et tu listes le tableau des résultats dans le html. Tu peux regarder l'exemple de CRUD dans le lien que j'ai donné plus haut pour exemple.
    Voilà, j’ai tout refais la page en prenant bien soins de faire les choses correctement. J’ai pris exemple de CRUD que j’ai étudié et que j’ai adapté pour la page. D’ailleurs, je vais faire de même avec toutes les autres pages de mon site.

    Ceci-dit, j'ai tout de même un souci avec ma page... Je pense que j'ai dû faire une erreur à quelque part, car je n'ai plus de messages qui m’informent si les entrées sur les formulaires sont correctes ou non, s’ils ont bien été enregistrés, modifiées ou supprimés. Je cherche depuis un bon moment pour trouver ce qui ne va pas, mais je pense que je ne suis pas encore assez au clair avec cette méthode pour trouver d’où vient le souci. Mis à part cela, tout fonctionne parfaitement

    Voici le résultat de ma page en entier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    <?
    define('MAJ','26.01.2021 10:26:29');
     
     
     
     
     
     
    //	Initialisations des sessions
    session_start();
    if (!isSet($_SESSION['site'])) {
    	$siteID = '';
    	$sitePrefixe = '';
    	$siteName = '';
    } else {
    	$siteID = $_SESSION['site']['id'];
    	$sitePrefixe = $_SESSION['site']['prefixe'];
    	$siteName = $_SESSION['site']['nom'];
    }
     
     
     
     
     
     
    //	Inclusions des fichiers primaires
    define('INCLUDES_FILES', array(
    													'header.php',
    													'footer.php',
    													'variables.php',
    													'fonctions.php'
    													));
     
    foreach (INCLUDES_FILES as $files) {
    	if (!file_exists('includes/'.$files)) { header('Location: alerte.php?warning=500'); }
    }
    include('includes/'.INCLUDES_FILES[2]);
    include('includes/'.INCLUDES_FILES[3]);
     
     
     
     
     
     
     
     
    /*
    CREATE TABLE adm_sites (
    	id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    	prefixe VARCHAR(200) NULL,
    	nom VARCHAR(200) NOT NULL,
    	infos TEXT NULL,
    	PRIMARY KEY (id),
    	UNIQUE (prefixe)
    );
    */
     
     
     
    // Fonction d'insertion
    function inserersolution($prefixe, $nom, $infos) {
    	try {
    		$connexion = C_PDO::getC();
    		$requete = "INSERT INTO adm_sites (prefixe, nom, infos) VALUES(?, ?,?)";
    		$stmt = $connexion->prepare($requete);
    		$stmt->execute([$prefixe, $nom, $infos]);
    		// Trouve l'id auto incrémenté
    		$id = $connexion->lastInsertId ();
    	}
    	catch(PDOException $e) {
    		exit($e->getMessage());
    	}
    	return $id;
    }
     
     
     
     
    // Fonction de modification
    function modifiersolution( $id, $prefixe, $nom, $infos) {
    	try {
    		$connexion = C_PDO::getC();
    		$requete = "UPDATE adm_sites SET prefixe = ?, nom = ?, infos = ? WHERE adm_sites.id = ?";
    		$stmt = $connexion->prepare($requete);
    		$stmt->execute([$prefixe, $nom, $infos, $id]);
    		$count = $stmt->rowCount();
    	}
    	catch(PDOException $e) {
    		exit($e->getMessage());
    	}
    	return $count ? "Modification réussie" : "Impossible de modifier"; 
    }
     
     
     
     
     
    // Fonction de suppression
    function supprimersolution($id) {
    	try {
    		$connexion = C_PDO::getC();
    		$requete = "DELETE FROM adm_sites WHERE adm_sites.id = ?";
    		$stmt = $connexion->prepare($requete);
    		$stmt->execute([$id]);
    		$count = $stmt->rowCount();
    	}
    	catch(PDOException $e) {
    		exit($e->getMessage());
    	}
    	return $count ? "Supression réussie" : "Impossible de supprimer"; 
    }
     
     
     
     
     
     
     
    // function de vérification commune à l'ajout et à la modification
    function verifpost ($post) {
    	$erreur = empty($post['nom']) ? "Le nom doit être renseignée" : $erreur;
    	$erreur = empty($post['prefixe']) ? "Le préfixe doit être renseignée" : $erreur;
    	return $erreur;
    }
     
     
     
     
     
     
    // Ajout en provenance du formulaire
    if (isset($_POST["ajout"]) && $_POST["ajout"] == "ajouter") {
     
    	// Enregistre le post en session pour éviter d'avoir à ressaisir tous les champs en cas d'erreur
    	$_SESSION['ajout_sites'] = $_POST;
     
    	//J'applique trim sur les éléments du tableau pour supprimer les espaces blancs en début et fin de chaine qui pourraient être rentrés inopinément par l'utilisateur
    	$post = array_map('trim',$_POST);
     
    	//Fonction de vérification
    	$erreur = verifpost($post);
     
    	// Si pas d'erreur on lance l'insertion en récupèrant l'id auto incrémenté
    	$id = empty($erreur) ? inserersolution($post['prefixe'], $post['nom'], $post['infos']) : null;
     
    	// On affiche un message d'erreur uniquement si nécéssaire. Si OK le header renverra vers l'élément inséré
    	$_SESSION['message_sites'] = isset($erreur) ? $erreur : null;
     
    	// Header pour éviter les multiples post et le messgae du navigateur si on réaffiche cette page. L'ancre id sert pour aller à l'élément inséré
    	header('Location: '.$_SERVER['PHP_SELF'].'?gestion=new#lent'.$id);exit;
    }
     
     
     
    // Modification en provenance du formulaire
    if (isset($_POST["modif"]) && $_POST["modif"] == "modifier") {
    	$_SESSION['modif_sites'] = $_POST;
    	$post = array_map('trim',$_POST);
    	$erreur = verifpost($post);
    	$_SESSION['message_sites'] = empty($erreur) ? modifiersolution($post['id'], $post['prefixe'], $post['nom'], $post['infos']) : $erreur;
    	header('Location: '.$_SERVER['PHP_SELF'].'#lent'.$post['id']);exit;
    }
     
     
     
    // Suppression en provenance du formulaire
    if (isset($_POST["suppr"]) && $_POST["suppr"] == "supprimer") {
    	$_SESSION['message_sites'] = supprimersolution($_POST['id']);
    	header('Location: '.$_SERVER['PHP_SELF']);exit;
    }
     
     
     
    // Variables qui pourront être affichées dans le html pour les ajouts, modifications et suppressions
    $message = isset($_SESSION['message_sites']) ? $_SESSION['message_sites'] : null;
     
    $modif = isset($_SESSION['modif_sites']) ? $_SESSION['modif_sites'] : null;
    // $id_modif pour cibler le formulaire de modification
    $id_modif = isset($_SESSION['modif_sites']['id']) ? $_SESSION['modif_sites']['id'] : null;
     
    // On fait également un test sur message pour ne pas remplir les champs du formulaire d'ajout si l'insertion est réussie
    $ajout = isset($_SESSION['ajout_sites'],$_SESSION['ajout_sites']) ? $_SESSION['ajout_sites'] : null;
     
    // On efface les variables de session pour qu'elles ne soient définies qu'une fois
    unset($_SESSION['message_sites'],$_SESSION['modif_sites'],$_SESSION['ajout_sites']);
     
     
    //Affichage des résultats en alimentant (hydratant) les champs des formulaires de modification et suppression
    $select = "SELECT id, prefixe, nom, infos FROM adm_sites ORDER BY id";
    $connexion = C_PDO::getC();
    // Pas besoin de requête préparée ici puisqu'il n'y a pas de variables utilisateur dans la requête
    $read = $connexion->query($select);
     
     
     
    ?>
     
    <!DOCTYPE html>
    <html lang="fr-CH">
    <head>
    	<title>Administrations</title>
    	<link rel="stylesheet" href="images/designs/styles.css">
    	<script src="https://kit.fontawesome.com/2e9b34a81e.js"></script>
    	<style>
    form p {
    	margin:0.5em;
    	padding:0;
    }
    form .label {
    	display:inline-block;
    	width:120px;
    }
    #message {
    	border:1px solid black;
    	background:#0CF;
    	font-size:1.5em;
    	text-align:center;
    }
    .saisie {
    	width: 400px;
    }
    button {
    	padding: 3px;
    	width: 100px;
    }
    </style>
    </head>
     
     
    <body>
    <? include('includes/'.INCLUDES_FILES[0]); ?>
     
     
     
     
    <h1>Gestion des Sites</h1>
    <div align="justify"  style="width: 600px;">
    	Concernant le nom du site ainsi que son pr&eacute;fixe, il serait important de ne pas mettre d&rsquo;accents, 
    	de caract&egrave;res sp&eacute;ciaux ou d&rsquo;espace. Il faudrait plut&ocirc;t jouer entre les majuscules 
    	et les minuscules pour diff&eacute;rencier les mots. En revanche pour les infos, aucun soucis, tous les 
    	caract&egrave;res sont accept&eacute;s et pr&eacute;senteront aucun danger niveau codage.
    </div>
    <br />
    <a href="sites.php?gestion=new" target="_parent" title="Ajouter une entr&eacute;e"><i class="fas fa-folder-plus" style="font-size: 30px;"></i></a>
    <br />
     
     
     
    <? 
    // On fait afficher ici les messages de suppression et d'ajout mais pas ceux de modification qui seront affichés dans le formulaire concerné
    if(isset($message) && empty($id_modif)) echo '<p id="message">'.htmlspecialchars($message).'</p>';
     
     
     
    if (!empty($_GET['gestion'])) {
    	?>
    	<br />
    	<form action="#" method="POST">
    		<fieldset style="width: 600px;">
    			<legend>Ajouter</legend>
    			<p><label><span class="label">Nom : </span><input type="text" name="nom" value="<?=isset($ajout['nom']) ? htmlspecialchars($ajout['nom']) : null;?>" class="saisie" /></label></p>
    			<p><label><span class="label">Prefixe : </span><input type="text" name="prefixe" value="<?=isset($ajout['prefixe']) ? htmlspecialchars($ajout['prefixe']) : null;?>" class="saisie" /></label></p>
    			<p><label><span class="label">Infos : </span><textarea name="infos" class="saisie"><?=isset($ajout['infos']) ? htmlspecialchars($ajout['infos']) : null;?></textarea></label></p>
    			<div align="center"><button type="submit" name="ajout" value="ajouter">Ajouter</button></div>
    		</fieldset>
    	</form>
    	<br />
    	<?
    }
     
     
     
     
    foreach ($read as $row) {
    	?>
    	<!-- l'id sert d'ancre de redirection pour les ajouts / modifications (Attention de ne pas utiliser d'id statique dans ces lignes puisque c'est une boucle)-->
    	<br />
    	<form action="#" method="post" style="margin-bottom:0.5em" id="lent<?= isset($row->id)? htmlspecialchars($row->id) : ''?>">
    		<fieldset style="width: 600px;">
    			<!-- message des modifications -->
    			<legend>Modifier/Supprimer : <b><?=htmlspecialchars($row->nom);?></b></legend>
    			<?= isset($id_modif, $message) && $row->id == $id_modif ? '<p style="color:blue">'.htmlspecialchars($message).'<p>' : ''?>
    			<input type="hidden" name="id" value="<?= htmlspecialchars($row->id)?>" >
    			<p><label><span class="label">Nom : </span><input type="text" name="nom" value="<?= $row->id == $id_modif ? htmlspecialchars($modif['nom']) : htmlspecialchars($row->nom) ?>" class="saisie" /></label></p>
    			<p><label><span class="label">Prefixe : </span><input type="text" name="prefixe" value="<?= $row->id == $id_modif ? htmlspecialchars($modif['prefixe']) : htmlspecialchars($row->prefixe) ?>" class="saisie" /></label></p>
    			<p><label><span class="label">Infos : </span><textarea name="infos" class="saisie"><?= $row->id == $id_modif ? htmlspecialchars($modif['infos']) : htmlspecialchars($row->infos) ?></textarea></label></p>
    			<div align="center">
    				<button type="submit" name="modif" value="modifier">Modifier</button>
    				<button type="submit" name="suppr" value="supprimer" style="margin-left:2em">Supprimer</button>
    			</div>
    		</fieldset>
    	</form>
    	<?
    }
    ?>
     
     
     
    <? include('includes/'.INCLUDES_FILES[1]); ?>
    </body>
    </html>


    Encore une fois, un très grand merci pour l'aide

  10. #10
    Expert confirmé

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 416
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 416
    Par défaut
    Salut,

    Attention dans ton code je vois que tu utilises les short tag "<?" pour ouvrir une session php, mais ils sont désactivés par défaut depuis un bon moment (je ne souviens plus de la version de php) pour éviter la confusion avec d'autres langages. A la place utilises "<?php". Par contre la syntaxe short tag "<?=" reste disponible pour faire afficher des variables dans le html.

    Citation Envoyé par RinaBK Voir le message
    Bonjour ABCIWEB
    Je me sus bêtement dis que peut-être mon serveur ne l’acceptait pas et j'ai testé avec les variables et là, tout à tout de suite fonctionné. Mais je vais prendre le temps aujourd'hui de voir tout cela plus en détail! Je dois avouer que hier, j'avais fait nuit blanche et je n'étais plus vraiment apte à réfléchir correctement.
    Les deux fonctionnent évidemment, mais pour les débutants ou dans certains cas, les paramètres nommés sont plus aisés à utiliser car plus lisibles, alors qu'avec les marqueurs il faut faire attention à ce que les éléments du tableau que tu passes dans le excecute() soient dans le même ordre que celui des marqueurs.

    Citation Envoyé par RinaBK Voir le message
    J'ai pris l'habitude de mettre ma connexion pour ma base de données via une fonction, car il me semble que pour protéger l'accès à mes données cela me semble plus sécuritaire.
    Oui évidemment inutile de répéter des mots de passe partout dans le code.

    Citation Envoyé par RinaBK Voir le message
    Je suis très heureuse de pouvoir enfin utiliser des class, car c'est l'une de mes plus grosses lacunes en matière de programmation et pourtant c'est une base très importante! J'ai donc remplacé ma fonction de connexion pour ma base de données avec la class C_PDO. Je ne connaissais pas la possibilité de faire une connexion statique pour ma base de données et c'est vraiment génial !!! J'adore tout simplement !!!
    Oui cela dit cette classe C_PDO n'est pas vraiment représentative de l'utilisation des classes puisque c'est une classe statique sans constructeur.

    Un autre avantage pratique des classes c'est que tu peux les appeler avec spl_autoload_register, pour peu que tu nommes ton fichier avec le même nom que la classe. Par exemple si tu as mis la classe C_PDO dans un fichier nommé C_PDO.php et que tu mets tes classes dans un répertoire nommé "Classes", il te suffira de faire en haut de la page d'appel: spl_autoload_register(function ($class) {require 'Classes/' . $class . '.php';}); pour charger les classes nécessaires du répertoire "Classes" en fonction de l'utilisation des classes dans ton code.

    Citation Envoyé par RinaBK Voir le message
    ...Et j'ai intégré le système de fonctions pour INSERT, UPDATE et DELETE dans ma page et je suis époustouflée ! Encore une fois, j'adore vraiment !!!
    C'est plus lisible n'est-ce pas ? Après tu pourrais même aller plus loin en faisant par exemple une classe "AdminCrud" dans un fichier "AdminCrud.php" que tu mettrais dans ton répertoire "Classes" :
    AdminCrud.php :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    <?php
    class AdminCrud {
     
    	private $connect;
     
    	// S'exécute lorsqu'on instancie la classe
    	public function __construct($connexion)
    	{
    		$this->connect = $connexion;
    	}
     
    	// Fonction de modification
    	public function modifier($id, $prefixe, $nom, $infos) {
    		try {
    			$requete = "UPDATE adm_sites SET prefixe = ?, nom = ?, infos = ? WHERE adm_sites.id = ?";
    			$stmt = $this->connect->prepare($requete);
    			$stmt->execute([$prefixe, $nom, $infos, $id]);
    			$count = $stmt->rowCount();
    		}
    		catch(PDOException $e) {
    			exit($e->getMessage());
    		}
    		return $count ? "Modification réussie" : "Impossible de modifier"; 
    	}
     
     
    	// Fonction de suppression
    	public function supprimer($id) {
    		try {
    			$requete = "DELETE FROM adm_sites WHERE adm_sites.id = ?";
    			$stmt = $this->connect->prepare($requete);
    			$stmt->execute([$id]);
    			$count = $stmt->rowCount();
    		}
    		catch(PDOException $e) {
    			exit($e->getMessage());
    		}
    		return $count ? "Supression réussie" : "Impossible de supprimer"; 
    	}
     
     
    	// Fonction d'insertion
    	public function inserer ($prefixe, $nom, $infos) {
    		try {
    			$requete = "INSERT INTO adm_sites (prefixe, nom, infos) VALUES(?, ?,?)";
    			$stmt = $this->connect->prepare($requete);
    			$stmt->execute([$prefixe, $nom, $infos]);
    			// Trouve l'id auto incrémenté
    			$id = $this->connect->lastInsertId ();
    		}
    		catch(PDOException $e) {
    			exit($e->getMessage());
    		}
    		return $id;
    	}
     
    	// Fonction d'insertion
    	public function lire () {
    		try {
    			$select = "SELECT id, prefixe, nom, infos FROM adm_sites ORDER BY id";
    			// Pas besoin de requête préparée ici puisqu'il n'y a pas de variables utilisateur dans la requête
    			$read = $this->connect->query($select);
    		}
    		catch(PDOException $e) {
    			exit($e->getMessage());
    		}
    		return $read;
    	}
    }
    ?>
    Ensuite dans ton fichier, il suffira de faire:
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    <?php
    session_start();
    // Charge les classes php avec spl_autoload_register (suppose ici que le répertoire Classes se trouve au même niveau que ce fichier, sinon à adapter)
    spl_autoload_register(function ($class) {require 'Classes/' . $class . '.php';}); 
     
    define('MAJ','26.01.2021 10:26:29');
     
    //	Initialisations des variables de sessions
    if (!isset($_SESSION['site'])) {
    	$siteID = '';
    	$sitePrefixe = '';
    	$siteName = '';
    } else {
    	$siteID = $_SESSION['site']['id'];
    	$sitePrefixe = $_SESSION['site']['prefixe'];
    	$siteName = $_SESSION['site']['nom'];
    }
     
     
    //	Inclusions des fichiers primaires
    define('INCLUDES_FILES', array('header'=>'header.php'
    						,'footer'=>'footer.php'
    						,'variables'=>'variables.php'
    						,'fonctions'=>'fonctions.php'
    						));
     
    foreach (INCLUDES_FILES as $index => $files) {
    	if (!file_exists('includes/'.$files)) { header('Location: alerte.php?warning=500'); }
    	if ($index == 'variables' || $index == 'fonctions') { include('includes/'.$files); } 
    }
     
     
     
    // Initialise la classe AdminCrud en passant la connexion en paramètre
    $crud = new AdminCrud(C_PDO::getC());
     
     
    // function de vérification commune à l'ajout et à la modification
    function verifpost ($post) {
    	$erreur = empty($post['nom']) ? "Le nom doit être renseignée" : null;
    	$erreur = empty($post['prefixe']) ? "Le préfixe doit être renseignée" : $erreur;
    	return $erreur;
    }
     
     
    // Ajout en provenance du formulaire
    if (isset($_POST["ajout"]) && $_POST["ajout"] == "ajouter") {
     
    	// Enregistre le post en session pour éviter d'avoir à ressaisir tous les champs en cas d'erreur
    	$_SESSION['ajout_sites'] = $_POST;
     
    	//J'applique trim sur les éléments du tableau pour supprimer les espaces blancs en début et fin de chaine qui pourraient être rentrés inopinément par l'utilisateur
    	$post = array_map('trim',$_POST);
     
    	//Fonction de vérification
    	$erreur = verifpost($post);
     
    	// Si pas d'erreur on lance l'insertion en récupèrant l'id auto incrémenté
    	$id = empty($erreur) ? $crud->inserer($post['prefixe'], $post['nom'], $post['infos']) : null;
     
    	// On affiche un message d'erreur uniquement si nécéssaire. Si OK le header renverra vers l'élément inséré
    	$_SESSION['message_sites'] = isset($erreur) ? $erreur : null;
     
    	// Header pour éviter les multiples post et le messgae du navigateur si on réaffiche cette page. L'ancre id sert pour aller à l'élément inséré
    	header('Location: '.$_SERVER['PHP_SELF'].'?gestion=new#lent'.$id);exit;
    }
     
     
     
    // Modification en provenance du formulaire
    if (isset($_POST["modif"]) && $_POST["modif"] == "modifier") {
    	$_SESSION['modif_sites'] = $_POST;
    	$post = array_map('trim',$_POST);
    	$erreur = verifpost($post);
    	$_SESSION['message_sites'] = empty($erreur) ? $crud->modifier($post['id'], $post['prefixe'], $post['nom'], $post['infos']) : $erreur;
    	header('Location: '.$_SERVER['PHP_SELF'].'#lent'.$post['id']);exit;
    }
     
     
     
    // Suppression en provenance du formulaire
    if (isset($_POST["suppr"]) && $_POST["suppr"] == "supprimer") {
    	$_SESSION['message_sites'] = $crud->supprimer($_POST['id']);
    	header('Location: '.$_SERVER['PHP_SELF']);exit;
    }
     
     
    // Variables qui pourront être affichées dans le html pour les ajouts, modifications et suppressions
    $message = isset($_SESSION['message_sites']) ? $_SESSION['message_sites'] : null;
     
    $modif = isset($_SESSION['modif_sites']) ? $_SESSION['modif_sites'] : null;
    // $id_modif pour cibler le formulaire de modification
    $id_modif = isset($_SESSION['modif_sites']['id']) ? $_SESSION['modif_sites']['id'] : null;
     
    // On fait également un test sur message pour ne pas remplir les champs du formulaire d'ajout si l'insertion est réussie
    $ajout = isset($message,$_SESSION['ajout_sites']) ? $_SESSION['ajout_sites'] : null;
     
    // On efface les variables de session pour qu'elles ne soient définies qu'une fois
    unset($_SESSION['message_sites'],$_SESSION['modif_sites'],$_SESSION['ajout_sites']);
     
     
    //Affichage des résultats en alimentant (hydratant) les champs des formulaires de modification et suppression
    $read = $crud->lire();
    ?>
    <!DOCTYPE html>
    ...
    <?php include('includes/'.INCLUDES_FILES['header']); ?>
    ...
    <?php include('includes/'.INCLUDES_FILES['footer']); ?>
    </html>

    Là tu as un exemple qui se rapproche du principe du MVC concernant la séparation des tâches. Les requêtes (le modèle) sont dans la classe "AdminCrud", le contrôleur en haut dans le code php, et la vue en bas dans le html.

    Cela permet une meilleure organisation du code et d'avoir des pages plus courtes à lire. Et tu n'aurais pas besoin de réécrire les requêtes si tu utilises les mêmes dans un autre fichier, il te suffirait d'initialiser "AdminCrud". On pourrait faire l'équivalent avec des fonctions, mais les classes permettent de grouper plusieurs fonctions, de partager des variables communes, de pouvoir créer des instances différentes, ainsi qu'une multitude d'autres fonctionnalités, et peuvent être appelées à la volée avec "spl_autoload_register". Bref c'est beaucoup plus puissant et pratique.

    Tu verras aussi que j'ai utilisé des index pour construire le tableau INCLUDES_FILES, c'est plus pratique et lisible. Et ça pique moins les yeux que ton "for" initial, non ?

    Pour l'ensemble du code, n'ayant pas tes données, il est possible que j'ai fais des erreurs puisque j'écris "à l'aveugle" sans pouvoir contrôler mais le principe est assez simple.

    Si tu arrives à mettre ça en place tu auras déjà pas mal progressé et fait un premier pas dans l'univers des classes. L'exemple je j'ai fait est très basique, mais on voit déjà que c'est pratique même en utilisation basique. Pour dire que tu aurais intérêt à t'intéresser aux classes si tu as du temps et que tu refais ton site car cela pourrait te rendre bien des services, et également en termes de possibilités d'évolution du code.

    Citation Envoyé par RinaBK Voir le message
    Ah bon, je ne savais pas Je pensais que par sécurité, il était préférable de convertir tous les caractères spéciaux avant l'enregistrement dans la DDB afin d'éviter que par exemple un utilisateur hack la base de données. Et j'utilisais d'office htmlentities car d'après la bible PHP de 2002, htmlentities convertit les caractères accentués contrairement à htmlspecialchars. Après, la bible PHP n'est plus d'actualité vu qu'elle est sortie en 2002 Mais j'avoue encore beaucoup l'utiliser, car elle est sacrément bien faite.
    Non cela n'empêche aucunement de hacker la base de donnée. L'histoire d'appliquer htmlentities dans les valeurs enregistrées en base de données c'était pour pouvoir les afficher telles quel dans le html sans utiliser htmlentities. On voyait souvent ça il y a 15/20 ans, mais c'était une fausse bonne idée. D'une part parce que cela encombre inutilement la base de données, ensuite tu dois passer obligatoirement par php pour décoder tes données ce qui peut poser des problèmes d'interopérabilité suivant les besoins, cela complqiue aussi les choses si tu fais des recherches en bdd, et enfin cela à tendance à rendre le développeur peu vigilent dans l'affichage de ses données dans le html alors qu'il faut l'être. J'en oublie peut-être c'est un vieux débat dont je ne me rappelle plus tous les détails.

    Sinon pour l'affichage, Utf-8 supporte les caractères accentués, donc htmlspecialchars est suffisant. Après je ne sais pas ce que tu appelles la bible php mais si elle date de 2002 tu peux la laisser dans un coin, ou tout du moins il est évident qu'elle n'est plus à jour. La vraie bible qui elle est mise à jour en temps réel est sur le site php.net et c'est sur ce site que tu tombes dans 99% des cas quand tu rentres le nom d'une fonction php suivi de "php" dans un moteur de recherche.

    Citation Envoyé par RinaBK Voir le message
    Concernant le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $valeur = str_replace('\'','&rsquo;',$valeur);
    Est-il encore bien nécessaire...
    Non effectivement.

    Citation Envoyé par RinaBK Voir le message
    Ceci-dit, j'ai tout de même un souci avec ma page... Je pense que j'ai dû faire une erreur à quelque part, car je n'ai plus de messages qui m’informent si les entrées sur les formulaires sont correctes ou non, s’ils ont bien été enregistrés, modifiées ou supprimés. Je cherche depuis un bon moment pour trouver ce qui ne va pas, mais je pense que je ne suis pas encore assez au clair avec cette méthode pour trouver d’où vient le souci. Mis à part cela, tout fonctionne parfaitement
    Alors tu as trouvé ? Je ne sais pas si c'est la seule erreur mais il y en avait une dans verifpost (regardes le second exemple de code de ce message).

    EDIT : Il y avait une autre erreur également dans la ligne sous le commentaire "// On fait également un test sur message pour ne pas remplir les champs du formulaire d'ajout si l'insertion est réussie", je viens de modifier mon code en conséquence.

  11. #11
    Membre confirmé Avatar de RinaBK
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2021
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 49
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2021
    Messages : 92
    Par défaut
    Bonjour ABCIWEB

    Je prends vraiment beaucoup de plaisir à échanger avec toi, car j'apprends tellement de chose et tu me fais découvrir tout autant, que cela me rends vraiment une femme très heureuse !! Je suis comblée de bonheur et je ne saurais comment te remercier du temps que tu passes pour m'aider !!! Je n'ai qu'une chose à dire, MERCI !!!



    Citation Envoyé par ABCIWEB Voir le message
    Attention dans ton code je vois que tu utilises les short tag "<?" pour ouvrir une session php, mais ils sont désactivés par défaut depuis un bon moment (je ne souviens plus de la version de php) pour éviter la confusion avec d'autres langages. A la place utilises "<?php". Par contre la syntaxe short tag "<?=" reste disponible pour faire afficher des variables dans le html.
    Décidément, j'ai des tonnes de versions PHP en retard Bon, sachant qu'à l'époque PHP était encore à ces débuts, il est normal qu'il se perfectionne de jour en jour. Plus possible de faire quelques années sabbatiques Ceci-dit, j'ai corrigé mes short tag.



    Citation Envoyé par ABCIWEB Voir le message
    Les deux fonctionnent évidemment, mais pour les débutants ou dans certains cas, les paramètres nommés sont plus aisés à utiliser car plus lisibles, alors qu'avec les marqueurs il faut faire attention à ce que les éléments du tableau que tu passes dans le excecute() soient dans le même ordre que celui des marqueurs.
    C'est pas faux, mais je n'ai pas peur de la difficulté et je suis du genre à persévérer, du moins, jusqu'à ce que je n'ai plus de solutions à disposition. Mais comme je le disais, mon manque d'expérience dans ce genre de méthode, n'aide pas vraiment. Mais je suis motivée et la motivation porte généralement ces fruits



    Citation Envoyé par ABCIWEB Voir le message
    Oui cela dit cette classe C_PDO n'est pas vraiment représentative de l'utilisation des classes puisque c'est une classe statique sans constructeur.

    Un autre avantage pratique des classes c'est que tu peux les appeler avec spl_autoload_register, pour peu que tu nommes ton fichier avec le même nom que la classe. Par exemple si tu as mis la classe C_PDO dans un fichier nommé C_PDO.php et que tu mets tes classes dans un répertoire nommé "Classes", il te suffira de faire en haut de la page d'appel: spl_autoload_register(function ($class) {require 'Classes/' . $class . '.php';}); pour charger les classes nécessaires du répertoire "Classes" en fonction de l'utilisation des classes dans ton code.
    Oui, mais c'est déjà un chouette aperçu ! Pour ce qui concerne l'appel des fichiers pour appeler les class, je l'ai justement lu hier après-midi Sur le moment, j'avais vaguement compris le système, mais grâce à toi, je le comprends bien mieux à présent !! Je pense qu'il me fallait un exemple visuel plutôt que de vagues explications comme le tuto sur lequel j'étais tombée. Grâce à l'exemple que tu m'as donné, c'est directement devenu plus clair et plus compréhensible et je t'en remercie ! Bon, pour l'instant, cela ne me sert pas à grand chose, car pour ma table adm_sites c'est la seule page qui la gère. Ceci-dit, j'ai déjà ma petite idée où je vais pouvoir utiliser et tester ce principe de class. Car sur le site, j'ai un système de messagerie pour les tutoriels et le futur forum que je veux réaliser. Donc, là je vais pouvoir me mettre en action ! ...Enfin, une fois que j'aurais terminé de revoir la partie admin


    Citation Envoyé par ABCIWEB Voir le message
    Non cela n'empêche aucunement de hacker la base de donnée. L'histoire d'appliquer htmlentities dans les valeurs enregistrées en base de données c'était pour pouvoir les afficher telles quel dans le html sans utiliser htmlentities. On voyait souvent ça il y a 15/20 ans, mais c'était une fausse bonne idée. D'une part parce que cela encombre inutilement la base de données, ensuite tu dois passer obligatoirement par php pour décoder tes données ce qui peut poser des problèmes d'interopérabilité suivant les besoins, cela complqiue aussi les choses si tu fais des recherches en bdd, et enfin cela à tendance à rendre le développeur peu vigilent dans l'affichage de ses données dans le html alors qu'il faut l'être. J'en oublie peut-être c'est un vieux débat dont je ne me rappelle plus tous les détails.

    Sinon pour l'affichage, Utf-8 supporte les caractères accentués, donc htmlspecialchars est suffisant. Après je ne sais pas ce que tu appelles la bible php mais si elle date de 2002 tu peux la laisser dans un coin, ou tout du moins il est évident qu'elle n'est plus à jour. La vraie bible qui elle est mise à jour en temps réel est sur le site php.net et c'est sur ce site que tu tombes dans 99% des cas quand tu rentres le nom d'une fonction php suivi de "php" dans un moteur de recherche.
    J'ai commencé à coder en PHP vers 1999/2000 donc je fais partie de cette génération là Et à cette époque, il y avait encore beaucoup de problème au niveau de l'affichage des accents suivant le navigateur ou encore le système d'exploitation qu'on utilisait. A cet époque, je bossais sur Mac et PC et question affichage c'était vraiment la galère. Mais je me rends bien compte que les choses se sont nettement améliorées sur ce point et c'est un vrai plaisir ! Bon, je ne suis plus du tout sur Mac aujourd'hui, vu que j'ai lâché au moment où Mac OS X est sorti.
    Concernant la bible PHP, je l'utilisais énormément à l'époque car le manuel PHP était uniquement en anglais et ne sachant pas l'anglais, j'avais beaucoup de mal. Il va de soit qu'aujourd'hui, la DOC PHP est traduite en français, ce qui est quand même bien pratique pour des personnes comme moi. Ceci-dit, cette bible fut mon livre de chevet durant pas mal de temps et il y a des habitudes qui ont du mal à changer ^^




    Citation Envoyé par ABCIWEB Voir le message
    Tu verras aussi que j'ai utilisé des index pour construire le tableau INCLUDES_FILES, c'est plus pratique et lisible. Et ça pique moins les yeux que ton "for" initial, non ?
    Oh oui effectivement, c'est bien mieux comme ça !! ..et si je regarde mon ancien code, je prends peur
    Je me rends compte que j'ai tendance à ajouter des lignes de codes en pensant les améliorer, et en fait, non seulement je complique les choses, mais beaucoup ne servent à pas grand chose.. En utilisant les bonnes fonctions et en les utilisant correctement tout devient subitement plus clair



    Citation Envoyé par ABCIWEB Voir le message
    Alors tu as trouvé ? Je ne sais pas si c'est la seule erreur mais il y en avait une dans verifpost (regardes le second exemple de code de ce message).

    EDIT : Il y avait une autre erreur également dans la ligne sous le commentaire "// On fait également un test sur message pour ne pas remplir les champs du formulaire d'ajout si l'insertion est réussie", je viens de modifier mon code en conséquence.
    J'avais fais quelques erreurs sur quelques noms de variables que j'ai corrigé. Ceci-dit, pour les deux où tu viens de me souffler doucement les réponses, je ne les avais pas remarquée
    Mais c'est corrigé !
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function verifpost ($post) {
    	$erreur = empty($post['nom']) ? "Le nom doit être renseignée" : null;
    	$erreur = empty($post['prefixe']) ? "Le préfixe doit être renseignée" : $erreur;
    	return $erreur;
    }
    Si j'ai bien compris mon erreur, la première ligne doit comporter null afin de spécifier que si la variable $post['nom'] est vide, la première condition doit être effectuée, donc, afficher le texte, sinon ne rien afficher. Ceci-dit, pour la 2e ligne, j'ai laissé la variable $erreur pour que si $post['prefixe'] est vide, afficher le message d'erreur, sinon afficher l'erreur de la première ligne, si erreur il y a.

    J'ai aussi corrigé la ligne :
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // On fait également un test sur message pour ne pas remplir les champs du formulaire d'ajout si l'insertion est réussie
    $ajout = isset($message,$_SESSION['ajout_sites']) ? $_SESSION['ajout_sites'] : null;

    En vue de la correction ci-dessus, j'ai observé le reste et j'ai remarqué que la variable $message n'était pas non plus sur la ligne de modification. Donc, cela m'a parut logique de la corriger aussi. Ceci-dit, je ne suis pas certaine que ma correction soit correct
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $modif = isset($message,$_SESSION['modif_sites']) ? $_SESSION['modif_sites'] : null;
    // $id_modif pour cibler le formulaire de modification
    $id_modif = isset($_SESSION['modif_sites']['id']) ? $_SESSION['modif_sites']['id'] : null;

    Je me suis rendue compte que l'affichage des messages d'erreurs ne se fait pas lorsque l'on oublie de renseigner des champs des formulaires, mais seulement si la modification est identique à ce qui est déjà enregistré dans la db. De plus, seul les messages d'erreurs de modifications des champs s'affichent et pas celle pour l'ajout. Ce qui fait que si l'on oublie de spécifier un champ, aucun message d'erreur n'apparait.
    J'ai voulu, dans un premier temps analyser les messages d'erreurs d'affichage pour l'ajout de nouvelles données, cela m'a redirigé vers la fonction inserersolution() qui retourne le numéro ID du dernier enregistrement effectué. Mais en cas d'erreur, ne renvoi rien. Dans mon ancienne manière de coder, j'aurais modifier le retour de la fonction comme ceci :
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    if ($stmt) { return $id; } else { return "Impossible d'enregistrer"; }
    Avec ce que tu m'as appris, je transformerais ce code en :
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    return $id ? $id : "Impossible d'enregistrer";
    La ligne de code semble être correct, mais même avec cela, si j'oublie de renseigner un champ, aucun message d'erreur ne s'affiche. De plus, si je me fie à ces deux lignes ci-dessous, ma modification de la fonction inserersolution() devient obsolète.
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    //Fonction de vérification
    $erreur = verifpost($post);
     
    // Si pas d'erreur on lance l'insertion en récupèrant l'id auto incrémenté
    $id = empty($erreur) ? inserersolution($post['prefixe'], $post['nom'], $post['infos']) : null;
    De là, cela me fait me retourner directement à la fonction verifpost() que je pensais avoir justement corrigée.
    Bref, j'ai beau regarder cette fonction à tors et à travers, tester différentes possibilités, mais rien à faire.. Si j'oublie de renseigner un champ, je n'obtiens aucun message d'erreur. J'ai suivi les trajet des variables $erreur et $_SESSION et rien trouvé qui n'allait pas... J'avoue que là, je ne vois pas pourquoi lorsque j'oublie un champ, je n'obtiens aucun message d'erreur et pourquoi dans la modification, j'obtiens une erreur seulement si l'entrée est identique à l’enregistrement dans la db. Mise à part les messages que devrait envoyer la fonction verifpost(), le reste fonctionne super bien.


    Ceci-dit, je vais encore continuer à chercher

    Voici quand même la page au complet :
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    <?php
     
    define('MAJ','27.01.2021 09:45:42');
     
     
     
     
     
    //	Initialisations des sessions
    session_start();
    if (!isSet($_SESSION['site'])) {
    	$siteID = '';
    	$sitePrefixe = '';
    	$siteName = '';
    } else {
    	$siteID = $_SESSION['site']['id'];
    	$sitePrefixe = $_SESSION['site']['prefixe'];
    	$siteName = $_SESSION['site']['nom'];
    }
     
     
     
     
     
     
    //	Inclusion des fichiers principaux
    define('INCLUDES_FILES', array('header'=>'header.php',
    													'footer'=>'footer.php',
    													'variables'=>'variables.php',
    													'fonctions'=>'fonctions.php'
    													));
     
    foreach (INCLUDES_FILES as $index => $files) {
    	if (!file_exists('includes/'.$files)) { header('Location: alerte.php?warning=500'); }
    	if ($index == 'variables' || $index == 'fonctions') { include('includes/'.$files); }
    }
     
     
     
     
     
     
     
     
    /*
    CREATE TABLE adm_sites (
    	id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    	prefixe VARCHAR(200) NULL,
    	nom VARCHAR(200) NOT NULL,
    	infos TEXT NULL,
    	PRIMARY KEY (id),
    	UNIQUE (prefixe)
    );
    */
     
     
     
    // Fonction d'insertion
    function inserersolution($prefixe, $nom, $infos) {
    	try {
    		$connexion = C_PDO::getC();
    		$requete = "INSERT INTO adm_sites (prefixe, nom, infos) VALUES(?,?,?)";
    		$stmt = $connexion->prepare($requete);
    		$stmt->execute([$prefixe, $nom, $infos]);
    		// Trouve l'id auto incrémenté
    		$id = $connexion->lastInsertId ();
    	}
    	catch(PDOException $e) {
    		exit($e->getMessage());
    	}
    	return $id;
    }
     
     
     
     
     
    // Fonction de modification
    function modifiersolution( $id, $prefixe, $nom, $infos) {
    	try {
    		$connexion = C_PDO::getC();
    		$requete = "UPDATE adm_sites SET prefixe = ?, nom = ?, infos = ? WHERE adm_sites.id = ?";
    		$stmt = $connexion->prepare($requete);
    		$stmt->execute([$prefixe, $nom, $infos, $id]);
    		$count = $stmt->rowCount();
    	}
    	catch(PDOException $e) {
    		exit($e->getMessage());
    	}
    	return $count ? "Modification réussie" : "Impossible de modifier"; 
    }
     
     
     
     
     
    // Fonction de suppression
    function supprimersolution($id) {
    	try {
    		$connexion = C_PDO::getC();
    		$requete = "DELETE FROM adm_sites WHERE adm_sites.id = ?";
    		$stmt = $connexion->prepare($requete);
    		$stmt->execute([$id]);
    		$count = $stmt->rowCount();
    	}
    	catch(PDOException $e) {
    		exit($e->getMessage());
    	}
    	return $count ? "Supression réussie" : "Impossible de supprimer"; 
    }
     
     
     
     
     
     
     
    // function de vérification commune à l'ajout et à la modification
    function verifpost($post) {
    	$erreur = empty($post['nom']) ? "Le nom doit être renseignée" : null;
    	$erreur = empty($post['prefixe']) ? "Le préfixe doit être renseignée" : $erreur;
    	return $erreur;
    }
     
     
     
     
     
     
    // Ajout en provenance du formulaire
    if (isset($_POST["ajout"]) && $_POST["ajout"] == "ajouter") {
     
    	// Enregistre le post en session pour éviter d'avoir à ressaisir tous les champs en cas d'erreur
    	$_SESSION['ajout_sites'] = $_POST;
     
    	//J'applique trim sur les éléments du tableau pour supprimer les espaces blancs en début et fin de chaine qui pourraient être rentrés inopinément par l'utilisateur
    	$post = array_map('trim',$_POST);
     
    	//Fonction de vérification
    	$erreur = verifpost($post);
     
    	// Si pas d'erreur on lance l'insertion en récupèrant l'id auto incrémenté
    	$id = empty($erreur) ? inserersolution($post['prefixe'], $post['nom'], $post['infos']) : null;
     
    	// On affiche un message d'erreur uniquement si nécéssaire. Si OK le header renverra vers l'élément inséré
    	$_SESSION['message_sites'] = isset($erreur) ? $erreur : null;
     
    	// Header pour éviter les multiples post et le messgae du navigateur si on réaffiche cette page. L'ancre id sert pour aller à l'élément inséré
    	header('Location: '.$_SERVER['PHP_SELF'].'#lent'.$id);exit;
    }
     
     
     
     
    // Modification en provenance du formulaire
    if (isset($_POST["modif"]) && $_POST["modif"] == "modifier") {
    	$_SESSION['modif_sites'] = $_POST;
    	$post = array_map('trim',$_POST);
    	$erreur = verifpost($post);
    	$_SESSION['message_sites'] = empty($erreur) ? modifiersolution($post['id'], $post['prefixe'], $post['nom'], $post['infos']) : $erreur;
    	header('Location: '.$_SERVER['PHP_SELF'].'#lent'.$post['id']);exit;
    }
     
     
     
    // Suppression en provenance du formulaire
    if (isset($_POST["suppr"]) && $_POST["suppr"] == "supprimer") {
    	$_SESSION['message_sites'] = supprimersolution($_POST['id']);
    	header('Location: '.$_SERVER['PHP_SELF']);exit;
    }
     
     
     
    // Variables qui pourront être affichées dans le html pour les ajouts, modifications et suppressions
    $message = isset($_SESSION['message_sites']) ? $_SESSION['message_sites'] : null;
     
    $modif = isset($message,$_SESSION['modif_sites']) ? $_SESSION['modif_sites'] : null;
    // $id_modif pour cibler le formulaire de modification
    $id_modif = isset($_SESSION['modif_sites']['id']) ? $_SESSION['modif_sites']['id'] : null;
     
    // On fait également un test sur message pour ne pas remplir les champs du formulaire d'ajout si l'insertion est réussie
    $ajout = isset($message,$_SESSION['ajout_sites']) ? $_SESSION['ajout_sites'] : null;
     
    // On efface les variables de session pour qu'elles ne soient définies qu'une fois
    unset($_SESSION['message_sites'],$_SESSION['modif_sites'],$_SESSION['ajout_sites']);
     
     
     
     
    //Affichage des résultats en alimentant (hydratant) les champs des formulaires de modification et suppression
    $select = "SELECT id, prefixe, nom, infos FROM adm_sites ORDER BY id";
    $connexion = C_PDO::getC();
    // Pas besoin de requête préparée ici puisqu'il n'y a pas de variables utilisateur dans la requête
    $read = $connexion->query($select);
     
     
     
    ?>
     
    <!DOCTYPE html>
    <html lang="fr-CH">
    <head>
    	<title>Administrations</title>
    	<link rel="stylesheet" href="images/designs/styles.css">
    	<script src="https://kit.fontawesome.com/2e9b34a81e.js"></script>
    	<style>
    form p {
    	margin:0.5em;
    	padding:0;
    }
    form .label {
    	display:inline-block;
    	width:120px;
    }
    #message {
    	border:1px solid black;
    	background:#0CF;
    	font-size:1.5em;
    	text-align:center;
    }
    .saisie {
    	width: 400px;
    }
    button {
    	padding: 3px;
    	width: 100px;
    }
    </style>
    </head>
     
     
    <body>
    <? include('includes/'.INCLUDES_FILES['header']); ?>
     
     
     
     
    <h1>Gestion des Sites</h1>
    <div align="justify"  style="width: 600px;">
    	Concernant le nom du site ainsi que son pr&eacute;fixe, il serait important de ne pas mettre d&rsquo;accents, 
    	de caract&egrave;res sp&eacute;ciaux ou d&rsquo;espace. Il faudrait plut&ocirc;t jouer entre les majuscules 
    	et les minuscules pour diff&eacute;rencier les mots. En revanche pour les infos, aucun soucis, tous les 
    	caract&egrave;res sont accept&eacute;s et pr&eacute;senteront aucun danger niveau codage.
    </div>
    <br />
    <a href="sites.php?gestion=new" target="_parent" title="Ajouter une entr&eacute;e"><i class="fas fa-folder-plus" style="font-size: 30px;"></i></a>
    <br />
     
     
     
    <?php
    // On fait afficher ici les messages de suppression et d'ajout mais pas ceux de modification qui seront affichés dans le formulaire concerné
    if(isset($message) && empty($id_modif)) echo '<p id="message">'.htmlspecialchars($message).'</p>';
     
     
     
    //if (!empty($_GET['gestion'])) {
    	?>
    	<br />
    	<form action="#" method="POST">
    		<fieldset style="width: 600px;">
    			<legend>Ajouter</legend>
    			<p><label><span class="label">Nom : </span><input type="text" name="nom" value="<?=isset($ajout['nom']) ? htmlspecialchars($ajout['nom']) : null;?>" class="saisie" /></label></p>
    			<p><label><span class="label">Prefixe : </span><input type="text" name="prefixe" value="<?=isset($ajout['prefixe']) ? htmlspecialchars($ajout['prefixe']) : null;?>" class="saisie" /></label></p>
    			<p><label><span class="label">Infos : </span><textarea name="infos" class="saisie"><?=isset($ajout['infos']) ? htmlspecialchars($ajout['infos']) : null;?></textarea></label></p>
    			<div align="center"><button type="submit" name="ajout" value="ajouter">Ajouter</button></div>
    		</fieldset>
    	</form>
    	<br />
    	<?php
    //}
     
     
     
     
    foreach ($read as $row) {
    	?>
    	<!-- l'id sert d'ancre de redirection pour les ajouts / modifications (Attention de ne pas utiliser d'id statique dans ces lignes puisque c'est une boucle)-->
    	<br />
    	<form action="#" method="post" style="margin-bottom:0.5em" id="lent<?= isset($row->id)? htmlspecialchars($row->id) : ''?>">
    		<fieldset style="width: 600px;">
    			<!-- message des modifications -->
    			<legend>Modifier/Supprimer : <b><?=htmlspecialchars($row->nom);?></b></legend>
    			<?= isset($id_modif, $message) && $row->id == $id_modif ? '<p style="color:blue">'.htmlspecialchars($message).'<p>' : ''?>
    			<input type="hidden" name="id" value="<?= htmlspecialchars($row->id)?>" >
    			<p><label><span class="label">Nom : </span><input type="text" name="nom" value="<?= $row->id == $id_modif ? htmlspecialchars($modif['nom']) : htmlspecialchars($row->nom) ?>" class="saisie" /></label></p>
    			<p><label><span class="label">Prefixe : </span><input type="text" name="prefixe" value="<?= $row->id == $id_modif ? htmlspecialchars($modif['prefixe']) : htmlspecialchars($row->prefixe) ?>" class="saisie" /></label></p>
    			<p><label><span class="label">Infos : </span><textarea name="infos" class="saisie"><?= $row->id == $id_modif ? htmlspecialchars($modif['infos']) : htmlspecialchars($row->infos) ?></textarea></label></p>
    			<div align="center">
    				<button type="submit" name="modif" value="modifier">Modifier</button>
    				<button type="submit" name="suppr" value="supprimer" style="margin-left:2em">Supprimer</button>
    			</div>
    		</fieldset>
    	</form>
    	<?php
    }
    ?>
     
     
     
    <? include('includes/'.INCLUDES_FILES['footer']); ?>
    </body>
    </html>

  12. #12
    Membre confirmé Avatar de RinaBK
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2021
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 49
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2021
    Messages : 92
    Par défaut
    J'ai passé toute la journée à revoir et tenter de corriger la page afin de trouver pourquoi les messages d'erreur lors de la saisi du formulaire ne s'affichait pas. J'avais fais quelques erreur au niveau des variables, que j'ai bien évidement corrigé. Ceci-dit, lorsque j'oublie de renseigner un champ du formulaire, j'ai une ligne qui s'affiche, mais aucun message..

    J'ai supprimé ensuite les 2 class CSS que j'avais ajouté :
    Code CSS : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    .saisie {
    	width: 400px;
    }
    button {
    	padding: 3px;
    	width: 100px;
    }
    Depuis que j'ai supprimé ces 2 class CSS, j'ai pu obtenir mon premier message en supprimant une entrée déjà enregistrée dans la DDB qui me disait que la suppression c'est passée correctement. Seulement, c'est le seul et unique message que j'obtiens

    Je continue mes recherches

  13. #13
    Expert confirmé

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 416
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 416
    Par défaut
    Citation Envoyé par RinaBKJe
    prends vraiment beaucoup de plaisir à échanger avec toi, car j'apprends tellement de chose et tu me fais découvrir tout autant, que cela me rends vraiment une femme très heureuse !! Je suis comblée de bonheur et je ne saurais comment te remercier du temps que tu passes pour m'aider !!! Je n'ai qu'une chose à dire, MERCI !!!
    Merci ça fait plaisir de savoir qu'on sert à quelque chose.

    Citation Envoyé par RinaBK Voir le message
    J'ai passé toute la journée à revoir et tenter de corriger la page afin de trouver pourquoi les messages d'erreur lors de la saisi du formulaire ne s'affichait pas.
    Une journée c'est beaucoup pour un code si simple... Il te manque sans doute les bonnes méthodes pour le débugage.
    1/ L'affichage des erreurs est-il activé dans ton serveur d'évaluation, au passage tu utilises quoi, wampserver, easyphp, et quelle version de php ?

    2/ Si aucune erreur ne s'affiche quand l'affichage des erreurs est activé, fais des var_dump($mavariable);exit; à différents endroits stratégiques de ton code (mais un à la fois puisque "exit" sort du code) pour suivre la progression de ton code et vérifier que tu as les valeurs attendues.

    3/ Quand ça devient trop compliqué, isoles les différentes parties de ton code pour faire des tests dans des pages de test distinctes, par exemple comme ci-dessous :

    Chez moi, ce code fonctionne (j'ai créé une table avec tes quatre champs). J'ai défini la variable $_GET['gestion'] en haut de ta page (qu'il faudra supprimer par la suite) pour faire le test sans trop modifier le reste du code, et bien entendu j'ai mis en commentaire l'inclusion de tes fichiers externes.

    Sinon on est bien d'accord que la variable $_GET['gestion'] ne doit pas être utilisée comme variable de sécurité, car il serait très facile de modifier l'url pour avoir accès à l'ajout de site.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    <?php 
    session_start();
     
    // Pour le test :
    $_GET['gestion']=1;
     
    // Charge les classes php avec spl_autoload_register
    // spl_autoload_register(function ($class) {require 'Classes/' . $class . '.php';});
     
    define('MAJ','26.01.2021 10:26:29');
     
    //	Initialisations des variables de sessions
    if (!isset($_SESSION['site'])) {
    	$siteID = '';
    	$sitePrefixe = '';
    	$siteName = '';
    } else {
    	$siteID = $_SESSION['site']['id'];
    	$sitePrefixe = $_SESSION['site']['prefixe'];
    	$siteName = $_SESSION['site']['nom'];
    }
     
     
    //	Inclusions des fichiers primaires
    define('INCLUDES_FILES', array('header'=>'header.php'
    						,'footer'=>'footer.php'
    						,'variables'=>'variables.php'
    						,'fonctions'=>'fonctions.php'
    						));
     
    /*
    foreach (INCLUDES_FILES as $index => $files) {
    	if (!file_exists('includes/'.$files)) { header('Location: alerte.php?warning=500'); }
    	if ($index == 'variables' || $index == 'fonctions') { include('includes/'.$files); } 
    }
    */
     
    class C_PDO
    {
    	private static $connexion;
     
    	private static function newC_PDO() 
    	{
    		// VARIABLES A REMPLACER
    		$hostname = "localhost";
    		$database = "alainbweb";
    		$username = "root";
    		$password = "";
     
    		// Options de configuration PDO utilisées dans les exemples
    		$pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;		
    		$pdo_options[PDO::ATTR_EMULATE_PREPARES] = false;
    		$pdo_options[PDO::ATTR_DEFAULT_FETCH_MODE] = PDO::FETCH_OBJ;
     
    		self::$connexion  = new PDO('mysql:host='.$hostname.';dbname='.$database.';charset=utf8', $username, $password, $pdo_options);
    	}
     
    	public static function getC() 
    	{
    		if(self::$connexion == NULL) {self::newC_PDO();}
    		return self::$connexion;
    	}	 
    }
     
     
    class AdminCrud {
     
    	private $connect;
     
    	// S'exécute lorsqu'on instancie la classe
    	public function __construct($connexion)
    	{
    		$this->connect = $connexion;
    	}
     
    	// Fonction de modification
    	public function modifier($id, $prefixe, $nom, $infos) {
    		try {
    			$requete = "UPDATE adm_sites SET prefixe = ?, nom = ?, infos = ? WHERE adm_sites.id = ?";
    			$stmt = $this->connect->prepare($requete);
    			$stmt->execute([$prefixe, $nom, $infos, $id]);
    			$count = $stmt->rowCount();
    		}
    		catch(PDOException $e) {
    			exit($e->getMessage());
    		}
    		return $count ? "Modification réussie" : "Impossible de modifier"; 
    	}
     
     
    	// Fonction de suppression
    	public function supprimer($id) {
    		try {
    			$requete = "DELETE FROM adm_sites WHERE adm_sites.id = ?";
    			$stmt = $this->connect->prepare($requete);
    			$stmt->execute([$id]);
    			$count = $stmt->rowCount();
    		}
    		catch(PDOException $e) {
    			exit($e->getMessage());
    		}
    		return $count ? "Supression réussie" : "Impossible de supprimer"; 
    	}
     
     
    	// Fonction d'insertion
    	public function inserer ($prefixe, $nom, $infos) {
    		try {
    			$requete = "INSERT INTO adm_sites (prefixe, nom, infos) VALUES(?, ?,?)";
    			$stmt = $this->connect->prepare($requete);
    			$stmt->execute([$prefixe, $nom, $infos]);
    			// Trouve l'id auto incrémenté
    			$id = $this->connect->lastInsertId ();
    		}
    		catch(PDOException $e) {
    			exit($e->getMessage());
    		}
    		return $id;
    	}
     
    	// Fonction d'insertion
    	public function lire () {
    		try {
    			$select = "SELECT id, prefixe, nom, infos FROM adm_sites ORDER BY id";
    			// Pas besoin de requête préparée ici puisqu'il n'y a pas de variables utilisateur dans la requête
    			//var_dump(C_PDO::getC());exit;
    			$read = $this->connect->query($select);
    		}
    		catch(PDOException $e) {
    			exit($e->getMessage());
    		}
    		return $read;
    	}
    }
     
     
     
    // Initialise la classe AdminCrud en passant la connexion en paramètre
    $crud = new AdminCrud(C_PDO::getC());
     
     
    // function de vérification commune à l'ajout et à la modification
    function verifpost ($post) {
    	$erreur = empty($post['nom']) ? "Le nom doit être renseignée" : null;
    	$erreur = empty($post['prefixe']) ? "Le préfixe doit être renseignée" : $erreur;
    	return $erreur;
    }
     
     
    // Ajout en provenance du formulaire
    if (isset($_POST["ajout"]) && $_POST["ajout"] == "ajouter") {
     
    	// Enregistre le post en session pour éviter d'avoir à ressaisir tous les champs en cas d'erreur
    	$_SESSION['ajout_sites'] = $_POST;
     
    	//J'applique trim sur les éléments du tableau pour supprimer les espaces blancs en début et fin de chaine qui pourraient être rentrés inopinément par l'utilisateur
    	$post = array_map('trim',$_POST);
     
    	//Fonction de vérification
    	$erreur = verifpost($post);
     
    	// Si pas d'erreur on lance l'insertion en récupèrant l'id auto incrémenté
    	$id = empty($erreur) ? $crud->inserer($post['prefixe'], $post['nom'], $post['infos']) : null;
     
    	// On affiche un message d'erreur uniquement si nécéssaire. Si OK le header renverra vers l'élément inséré
    	$_SESSION['message_sites'] = isset($erreur) ? $erreur : null;
     
    	// Header pour éviter les multiples post et le messgae du navigateur si on réaffiche cette page. L'ancre id sert pour aller à l'élément inséré
    	header('Location: '.$_SERVER['PHP_SELF'].'?gestion=new#admin'.$id);exit;
    }
     
     
    // Modification en provenance du formulaire
    if (isset($_POST["modif"]) && $_POST["modif"] == "modifier") {
    	$_SESSION['modif_sites'] = $_POST;
    	$post = array_map('trim',$_POST);
    	$erreur = verifpost($post);
    	$_SESSION['message_sites'] = empty($erreur) ? $crud->modifier($post['id'], $post['prefixe'], $post['nom'], $post['infos']) : $erreur;
    	header('Location: '.$_SERVER['PHP_SELF'].'#admin'.$post['id']);exit;
    }
     
     
     
    // Suppression en provenance du formulaire
    if (isset($_POST["suppr"]) && $_POST["suppr"] == "supprimer") {
    	$_SESSION['message_sites'] = $crud->supprimer($_POST['id']);
    	header('Location: '.$_SERVER['PHP_SELF']);exit;
    }
     
     
    // Variables qui pourront être affichées dans le html pour les ajouts, modifications et suppressions
    $message = isset($_SESSION['message_sites']) ? $_SESSION['message_sites'] : null;
     
    $modif = isset($_SESSION['modif_sites']) ? $_SESSION['modif_sites'] : null;
    // $id_modif pour cibler le formulaire de modification
    $id_modif = isset($_SESSION['modif_sites']['id']) ? $_SESSION['modif_sites']['id'] : null;
     
    // On fait également un test sur message pour ne pas remplir les champs du formulaire d'ajout si l'insertion est réussie
    $ajout = isset($message,$_SESSION['ajout_sites']) ? $_SESSION['ajout_sites'] : null;
     
    // On efface les variables de session pour qu'elles ne soient définies qu'une fois
    unset($_SESSION['message_sites'],$_SESSION['modif_sites'],$_SESSION['ajout_sites']);
     
     
    //Affichage des résultats en alimentant (hydratant) les champs des formulaires de modification et suppression
    $read = $crud->lire();
    ?>
    <!DOCTYPE html>
    <html lang="fr-CH">
    <head>
    	<title>Administrations</title>
        <!--
    	<link rel="stylesheet" href="images/designs/styles.css">
    	<script src="https://kit.fontawesome.com/2e9b34a81e.js"></script>-->
    	<style>
    form p {
    	margin:0.5em;
    	padding:0;
    }
    form .label {
    	display:inline-block;
    	width:120px;
    }
    #message {
    	border:1px solid black;
    	background:#0CF;
    	font-size:1.5em;
    	text-align:center;
    }
    .saisie {
    	width: 400px;
    }
    button {
    	padding: 3px;
    	width: 100px;
    }
    </style>
     
    </head>
     
     
    <body>
    <?php //include('includes/'.INCLUDES_FILES['header']); ?>
     
     <h1>Gestion des Sites</h1>
    <div align="justify"  style="width: 600px;">
    	Concernant le nom du site ainsi que son pr&eacute;fixe, il serait important de ne pas mettre d&rsquo;accents, 
    	de caract&egrave;res sp&eacute;ciaux ou d&rsquo;espace. Il faudrait plut&ocirc;t jouer entre les majuscules 
    	et les minuscules pour diff&eacute;rencier les mots. En revanche pour les infos, aucun soucis, tous les 
    	caract&egrave;res sont accept&eacute;s et pr&eacute;senteront aucun danger niveau codage.
    </div>
    <br />
    <a href="sites.php?gestion=new" target="_parent" title="Ajouter une entr&eacute;e"><i class="fas fa-folder-plus" style="font-size: 30px;"></i></a>
    <br />
     
     
     <?php
    // On fait afficher ici les messages de suppression et d'ajout mais pas ceux de modification qui seront affichés dans le formulaire concerné
    if(isset($message) && empty($id_modif)) echo '<p id="message">'.htmlspecialchars($message).'</p>';
     
    if (!empty($_GET['gestion'])) {
    	?>
    	<br />
    	<form action="#" method="POST">
    		<fieldset style="width: 600px;">
    			<legend>Ajouter</legend>
    			<p><label><span class="label">Nom : </span><input type="text" name="nom" value="<?=isset($ajout['nom']) ? htmlspecialchars($ajout['nom']) : null;?>" class="saisie" /></label></p>
    			<p><label><span class="label">Prefixe : </span><input type="text" name="prefixe" value="<?=isset($ajout['prefixe']) ? htmlspecialchars($ajout['prefixe']) : null;?>" class="saisie" /></label></p>
    			<p><label><span class="label">Infos : </span><textarea name="infos" class="saisie"><?=isset($ajout['infos']) ? htmlspecialchars($ajout['infos']) : null;?></textarea></label></p>
    			<div align="center"><button type="submit" name="ajout" value="ajouter">Ajouter</button></div>
    		</fieldset>
    	</form>
    	<br />
    	<?php
    }
     
    foreach ($read as $row) {
     
    	?>
    	<!-- l'id sert d'ancre de redirection pour les ajouts / modifications (Attention de ne pas utiliser d'id statique dans ces lignes puisque c'est une boucle)-->
    	<br />
    	<form action="#" method="post" style="margin-bottom:0.5em" id="admin<?= isset($row->id)? htmlspecialchars($row->id) : ''?>">
    		<fieldset style="width: 600px;">
    			<!-- message des modifications -->
    			<legend>Modifier/Supprimer : <b><?=htmlspecialchars($row->nom);?></b></legend>
    			<?= isset($id_modif, $message) && $row->id == $id_modif ? '<p style="color:blue">'.htmlspecialchars($message).'<p>' : ''?>
    			<input type="hidden" name="id" value="<?= htmlspecialchars($row->id)?>" >
    			<p><label><span class="label">Nom : </span><input type="text" name="nom" value="<?= $row->id == $id_modif ? htmlspecialchars($modif['nom']) : htmlspecialchars($row->nom) ?>" class="saisie" /></label></p>
    			<p><label><span class="label">Prefixe : </span><input type="text" name="prefixe" value="<?= $row->id == $id_modif ? htmlspecialchars($modif['prefixe']) : htmlspecialchars($row->prefixe) ?>" class="saisie" /></label></p>
    			<p><label><span class="label">Infos : </span><textarea name="infos" class="saisie"><?= $row->id == $id_modif ? htmlspecialchars($modif['infos']) : htmlspecialchars($row->infos) ?></textarea></label></p>
    			<div align="center">
    				<button type="submit" name="modif" value="modifier">Modifier</button>
    				<button type="submit" name="suppr" value="supprimer" style="margin-left:2em">Supprimer</button>
    			</div>
    		</fieldset>
    	</form>
    	<?php
    }
    ?>
     
    <?php //include('includes/'.INCLUDES_FILES['footer']); ?>
    </body>
    </html>
    EDIT: Ah oui au passage mon précédent exemple avec la classe "AdminCrud" ne pouvait pas fonctionner car j'avais écrit "contruct" à la place de "construct", c'est corrigé.

    RE EDIT: Autre chose, le message "Impossible de modifier" n'est pas le plus pertinent, car en fait si on clique sur le bouton modifier sans changer aucune donnée, le rowcount va retourner 0 puisqu'aucun champ n'a été modifié donc ce message sera affiché. Mais ce n'est pas pour autant qu'il est impossible de modifier, c'est juste que l'on a rien modifié, c'est pour cela que j'avais mis à l'origine "Aucune modification n'a été faite".

    Par ailleurs tu utilisais encore des short tag "<?" dans tes includes (et fais attention aussi pour la fermeture de conditions php dans le html, bien faire "<?php } ?>" ). Le plus simple peut-être est de faire une recherche avec ton éditeur de texte sur "<?" et si ce n'est pas suivi de "=" ou de "php" c'est certainement qu'il y a problème.

  14. #14
    Membre confirmé Avatar de RinaBK
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2021
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 49
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2021
    Messages : 92
    Par défaut
    Bonjour ABCIWEB


    Citation Envoyé par ABCIWEB Voir le message
    Une journée c'est beaucoup pour un code si simple... Il te manque sans doute les bonnes méthodes pour le débugage.
    1/ L'affichage des erreurs est-il activé dans ton serveur d'évaluation, au passage tu utilises quoi, wampserver, easyphp, et quelle version de php ?
    Je suis chez OVH et pour afficher les gestions d’erreur, je dois simplement remplacer la variable d’environnement de ‘production’ à ‘development’ de mon fichier de configurations du serveur. Sur ce même fichier, je peux aussi choisir la version PHP que je souhaite utiliser entre 8.0 (version beta) / 7.2. Personnellement, cela ne me pose aucun problème de mettre la version 8, même si elle est en version beta. D’ailleurs, je la change et je peux toujours revenir à la 7.2 si nécessaire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    app.engine=php
    app.engine.version=7.2
     
    http.firewall=none
    environment=development
    Maintenant, pour le reste, j’utilise uniquement MySQL, Ultra-Edit et FileZilla. Du moins quand je bosse directement via mon serveur (ce que je fais généralement, bien que je ne devrais pas). En local, j’ai EasyPHP, mais je l’utilise que très rarement. Pour ce qui est de mon serveur chez OVH, je ne peux pas t’en dire plus, ça fait depuis l’an 2000 que je suis cliente chez eux et j’ai vu tellement de changement, que je dois avouer que j’ai perdu le fil depuis longtemps. Tout ce que je peux dire c’est que j’ai l’offre ‘pro2014’ qui est le MX Plan Développeur Cloud Web 1





    Citation Envoyé par ABCIWEB Voir le message
    2/ Si aucune erreur ne s'affiche quand l'affichage des erreurs est activé, fais des var_dump($mavariable);exit; à différents endroits stratégiques de ton code (mais un à la fois puisque "exit" sort du code) pour suivre la progression de ton code et vérifier que tu as les valeurs attendues.
    Alors pour bien faire les choses, je suis passée en local avec EasyPHP, histoire de voir si le problème venait du serveur chez OVH. J’ai exactement le même problème en local. Je sais que ce n’est pas le problème de la version de EasyPHP, je l’ai téléchargée à Noël et j’ai la toute dernière version.
    Ceci-dit, j’ai enfin trouvé d’où vient le souci. Ou du moins, je pense avoir trouvé. Il s’agit de cette ligne-là :
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     // On fait afficher ici les messages de suppression et d'ajout mais pas ceux de modification qui seront affichés dans le formulaire concerné
    if(isset($message) && empty($id_modif)) echo '<p id="message">'.htmlspecialchars($message).'</p>';
     
    var_dump($message);
    var_dump($id_modif);
    Bien que la variable $message comporte le message d’erreur, et que la variable $id_modif est à NULL, rien ne s’affiche. J’ai essayé de modifier la ligne de plusieurs façons différentes, mais rien à faire… Seule chose qui s’affiche est la ligne apportée par le style CSS ( #message). Pour finir, j’ai placé la variable $message toute seule et le message c’est enfin affiché. D’après ce que j’ai pu voir, se serait la fonction htmlspecialchars() qui poserait problème. Je l’ai donc supprimée et comme par magie, les messages d’alerte s’affichent correctement. J’ai donc, essayé d’utiliser htmlentities() juste pour voir et faire en sorte que les caractère accentués s’affichent correctement, mais là aussi, plus rien ne s’affiche… C’est comme si ces fonctions PHP étaient devenue obsolète et refusait tout affichage.



    Citation Envoyé par ABCIWEB Voir le message
    3/ Quand ça devient trop compliqué, isoles les différentes parties de ton code pour faire des tests dans des pages de test distinctes, par exemple comme ci-dessous :
    C’est ce que j’avais fait mais malgré cela, impossible de trouver la cause du souci. En utilisant var_dump ce fut un jeu d’enfant !




    Citation Envoyé par ABCIWEB Voir le message
    Sinon on est bien d'accord que la variable $_GET['gestion'] ne doit pas être utilisée comme variable de sécurité, car il serait très facile de modifier l'url pour avoir accès à l'ajout de site.
    La variable $_GET['gestion'] est juste pour faire afficher le formulaire d’ajout, car je n’ajoute pas souvent de nouveaux sites, mais ça m’arrive plus souvent de modifier. Cela m’évite de me tromper et aussi, cela prend moins de place à l’affichage si je veux juste récupérer le préfixe d’un site.

    A savoir que ma partie administration, il y a que moi qui l’utilise. Elle ne se trouve même pas dans le même répertoire du(des) site(s) ‘public’. Généralement, on réalise une partie administration associée à chaque site. Moi j’ai préféré pour me faciliter la tâche d’en réaliser qu’une seule qui me permet de gérer chaque site que je réalise. A l’époque, j’avais 7 sites web à mon actif et ça devenait saoulant de passer de partie admin à une autre partie admin..

    Il y a aussi un autre point qui est très utile, c’est que les sites que je réalise ont souvent les mêmes fonctions. A l’époque, j’avais réalisé des fichiers avec certaines fonctions que je greffais sur chaque partie admin.. Un peu comme tu m’as montré avec les class. J’ai vite abandonné cette technique car j’ai trouvé une méthode qui me convient mieux. Par exemple, j’ai réalisé une page pour la gestion des News. Il me suffit simplement de sélectionner le site par le biais de mes préfixes pour gérer les News sur un site. La page reste la même, c’est juste le préfixe qui va modifier les noms de mes tables, etc. Simple et rapide ! Surtout lorsque je dois modifier un page.



    Citation Envoyé par ABCIWEB Voir le message
    RE EDIT: Autre chose, le message "Impossible de modifier" n'est pas le plus pertinent, car en fait si on clique sur le bouton modifier sans changer aucune donnée, le rowcount va retourner 0 puisqu'aucun champ n'a été modifié donc ce message sera affiché. Mais ce n'est pas pour autant qu'il est impossible de modifier, c'est juste que l'on a rien modifié, c'est pour cela que j'avais mis à l'origine "Aucune modification n'a été faite".
    J’avais bien compris cela Mais pour moi c’est juste plus clair aux niveau visuel. Car j’ai pris l’habitude de me mettre ces mots. Pour moi, ça veut juste dire que la modification n’a pas été faite. Vu que cette partie admin je suis la seule à l’utiliser, c’est un détail. Après, il est clair que si se serait une partie public, le message aurait été bien différent.




    Citation Envoyé par ABCIWEB Voir le message
    Par ailleurs tu utilisais encore des short tag "<?" dans tes includes (et fais attention aussi pour la fermeture de conditions php dans le html, bien faire "<?php } ?>" ). Le plus simple peut-être est de faire une recherche avec ton éditeur de texte sur "<?" et si ce n'est pas suivi de "=" ou de "php" c'est certainement qu'il y a problème.
    Oui, je les modifié partout ! Sauf quand j’utilise PHP dans le contenu de la page sous forme <?=$variable;?>
    Voilà, la page fonctionne à présent super bien ! D'ailleurs, voici le code source :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    <?php
    define('MAJ','28.01.2021 08:13:42');
     
     
     
     
     
     
    //	Initialisations des sessions
    session_start();
     
    if (!isSet($_SESSION['site'])) {
    	$siteID = '';
    	$sitePrefixe = '';
    	$siteName = '';
    } else {
    	$siteID = $_SESSION['site']['id'];
    	$sitePrefixe = $_SESSION['site']['prefixe'];
    	$siteName = $_SESSION['site']['nom'];
    }
     
     
     
     
     
     
    //	Inclusion des fichiers principaux
    define('INCLUDES_FILES', array('header'=>'header.php',
    								'footer'=>'footer.php',
    								'variables'=>'variables.php',
    								'fonctions'=>'fonctions.php'
    								));
     
    foreach (INCLUDES_FILES as $index => $files) {
    	if (!file_exists('includes/'.$files)) { header('Location: alerte.php?warning=500'); }
    	if ($index == 'variables' || $index == 'fonctions') { include('includes/'.$files); }
    }
     
     
     
     
     
     
     
     
    /*
    CREATE TABLE adm_sites (
    	id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    	prefixe VARCHAR(200) NULL,
    	nom VARCHAR(200) NOT NULL,
    	infos TEXT NULL,
    	PRIMARY KEY (id),
    	UNIQUE (prefixe)
    );
    */
     
     
     
    // Fonction d'insertion
    function inserersolution($vPrefixe, $vNom, $vInfos) {
    	try {
    		$connexion = C_PDO::getC();
    		$requete = "INSERT INTO adm_sites (prefixe, nom, infos) VALUES(?, ?,?)";
    		$stmt = $connexion->prepare($requete);
    		$stmt->execute([$vPrefixe, $vNom, $vInfos]);
    		// Trouve l'id auto incrémenté
    		$id = $connexion->lastInsertId ();
    	}
    	catch(PDOException $e) {
    		exit($e->getMessage());
    	}
    	return $id; 
    }
     
     
     
     
    // Fonction de modification
    function modifiersolution( $id, $vPrefixe, $vNom, $vInfos) {
    	try {
    		$connexion = C_PDO::getC();
    		$requete = "UPDATE adm_sites SET prefixe = ?, nom = ?, infos = ? WHERE adm_sites.id = ?";
    		$stmt = $connexion->prepare($requete);
    		$stmt->execute([$vPrefixe, $vNom, $vInfos, $id]);
    		$count = $stmt->rowCount();
    	}
    	catch(PDOException $e) {
    		exit($e->getMessage());
    	}
    	return $count ? "Mise &agrave; jour OK" : "Aucune mise &agrave; jour n'a &eacute;t&eacute; faite"; 
    }
     
     
     
     
    //	Fonction de suppression
    function supprimersolution($id) {
    	try {
    		$connexion = C_PDO::getC();
    		$requete = "DELETE FROM adm_sites WHERE adm_sites.id = ?";
    		$stmt = $connexion->prepare($requete);
    		$stmt->execute([$id]);
    		$count = $stmt->rowCount();
    	}
    	catch(PDOException $e) {
    		exit($e->getMessage());
    	}
    	return $count ? "Supression OK" : "Aucune suppression n'a &eacute;t&eacute; faite"; 
    }
     
     
     
     
    // function de vérification commune à l'ajout et à la modification
    function verifpost ($post) {
    	$erreur = empty($post['vPrefixe']) ? "Le prefixe doit &ecirc;tre renseign&eacute;" : null;
    	$erreur = empty($post['vNom']) ? "Le nom doit &ecirc;tre renseign&eacute;e" : $erreur;
    	return $erreur;
    }
     
     
     
     
     
    // Ajout en provenance du formulaire
    if (isset($_POST["ajout"]) && $_POST["ajout"] == "ajouter")
    {
    	// Enregistre le post en session pour éviter d'avoir à ressaisir tous les champs en cas d'erreur
    	$_SESSION['ajout_sites'] = $_POST;
     
    	//J'applique trim sur les éléments du tableau pour supprimer les espaces blancs en début et fin de chaine qui pourraient être rentrés inopinément par l'utilisateur
    	$post = array_map('trim',$_POST);
     
    	//Fonction de vérification
    	$erreur = verifpost($post);
     
    	// Si pas d'erreur on lance l'insertion en récupèrant l'id auto incrémenté
    	$id = empty($erreur) ? inserersolution($post['vPrefixe'], $post['vNom'], $post['vInfos']) : null;
     
    	// On affiche un message d'erreur uniquement si nécéssaire. Si OK le header renverra vers l'élément inséré
    	$_SESSION['message_sites'] = isset($erreur) ? $erreur : null;
     
    	// Header pour éviter les multiples post et le messgae du navigateur si on réaffiche cette page. L'ancre id sert pour aller à l'élément inséré
    	header('Location: '.$_SERVER['PHP_SELF'].'#lent'.$id);exit;
    }
     
     
     
     
     
    // Modification en provenance du formulaire
    if (isset($_POST["modif"]) && $_POST["modif"] == "modifier") {
    	$_SESSION['modif_sites'] = $_POST;
    	$post = array_map('trim',$_POST);
    	$erreur = verifpost($post);
    	$_SESSION['message_sites'] = empty($erreur) ? modifiersolution($post['id'], $post['vPrefixe'], $post['vNom'], $post['vInfos']) : $erreur;
    	header('Location: '.$_SERVER['PHP_SELF'].'#lent'.$post['id']);exit;
    }
     
     
     
     
    // Suppression en provenance du formulaire
    if (isset($_POST["suppr"]) && $_POST["suppr"] == "supprimer") {
    	$_SESSION['message_sites'] = supprimersolution($_POST['id']);
    	header('Location: '.$_SERVER['PHP_SELF']);exit;
    }
     
     
     
     
     
    // Variables qui pourront être affichées dans le html pour les ajouts, modifications et suppressions
    $message = isset($_SESSION['message_sites']) ? $_SESSION['message_sites'] : null;
     
    $modif = isset($message,$_SESSION['modif_sites']) ? $_SESSION['modif_sites'] : null;
    // $id_modif pour cibler le formulaire de modification
    $id_modif = isset($_SESSION['modif_sites']['id']) ? $_SESSION['modif_sites']['id'] : null;
     
    // On fait également un test sur message pour ne pas remplir les champs du formulaire d'ajout si l'insertion est réussie
    $ajout = isset($message,$_SESSION['ajout_sites']) ? $_SESSION['ajout_sites'] : null;
     
    // On efface les variables de session pour qu'elles ne soient définies qu'une fois
    unset($_SESSION['message_sites'],$_SESSION['modif_sites'],$_SESSION['ajout_sites']);
     
     
     
    //Affichage des résultats en alimentant (hydratant) les champs des formulaires de modification et suppression
    $select = "SELECT id, prefixe, nom, infos FROM adm_sites ORDER BY prefixe";
    $connexion = C_PDO::getC();
    // Pas besoin de requête préparée ici puisqu'il n'y a pas de variables utilisateur dans la requête
    $read = $connexion->query($select);
     
     
    ?>
    <!DOCTYPE html>
    <html lang="fr-CH">
    <head>
    	<title>Administrations</title>
    	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    	<link rel="stylesheet" href="images/designs/styles.css">
    	<script src="https://kit.fontawesome.com/2e9b34a81e.js"></script>
    	<style>
    form p {
    	margin:0.5em;
    	padding:0;
    }
    form .label {
    	display:inline-block;
    	width:120px;
    }
    #message {
    	border:1px solid black;
    	background:#0CF;
    	font-size:1.5em;
    	text-align:center;
    }
    </style>
    </head>
     
     
    <body>
    <? include('includes/'.INCLUDES_FILES['header']); ?>
     
     
     
     
    <h1>Gestion des Sites</h1>
    <div align="justify"  style="width: 600px;">
    	Concernant le nom du site ainsi que son pr&eacute;fixe, il serait important de ne pas mettre d&rsquo;accents, 
    	de caract&egrave;res sp&eacute;ciaux ou d&rsquo;espace. Il faudrait plut&ocirc;t jouer entre les majuscules 
    	et les minuscules pour diff&eacute;rencier les mots. En revanche pour les infos, aucun soucis, tous les 
    	caract&egrave;res sont accept&eacute;s et pr&eacute;senteront aucun danger niveau codage.
    </div>
    <br />
    <a href="sites.php?gestion=new" target="_parent" title="Ajouter une entr&eacute;e"><i class="fas fa-folder-plus" style="font-size: 30px;"></i></a>
    <br />
     
     
     
    <?php 
    // On fait afficher ici les messages de suppression et d'ajout mais pas ceux de modification qui seront affichés dans le formulaire concerné
    if(isset($message) && empty($id_modif)) echo '<p id="message">'.$message.'</p>';
     
     
    if (!empty($_GET['gestion'])) {
    	?>
    	<br />
    	<form action="#" method="POST">
    		<fieldset style="width: 600px;">
    			<legend>Ajouter</legend>
    			<p><label><span class="label">Nom : </span><input type="text" name="vNom" value="<?=isset($ajout['vNom']) ? ($ajout['vNom']) : null;?>" /></label></p>
    			<p><label><span class="label">Prefixe : </span><input type="text" name="vPrefixe" value="<?=isset($ajout['vPrefixe']) ? ($ajout['vPrefixe']) : null;?>" /></label></p>
    			<p><label><span class="label">Infos : </span><textarea name="vInfos"><?=isset($ajout['vInfos']) ? ($ajout['vInfos']) : null;?></textarea></label></p>
    			<div align="center"><button type="submit" name="ajout" value="ajouter">Ajouter</button></div>
    		</fieldset>
    	</form>
    	<br />
    	<?php
    }
    foreach ($read as $row) {
    	?>
    	<!-- l'id sert d'ancre de redirection pour les ajouts / modifications (Attention de ne pas utiliser d'id statique dans ces lignes puisque c'est une boucle)-->
    	<br />
    	<form action="#" method="post" style="margin-bottom:0.5em" id="lent<?= isset($row->id)? ($row->id) : ''?>">
    		<fieldset style="width: 600px;">
    			<!-- message des modifications -->
    			<legend>Modifier/Supprimer</legend>
    			<?= isset($id_modif, $message) && $row->id == $id_modif ? '<p style="color:blue">'.($message).'<p>' : ''?>
    			<input type="hidden" name="id" value="<?= ($row->id)?>" >
    			<p><label><span class="label">Nom : </span><input type="text" name="vNom" value="<?= $row->id == $id_modif ? ($modif['vNom']) : ($row->nom) ?>" /></label></p>
    			<p><label><span class="label">Prefixe : </span><input type="text" name="vPrefixe" value="<?= $row->id == $id_modif ? ($modif['vPrefixe']) : ($row->prefixe) ?>" /></label></p>
    			<p><label><span class="label">Infos : </span><textarea name="vInfos"><?= $row->id == $id_modif ? ($modif['vInfos']) : ($row->infos) ?></textarea></label></p>
    			<div align="center">
    				<button type="submit" name="modif" value="modifier">Modifier</button>
    				<button type="submit" name="suppr" value="supprimer" style="margin-left:2em">Supprimer</button>
    			</div>
    		</fieldset>
    	</form>
    	<?php
    }
    ?>
     
     
     
    <? include('includes/'.INCLUDES_FILES['footer']); ?>
    </body>
    </html>

    Maintenant, je vais prendre exemple sur cette page et construire les autres page. La prochaine est la page config.php qui aura quelques difficultés et qui m'obligera à modifier pas mal de chose, vu que la table utilisé sur ma page config.php n'a pas de numéro ID et qu'en plus, je dois réaliser une fonction qui va créer la table si elle n'existe pas. Bref, je me mets de suite au travail


    Je ne le dirais jamais assez, GRAND MERCI à toi ABCIWEB

  15. #15
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 505
    Par défaut
    Salut,

    N'oublie pas ligne 12
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (!isSet($_SESSION['site'])) {
    Je suis assez surpris que OVH laisse passer cette condition.

  16. #16
    Membre confirmé Avatar de RinaBK
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2021
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 49
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2021
    Messages : 92
    Par défaut
    Citation Envoyé par MaitrePylos Voir le message
    Salut,

    N'oublie pas ligne 12
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (!isSet($_SESSION['site'])) {
    Je suis assez surpris que OVH laisse passer cette condition.
    Je ne comprends pas où tu veux en venir?
    Il aurait été préférable que j'utilise empty() à la place?
    Ou es-ce que je devrais plutôt utiliser la forme : (Je comptais de toute façon tout refaire en essayant d'utiliser cette méthode (Un moyen de bien comprendre et d'apprendre)
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    $selectionne = empty($siteID) ? 'Expression 1' : 'Expression 2';

  17. #17
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 505
    Par défaut
    Non, beaucoup plus simple .

    je ne comprend pas comment passe , alors que le nomenclature officielle est

  18. #18
    Membre confirmé Avatar de RinaBK
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2021
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 49
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2021
    Messages : 92
    Par défaut
    Aaah oui !!!
    Effectivement, je pensais les avoir toutes modifiées.. En voilà une qui est passée à la trappe ^^
    Merci pour la remarque

  19. #19
    Membre confirmé Avatar de RinaBK
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2021
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 49
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2021
    Messages : 92
    Par défaut
    Comme je l'ai dis dans un message plus haut, j'ai pris exemple sur la page sites.php afin de refaire ma page config.php.
    La page config.php me permet en quelques sorte de gérer certaines variables via ma partie administration sans avoir besoin de toucher à mes fichiers. Par exemple, si j'affiche une liste avec les dernières News sur la page d'un site, il va de soit que je ne vais pas afficher toutes les News enregistrées, mais juste un nombre spécifique. Dans le cas où je déciderais de changer ce nombre limite, qui par exemple est défini à 10 News affichées, j'ai besoin que de venir sur ma partie administration et modifier ma variable 10 par 15 ou 5. Grosso modo, c'est une page ADMIN qui comporte des variables enregistrées dans ma base de données.

    Grâce à la page sites.php, j'ai mon gestionnaire de préfixe qui va me permettre de sélectionner un site qui sera récupérer grâce aux sessions. De plus, je dois réaliser 2 fonctions qui seront utilisées sur une grande partie des pages de ma partie administration. Ces fonctions vont contrôler si une table utilisée sur la page existe. Si la table n'existe pas encore, je propose de la créer.

    Ma première fonction qui va contrôler si une table existe :
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function tableExists($table) {
    	try {
    		$pdo = C_PDO::getC();
    		$result = $pdo->query("SELECT 1 FROM $table LIMIT 1");
    	}
    	catch (Exception $e) {
    		return FALSE;
    	}
    	return $result !== FALSE;
    }
    Cette fonction retour FALSE si elle n'existe pas.
    Dans les page, j'aurais simplement qu'à appeler cette fonction pour le contrôle.
    Dans le cas où la table $table n'existe pas, j'ai créé une autre fonction qui va créer la table :
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    //	Fonction de création de la table
    function creationtable($table,$requete) {
    	global $sitePrefixe;
     
    	try {
    		$connexion = C_PDO::getC();
    		$requete = 'CREATE TABLE '.$table.' '.$requete.');';
    		$stmt = $connexion->exec($requete);
    	}
    	catch(PDOException $e) {
    		exit($e->getMessage());
    	}
    	return $stmt ? "Cr&eacute;ation de la table termin&eacute;" : "Impossible de cr&eacute;er la table";
    }
    Vu que je vais utiliser ces fonctions sur une bonne partie des pages de la partie ADMIN, j'ai placé ces deux fonctions dans mon fichier fonctions.php qui est appelé au début de chaque page.

    ...Et bien évidement, la page config.php en son intégralité :
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    <?php
    define('MAJ','28.01.2021 19:31:59');
     
     
     
     
    //	Initialisations des sessions
    session_start();
     
    if (!isset($_SESSION['site'])) {
    	$siteID = '';
    	$sitePrefixe = '';
    	$siteName = '';
    } else {
    	$siteID = $_SESSION['site']['id'];
    	$sitePrefixe = $_SESSION['site']['prefixe'];
    	$siteName = $_SESSION['site']['nom'];
    }
     
     
     
     
    //	Inclusion des fichiers principaux
    define('INCLUDES_FILES', array('header'=>'header.php',
    								'footer'=>'footer.php',
    								'variables'=>'variables.php',
    								'fonctions'=>'fonctions.php'
    								));
     
    foreach (INCLUDES_FILES as $index => $files) {
    	if (!file_exists('includes/'.$files)) { header('Location: alerte.php?warning=500'); }
    	if ($index == 'variables' || $index == 'fonctions') { include('includes/'.$files); }
    }
     
     
     
     
    /*
    CREATE TABLE XXX_config (
    	nom VARCHAR (50) NOT NULL,
    	valeur TEXT NULL,
    	infos TEXT NULL,
    	UNIQUE (nom)
    );
    */
     
    //	Initialisation de ma variable 
    $table = $sitePrefixe.'_config';
     
     
    //	Contrôle si la table utilisée existe
    $tblExist = tableExists($table) ? TRUE : FALSE;
    $requete = '(nom VARCHAR (50) NOT NULL,valeur TEXT NULL,infos TEXT NULL,UNIQUE (nom)';
     
    //	Création de la table, si accepté
    if (isset($_POST["configdb"]) && $_POST["configdb"] == "oui") {
    	$erreur = creationtable($table,$requete);
    	header('Location: '.$_SERVER['PHP_SELF']);exit;
    }
     
     
     
     
    // Fonction d'insertion
    function inserersolution($vNom, $vValeur, $vInfos) {
    	global $table;
    	try {
    		$connexion = C_PDO::getC();
    		$requete = 'INSERT INTO '.$table.' (nom, valeur, infos) VALUES(?,?,?)';
    		$stmt = $connexion->prepare($requete);
    		$stmt->execute([$vNom, $vValeur, $vInfos]);
     
    		// Trouve l'id auto incrémenté
    		//$id = $connexion->lastInsertId ();
    	}
    	catch(PDOException $e) {
    		exit($e->getMessage());
    	}
    	//return $id; 
    	return $stmt ? $vNom : "Impossible d'enregistrer";
    }
     
     
     
     
     
    // Fonction de modification
    function modifiersolution($vValeur, $vInfos, $vNom) {
    	global $table;
    	try {
    		$connexion = C_PDO::getC();
    		$requete = 'UPDATE '.$table.' SET valeur = ?, infos = ? WHERE '.$table.'.nom = ?';
    		$stmt = $connexion->prepare($requete);
    		$stmt->execute([$vValeur, $vInfos, $vNom]);
    		$count = $stmt->rowCount();
    	}
    	catch(PDOException $e) {
    		exit($e->getMessage());
    	}
    	return $count ? "Modification r&eacute;ussie" : "Impossible de modifier"; 
    }
     
     
     
     
     
    // Fonction de suppression
    function supprimersolution($id) {
    	global $table;
    	try {
    		$connexion = C_PDO::getC();
    		$requete = 'DELETE FROM '.$table.' WHERE '.$table.'.nom = ?';
    		$stmt = $connexion->prepare($requete);
    		$stmt->execute([$id]);
    		$count = $stmt->rowCount();
    	}
    	catch(PDOException $e) { 
    		exit($e->getMessage());
    	}
    	return $count ? "Supression r&eacute;ussie" : "Impossible de supprimer"; 
    }
     
     
     
     
     
     
    // function de vérification commune à l'ajout et à la modification
    function verifpost ($post) {
    	$erreur = empty($post['vNom']) ? "Le nom de la variavle doit &ecirc;tre renseign&eacute;e" : $erreur;
    	$erreur = empty($post['vValeur']) ? "La valeur de la variable doit &ecirc;tre renseign&eacute;e" : $erreur;
    	return $erreur;
    }
     
     
     
     
     
     
     
    // Ajout en provenance du formulaire
    if (isset($_POST["ajout"]) && $_POST["ajout"] == "ajouter") {
    	// Enregistre le post en session pour éviter d'avoir à ressaisir tous les champs en cas d'erreur
    	$_SESSION['ajout_config'] = $_POST;
     
    	//J'applique trim sur les éléments du tableau pour supprimer les espaces blancs en début et fin de chaine qui pourraient être rentrés inopinément par l'utilisateur
    	$post = array_map('trim',$_POST);
     
    	//Fonction de vérification
    	$erreur = verifpost($post);
     
    	// Si pas d'erreur on lance l'insertion en récupèrant l'id auto incrémenté
    	$id = empty($erreur) ? inserersolution($post['vNom'], $post['vValeur'], $post['vInfos']) : null;
     
    	// On affiche un message d'erreur uniquement si nécéssaire. Si OK le header renverra vers l'élément inséré
    	$_SESSION['message_config'] = isset($erreur) ? $erreur : null;
     
    	// Header pour éviter les multiples post et le messgae du navigateur si on réaffiche cette page. L'ancre id sert pour aller à l'élément inséré
    	header('Location: '.$_SERVER['PHP_SELF'].'#lent'.$id);exit;
    }
     
     
     
     
     
     
    // Modification en provenance du formulaire
    if (isset($_POST["modif"]) && $_POST["modif"] == "modifier") {
    	$_SESSION['modif_config'] = $_POST;
    	$post = array_map('trim',$_POST);
    	$erreur = verifpost($post);
    	$_SESSION['message_config'] = empty($erreur) ? modifiersolution($post['vValeur'],$post['vInfos'],$post['vNom']) : $erreur;
    	header('Location: '.$_SERVER['PHP_SELF'].'#lent'.$post['vNom']);exit;
    }
     
     
     
     
     
     
     
    // Suppression en provenance du formulaire
    if (isset($_POST["suppr"]) && $_POST["suppr"] == "supprimer") {
    	$_SESSION['message_config'] = supprimersolution($_POST['vNom']);
    	header('Location: '.$_SERVER['PHP_SELF']);exit;
    }
     
     
     
     
     
     
    // Variables qui pourront être affichées dans le html pour les ajouts, modifications et suppressions
    $message = isset($_SESSION['message_config']) ? $_SESSION['message_config'] : null;
     
    $modif = isset($_SESSION['modif_config']) ? $_SESSION['modif_config'] : null;
    // $id_modif pour cibler le formulaire de modification
    $id_modif = isset($_SESSION['modif_config']['vNom']) ? $_SESSION['modif_config']['vNom'] : null;
     
    // On fait également un test sur message pour ne pas remplir les champs du formulaire d'ajout si l'insertion est réussie
    $ajout = isset($_SESSION['ajout_config'],$_SESSION['message_config']) ? $_SESSION['ajout_config'] : null;
     
    // On efface les variables de session pour qu'elles ne soient définies qu'une fois
    unset($_SESSION['message_config'],$_SESSION['modif_config'],$_SESSION['ajout_config']);
     
     
     
     
     
     
     
    if (($siteID != '') && ($sitePrefixe != '') && ($siteName != '') && ($tblExist == TRUE)) {
    	//Affichage des résultats en alimentant (hydratant) les champs des formulaires de modification et suppression
    	$select = 'SELECT * FROM '.$table.' ORDER BY nom';
    	$connexion = C_PDO::getC();
    	$read = $connexion->query($select);
    }
     
     
     
    ?>
     
    <!DOCTYPE html>
    <html lang="fr-CH">
    <head>
    	<title>Administrations</title>
    	<link rel="stylesheet" href="images/designs/styles.css">
    	<script src="https://kit.fontawesome.com/2e9b34a81e.js"></script>
    	<style>
    body {
    	font-family:Verdana, Geneva, sans-serif
    }
    form p {
    	margin:0.5em;
    	padding:0;
    }
    form .label {
    	display:inline-block;
    	width:120px;
    }
    #message {
    	border:1px solid black;
    	background:#0CF;
    	font-size:1.5em;
    	text-align:center;
    }
    .saisie {
    	width: 400px;
    }
    button {
    	padding: 3px;
    	width: 100px;
    }
    </style>
    </head>
     
     
     
    <body>
    <? include('includes/'.INCLUDES_FILES['header']); ?>
     
     
     
     
     
    <h1>Configurations</h1>
    <?
    //	Contrôle si un site a été préalablement sélectionné, sinon : message d'alerte
    if (($siteID == '') || ($sitePrefixe == '') || ($siteName == '')) {
    	echo '<a href="index.php" target="_parent"><span class="error"><i class="fas fa-exclamation-triangle"></i>&nbsp;<b>Veuillez s&eacute;lectionner le site&nbsp;<i class="fas fa-exclamation-triangle"></i></b></span></a><br />';
    } else {
    	echo 'Site actuellement s&eacute;lectionn&eacute;&nbsp;:&nbsp;&nbsp;&nbsp;<b>'.$siteID.'.&nbsp;'.$siteName.'&nbsp;&nbsp;['.$sitePrefixe.']</b>';
    	echo '&nbsp;&nbsp;&nbsp;<a href="index.php" target="_parent" title="Changer de site actif"><i class="fas fa-exchange-alt"></i></a><br />';
     
    	//	Si la table n'existe pas, demander si la créer
    	if ($tblExist == FALSE) {
    		?>
    		<br />
    		<div align="left" class="error">
    			<i class="fas fa-exclamation-triangle"></i>&nbsp;<u>Aucune base de donn&eacute;es disponible pour ce site&nbsp;!</u>&nbsp;<i class="fas fa-exclamation-triangle"></i>
    		</div>
    		<br />
    		<div align="left" style="padding: 10px 0px 10px 0px;">Voulez-vous cr&eacute;er un table pour le site &quot;<b><?=$siteName;?></b>&quot;&nbsp;?<br /></div>
    		<form method="POST">
    			<button type="submit" name="configdb" value="oui">Oui</button>
    			<button type="reset" name="" value="non" onclick="location.href='index.php'">Non</button>
    		</form>
    		<?
    	}
    }
    ?>
     
     
     
     
     
     
    <?
    // On fait afficher ici les messages de suppression et d'ajout mais pas ceux de modification qui seront affichés dans le formulaire concerné
     if(isset($message) && empty($id_modif)) echo '<p id="message">'.($message).'</p>';
     
     
     
    if (($siteID != '') && ($sitePrefixe != '') && ($siteName != '') && ($tblExist == TRUE)) {
     	?>
     	<br />
     	<br />
     	<form action="#" method="post">
     		<fieldset style="width: 600px;">
     			<legend>Ajouter</legend>
     			<p><label><span class="label">Nom : </span><input type="text" name="vNom" value="<?=isset($ajout['vNom']) ? ($ajout['vNom']) : null;?>" class="saisie" /></label></p>
     			<p><label><span class="label">Valeur : </span><input type="text" name="vValeur" value="<?=isset($ajout['vValeur']) ? ($ajout['vValeur']) : null;?>" class="saisie" /></label></p>
     			<p><label><span class="label">Infos : </span><textarea name="vInfos" class="saisie"><?=isset($ajout['vInfos']) ? ($ajout['vInfos']) : null;?></textarea></label></p>
     			<div align="center"><button type="submit" name="ajout" value="ajouter">Ajouter</button></div>
     		</fieldset>
     	</form>
     	<br />
     
     
     	<?
     	foreach ($read as $row) {
     		?>
     		<br />
     		<br />
     		<!-- l'id sert d'ancre de redirection pour les ajouts / modifications (Attention de ne pas utiliser d'id statique dans ces lignes puisque c'est une boucle)-->
     		<form action="#" method="post" style="margin-bottom:0.5em" id="lent<?= isset($row->nom)? ($row->nom) : ''?>">
     			<fieldset style="width: 600px;">
     				<legend>Modifier ou Supprimer</legend>
     				<!-- message des modifications -->
     				<?= isset($id_modif, $message) && $row->nom == $id_modif ? '<p style="color:blue">'.($message).'<p>' : ''?>
     				<input type="hidden" name="nom" value="<?= ($row->nom)?>" >
     				<p><label><span class="label">Nom : </span><input type="text" name="vNom" readonly value="<?=($row->nom) ?>" class="saisie" /></label></p>
     				<p><label><span class="label">Valeur : </span><input type="text" name="vValeur" value="<?= $row->nom == $id_modif ? ($modif['vValeur']) : ($row->valeur) ?>" class="saisie" /></label></p>
     				<p><label><span class="label">Infos : </span><textarea name="vInfos" class="saisie"><?= $row->nom == $id_modif ? ($modif['vInfos']) : ($row->infos) ?></textarea></label></p>
     				<div align="center">
    					<button type="submit" name="modif" value="modifier">Modifier</button>
    					<button type="submit" name="suppr" value="supprimer" style="margin-left:2em">Supprimer</button>
    				</div>
     			</fieldset>
     		</form>
     		<?
     	}
     }
    ?>
     
     
     
     
    <? include('includes/'.INCLUDES_FILES['footer']); ?>
    </body>
    </html>

    Donc, je pense avoir compris le principe de travailler en PHP orienté objets, si c'est bien le terme de cette méthode
    Je vais donc, continuer à corriger toute ma partie administration en utilisant cette méthode!


    Je ne le répèterais pas assez, un GRAND MERCI à ABCIWEB pour m'avoir aidé à redécouvrir PHP

  20. #20
    Expert confirmé

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 416
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 416
    Par défaut
    Salut,

    Citation Envoyé par RinaBK Voir le message
    Maintenant, je vais prendre exemple sur cette page et construire les autres page.
    NON surtout pas !
    Quand une fonction aussi basique que htmlspecialchars ne fonctionne pas comme prévu dans le cadre d'une utilisation normale, il faut résoudre le problème et surtout pas le contourner, car cela veut dire que tu as un problème quelque part. En plus te tu prives d'une fonction essentielle, c'est à dire que toutes tes pages seront mal codées et exposées à des failles de sécurité majeure.

    Là tu ne risques rien puisque ce sont des messages définis en dur dans le code mais comment feras-tu pour les variables utilisateurs. Il faut toujours résoudre le problème avant de prendre modèle sur un code sinon toutes tes pages seront à refaire.

    Enfin bon tu as déjà avancé puisque tu sais que c'est cette fonction qui pose problème mais plutôt que de ne pas l'utiliser il faut savoir pourquoi elle ne fonctionne pas. Et le fait que tu te traines encore des &eacute etc. dans ton code confirme aussi que ta page n'est pas correctement encodée. Tu ne vas pas trainer ce boulet en 2021 quand même!

    Dans ton éditeur de texte, crée une nouvelle page encodée en utf8 et copie le code que je t'ai donné dans mon dernier message (il te suffit d'adapter les variables de connexion de la classe C_PDO). Cela devrait fonctionner, sinon débrouilles-toi pour que ça fonctionne avant d'aller plus loin. Et tu dois pouvoir écrire des caractères accentués normalement en dur dans ton code sans passer par des entités html qu'on ne voit plus que dans les sites préhistoriques.

    Possible aussi que tu aies des problèmes si tes champs de tables bdd ne sont pas en utf-8, si non, changes-les en "utf8_general_ci".

    Après c'est normal que tu aies ces problèmes si ton site est très ancien car avant la norme était "latin..." mais il faut aujourd'hui ABSOLUMENT de l'utf-8, y compris au niveau de l'encodage de tes fichiers (quand tu les crées).

    Ensuite prends l'habitude de créer des classes, même si dans un premier temps tu ne les emploie que pour grouper des fonctions ayant un objectif commun. En plus de t'habituer à les utiliser, cela te fais un code qui expose beaucoup moins de variables, donc moins de conflits possibles, et de plus tu peux faire un code générique beaucoup plus simple à utiliser plutôt que d'avoir à inventer des noms de fonctions différentes.

    Par exemple la classe AdminCrud possède ses quatre méthodes basiques "inserer", "modifier","supprimer", "lire" pour la table "adm_site". Si dans le même script tu dois faire d'autres requêtes sur une autre table, par exemple une table "blog", tu peux te créer une classe BlogCrud avec à l'intérieur les mêmes noms de fonction. Ensuite pour t'en servir tu peux faire simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    // Initialisation des classes modèle
    $admin_c = new AdminCrud ($connexion);
    $blog_c = new BlogCrud ($connexion);
     
    $lire_blog = $blog_c->lire();
    $lire_admin = $admin_c->lire();
    C'est à la fois plus simple à écrire et en même temps tu n'as que deux classes qui doivent être nommées différemment. Avec un système de fonction, il faudrait huit noms de fonctions différentes.

    Autre avantage, étant donné que l'on passe la $connexion comme paramètre dans la classe, si on venait à travailler simultanément avec deux bases de données différentes il suffirait de changer uniquement la valeur du paramètre $connexion dans l'initialisation d'une des classes pour que toutes les requêtes fonctionnent, alors qu'en mettant ce paramètre de connexion dans les requêtes elle-mêmes il faudrait changer ce paramètre dans toutes tes fonctions.

    Si tu ne veux pas utiliser "spl_autoload_register" pour charger tes classes, tu peux écrire des classes dans le fichier lui-même comme dans mon dernier exemple. Si plus tard tu veux mieux t'organiser pour séparer tes couches MVC il te suffiras de copier ces classes dans des fichiers distincts. C'est donc plus facilement évolutif et tu gagnes en lisibilité dans ton code tout en minimisant le conflit de variables. Si tu regardes la classe "AdminCrud" c'est quand même très facile à comprendre et rapide à écrire, en même temps cela te fais un exercice pour créer et utiliser des classes qui comme tu le disais plus haut, font maintenant partie de la base indispensable dans tous les langages de programmation.

    Après tu fais comme tu veux, mais si vraiment la programmation t'intéresse et que tu veux continuer d'écrire des scripts un peu évolués et évolutifs il faut en passer par là. Par exemple tu peux télécharger ce module d'upload pour voir ce que l'on peut faire avec des classes. C'est prêt à l'emploi, il te suffit de poser le dossier (décompressé) sur le serveur pour faire les premiers tests de téléchargement. Tu verras dans les scripts serveur (du dossier Php_Upload) que cela permet de faire des choses très simples à beaucoup plus compliquées avec dans tous les cas des fonctionnalités avancées: retour d'informations en temps réel, surpasse les limitations serveur upload_max_filesize, post_max_size et max_file_uploads, gestion des erreurs, contrôle des MIMETYPE, tout cela de manière transparente et il suffit de compléter avec des lignes de code qui utilisent d'autres classes si l'on veut redimensionner des images, alimenter une bdd etc.

    Ce n'est pas un exemple très pointu d'utilisation des classes côté php, mais quand même diversifié avec l'utilisation de classes standard, d'autres abstraites, des traits, des méthodes statiques, des héritages etc. Tout ça au final pour avoir une interface utilisateur qui peut être utilisée aussi bien par un débutant que par un utilisateur confirmé pour des scripts beaucoup plus complexes. C'est un framework pour l'upload de fichiers. Ce serait impossible à faire avec des fonctions ou alors ce serait un bin's innommable très difficile à manier. Tandis que là, même les débutants peuvent déjà faire des choses évoluées et sécurisées en suivant simplement les exemples et le mode d'emploi. Côté javascript c'est également une classe paramétrable (avec prévisualisation des images etc.) ce qui était également indispensable pour pouvoir créer facilement si besoin plusieurs formulaires d'upload dans une même page. En complément de la facilité de paramétrage c'est là que l'on voit tout l'intérêt des classes qui supportent plusieurs instances. Au passage, il y a une quinzaine d'exemples de formulaires complets et prêt à l'emploi, tu peux t'en servir pour tes besoins si tu veux, il n'y a rien à faire si les fonctionnalités te conviennent.

    En fait on fait la même chose puisqu'on fait des sites from scratch, et l'expérience montre qu'on a intérêt à faire du code facilement utilisable et réutilisable quitte à y passer plus de de temps au départ. Il n'est pas raisonnable aujourd'hui de négliger les classes surtout si l'on fait du from scrath.

    Dernier exemple, les pages d'information de ce site pour ce fabriquant de poêles/cheminées utilisent exactement le même module de création de page (WYSIWYG fait maison) qui permet de faire toutes les pages de cet autre site pour une association. Bien évidemment ces sites sont administrables et le même module d'upload (en lien ci-dessus) fait partie des outils pour télécharger les fichiers sur le serveur, de même qu'un même module de création de formulaire que j'ai créé à partir ce module (il faut créer en complément toute la partie php pour que ce soit administrable) pour que les propriétaires des sites puissent créer les formulaires qu'ils veulent et autant qu'ils le veulent. Au total cela fait beaucoup de code qui s'empile, heureusement qu'il existe des classes pour organiser le code et faciliter l'utilisation des fonctionnalités.

    Bon j'arrête là mon topo sur l'intérêt des classes, à force de trop insister je vais finir par t'en dégoûter. En tout cas quoique tu fasses, il faut résoudre le problème d'encodage et utiliser utf8 tout au long de ta chaine, de la création des fichiers et à tous les niveaux. Pour php il n'y a rien à faire à partir de la version 5.6 qui utilise utf8 par défaut. Vérifies tes tables et leurs champs. Et recopies ton code html/php dans de nouveaux fichiers si tu n'arrives pas à changer l'encodage initial.

    Après il existe aussi une option pour paramétrer l'encodage dans la fonction htmlspecialchars (qui par défaut est utf-8), mais il faudra faire pareil pour toutes les fonctions qui traitent des chaines de caractères, et ça va être un chantier qui va te poser des problèmes d'homogénéité du code suivant qu'il vienne de ta base de données ou d'ailleurs sans compter les entités html que tu vas trainer comme un handicap. Mieux vaut prendre le temps de tout remettre au propre.

    Aller, à une prochaine fois

Discussions similaires

  1. Cherche Hébergement gratuit site web [PHP-MySQL]
    Par HULK dans le forum Gratuit
    Réponses: 15
    Dernier message: 20/01/2010, 22h53
  2. [MySQL] Aide à la création site en php mysql
    Par nbjr1858 dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 03/06/2007, 16h10
  3. Extranet et les sites Internet : php/mysql
    Par kagura dans le forum Outils
    Réponses: 12
    Dernier message: 21/06/2006, 10h48
  4. créer son site en php/mysql entierement
    Par zimotep dans le forum Requêtes
    Réponses: 15
    Dernier message: 24/03/2006, 23h39
  5. Cherche Hébergement gratuit site web [PHP-MySQL]
    Par HULK dans le forum Hébergement
    Réponses: 11
    Dernier message: 23/08/2005, 14h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo