Voici quelques bouts de codes PHP tout faits. Vous pouvez tout reprendre comme bon vous semble !
Le code suivant permet de chronométrer le temps de génération des pages par PHP.
Attention : seul le temps de génération de la page est mesuré. Ni le temps de la requête DNS, ni le temps de téléchargement de la page ne sont pris en compte (pour cela il faut coupler PHP et JavaScript).
<?php $time = microtime(); // Actual timestamp $time = explode(' ', $time); // separate integer and fractional part of time $begin = $time[0]+$time[1]; // Needed to get "0.000025 sec" instead of "2.5E-5 sec" format // YOUR CODE HERE $time = microtime(); $time = explode(' ', $time); $end = $time[0]+$time[1]; echo round(($end - $begin),6).' seconds'; ?>
Sous PHP 5, c'est même encore plus simple :
<?php
$begin = microtime(TRUE);
// YOUR CODE HERE
$end = microtime(TRUE);
echo round(($end - $begin),6).' seconds';
?>
Base64 est la représentation en texte (chaine de caractères) d'un fichier binaire comme une image. Quand on veut transférer une image sur un système ne pouvant traiter que du texte, on peut transformer les fichiers en BASE64 pour les mettre en texte.
Les fonctions suivantes peuvent alors être utiles : la première lit une image, la transforme en texte au format BASE64. La seconde fait l'inverse : elle écrit une image à partir d'un code en BASE64.
<?php // conversion d'une image en BASE64 function file2base64($source) { $bin_data_source = fread(fopen($source, "r"), filesize($source)); // reading as binary string $b64_data_source = base64_encode($bin_data_source); // BASE64 encodage return $b64_data_source; } // création d'une image à partir d'un code en BASE64 function base642file($b64_data_target, $image_target_name) { $bin_data_target = base64_decode($b64_data_target); // base64 decodage $image_target = fopen($image_target_name, 'wb'); // Create a file if (fwrite($image_target, $bin_data_target)) // Write the file return TRUE; else return FALSE; }
$source = 'image.png';
$base64_data = file2base64($source);
//
$data64 = 'iVBORw0KGgoAAAANSU [ … / … ] FTkSuQmCC';
base642file($data64, 'destination.png');
?>
Cette méthode :
Voici une fonction qui génère la page du mois actuel d'un calendrier :
<?php function afficher_calendrier() { $ce_mois_lettres = date('F'); $jours_semaine = array('Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'); $premier_jour = mktime('0', '0', '0', date('m'), '1', date('Y')); // haut du tableau $calendar = '<table id="calendrier">'."\n"; $calendar.= '<caption>'.$ce_mois_lettres.'</caption>'."\n"; $calendar.= '<tr><th>'.implode('</th><th>', $jours_semaine).'</th></tr><tr>'; // un nouveau mois ne commence pas forcément le premier jour de la semaine (lundi) $decalage_jour = date('w', $premier_jour-'1'); if ($decalage_jour > 0) { for ($i = 0; $i < $decalage_jour; $i++) { $calendar.= '<td></td>'; } } // création du tableau $date_t = date('t'); $date_d = date('d'); for ($jour = 1; $jour <= $date_t; $jour++) { $calendar.= '<td'; // ajoute une classe CSS sur aujourd'hui $calendar .= ($jour == $date_d) ? ' class="active"' : ''; $calendar.= '>'; $calendar.= $jour; $calendar.= '</td>'; $decalage_jour++; if ($decalage_jour == '7') { $decalage_jour = '0'; $calendar.= '</tr>'."\n"; $calendar.= ($jour < $date_d) ? '<tr>' : ''; } } // complète le tableau HTML avec des cases vides à la fin if ($decalage_jour > '0') { for ($i = $decalage_jour; $i < '7'; $i++) { $calendar.= '<td></td>'; } $calendar.= '</tr>'."\n"; } $calendar.= '</table>'."\n"; return $calendar; } ?>
Le calendrier généré possède l'ID CSS "calendrier" ; la date actuelle possède la classe CSS "active".
Les abréviations des jours sont définissables au début de la fonction, et le le nom du mois est affiché en Anglais. Pour l'avoir en Français ou dans une autre langue, on peut par exemple utiliser un switch sur $ce_mois_lettres.
Si vous devez supprimer un fichier (image, ou autre) en PHP à partir d'une requête d'un utilisateur, il convient de faire gaffe : never trust user input.
Considérons ce code :
$dossier = 'sous_dossier/'; $fichier = $_GET['nom_du_fichier']; if (TRUE === unlink($dossier.$fichier)) echo 'fichier supprimé';
Il marche très bien : ce code supprime un fichier dont le nom est contenu dans l'URL.
Si je vais sur cette URL : http://monsite/page.php?nom_du_fichier=image.jpg, alors le fichier /sous_dossier/image.jpg sera supprimé. Bien.
Maintenant, imaginons qu'un utilisateur utilise cette URL : http://monsite/page.php?nom_du_fichier=../page.php. Vous voyez ? Le fichier supprimé sera donc /sous_dossier/../page.php, autrement dit /page.php !
Ceci n'est pas acceptable : n'importe quel fichier peut-ainsi être supprimé, y compris des fichiers importants !
La solution que j'ai retenue, c'est de partir du principe que les fichiers que l'utilisateur gère se trouvent dans un dossier à part des fichiers PHP. Par exemple, si ce sont des fichiers images, ils sont dans un dossier /image. Nous allons donc lister tous les fichiers dans ce dossier, et comparrer au fichier dans le $_GET. S'il y a correpondance, alors c'est bon, sinon on ne fait rien :
$dossier = 'sous_dossier';
$liste = scandir($dossier); // listage des fichiers
$fichier = $_GET['nom_du_fichier'];
$nb_fichier = count($liste);
for ($i = 0 ; $i < $nb_fichiers ; $i++) {
if ($liste[$i] == $fichier and !($liste[$i] == '..' or $liste[$i] == '.')) {
if (TRUE === unlink($dossier.$liste[$i])) echo 'fichier supprimé';
}
}
Ici, j'ai même rajouté un test : le fichier ne dois pas être '.' ni '..' (qui sont tout le dossier et le dossier parent).
Évidement, il convient d'ajouter les traditinnels « htmlspecialchars() »
J’ai passé quelques heures sur ce problème : j’ai une image PNG avec une région transparente, et je veux la transformer en JPG avec la transparence mise en blanc. Le soucis, c’est qu’à l’arrivé je me retrouve avec une image où transparence est remplacée par du noir !
Le code suivant fonctionne à merveille (vous pouvez remplacer la fonction « imagejpeg » par « imagepng », ça marche aussi). Ce qui compte ce sont les autres fonctions de manipulation d’image avec GD.
$image = 'troll-troll-dad-dance-jump-l.png'; function remove_alpha($FichierSource) { $FichierDest = 'destination.jpg'; // largeur et hauteur list($width, $height) = getimagesize($FichierSource); // Crée une ressource image de destination $IMG_dest = imagecreatetruecolor($width, $height); // Remplie cette image de blanc imagefill($IMG_dest, 0, 0, imagecolorallocate($IMG_dest, 255, 255, 255)); // Ouvre le fichier source en PNG. $IMG_source = imagecreatefrompng($FichierSource); // Place le fichier PNG sur le fond blanc imagecopy($IMG_dest, $IMG_source, 0, 0, 0, 0, $width, $height); imagedestroy($IMG_source); // enregistrement en JPG, qualité 90% imagejpeg($IMG_dest, $FichierDest, 90); imagedestroy($IMG_dest); return $FichierDest; } echo '<img src="'.remove_alpha($image).'"/>';
En PHP on peut ajouter un fichier dans uen archive ZIP. Pour ajouter un dossier, il faut ajouter les fichiers un par un.
L’idée est simple : on fait une fonction récursive à l’aide de GOTO. Listant les entrées d’un dossier, si l’entrée est un fichier, on l’ajoute, si c’est un dossier on reboucle sur la fonction elle même avec le fichier en question.
Le code qui suit utilise la POO ainsi que l’instruction goto apparue en PHP 5.3. Notez qu’il est sûrement possible de faire beaucoup plus simple avec les bibliothèques Gzip ou autres.
// nouvelle archive $zip = new ZipArchive; // ouverture if ($zip->open('test.zip', ZipArchive::CREATE) === TRUE) { $folder = 'mon_dossier'; inputfolder: // "goto" apparu en php >= 5.3.0 // ouvre le dossier if ($handle = opendir($folder)) { // parcourt les entrées une par unes. while (FALSE !== ($entry = readdir($handle))) { // on exclu les dossiers parents (..) et courant (.), // ainsi que les fichiers dont on n’a pas les droits en lecture if ($entry != "." AND $entry != ".." AND is_readable($folder.'/'.$entry)) { // si c’est un dossier, on reboucle avec le GOTO if (is_dir($folder.'/'.$entry)) { // ne surtout pas oublier ceci :) $folder = $folder.'/'.$entry; goto inputfolder; } // on ajoute le fichier (l’arborescence d’origine est conservée) $zip->addFile($folder.'/'.$entry, $folder.'/'.$entry); } } // ferme le dossier closedir($handle); } // ferme l’archive ZIP $zip->close(); echo '<p>ok : <a href="test.zip">test.zip</a></p>'; } else { echo '<p>échec lors du open()</p>'; }
Ce code génère une liste déroulante (de type optgroup/option) des fuseaux horaires, regroupés par continent et affichant les décallages (+2h, +3h…). Il fonctionne pour PHP 5.2 et supérieur.
Retourne le formulaire html, dans une liste d’options. function form_fuseau_horaire() { Liste tous les fuseaux, sous la forme "Europe/Paris" $all_timezones = timezone_identifiers_list(); $liste_fuseau = array(); $cities = array(); Les séparre par continent, en sous-tableaux foreach($all_timezones as $tz) { $spos = strpos($tz, '/'); if ($spos !== FALSE) { $continent = substr($tz, 0, $spos); $city = substr($tz, $spos+1); $liste_fuseau[$continent][] = array('tz_name' => $tz, 'city' => $city); } Même chose pour UTC, sauf que lui n’a pas de continent… if ($tz == 'UTC') { $liste_fuseau['UTC'][] = array('tz_name' => 'UTC', 'city' => 'UTC'); } } $form = '<p>'; $form .= '<label for="fuseau_horaire">Fuseau Horaire :</label>'; $form .= '<select id="fuseau_horaire" name="fuseau_horaire">' ; foreach ($liste_fuseau as $continent => $zone) { $form .= '<optgroup label="'.ucfirst(strtolower($continent)).'">'."\n"; foreach ($zone as $fuseau) { $form .= '<option value="'.htmlentities($fuseau['tz_name']).'"'; Affiche les informations sur le décallage : (UTC+02:30) $timeoffset = date_offset_get(date_create('now', timezone_open($fuseau['tz_name'])) ); $formated_toffset = '(UTC'.(($timeoffset < 0) ? '–' : '+').str_pad(floor((abs($timeoffset) / 3600)), 2, '0', STR_PAD_LEFT).':'.str_pad( floor((abs($timeoffset) % 3600) / 60), 2, '0', STR_PAD_LEFT).') '; $form .= '>'.$formated_toffset.' '.htmlentities($fuseau['city']).'</option>'."\n"; } $form .= '</optgroup>'."\n"; } $form .= '</select> '."\n"; $form .= '</p>'."\n"; return $form; }
Ce code retourne un tableau des entêtes d’une requête PHP. Il prend en entrée soit une chaine des entêtes brutes (retournées par exemple par CURL), soit un tableau à une dimension (par exemple celui de $http_response_header
créée par la fonction file_get_contents
).
Il retourne un tableau associatif des entêtes HTTP :
if (!function_exists('http_parse_headers')) { function http_parse_headers($raw_headers) { $headers = array(); $array_headers = (is_array($raw_headers) ? $raw_headers : explode("\n", $raw_headers)); foreach ($array_headers as $i => $h) { $h = explode(':', $h, 2); if (isset($h[1])) { $headers[$h[0]] = trim($h[1]); } } return $headers; } }
Il retourne un tableau associatif des entêtes HTTP (dont le contenu peut varier, toutes les entêtes n’étant pas pareil sur tous les serveurs) :
Array ( [0] => HTTP/1.1 200 OK [Date] => Sat, 29 May 2004 12:28:14 GMT [Server] => Apache/1.3.27 (Unix) (Red-Hat/Linux) [Last-Modified] => Wed, 08 Jan 2003 23:11:55 GMT [Accept-Ranges] => bytes [Content-Length] => 438 [Connection] => close [Content-Type] => text/html … … )
À nouveau, la fonction file_get_contents
est généralement ce qui suffit pour récupérer un fichier distant. Généralement, mais pas toujours : comment ça se passe s’il y a une redirection ? Si la page est chiffrée ? S’il nécessite un user-agent non vide ? Très vite, file_get_contents
ne suffit plus et il faut se tourner vers un outil plus puissant.
Cet outil, c’est curl
. Elle existe en PHP et permet de récupérer une ou plusieurs pages distantes (en parallèle, donc en gagant du temps).
Ce qui suit est mon code pour récupérer des pages distantes : il couvre une bonne partie des problèmes que j’ai pu rencontrer, dont ceux listés plus haut.
$urls = array( 1 => "http://example.com/url1", 2 => "http://example.com/url3", 2 => "http://example.com/url3", );
// a timeout $timeout = 30; // init curl handlers $master = curl_multi_init(); // init each url foreach ($urls as $i => $url) { $curl_arr[$url] = curl_init(trim($url)); curl_setopt_array($curl_arr[$url], array( // force Curl to return data instead of displaying it CURLOPT_RETURNTRANSFER => TRUE, // follow 302 ans 301 redirects CURLOPT_FOLLOWLOCATION => TRUE, // connection timeout CURLOPT_CONNECTTIMEOUT => $timeout, // downloading timeout CURLOPT_TIMEOUT => $timeout, // User-agent (uses the UA of browser) CURLOPT_USERAGENT => $_SERVER['HTTP_USER_AGENT'], // ignore SSL host error CURLOPT_SSL_VERIFYHOST => FALSE, // ignore SSL cyphering error CURLOPT_SSL_VERIFYPEER => FALSE, // accept GZIPed pages CURLOPT_ENCODING => "gzip", //CURLOPT_VERBOSE => 1, // ignore header CURLOPT_HEADER => 0, )); curl_multi_add_handle($master, $curl_arr[$url]); } do { curl_multi_exec($master, $running); usleep(100000); } while ($running > 0); // multi select contents foreach ($chunk as $i => $url) { $response = curl_multi_getcontent($curl_arr[$url]); $results[$i] = $response; } // Ferme les gestionnaires curl_multi_close($master);
Le contenu des URL récupérées se trouve dans $result
.
Page créée en janvier 2011. Dernière mise à jour le vendredi 8 décembre 2017.
Adresse de la page : https://lehollandaisvolant.net/tuto/php/