Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Conseils pour debutant

10 réponses
Avatar
jaunit
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>

10 réponses

Avatar
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)
Personnellement je remplaçerais donc tout le bloc

<?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();
?>


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é

Avatar
P'tit Marcel
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 réponds juste sur l'aspect sécurité :


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)


$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/

Avatar
Bruno Desthuilliers
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.

Avatar
Bruno Desthuilliers
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 !-)

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 ?

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.

Merci


De rien !-)

<div>
<?php
include('menu.htm');


<HS>
.htm est un peu non-standard. Généralement, on utilise plutôt .html
</HS>

?>
</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.

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>

}
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.

<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...

Avatar
Thierry
bonjour,

Jusque là, d'accord.
merci :)


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.

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

Avatar
Bruno Desthuilliers
bonjour,


Jusque là, d'accord.


merci :)


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)...

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.


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 ?

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".

Si tu pensais à l'argument transfo lourde pour le serveur je réponds
d'avance:
1/ ça reste à prouver


Suffit de faire un bench. Mais n'y perds pas ton temps, la question est
réglée depuis longtemps.

(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.


Avatar
Rakotomandimby (R12y) Mihamina
Bruno Desthuilliers wrote:

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.

Avatar
jaunit
Bruno Desthuilliers sur fr.comp.lang.php le jeudi 08 février 2007 00:16

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 :)


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.


<HS>
.htm est un peu non-standard. Généralement, on utilise plutôt .html
</HS>

?>
</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.


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>


Ç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.


}
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"
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.


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

C'est ce que je vais faire ce week-end


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 :)

<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 :-/


Mes deux centimes...


Merci beaucoup
Je vais bosser dessus et je viendrais vous donner des nouvelles :)


Avatar
jaunit
P'tit Marcel sur fr.comp.lang.php le mercredi 07 février 2007 22:53

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 réponds juste sur l'aspect sécurité :


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


Avatar
Bruno Desthuilliers
Bruno Desthuilliers sur fr.comp.lang.php le jeudi 08 février 2007 00:16



(snip)



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>



Ç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)

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...