Cette page décrit les outils et procédures que je me suis forgés dans la cadre de mon apprentissage en solitaire du développement de site à l'aide du langage PHP.
Les plus gros problèmes que j'ai rencontrés on été
Il faut utiliser à fond la session ($_SESSION) dans laquelle on peut tout stocker SAUF les ressources. Sont des ressources toutes les références hors du monde php : handlers de fichiers, connexion à une base de données …)
Un sous répertoire commun permet de regrouper les images, css, script à inclure ...
error_reporting = E_ALL display_errors = On
Pour tester, valider des expressions, fonctions plus ou moins tordues, une page php n'est pas indispensable, un simple script exécutable en ligne de commande peut faire l'affaire
Avec en première ligne la référence à l'interpréteur (#! /usr/bin/php), et en le rendant exécutable (chmod +x test.php) on peut le lancer comme un fichier quelconque script local : ./test.php
#! /usr/bin/php <?php //phpinfo () ; /* default locale is taken from this ini setting */ ini_set('intl.default_locale', 'fr_FR'); $cal = IntlCalendar::createInstance() ; echo IntlDateFormatter::formatObject($cal) , "\n\r";
<?php /* Créé le : 14 décembre 2019, 11:21:00 Auteur : */ session_start(); /* Toutes les variables stockées dans la session deviennent des variables du script */ foreach($_SESSION as $key=>$valeur) $$key = $valeur ; /* * Séparer la connexion de ce fichier permet de * ne changer que le fichier connexion.php pour passer * d'un hébergement à l'autre (site de développement vers site de production) */ require 'connexion.php' ; /* * Quelques fonctions fort utiles dans bien des cas dont * la fonction trace($message, $script) utilisée ci-dessous * les fonctions de formatage de date en fonction de l'init_set ci-dessous * et bien d'autres */ require 'fonctions.inc.php' ; /* * un pied de page à insérer en bas de chaque page */ $piedPage = "<p align='center'>© 2019-" . date("Y") . "</p>"; /* * default locale is taken from this ini setting */ */ ini_set('intl.default_locale', 'fr_FR'); //$trace = true ; // Active une trace $trace = false ; // Pas de trace $_SESSION['trace'] = $trace ; //pour ici ou ailleurs if ($trace) {switch (session_status ()) { case PHP_SESSION_DISABLED : $message = "Session désactivée"; break ; case PHP_SESSION_NONE : $message = "Sessions activée mais inactive"; break ; case PHP_SESSION_ACTIVE : $message = "Session activée et active"; break ; } ; recordLog ("trace", "{$message} dans enTete.php") ; } ; ?>
Une simple page php, qui inclut le fichier enTete.php va permettre d'afficher tout le contenu de la session, des bribes de cette session ... ou suppléer le script php quand des données de la session doivent être testées.
<?php require 'commun/enTete.php' ; if (isset ($_POST['effacer'])) { session_unset(); $_SESSION['loginTime'] = time(); $loginTime = $_SESSION['loginTime'] ; } if (isset($_POST['preTest'])) { header("Location: preTest.html"); } if (isset($_POST['razLog'])) { $requete = "call consomacfgspip.viderLog();" ; $connexion->query($requete) ; } ?> <html> <head> <link href="commun/consom.css" media="all" rel="stylesheet" type="text/css" /> </head> <body> <h1>Test du <?=strftime('%A %d %B %Y à %H:%M:%S', time())?></h1> <?php /* * On peut ici inspecter les variables de la session, tester des accès aux bases ... */ ecrireTableau($_SESSION, "La session") ; if (isset($_POST['log']) && $_POST['log'] == "on" ) { echo "<h2>Les logs</h2>" ; $tableLog = tableSQL("select * from log order by `id` desc ;"); if($tableLog == null || count ($tableLog) == 0) echo "<p>Y'en a pas !!!</p>" ; else { echo '<table><th align="center">timeStamp</th><th headers="niveau"', 'align="center">niveau</th>', '<th headers="executant" align="center">Exécutant</th><th headers="message"', 'align="center">message</th>' ; foreach($tableLog as $t) echo "<tr><td>", $t['timeStamp'], "</td><td>", $t['niveau'], "</td><td>", $t['executant'], "</td><td>", $t['message'], "</td></tr>" ; echo "</table>" ; } } ?> <form action="test.php" method="post"> <label for="log">Afficher les log</label> <input type="checkbox" id="log" name="log" value"afficher les logs" checked="on" /> <input type=submit name ="effacer" value="réinitialiser la session" /> <input type=submit name="preTest" value="retour au pré-test"/> <input type=submit name="razLog" value="Effacer les log"/> </form> </h1> <?= $piedPage ?> </body> </html>
function recordLog ($niveau, $message) { global $connexion ; $executant = $_SERVER['SCRIPT_NAME'] ; $requete = "INSERT INTO `log` (`timeStamp`, `niveau`, `executant`, `message`) " ."VALUES (now(), \"{$niveau}\", \"{$executant}\", \"{$message}\") ;" ; return $connexion->query($requete) ; }
Note : la gestion des \ n'est pas évidente, il faut vérifier pour chaque message.
function popup ($message) { $filtre = '"' . "'" ; echo '<script type="text/javascript">alert (\'', addcslashes($message, $filtre) , '\');</script>' ; }ou mieux utiliser une boite de dialogue avec la balise <dialog> qui ne fonctionne pas, sans configuration, avec certains butineurs;
Note : les problèmes des \n ne sont pas complètement résolus quand on doit se rabattre sur la fonction popup ().
function popDialog ($nomDialogue, $message) { $refusDialog = addslashes($message) . "\\nVotre explorateur web n\'accepte pas les dialogues améliorés\\n" . "pour y remédier voir la page estay.fr/Dialog.html" ; echo "<script type=\"text/javascript\">", "dialogue = document.getElementById('", $nomDialogue, "');", "if (typeof dialogue.showModal === \"function\") ", "dialogue.showModal () ;", "else alert (\"", $refusDialog, "\") ;" , "</script>"; }
function ecrireTableau($tableau, $nom) { echo "-------------------{$nom}---------------------$lt;br />"; if (!isset($tableau) || count($tableau) == 0) { echo "Vide<br />----------------------------------------------------<br />"; return; } echo "<table>"; foreach ($tableau as $key => $value) { echo "<tr><td align='right'>{$key }</td><td>"; if (stripos($key, 'time')) echo "le ", date("j/m/y H:m:s T", $value); else if (stripos($key, "date")) echo "le ", stamp($value) ; else if (is_array($value)) ecrireTableau($value, $key) ; else echo $value; echo "</td></tr>"; } echo "<</table>----------------------------------------------------<br />"; }
Il peut être pratique de stocker les résultats des requêtes sql dans la session sous forme de tableaux associatifs représentant un tuple ou tous les tuples d'un curseur.
Pour garantir la fermeture d'un curseur, les fonctions suivantes offrent facilitation et uniformisation. Ces fonctions ne vérifient aucunement la rectitude des requêtes.
La première tupleSQL () retourne le premier tuple de la requête, a priori unique, alors que la suivante tableSQL () produit une table des tuples produits par la requête
function tupleSQL (string $requete) { global $connexion ; $reponse = $connexion->query($requete) ; $tuple = $reponse->fetch(PDO::FETCH_ASSOC) ; $reponse->closeCursor () ; return $tuple ; } function tableSQL (string $requete) { global $connexion ; $reponse = $connexion->query($requete) ; $tuple= array () ; while ($t = $reponse->fetch(PDO::FETCH_ASSOC)) { $tuple[] = $t ; } $reponse->closeCursor () ; return $tuple ; }