Circum Blog

Circum Net – IT – Conseils pratiques

Comment constituer une expression régulière ?

Uncategorized

Les expressions régulières permettent de définir des modèles à comparer à une chaîne de caractères. En pratique, elles facilitent grandement la manipulation de textes et de données: recherche, comparaison, substitution, tri de caractères.Elles sont utilisées par de nombreux programmes et leur exploitation constitue pour certains langages de programmation un atout.

Le “modèle” d’une expression régulière pourra être comparé à un ensemble de chaînes de caractères. Ce modèle détermine les critères d’appartenance d’une chaîne à un ensemble (les mots commençant par la lettre ‘s’, les mots contenant la suite de caractères ‘http’ ou se terminant par ‘.com’ …).

Exemples :

[0-9]
correspond à un chiffre de 0 à 9

[^0-9]
correspond à tout sauf à un chiffre de 0 à 9

^[0-9]+$
correspond aux nombres entiers

[a-zA-Z0-9_]
correspond à un caractère mot

[ \t\n\r]
correspond à un caractère d’espace (espace simple, tabulation, nouvelle ligne, retour à la ligne)

^[^@ ]+@[^@ ]+\.[^@ \.]+$
correspond à une adresse de courrier électronique

^[a-zA-Z0-9]+://[^ ]+$
correspond à une adresse url

Une expression régulière, comme on peut le constater dans les exemples ci-dessus, se limite à une suite de caractères. Cette suite est composée de deux types de caractères: les caractères dits “spéciaux” et les caractères dits “normaux”. Les caractères spéciaux (ou caractères “réservés”) ont une signification particulière pour le moteur/programme qui interprètera l’expression régulière. Les caractères normaux (ou standards) représentent, eux, les caractères alphanumériques habituels (abc …, 123 …).

L’exemple le plus basic d’expression régulière est certainement un suite de caractères standards (l’expression “ville” représente simplement le mot “ville”). Mais, en utilisant des caractères spéciaux on peut rendre cet exemple plus sophistiqué (l’expression “villes?” représente les mots “ville” et “villes”).

Analysons à présent la signification de quelques caractères spéciaux :

Le caractère “^” indique le début d’une chaîne de caractères
^u : représente les chaînes qui commencent par la lettre “u”

Le caractère “$” indique la fin d’une chaîne de caractères
s$ : représente les chaînes qui se terminent par la lettre “s”

Les caractères “+”, “*” et “?” expriment le nombre d’occurences d’un caractère ou d’une séquence
a+ : représente les chaînes contenant au moins une fois la lettre “a”
e*: représente 0,1, ou plusieurs occurences de la lettre “e”
s? : représente 0 ou 1 occurence de la lettre “s”

Le caractère “.” représente n’importe quel caractère unique
a.+ : représente les chaînes contenant la lettre “a” suivie d’au moins un caractère

La barre verticale “|” traduit une alternative
du|des : représente les chaînes “du” ou “des”

Les crochets [ ] précisent une liste de caractères à envisager
[abc] : représente les lettres “a”, “b” ou “c”
[^abc] : représente n’importe quel caractère sauf les lettres “a”, “b” et “c”
^[abc] : représente les mots qui commencent par la lettre “a”, “b” ou “c”
^[a-z] : représente les mots qui commencent par une lettre minuscule



Apprentissage de PHP

PHP, Programmation

Deux questions s’imposent d’entrée de jeu : PHP est-il facile à apprendre et cela prend-il beaucoup de temps? Dans la littérature sur le sujet, on trouve de nombreux auteurs qui répondent sans préambule OUI à la première question et NON à la deuxième. Il faut cependant nuancer ces propos.

PHP, pour être bien maîtrisé, nécessite de l’étudiant la même énergie et les mêmes efforts que pour tout langage de programmation. Si certaines de ses fonctionnalités sont aisées à manipuler d’autres concepts peuvent être plus ardus (telle que l’approche “orienté objet” introduite dans la version 5 de PHP).

Le temps d’apprentissage va grandement dépendre de votre “background” et des objectifs que vous vous êtes fixés: il est évident qu’une personne ayant déjà pratiqué un langage de programmation découvrira PHP avec un oeil différent de celui du débutant en programmation. La tâche sera plus difficile pour le débutant, mais certainement pas impossible. PHP présente sans conteste les avantages d’offrir aux développeurs Web une suite de procédures clairement définies et d’application directe.



Passage en minuscules des noms de fichiers

Systèmes, Unix

Il se peut que dans certaines situations (par souci de cohérence, de compatibilité…) l’on doive s’assurer de la basse casse des noms de fichiers d’un répertoire. Dans ce cas, les possibilités de scripting offertes par le shell peuvent s’avérer très utiles afin d’obtenir rapidement un conversion.

Voici, à titre d’exemple, un script de base qui permet de convertir en minuscules le nom des fichiers se trouvant dans un répertoire.

for x in *
do
mv $x `echo $x |tr ‘[:upper:]’ ‘[:lower:]’`
done

Pour exécuter ce script, il suffit, à partir d’une fenêtre terminal, de se placer dans le répertoire à traiter (cd) et de taper les lignes de codes présentées ci-dessus. Après avoir fourni l’instruction ‘done’, la conversion sera opérée.

Description des composants du script

– Une boucle ‘for’ prenant en compte tous les fichiers (*) du répertoire courant. A chaque passage dans la boucle le nom d’un fichier est stocké dans la variable ‘x’.

– Une instruction ‘mv’ qui renomme les fichiers. Cette commande prend 2 arguments: le premier étant le nom initial du fichier en cours de traitement (représenté par l’appel à la variable ‘x’) et le second étant le nouveau nom en minuscules (`echo…`).

– Une instruction qui donne le nom en minuscules du fichier. Celle-ci est encadrée par des backquotes (`) qui donne lieu à son évaluation. Elle utilise la commande ‘echo’ qui envoie le nom du fichier (c’est-à-dire la variable ‘x’) via l’opérateur de redirection d’input ‘|’ à la commande ‘tr’ qui effectue elle la traduction en minuscules.



Redirection : Headers already sent by

PHP, Programmation

Lorsque l’on utilise une instruction PHP qui manipule les en-têtes HTTP (par exemple via la fonction ‘header’ permettant d’enclencher une redirection), il faut s’assurer des les appeler avant d’avoir généré le moindre flux de sortie vers le client.

En effet, dès qu’un début de contenu est envoyé via le serveur Web (soit via des instructions HTML classiques, soit via des instructions PHP d’output comme echo et print) cela implique que les en-têtes HTTP ont déjà été précisés et communiqués au client. Or, il n’est plus possible de remanier les en-têtes HTTP une fois qu’ils sont envoyés. En conséquence, si -après avoir produit du code HTML ou lancé des instructions ‘echo’- on utilise dans un script la fonction ‘header’ pour rediriger un appel de page, le moteur PHP génère automatiquement un message d’erreur ‘Headers already sent by …’.

Il y a toutefois un moyen d’éviter cette difficulté : en utilisant la bufferisation de sortie – c’est-à-dire la mise en mémoire temporaire des données de sortie. On utilisera pour cela les fonctions prédéfinies ‘ob_start’ et ‘ob_end_flush’.

ob_start()

ob_start() démarre la bufferisation de sortie. Tant qu’elle est enclenchée, les données -hormis les en-têtes- ne sont pas envoyées au navigateur, mais temporairement placées dans un buffer.

ob_end_flush()

ob_end_flush() envoie vers le client le contenu du buffer de sortie (s’il existe) et désactive la bufferisation.

Utilisation d’un buffer d’output

<?php
// Démarrage de la bufferisation de sortie
ob_start();
	
echo "Cet output est issu d'un buffer de sortie.";

// Envoi vers le client du contenu du buffer
ob_end_flush();
?>

Note : ob_gzhandler() est une fonction qui -combinée à ‘ob_start()’- permet l’envoi de données compressées aux navigateurs qui supportent les pages compressées. Elle détermine le type d’encodage accepté par un navigateur, et retourne le contenu le plus adéquat. Ce procédé réduit considérablement le poids des pages à délivrer.

Pages compressées

Pour compresser les pages à la volée : il suffit de placer en tête de fichier la ligne suivante :

<?php ob_start('ob_gzhandler'); ?>
 ... suite du code ou de l'output ...


PHP et les chaînes de caractères

PHP, Programmation

En PHP, les chaînes de caractères peuvent être définies en utilisant deux types de délimiteurs : les apostrophes doubles et les apostrophes simples.

Dans le cas d’une chaîne de caractères délimitée par des apostrophes doubles (double-quotes), les variables à l’intérieur de la chaîne de caractères seront remplacées par leur valeur. Comme en C ou en Perl, le caractère anti-slash (\) peut ici être utilisé pour “protéger” un caractère spécial.

Si la chaîne de caractères est par contre limitée par des apostrophes simples (simple-quotes), les variables présentes dans la chaîne ne seront pas substituées et le caractère anti-slash (caractère d’échappement), n’aura aucun effet (à deux exceptions près, pour \’ et \\ , afin de pouvoir utiliser les caractères simple-quote et anti-slash dans la chaîne de caractères).

De nombreux programmeurs privilégient la limitation par des apostrophes simples lorsque qu’aucune substitution n’est nécessaire. Il n’y a alors pas d’analyse de chaîne impliquée et c’est donc sensé faire gagner du temps à l’interpréteur PHP.

Quelques bonnes pratiques :

<?php
// préférez la concaténation à l'imbrication :
echo "Hello $name"; 
echo 'Hello' . $name; // recommandé

// attention aux indices de tableaux
echo $users[admin]; // faux, si si admin est une constante
echo $users['admin']; // recommandé

echo "Hello $users[admin]"; 
echo 'Hello' . $users['admin']; // recommandé
?>


Générer du PDF avec PHP

PHP, Programmation

Il s’avère souvent pratique dans une application (Web ou autre) de pouvoir fixer des données au format PDF : formulaire, certificat, version imprimable, fichier attaché. PHP 5 permet la génération dynamique de fichiers PDF.

La librairie PDFlib
En PHP, la librairie principale de production PDF est pour l’instant PDFlib. Cette API, riche en fonctionnalités, n’est cependant pas gratuite et est distribuée sous licence commerciale (une version gratuite appelée PDFlib Lite est également disponible).

Fonctionnalités proposées par PDFlib :

– mise en page standard
– images
– éléments graphiques
– annotations
– signets
– tableaux
– protection

Plus d’information et téléchargement : www.pdflib.com

FPDF
Une alternative à PDFlib consiste à utiliser la classe FPDF. Celle-ci, distribuée gratuitement, même si elle offre moins de possibilités est beaucoup plus accessible : pas d’installation préalable, pas de licence commerciale, simplicité de mise en oeuvre.

Pour l’utiliser, il suffit de télécharger le package FPDF, de le décompresser dans un répertoire accessible pour votre application et d’en inclure le fichier principal dans votre code.

Exemple de création d’un document PDF :

<?php
include('fpdf/fpdf.php');

$pdf=new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial','B',18);
$pdf->Cell(40,10,'Bonjour à tous!');
$pdf->Output("test.pdf");
?>

Vous trouverez la documentation de cette classe sur le site www.fpdf.org.



Vérifier le type de navigateur avec PHP

PHP

En accédant aux informations véhiculées par la requête HTTP émise à partir du client, on peut détecter le type de navigateur utilisé. Pour cela, en PHP, il suffit d’invoquer le tableau super glogal $_SERVER. Celui-ci peut être vu comme une variable spéciale de PHP qui contient toutes les informations relatives au serveur et à l’exécution (comme les en-têtes HTTP, les dossiers et chemins du script).

Il est toujours possible d’utiliser la fonction ‘var_dump’ pour afficher les informations structurées d’un tableau (en l’occurence $_SERVER). Vous en découvrirez ainsi toutes les composantes et informations utiles:

<?php
var_dump($_SERVER);
?>

L’élément particulier qui nous intéresse dans ce tableau est $_SERVER[‘HTTP_USER_AGENT’]. Sa valeur décrit le client HTML utilisé pour voir la page courante (exemple : Mozilla/4.5 [en] (X11; U; Linux 2.2.9 i586).

Affichage du contenu de l’élément HTTP_USER_AGENT :

<?php
echo $_SERVER['HTTP_USER_AGENT'];
?>

Une fois sa valeur connue/récupérée, on peut l’utiliser pour optimiser l’affichage de sa page en fonction des capacités du client – notamment en exploitant la fonction prédéfinie get_browser().

HTTP_USER_AGENT et get_browser() :

<?php
$browser = get_browser($_SERVER['HTTP_USER_AGENT'], true);
print_r($browser);
?>

Les valeurs retournées reprennent les caractéristiques du navigateur : version, css, frames, JavaScript, cookie …

Vous pouvez évidemment à la suite mettre en oeuvre votre propre batterie de tests afin de détecter les propriétés/caractéristiques qui vous paraissent les plus pertinentes dans votre projet.

Détection de la plateforme du client:

<?php
$u_agent = $_SERVER['HTTP_USER_AGENT']; 
$platform = '';
if (preg_match('/linux/i', $u_agent)) 
    {
    $platform = 'linux';
    }
elseif (preg_match('/macintosh|mac os x/i', $u_agent)) 
    {
    $platform = 'mac';
    }
elseif (preg_match('/windows|win32/i', $u_agent)) 
    {
    $platform = 'windows';
    }
?>


Prolonger la durée de vie des objets en PHP

PHP, Programmation

Etant donnée que la durée de vie d’un objet n’excède pas la durée d’exécution du script qui le crée, quand un objet est détruit, les valeurs de ses attributs (les variables membres) sont perdues! Situation peu confortable si l’on pense à utiliser ces données ultérieurement ou à les échanger entre programmes.

Pour pallier cette difficulté on peut avoir recours aux opérations de sérialisation et désérialisation. Grâce à celles-ci, il est possible de conserver l’état d’un objet sur un support de stockage de façon à pouvoir en recréer une copie exacte ultérieurement ; mais également de transmettre l’objet par valeur d’une application à une autre.

La sérialisation consiste donc à stocker les valeurs des attributs d’une instance d’un objet dans une séquence linéaire. La fonction “serialize” retourne une chaîne contenant une représentation linéaire de l’objet qui lui est passé en argument, pour stockage.

La désérialisation consiste à accepter des informations stockées et à recréer des objets à partir de celles-ci. La fonction “unserialize” retourne sous forme d’objet la séquence passée en argument.

Voyons cela à travers un exemple :

Script tools.inc.php – la classe à l’origine des objets dont on veut enregistrer l’état.

<?php
class Book
   {
   private $type;
   private $price;
   private $title;

   function Book($par)
        {
        $this->type = $par;
        }

   public function setPrice($par)
        {
        $this->price = $var;
        }
        
   public function getPrice()
        {
        return $this->price;
        }
        
   public function setTitle($par)
        {
        $this->title = $par;
        }
        
   public function getTitle()
        {
        return $this->title;
        }
    }
?>
page1.php – l’instanciation de l’objet et sa sérialisation.

<?php
/* Appel à la définition de classe */
include("tools.inc.php");

$myBook = new Book('1');
$myBook->setTitle('The Black Dahlia');
$myBook->setPrice('19');	


/* Sérialisation de l'objet */
$s = serialize($myBook);

/* Ecriture de la séquence sur disque */
$fp = fopen("store", "w");
fputs($fp, $s);
fclose($fp);
?>
page2.php – la récupération de l’objet sérialisé.

<?php
/* Appel à la définition de classe */
include("tools.inc.php");

/* Récupération de la séquence */
$s = implode("", @file("store"));

/* Désérialisation et récupéartion de l'objet*/
$aBook = unserialize($s);

echo $aBook->getTitle();
/* Affiche "The Black Dahlia" */
?>


Déboguer un script PHP

PHP, Programmation

Commenter et faire parler vos scripts

On ne saurait trop insister sur le fait qu’inclure des commentaires dans un programme ne peut être que bénéfique. On l’appréciera d’ailleurs assez rapidement: une bonne documentation facilite grandement le développement, la correction, la mise à jour et le partage des scripts. 

Mais si les commentaires sont fort utilisés pour annoter un programme php, ils sont également particulièrement sollicités lorsque l’on doit déboguer un script. Les commentaires permettent en effet de mettre entre parenthèses (en d’autres termes de désactiver) une partie du code afin d’identifier plus facilement où se situe le problème. 

Ajoutons à cela que pour suivre encore de plus près ce que fait un script et pour comprendre ou identifier clairement les sources d’erreurs éventuelles, il est utile de parsemer son code d’output de test ou de vérification à l’aide -par exemple- de la fonction ‘print_r’. 

print_r($variable_du_script); 

Cette fonction affiche la valeur des variables et s’il s’agit d’un tableau le détail de ses clés/valeurs. On obtient ainsi de façon contextuelle la composition des variables utilisées dans le script. Il est alors aisé de vérifier si ces variables ont bien été affectées et si la logique du script est respectée et valide.

Mettre au point un fonction de déboguage

Si l’insertion d’instructions d’output dans le code peut faciliter le déboguage, elle peut également, si l’on y prend pas garde, déboucher sur une pollution du code. En effet, ces instructions ne font pas partie de l’affichage “normal” du script et elles doivent être effacées ou mises en commentaires avant de passer à la phase de production.

Le recours à une fonction adéquate peut éviter ces difficultés.

Définition d’une fonction de déboguage      

<?php
$debugmode = true;
function debug($var)
    {
    global $debugmode;
    if ($debugmode) print_r($var);
    }



debug($unevariable);



debug($uneautrevariable);
?>

 
La fonction ‘debug’ prend une variable en paramètre. Elle teste si la variable ‘$debugmode’ est à ‘true’. Si c’est le cas elle lance l’instruction d’affichage ‘print_r’ pour la variable reçue en paramètre. Si on ne désire plus voir apparaître les affichages de déboguage il suffit de fixer ‘$debugmode’ à ‘false’.

Adaptation de la fonction pour un affichage HTML     

<php
$debugmode = true;
function html_print_r($var)
    {
    echo “<pre>”;
    echo str_replace(“n”, “<br/>”, print_r($var)).
    echo “</pre>”;
    }
 
function debug($var)
    {
    global $debugmode;
    if ($debugmode) html_print_r($var);
    }



debug($unevariable);



debug($uneautrevariable);
?>

Pour que les informations fournies par ‘print_r’ soient directement visibles dans le navigateur Web, il faut légèrement adapter notre fonction de façon à ce que les retours de ligne soient traduits en code html “<br/>”. Ceci peut être très facilement réalisé en faisant intervenir l’instruction de remplacement de chaînes “str_replace”.



L’ « orienté objet » et le langage PHP

PHP, Programmation

L’approche « orientée objet » consiste à créer une représentation informatique du monde auquel on s’intéresse, dans laquelle un objet représente un concept, une idée ou toute entité du monde physique, comme une personne, un livre ou encore une pièce de moteur. Un objet est ainsi une abstraction d’un élément du monde réel.

Il s’agit donc pour l’analyste/programmeur de déterminer les objets pertinents et d’en isoler les données ainsi que les opérations qui leur sont associées.

Selon cette modélisation un objet va se caractériser par ses attributs et ses méthodes.

• Les attributs (appelés également membres): il s’agit des données caractérisant la structure interne de l’objet. On peut les voir comme des variables stockant les informations d’état de l’objet.
• Les méthodes (appelées également fonctions membres): elles définissent l’ensemble des actions/opérations que l’objet est à même de réaliser.

L’approche « orientée objet » est particulièrement adaptée au développement d’applications qui évoluent de façon conséquente et dont la complexité croit continuellement.

Points forts de l’approche « orientée objet » :

• modularité ;
• réutilisabilité ;
• extensibilité.

Qu’en est-il en PHP ?

A l’origine, PHP n’était pas un langage destiné à suivre le modèle orienté objet. Ce n’est que progressivement (à partir de la version 4) que des fonctionnalités « objet » ont été introduites. Mais cette implémentation était pour le moins légère et il manquait des concepts fondamentaux comme les constructeurs/destructeurs, les modificateurs d’accès, ou encore la gestion des exceptions. On était loin de pouvoir comparer PHP à un langage objet tel Java.

PHP5, reposant sur le moteur Zend2, va lui nettement plus loin : celui-ci permet en effet une mise en oeuvre beaucoup plus aboutie (contrairement à PHP4 et au moteur Zend) de l’approche “orientée objet”.