PHP : la bonne pratique

Apprendre les bonnes pratiques de programmation en PHP


précédentsommairesuivant

V. Pratiques de programmation

V-A. Les bases

PHP est un langage vaste permettant aux programmeurs de tout niveau de produire du code non seulement rapidement, mais aussi efficacement. Cependant, en avançant dans le langage, nous oublions parfois les bases que nous avions apprises (ou survolées) de façon un peu légère en faveur de raccourcis et autres mauvaises habitudes. Pour combattre ce problème récurrent, cette section tient à rappeler aux programmeurs les pratiques de programmations de base de PHP.

V-B. La date et le temps

Le PHP a une classe nommée DateTime afin d'aider à lire, écrire, comparer et calculer avec les dates et le temps. Il existe beaucoup de fonctions liées aux dates en PHP en plus de DateTime, mais ce dernier fournit une interface orientée objet à la plupart des usages courants. Il peut gérer les fuseaux horaires, mais cela dépasse le cadre de notre introduction.

Pour commencer à travailler avec DateTime, convertissez les chaînes de caractères représentant des dates ou du temps avec la fabrique createFromFormat() ou faites new \DateTime. Utilisez la méthode format() pour convertir la date vers une représentation sous forme de chaîne de caractères.

 
Sélectionnez
1.
2.
3.
4.
5.
<?php
$raw = '22. 11. 1968';
$start = \DateTime::createFromFormat('d. m. Y', $raw);

echo 'Date : ' . $start->format('m/d/Y') . "\n";

Le calcul des dates avec DateTime est possible à l'aide de la classe DateInterval. DateTime a des méthodes comme add() et sub() qui prennent une variable de type DateInterval en argument. N'écrivez pas du code qui attend que chaque jour ait le même nombre de secondes, car le passage à l'heure d'été/d'hiver et les changements de fuseaux horaires brisent cette assertion. Utilisez plutôt les intervalles de date. Pour calculer ces différences, utilisez la méthode diff(). Cette dernière va retourner un objet DateInterval qui est super facile à afficher.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
<?php
// créer une copie de $start et ajouter un mois et six jours
$end = clone $start;
$end->add(new \DateInterval('P1M6D'));

$diff = $end->diff($start);
echo 'Différence: ' . $diff->format('%m mois, %d jours (total: %a jours)') . "\n";
// Différence: 1 mois, 6 jours (total: 37 jours)

Avec les objets DateTime vous pouvez utiliser les opérateurs de comparaison :

 
Sélectionnez
1.
2.
3.
4.
<?php
if ($start < $end) {
    echo "$start est avant $end!\n";
}

Un dernier exemple pour faire la démonstration de la classe DatePeriod. Il est utilisé pour itérer sur des évènements récurrents. Il peut prendre deux objets DateTime, start et end, et l'intervalle pour lequel tous les évènements seront retournés.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
<?php
// affiche tous les jeudis entre $start et $end
$periodInterval = \DateInterval::createFromDateString('first thursday');
$periodIterator = new \DatePeriod($start, $periodInterval, $end, \DatePeriod::EXCLUDE_START_DATE);
foreach ($periodIterator as $date) {
    // affiche chaque date pour la période
    echo $date->format('m/d/Y') . ' ';
}

V-C. Les motifs de conception

Lorsque vous construisez votre application, il est souvent utile d'utiliser des motifs courants dans votre code et dans la structure générale de votre projet. Utiliser ces motifs est utile, car il devient alors plus facile de gérer le code et de permettre aux autres développeurs de comprendre plus rapidement comment tout cela tient.

Si vous utilisez un framework alors la plus grande partie du code métier et la structure du projet se baseront sur ce framework, donc de nombreuses décisions sur les motifs à utiliser seront prises à votre place. Mais c'est à vous de choisir les motifs les plus utiles à utiliser au sein de votre code. Si, d'un autre côté, vous n'utilisez pas de framework pour construire votre application, cela ne vous empêchera pas de choisir un certain nombre de motifs que vous jugerez nécessaires.

Continuer la lecture sur les motifs de conceptions.

V-D. Travailler avec de l'UTF-8

Cette section a été traduite à partir de la page d'Alex Cabal sur les meilleures pratiques PHP et sert de base pour vous donner des conseils sur l'utilisation de l'UTF-8.

V-D-1. Il n'y a pas de recette magique. Faites attention, soyez consciencieux et cohérent.

Jusqu'à présent PHP n'inclut pas de support bas niveau pour l'Unicode. Il existe des moyens de s'assurer que les chaînes de caractères encodées en UTF-8 seront traitées correctement, mais cela n'est pas facile et demande une attention particulière tout le long de la chaîne de traitement, allant de la page HTML à vos requêtes SQL en passant par le PHP. Les prochains paragraphes vont tenter de vous résumer la bonne approche à adopter face à du contenu Unicode.

V-D-2. UTF-8 au niveau de PHP

Les opérations basiques sur les chaînes de caractères comme la concaténation ou l'affectation de chaînes à des variables ne demandent rien de particulier en ce qui concerne l'UTF-8. En revanche, la plupart des fonctions manipulant les chaînes comme strpos() et strlen() ont besoin d'une attention particulière. Ces fonctions ont en effet souvent leur contrepartie mb_* comme mb_strpos() et mb_strlen(). Ces fonctions mb_* proviennent de l'extension pour les chaînes de caractères multioctets et ont été conçues spécialement pour les chaînes Unicode.

Vous devez utiliser les fonctions mb_* à chaque fois que vous manipulez une chaîne de caractères Unicode. Par exemple, si vous utilisez substr() sur une chaîne UTF-8, il y a de fortes chances pour que le résultat contienne des caractères à moitié tronqués. La fonction correcte dans ce genre de cas serait d'utiliser mb_substr().

La difficulté réside dans le fait de se souvenir à chaque fois d'utiliser les fonctions mb_* quand c'est nécessaire. Si jamais vous l'oubliez ne serait-ce qu'une seule fois alors votre chaîne Unicode aura de grandes chances d'être incompréhensible en sortie de traitement.

Les fonctions traitant les chaînes n'ont pas toutes leur équivalent mb_*. S'il y en a une qui est dans ce cas alors, vous n'avez pas de chance.

Vous devriez utiliser la fonction mb_internal_encoding() en haut de tous vos scripts PHP (ou en haut d'un fichier d'en-tête global) et la fonction mb_http_output() juste après si vous devez afficher du texte en sortie. Définir explicitement l'encodage de caractères de vos chaînes vous simplifiera énormément la vie.

Par ailleurs, beaucoup de fonctions PHP opérant sur les chaînes ont un paramètre optionnel vous permettant de spécifier l'encodage de caractères. Vous devriez alors toujours indiquer explicitement que vous utilisez de l'UTF-8. Par exemple, la fonction htmlentities() possède une option pour l'encodage des caractères. Notez que depuis PHP 5.4.0, l'UTF-8 est l'encodage par défaut pour htmlentities() et htmlspecialchars().

Finalement, si vous développez et déployez une application utilisant l'UTF-8 sans être certain que l'extension mbstring sera présente, pensez alors à utiliser des alternatives comme le package Composer patchwork/utf8. Il utilisera mbstring si jamais il le trouve sinon il utilisera les fonctions non-UTF8.

V-D-3. UTF-8 au niveau de la base de données

Si votre script PHP a accès à MySQL, il y a une forte chance que vos chaînes de caractères soient stockées en tant que chaînes non UTF8 même si vous suivez les précautions vues plus haut.

Pour vous assurer que vos chaînes aillent de PHP vers MySQL en UTF-8, vérifiez que votre base de données et les tables qu'elle contient sont toutes enregistrées avec l'encodage de caractères et la collation utf8mb4 et que votre connexion PDO est aussi mise sur cet encodage. Voir l'exemple plus bas. Ceci est extrêmement important.

Notez que pour utiliser le support complet pour UTF-8, vous devez utiliser l'encodage de caractères utf8mb4 et non utf8 ! Voir les détails plus loin pour comprendre pourquoi.

V-D-4. UTF-8 au niveau du navigateur web

Utilisez la fonction mb_http_output() pour vous assurer que votre script PHP affichera du texte en UTF-8 dans votre navigateur.

Le navigateur devra ensuite être averti par le biais de la réponse HTTP que cette page est encodée en UTF-8. L'approche historique pour faire cela était d'inclure le tag <meta> dans le tag <head>. Cette approche est parfaitement valide, mais indiquer l'encodage directement dans l'en-tête HTTP Content-Type est en fait plus rapide.

 
Sélectionnez
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.
<?php
// Indique à PHP que nous allons effectivement manipuler du texte UTF-8
mb_internal_encoding('UTF-8');
 
// indique à PHP que nous allons afficher du texte UTF-8 dans le navigateur web
mb_http_output('UTF-8');
 
// Notre chaîne UTF-8 de test
$string = 'Êl síla erin  e-govaned vîn.';
 
// Découpe une sous partie de la chaîne à l'aide d'une fonction multioctet
// Notez que la découpe se fait au niveau d'un caractère non ASCII pour la démonstration
$string = mb_substr($string, 0, 15);
 
// Connexion à une base de données pour stocker la chaîne transformée
// Voir les exemples d'utilisation de PDO dans ce document
// Notez la commande `set names utf8mb4`
$link = new \PDO(   
                    'mysql:host=your-hostname;dbname=your-db;charset=utf8mb4',
                    'your-username',
                    'your-password',
                    array(
                        \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
                        \PDO::ATTR_PERSISTENT => false
                    )
                );

// Stocke notre chaîne en tant que chaîne UTF-8 dans la base de données
// Votre base ainsi que ses tables doivent être encodées avec utf8mb4 (character set et collation).
$handle = $link->prepare('insert into ElvishSentences (Id, Body) values (?, ?)');
$handle->bindValue(1, 1, PDO::PARAM_INT);
$handle->bindValue(2, $string);
$handle->execute();

// Récupère la chaîne que l'on vient juste de stocker pour prouver qu'elle a été correctement stockée
$handle = $link->prepare('select * from ElvishSentences where Id = ?');
$handle->bindValue(1, 1, PDO::PARAM_INT);
$handle->execute();

// stocke le résultat dans un objet que l'on affichera dans notre HTML
$result = $handle->fetchAll(\PDO::FETCH_OBJ);

header('Content-Type: text/html; charset=utf-8');
?><!doctype html>
<html>
    <head>
        <title>page de test UTF-8</title>
    </head>
    <body>
        <?php
        foreach($result as $row){
            print($row->Body);  // Cela devrait correctement afficher notre contenu en UTF-8
        }
        ?>
    </body>
</html>

précédentsommairesuivant

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Licence Creative Commons
Le contenu de cet article est rédigé par Josh Lockhart et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale 3.0 non transposé.
Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright © 2017 Developpez.com.