Discussion:
Conseils pour debutant
(trop ancien pour répondre)
jaunit
2007-02-07 09:41:29 UTC
Permalink
Bonjour

J'ai commencé hier à tenter de créer une petite appli php/mysql. Je vous
préviens, je suis une vraie quiche.

Histoire de démarrer sur de bonnes bases, pouvez-vous me dire si ce bout de
code vous semble correct et un minimum sécurisé svp ? Je me suis basé sur
quelques exemples trouvé çà et là, ainsi que sur un bouquin.

Désolé si je ne suis pas sur le bon groupe.

Merci

<div>
<?php
include('menu.htm');
?>
</div>
<div>
<?php
include('menu_batiments.htm');
?>
</div>
<div>
<?php
include('connect_base.php');
$sql = 'SELECT id_batiment,designation_batiment,nombre_niveaux_batiment FROM
batiments';
$req = mysql_query($sql) or die('Erreur SQL !<br>'
$sql.'<br>'.mysql_error());
while($data = mysql_fetch_assoc($req))
{
echo '<br />
Code du b&acirc;timent ::: '.$data['id_batiment'].'<br />
D&eacute;signation du b&acirc;timent ::: '.$data['designation_batiment'].'
<br />
Nombre de niveaux ::: '.$data['nombre_niveaux_batiment'].'<br /><br />
';
}
mysql_close();
?>
</div>
<div>
<br />
<a href="nouveau_batiment.php">Ajouter un b&acirc;timent</a> | <a
href="delete_batiment.php">Supprimer un b&acirc;timent</a>
</div>
thierry
2007-02-07 21:00:33 UTC
Permalink
bonjour

j'aurais tendance à croire qu'il y a autant de façons de coder que de
codeurs. Voir autant de façons de bien coder que de bon codeurs.

Je vais donc me contenter de faire des remarques générales n'engageant
que moi codeur normal (ça aussi ça n'engage que moi).

Dans ton code PHP tu mélanges le traitement (sélection des batiments)
et la présentation (prodution du HTML)
Personnellement je remplaçerais donc tout le bloc
Post by jaunit
<?php
include('connect_base.php');
$sql = 'SELECT
id_batiment,designation_batiment,nombre_niveaux_batiment FROM
Post by jaunit
batiments';
$req = mysql_query($sql) or die('Erreur SQL !<br>'
$sql.'<br>'.mysql_error());
while($data = mysql_fetch_assoc($req))
{
echo '<br />
Code du b&acirc;timent ::: '.$data['id_batiment'].'<br />
'.$data['designation_batiment'].'
Post by jaunit
<br />
Nombre de niveaux ::: '.$data['nombre_niveaux_batiment'].'<br /><br />
';
}
mysql_close();
?>
par qqch du genre
//**************************************************************
require_once ('batiments.class.php')
$batiments = new cBatiments();
try {
echo $batiments->getBatList($critereDeSelection, $feuilleXsl);
}
catch (Exception $e) {
echo $e->getMessage();
}
//**************************************************************

avec le fichier batiments.class.php du genre

//*************************************************************
require_once('MDB2.php')
class cBatiments {
private $dsn = mysql://...;

public function __construct() {
....
}
private function &getDB() {
$db =& MDB2::connect($this->dsn);
$db->setFetchMode(MDB2_FETCHMODE_ASSOC);
return $db
}
public function getBatList($crit, $xsl = null) {
$db = $this->getDB();
//construire la requête $req selon les critères
....
$res = $db->query($req);
if ( PEAR::isError($res) )
throw new Exception('', 0);
//production d'un $xml
while ( $row = $res->fetchRow() ) {
//produire le xml
}
if ($xsl ) {
return "le resultat d'une transfo xsl";
//voir: http://fr2.php.net/manual/fr/ref.xsl.php
}
return $xml;
}
}
//******************************************************

voila, c'est court, pas complet mais ça illustre mon opinion.
au passage tu remarqueras:
- l'utilisation de la classe MDB2 de http://PEAR.php.net
qui te permet de t'abstraire d'une base de données donnée
- l'absence de gestion d'erreur: c'est mal
- l'absence de vérification des entrées (mais pas d'entrée dans ton
script): c'est vraiment tres mal
- ta page 'principale' ne comporte que des instructions
du type echo

Pq faire si compliqué ?:
- plus facile de faire évoluer la mise en page
- code plus lisible
- meilleure capitalisation du développement
- une mise en oeuve de toutes (beaucoup, certaines) les facilités
proposées par PHP5 (ce qui n'est pas forcement compatible avec ton mode
d'hébergement)

voilà, j'espère ne pas t'avoir plus embrouillé
Bruno Desthuilliers
2007-02-07 21:53:29 UTC
Permalink
Post by thierry
bonjour
j'aurais tendance à croire qu'il y a autant de façons de coder que de
codeurs. Voir autant de façons de bien coder que de bon codeurs.
Je vais donc me contenter de faire des remarques générales n'engageant
que moi codeur normal (ça aussi ça n'engage que moi).
Dans ton code PHP tu mélanges le traitement (sélection des batiments)
et la présentation (prodution du HTML)
Jusque là, d'accord. Par contre, par pitié, évite nous les classes
inutiles et le XML/XSL superinutile.
Thierry
2007-02-08 11:22:00 UTC
Permalink
bonjour,
Post by Bruno Desthuilliers
Jusque là, d'accord.
merci :)
Post by Bruno Desthuilliers
Par contre, par pitié, évite nous les classes
inutiles
Pour les classes j'ai tendance à croire que même pour un exemple si simple,
qui n'est
à mon avis qu'une partie du projet complet et plus complexe ayant donné
naissance à ce fil,
cela force à une rigueur de conception et à se poser des questions qui ne
sont pas inutiles.
Mais je suis d'accord relativement à l'exemple c'est de l'artillerie super
lourde.
Post by Bruno Desthuilliers
et le XML/XSL superinutile.
Relativement à la réponse que tu as apporté, j'ai tendance à croire que
l'emploi de XML / XSL
est équivalent (en un tout petit peu moins simple à mettre en oeuvre pour un
débutant)
à la solution que tu proposes avec l'inclusion de
"vues/liste_batiments.php" qui amha
est un équivalent "non standardisé" d'un fichier XSL ou d'un template de
présentation de manière
générale.
Si tu pensais à l'argument transfo lourde pour le serveur je réponds
d'avance:
1/ ça reste à prouver (mais j'ai tendance à être d'accord)
2/ tu envoies vers le client un XML comportant un lien vers le XSL et c'est
le client qui se charge de la transfo.

en toute humilité

thierry
Bruno Desthuilliers
2007-02-08 21:54:12 UTC
Permalink
Post by Thierry
bonjour,
Post by Bruno Desthuilliers
Jusque là, d'accord.
merci :)
Post by Bruno Desthuilliers
Par contre, par pitié, évite nous les classes
inutiles
Pour les classes j'ai tendance à croire que même pour un exemple si simple,
qui n'est
à mon avis qu'une partie du projet complet et plus complexe ayant donné
naissance à ce fil,
cela force à une rigueur de conception
Excuse moi, mais je ne vois absolument pas où est le rapport entre
utiliser des classes (surtout dans un langage comme PHP) et être
rigoureux sur la conception. Si tu savais les horreurs que j'ai vu dans
ce domaine (-> PHP + OO)...
Post by Thierry
et à se poser des questions qui ne
sont pas inutiles.
Mais je suis d'accord relativement à l'exemple c'est de l'artillerie super
lourde.
Plus que ça encore. Et puis franchement, balancer ça dans les gencives
d'un débutant qui à vue de nez doit tout juste être en train de
découvrir la notion de fonction, je ne pense pas que ce soit une bonne
idée, surtout dans un langage aussi désespérement procédural que PHP.
Post by Thierry
Post by Bruno Desthuilliers
et le XML/XSL superinutile.
Relativement à la réponse que tu as apporté, j'ai tendance à croire que
l'emploi de XML / XSL
est équivalent (en un tout petit peu moins simple à mettre en oeuvre pour un
débutant)
à la solution que tu proposes avec l'inclusion de
"vues/liste_batiments.php"
Heu, pas vraiment, non. A moins que tu ne considères que bash script et
C++ soient équivalents ?
Post by Thierry
qui amha
est un équivalent "non standardisé" d'un fichier XSL ou d'un template de
présentation de manière
générale.
C'est parfaitement standardisé. Ca s'appelle des "processing instructions".
Post by Thierry
Si tu pensais à l'argument transfo lourde pour le serveur je réponds
1/ ça reste à prouver
Suffit de faire un bench. Mais n'y perds pas ton temps, la question est
réglée depuis longtemps.
Post by Thierry
(mais j'ai tendance à être d'accord)
2/ tu envoies vers le client un XML comportant un lien vers le XSL et c'est
le client qui se charge de la transfo.
Ouais, chouette. A condition d'en être capable. Et puis c'est vrai que
c'est tellement plus simple de générer du XML, puis d'écrire une feuille
XSL qui va le transformer (si tout va bien, et à quel prix) en html,
quand on pourrait s'embêter à générer directement du html...

Thierry, excuse moi si je chambre un peu, mais franchement, ta solution,
c'est de l'usineàgaz javaesque - en d'autres termes, l'art de
complexifier arbitrairement (et inutilement) des choses simples.
Rakotomandimby (R12y) Mihamina
2007-02-08 22:27:37 UTC
Permalink
Post by Bruno Desthuilliers
Plus que ça encore. Et puis franchement, balancer ça dans les gencives
d'un débutant qui à vue de nez doit tout juste être en train de
découvrir la notion de fonction, je ne pense pas que ce soit une bonne
idée, surtout dans un langage aussi désespérement procédural que PHP.
Ah! ça, ça me mets sur une piste concernant quelques questions que je me
pose sur PHP. Merci Bruno.
P'tit Marcel
2007-02-07 21:53:29 UTC
Permalink
Post by jaunit
Histoire de démarrer sur de bonnes bases, pouvez-vous me dire si ce bout de
code vous semble correct et un minimum sécurisé svp
include('connect_base.php');
il vaudrait mieux mettre ce script sensible dans un autre répertoire
inaccessible du web (protégé par un .htaccess ou mieux situé en dehors
de l'arborescence accessible du serveur web)
Post by jaunit
$sql = 'SELECT id_batiment,designation_batiment,nombre_niveaux_batiment FROM
batiments';
$req = mysql_query($sql) or die('Erreur SQL !<br>'
$sql.'<br>'.mysql_error());
Dans une appli professionnelle, les erreurs sont détaillées dans une Log
et pas à l'écran. L'utilisateur préfère un message d'erreur simple et en
français, et pour la sécurité il vaut mieux lui cacher les instructions
SQL ou le messages d'erreur de MySQL.


eça
--
P'tit Marcel
stats sur les forums modérés http://www.centrale-lyon.org/ng/
jaunit
2007-02-09 14:03:02 UTC
Permalink
P'tit Marcel sur fr.comp.lang.php le mercredi 07 février 2007 22:53
Post by P'tit Marcel
Post by jaunit
Histoire de démarrer sur de bonnes bases, pouvez-vous me dire si ce bout
de code vous semble correct et un minimum sécurisé svp
include('connect_base.php');
il vaudrait mieux mettre ce script sensible dans un autre répertoire
inaccessible du web (protégé par un .htaccess ou mieux situé en dehors
de l'arborescence accessible du serveur web)
Je comprend. Je vais les déplacer dans /var/toto par exemple.

Merci
Bruno Desthuilliers
2007-02-07 23:16:12 UTC
Permalink
Post by jaunit
Bonjour
J'ai commencé hier à tenter de créer une petite appli php/mysql. Je vous
préviens, je suis une vraie quiche.
Dans ce cas là, on ne te mangera pas - "real programmers don't eat
quiche", parait-il !-)
Post by jaunit
Histoire de démarrer sur de bonnes bases, pouvez-vous me dire si ce bout de
code vous semble correct
Déjà, est-ce que ça donne le résultat attendu ?
Post by jaunit
et un minimum sécurisé svp ? Je me suis basé sur
quelques exemples trouvé çà et là, ainsi que sur un bouquin.
Désolé si je ne suis pas sur le bon groupe.
Attend... C'est bien de PHP que tu parles ? Oui ? Bon alors tu es à la
bonne adresse.
Post by jaunit
Merci
De rien !-)
Post by jaunit
<div>
<?php
include('menu.htm');
<HS>
.htm est un peu non-standard. Généralement, on utilise plutôt .html
</HS>
Post by jaunit
?>
</div>
<div>
<?php
include('menu_batiments.htm');
?>
</div>
<div>
<?php
include('connect_base.php');
$sql = 'SELECT id_batiment,designation_batiment,nombre_niveaux_batiment FROM
batiments';
$req = mysql_query($sql) or die('Erreur SQL !<br>'
$sql.'<br>'.mysql_error());
Tu affiche la requête dans ton message d'erreur ? Mauvaise idée. Utilise
plutôt une fonction de logging pour garder une trace de l'erreur, et
retourne un joli message à l'utilisateur final.
Post by jaunit
while($data = mysql_fetch_assoc($req))
{
echo '<br />
Code du b&acirc;timent ::: '.$data['id_batiment'].'<br />
D&eacute;signation du b&acirc;timent ::: '.$data['designation_batiment'].'
<br />
Nombre de niveaux ::: '.$data['nombre_niveaux_batiment'].'<br /><br />
';
<HS>
En général, pour présenter des données tabulaires, on utilise une table
</HS>
Post by jaunit
}
mysql_close();
?>
Bon, globalement, pour un débutant, c'est correct. Maintenant, il y a
certainement mieux à faire. Par exemple, séparer la partie SQL de la
partie présentation. Le plus courant est de distinguer:

1/ le "modèle", c'est à dire tout le code d'accès aux données. En
l'occurrence, avec par exemple un fichier modeles/batiments.php, dans
lequel tu aura uniquement les fonctions de gestions des bâtiments
(lister les bâtiments, retrouver un bâtiment particulier, ajouter un
bâtiment, supprimer un bâtiment etc). Ici, tu a déjà comme candidat une
fonction lister_batiments():

# modeles/batiments.php
<?php
include('connect_base.php');

function lister_batiments() {
results = Array();
$sql = "SELECT id_batiment, designation_batiment,"
. " nombre_niveaux_batiment "
. " FROM batiments";

$req = mysql_query($sql);
if (is_resource($req)) {
$donnees = Array();
while($data = mysql_fetch_assoc($req)) {
$donnes[] = $data;
}
$results["donnees"] = $donnees;
}
else {
results["erreur"] = mysql_error();
}
return $results;
}
?>


2/ La présentation - on parle généralement d'une "vue". Il s'agit d'une
partie qui sert à présenter le modèle. C'est bien sûr un mélange de html
et de php, mais la seule logique gérée est celle de la présentation:

# vues/liste_batiments.php
<table class="listing">
<thead>
<tr>
<th>id</th>
<th>désignation</th>
<th>nb de niveaux</th>
</tr>
</thead>
<tbody>
<?php foreach($donnees['batiments'] as $batiment) { ?>
<tr>
<td><?php echo $batiment['id'] ?></td>
<td><?php echo $batiment['designation_batiment'] ?></td>
<td><?php echo $batiment['nombre_niveaux_batiment'] ?></td>
</tr>
<?php } //foreach ?>
</tbody>
</table>

<ul class="actions">
<li><a href="ajouter_batiment.php">Ajouter un bâtiment</a></li>
<li><a href="supprimer_batiment.php">Supprimer un bâtiment</a></li>
</ul>

Note que cette vue est un fragment de html - le reste de la page est
construit plus loin...

3/ Le controlleur. C'est la page effectivement appelée par la requête
HTTP, et c'est elle qui est chargée d'appeller le modèle et la vue:

# liste_batiments.php
<?php
include "modeles/batiments.php";
$results = lister_batiments();
inclure "rendu/entete.php";
if (isset($results["donnees"]) {
$batiments = $results["donnees"];
inclure "vues/liste_batiments.php";
}
else {
$erreur = $results["erreur"];
inclure "rendu/erreur.php";
}
inclure "rendu/pied.php";
?>

Et voilà... Bon, après, c'est encore très perfectible. Par exemple:
1/ tu peux vouloir trier/filtrer/paginer la liste de documents
2/ il te faut une possibilité de sélectionner un bâtiment pour modif ou
suppression - en général, on met dans chaque ligne du tableau un lien
pour l'édition et une case à cocher pour sélectionner le batiment à
supprimer.
3/ il serait plus propre (et plus simple) d'avoir une fonction qui
"assemble" l'entete, la vue et le pied de page

Mais bon, si tu débute, tu a encore le temps avant d'en arriver là. Et
puis avant de réinventer la proverbiale roue carrée, autant s'intéresser
aux solutions existantes (genre CakePHP : simple et utilisable - pas une
horreur à la Java avec du XML partout). Mais AMHA, il est préférable
d'avoir quelques notions de développement web avant de venir à ce genre
de solutions - ne serait-ce que pour comprendre ce qu'elles apportent.
Post by jaunit
<br />
<a href="nouveau_batiment.php">Ajouter un b&acirc;timent</a> | <a
href="delete_batiment.php">Supprimer un b&acirc;timent</a>
</div>
<HS>
Si tu précise l'encodage dans l'entête de ta page, tu n'a pas besoin de
ces &entitees; à la con.
</HS>

Mes deux centimes...
jaunit
2007-02-09 14:03:02 UTC
Permalink
Bruno Desthuilliers sur fr.comp.lang.php le jeudi 08 février 2007 00:16
Post by Bruno Desthuilliers
Post by jaunit
Bonjour
J'ai commencé hier à tenter de créer une petite appli php/mysql. Je vous
préviens, je suis une vraie quiche.
Dans ce cas là, on ne te mangera pas - "real programmers don't eat
quiche", parait-il !-)
Bonjour et merci pour votre accueil :)
Post by Bruno Desthuilliers
Post by jaunit
Histoire de démarrer sur de bonnes bases, pouvez-vous me dire si ce bout
de code vous semble correct
Déjà, est-ce que ça donne le résultat attendu ?
Oui j'ai réussi à obtenir un résultat visiblement correct.. Mais je me
doutais bien que niveau organisation globale, ça ne collait pas.
Post by Bruno Desthuilliers
<HS>
.htm est un peu non-standard. Généralement, on utilise plutôt .html
</HS>
Post by jaunit
?>
</div>
<div>
<?php
include('menu_batiments.htm');
?>
</div>
<div>
<?php
include('connect_base.php');
$sql = 'SELECT id_batiment,designation_batiment,nombre_niveaux_batiment
FROM batiments';
$req = mysql_query($sql) or die('Erreur SQL !<br>'
$sql.'<br>'.mysql_error());
Tu affiche la requête dans ton message d'erreur ? Mauvaise idée. Utilise
plutôt une fonction de logging pour garder une trace de l'erreur, et
retourne un joli message à l'utilisateur final.
J'ai rectifié cette erreur que vous êtes plusieurs à avoir soulignée. En
fait lorsque j'ai posté ce message je n'avais pas traité la partie 'erreur'
mais simplement tenté de la gérer un minimum.
Post by Bruno Desthuilliers
Post by jaunit
while($data = mysql_fetch_assoc($req))
{
echo '<br />
Code du b&acirc;timent ::: '.$data['id_batiment'].'<br />
'.$data['designation_batiment'].' <br />
Nombre de niveaux ::: '.$data['nombre_niveaux_batiment'].'<br /><br />
';
<HS>
En général, pour présenter des données tabulaires, on utilise une table
</HS>
Ça c'est un mauvais réflexe que j'ai eu. On entend tellement partout que les
tables sont 'mauvaises' que j'ai fini par omettre que leur seul but c'est
justement d'afficher des données de ce style.
Post by Bruno Desthuilliers
Post by jaunit
}
mysql_close();
?>
Bon, globalement, pour un débutant, c'est correct. Maintenant, il y a
certainement mieux à faire. Par exemple, séparer la partie SQL de la
1/ le "modèle"
2/ La présentation -
3/ Le controlleur.
J'ai tout réorganisé et c'est vrai que c'est bien plus clair et surtout
logique. À vrai dire si je suis venu poser ma question c'est que j'étais en
train de me rendre compte qu'en grossissant, mon code allait devenir
ingérable ou alors au prix de nombreuses gymnastiques.
Post by Bruno Desthuilliers
1/ tu peux vouloir trier/filtrer/paginer la liste de documents
2/ il te faut une possibilité de sélectionner un bâtiment pour modif ou
suppression - en général, on met dans chaque ligne du tableau un lien
pour l'édition et une case à cocher pour sélectionner le batiment à
supprimer.
3/ il serait plus propre (et plus simple) d'avoir une fonction qui
"assemble" l'entete, la vue et le pied de page
C'est ce que je vais faire ce week-end
Post by Bruno Desthuilliers
Mais bon, si tu débute, tu a encore le temps avant d'en arriver là. Et
puis avant de réinventer la proverbiale roue carrée, autant s'intéresser
aux solutions existantes (genre CakePHP : simple et utilisable - pas une
horreur à la Java avec du XML partout). Mais AMHA, il est préférable
d'avoir quelques notions de développement web avant de venir à ce genre
de solutions - ne serait-ce que pour comprendre ce qu'elles apportent.
J'ai jeté un coup d'oeil à Cake et comme tous les débutants qui l'ont
installé (d'après les forums), je n'ai pas compris le fonctionnement :)
Post by Bruno Desthuilliers
<HS>
Si tu précise l'encodage dans l'entête de ta page, tu n'a pas besoin de
ces &entitees; à la con.
</HS>
Je rencontre quelques soucis avec mon éditeur texte (vi) et j'ai pris
l'habitude d'éviter les accents :-/
Post by Bruno Desthuilliers
Mes deux centimes...
Merci beaucoup
Je vais bosser dessus et je viendrais vous donner des nouvelles :)
Bruno Desthuilliers
2007-02-14 07:53:48 UTC
Permalink
Post by jaunit
Bruno Desthuilliers sur fr.comp.lang.php le jeudi 08 février 2007 00:16
(snip)
Post by jaunit
Post by Bruno Desthuilliers
Post by jaunit
while($data = mysql_fetch_assoc($req))
{
echo '<br />
Code du b&acirc;timent ::: '.$data['id_batiment'].'<br />
'.$data['designation_batiment'].' <br />
Nombre de niveaux ::: '.$data['nombre_niveaux_batiment'].'<br /><br />
';
<HS>
En général, pour présenter des données tabulaires, on utilise une table
</HS>
Ça c'est un mauvais réflexe que j'ai eu. On entend tellement partout que les
tables sont 'mauvaises' que j'ai fini par omettre que leur seul but c'est
justement d'afficher des données de ce style.
Il est courant dans tous les domaines, et particulièrement en
informatique, que des personnes érigent en règles absolues des
recommandations d'usages qu'elles n'ont pas bien compris... En
l'occurrence, les tables ne sont ni bonnes ni mauvaises, mais il est
recommandé de les utiliser *de préférence* pour des données tabulaires -
pas pour gérer la mise en page !-)

(snip)
Post by jaunit
Post by Bruno Desthuilliers
Mais bon, si tu débute, tu a encore le temps avant d'en arriver là. Et
puis avant de réinventer la proverbiale roue carrée, autant s'intéresser
aux solutions existantes (genre CakePHP : simple et utilisable - pas une
horreur à la Java avec du XML partout). Mais AMHA, il est préférable
d'avoir quelques notions de développement web avant de venir à ce genre
de solutions - ne serait-ce que pour comprendre ce qu'elles apportent.
J'ai jeté un coup d'oeil à Cake et comme tous les débutants qui l'ont
installé (d'après les forums), je n'ai pas compris le fonctionnement :)
C'est bien pour ça qu'il faut mieux commencer par les notions de bases
AMHA...

Continuer la lecture sur narkive:
Loading...