Blog geekesque... ou presque

Aller au contenu | Aller au menu | Aller à la recherche

Mot-clé - fonctions utiles

Fil des billets - Fil des commentaires

dimanche 9 octobre 2016

Log coloré en TCL

Pour faire suite au billet Log coloré en PHP, voici la version utilisable en TCL.

Je me suis appuyé sur une astuce donnéesur wiki.tcl.tk et tout particulièrement sur la proposition d'Andy Goth.

Code

namespace eval d {
   variable levels {"error" "warning" "notice" "debug" "info" "success"}
   foreach {name value} {r 1 g 2 b 4 c 6 m 5 y 3} {
      proc $name {} "return \033\\\[01\\;3${value}m"
      proc [string toupper $name] {} "return \033\\\[01\\;4${value}m"
   }
   proc n {} {return \033\[\;0m}
   proc puts {text {level ""}} {
      switch -nocase $level {
         "error" { ::puts "[r]$text[n]" }
         "warning" { ::puts "[y]$text[n]" }
         "notice" { ::puts "[c]$text[n]" }
         "debug" { ::puts "[m]$text[n]" }
         "info" { ::puts "[b]$text[n]" }
         "success" { ::puts "[g]$text[n]" }
         default { ::puts "$text" }
      }
   }
}

Utilisation

Voici un petit script de test:

#/usr/bin/tclsh
source debugger.tcl
foreach level $::d::levels {
   ::d::puts "Level is set to $level" $level
}

Le rendu sera:

Level is set to error
Level is set to warning
Level is set to notice
Level is set to debug
Level is set to info
Level is set to success

jeudi 28 juillet 2016

Log coloré avec PHP en console (PHP-CLI)

Il arrive que l'on fasse des scripts PHP qui doivent fonctionner en console, mais l'affichage est terne (blanc sur fond noir) et ne permet pas de mettre en valeur les messages importants.

J'ai donc créé une fonction log qui permet de coloriser le texte affiché sur une console linux. Elle fonctionne aussi avec MobaXterm, je ne l'ai pas testée avec cygwin.

La fonction

/*
 * Display a colored message, based on level
 * @var string $message The message to display
 * @var string $level The level (none, success, info, warning, error)
 * @var array $disp An array of informations to display
 * @void
 */
function log($message, $level='', $disp=array('class'=>true, 'function'=>true, 'file'=>true, 'line'=>true)) {
    $c = array(
        'r' => "\033[31m",
        'g' => "\033[32m",
        'b' => "\033[34m",
        'y' => "\033[33m",
        'n' => "\033[0m"
    );
    $bt = debug_backtrace();
    $caller = array_shift($bt);
    $precaller = array();
    if (count($bt)>0) {
        $precaller = array_shift($bt);
    }
    $prefixes = array();
    if ($disp['class'] === true && array_key_exists('class', $precaller)) { $prefixes[] = $precaller['class']; }
    if ($disp['function'] === true && array_key_exists('function', $precaller)) { $prefixes[] = $precaller['function']; }
    if ($disp['file'] === true && array_key_exists('file', $precaller)) {
        $prefixes[] = $precaller['file'];
    } elseif ($disp['file'] === true) {
        $prefixes[] = $caller['file'];
    }
    if ($disp['line'] === true) { $prefixes[] = $caller['line']; }
    $prefix = implode('::', $prefixes).'::';
    switch($level) {
        case 'success': echo $c['g'], $prefix, ' ', $message, $c['n'], PHP_EOL; break;
        case 'info': echo $c['b'], $prefix, ' ', $message, $c['n'], PHP_EOL; break;
        case 'warning': echo $c['y'], $prefix, ' ', $message, $c['n'], PHP_EOL; break;
        case 'error': echo $c['r'], $prefix, ' ', $message, $c['n'], PHP_EOL; break;
        default: echo $prefix, ' ', $message, PHP_EOL; break;
    }
}

Explications

Les couleurs

On crée un tableau contenant les différents codes couleurs ANSI a appliquer. Je ferai bientôt une petite explication sur ces codes. Notez bien que les codes doivent être entre guillemets et pas entre apostrophes, sans quoi ils ne seront pas interprétés.

La couleur n (normal) est en fait le retour à la normale, une suppression du code précédemment appliqué.

backtrace

La fonction PHP debug_backtrace permet d'obtenir dans un tableau toute la chaîne ayant permis d'arriver à l'exécution de la ligne courante, dans l'ordre anté-chronologique.

La première entrée du tableau contient une information très importante pour nous: le numéro de la ligne ayant appelé la fonction courante. La deuxième entrée du tableau, si elle existe, contient les informations sur le fichier, la classe et la fonction ayant appelés la fonction courante. S'il n'y a qu'une entrée dans le tableau, cela signifie que l'appel a été fait hors de toute fonction.

jeudi 2 octobre 2014

Des arrondis précis : le retour

Il y a quelques années, j'avais fait un petit billet sur les arrondis précis dans lequel je fournissais une source.

Cette source a changé, car j'ai eu besoin d'une nouvelle fonction, en plus de floor et ceil: round.

/**
 * Arrondit au plus près
 * @param float $value Valeur à arrondir
 * @param integer $precision Précision (défaut: 0)
 * @param float $step Pas à adopter
 * @return float
 */
public function round($value,$precision=0, $step=1) {
   $precision = abs(intval($precision));
   $step = abs(floatval($step));
   if (($step == 0) || ($step == 1)) {
      $value = round($value, $precision);
   } else {
      $value = round( round($value/$step)*$step, $precision);
   }
   return $value;
}

Et j'en ai profité pour corriger un léger bug dans les fonctions précédentes.

lundi 17 mars 2014

Un bloc à onglets sous Yii

J'ai eu besoin de pouvoir intégrer facilement un bloc avec des onglets dans une page générée par Yii et je n'ai rien trouvé d'assez léger, j'ai donc développé une petite extension: ETabbedDiv.

Elle utilise les fonctionnalités de jquery-ui et s'implémente très facilement:

Utilisation

  • dézippez le fichier et copiez ETabbedDiv.php dans votre répertoire protected/extensions/
  • appelez le widget depuis votre vue, comme dans l'exemple suivant:
<?php $this->widget('application.extensions.ETabbedDiv',
   array(
      'divClass' => 'tabbed',
      'tabs' => array(
         'tab1' => array('content' => '<p>Ceci est le premier onglet</p>'),
         'tab2' => array('title'=>'Second', 'content' => '<p>Ceci est le second onglet</p>'),
         'other' => array('content' => '<p>Et voila le dernier onglet</p>'),
      ),
   ),
);
?>

Paramètres

  • divClass (optionnel) est la classe CSS qui sera appliquée au bloc contenant les onglets,
  • tabs est un tableau associatif des onglets, sous la forme id => tableau de contenu décrit ci-dessous
    • title (optionnel) est le titre qui sera affiché dans l'onglet. S'il n'est pas renseigné, id sera utilisé
    • content est le contenu HTML a afficher dans l'onglet

Source

Vous trouverez la version anglaise sur Yii Framework

Lien de téléchargement sur ce blog : ETabbedDiv

lundi 14 octobre 2013

[MàJ] Yii : ajout d'une entrée depuis le CGridView

(Mise à jour : ajout de l'option fillIsFilter) Il est parfois utile de pouvoir remplir un CGridView directement depuis sa vue sans avoir à changer de page. Cette extension permet d'avoir un formulaire dans la grille et d'ajouter à la volée de nouvelles entrées.

Pour les anglophones, la source originale est sur cette page.

Lire la suite...

vendredi 21 juin 2013

Recherche sur plage de taille avec CGridView

En travaillant sur un système de reporting de transferts de fichier (utilisant Yii), j'ai eu besoin d'un champ permettant de faire une recherche sur la taille des fichiers, avec une syntaxe "humainement compréhensible". Et cela avec un seul champ de recherche. (traduction de mon article à http://www.yiiframework.com/wiki/516/search-a-file-size-range-in-cgridview/)

Lire la suite...

Lecture de date en PHP

Etant très souvent embêté avec les différents formats de dates utilisés au sein d'un même site, j'ai exploré le manuel PHP et j'avais trouvé DateTime::createFromFormat très pratique. Mais valable uniquement en PHP 5.3 minimum. Qu'à cela ne tienne, voici presque une équivalence pour PHP 5.1 et plus.

Lire la suite...

mercredi 11 avril 2012

[MàJ] Utiliser OpenStreetMap plutôt que GoogleMap ?

Edition du 11 avril: Je me rends compte que je n'ai pas mis l'adresse du site dédié, il s'agit de osmLeaflet.jQuery. C'est là que l'on peut facilement suivre les mises à jour et évolutions.

Depuis quelques temps, je m'intéresse au projet OpenStreetMap qui me semble une bonne alternative à GoogleMap pour l'intégration de cartes sur des sites.

Malheureusement pour les plus fainéant d'entre nous (moi y compris), aucun code officiel à utiliser directement n'existe. Sauf depuis l'intervention de Mathieu Robin qui a créé un plugin OSM pour JQuery, qu'il a appelé osmLeaflet.jQuery.

Voici l'exemple d'utilisation qu'il donne sur son billet d'explication qui vous montre la simplicité déconcertante de son utilisation, mais je vous invite fortement à aller voir le blog.

$(document).ready(function () {
    // Initialisation de la map
    var osmMap = $(document).osmLeaflet({
           target : 'map',
           zoom : 12,
           lattitude : 51.50,
           longitude : -0.09
    });
 
    // Ajout d'un marker
    osmMap.osmLeaflet('addMarker', {lattitude : 51.50, longitude : -0.09});
 
    // Ajout d'une popup
    osmMap.osmLeaflet('addPopup', {lattitude : 51.51, longitude : -0.13, text : "Hey !"});
});

lundi 5 septembre 2011

Vérification d'adresse IP

Bien qu'il soit rare que l'on ait à mettre une adresse IP dans un formulaire, il arrive que l'on ait besoin de les vérifier.

Donc, pour faire suite au billet Les assertions et vérification de formulaire, voici la petite fonction qui me permet de vérifier la syntaxe d'une adresse IP.

Fonction

<?php
function isIPAddress($ip) {
   $pattern = '/^\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b$/';
   if (preg_match($pattern, $ip) == 1) return true;
   else return false;
}
?>

Explications de l'expression régulière

L'expression vérifie que l'adresse contient 4 termes séparés par des points. La partie importante est celle que l'on retrouve deux fois:

(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)

Cette partie vérifie que les termes:

  • commencent par 25 et sont suivi d'un chiffre de 0 à 5
  • ou commencent par 2, suivi d'un chiffre de 0 à 4, suivi d'un chiffre de 0 à 9
  • ou peut commencer par un 0 ou un 1, suivi des nombres de 0 à 99

Ceci nous permet donc de vérifier que les termes couvrent la plage 000 à 255.

vendredi 22 octobre 2010

Traiter le BBCode

Le BBCode est fréquemment utilisé, voici une fonction qui permet de s'en servir sur son site. Il y a en fait plusieurs fonctions, la plus importante est bbcode() qui traite la chaîne (donc à utiliser à l'affichage).

Les autres fonctions servent à reformater les chaînes particulières qui ont besoin d'un remplacement plus évolué, comme les liens, les images ou les listes.

<?php
function bbcode($string) {
    $pattern = array(
        '/\\n/',
        '/\\r/',
        '/\[list\](.*?)\[\/list\]/ise',
        '/\[b\](.*?)\[\/b\]/is',
        '/\[strong\](.*?)\[\/strong\]/is',
        '/\[i\](.*?)\[\/i\]/is',
        '/\[u\](.*?)\[\/u\]/is',
        '/\[s\](.*?)\[\/s\]/is',
        '/\[del\](.*?)\[\/del\]/is',
        '/\[url=(.*?)\](.*?)\[\/url\]/ise',
        '/\[email=(.*?)\](.*?)\[\/email\]/is',
        '/\[img](.*?)\[\/img\]/ise',
        '/\[color=(.*?)\](.*?)\[\/color\]/is',
        '/\[quote\](.*?)\[\/quote\]/ise',
        '/\[code\](.*?)\[\/code\]/ise'
    );
 
    $replace = array(
        '',
        '',
        'sList(\'\\1\')',
        '<b>\1</b>',
        '<strong>\1</strong>',
        '<i>\1</i>',
        '<span style="text-decoration: underline;">\1</span>',
        '<span style="text-decoration: line-through;">\1</span>',
        '<span style="text-decoration: line-through;">\1</span>',
        'urlfix(\'\\1\',\'\\2\')',
        '<a href="mailto:\1" title="\1">\2</a>',
        'imagefix(\'\\1\')',
        '<span style="color: \1;">\2</span>',
        'sQuote(\'\1\')',
        'sCode(\'\1\')'
    );
 
    return preg_replace($pattern, $replace, nl2br(htmlspecialchars(stripslashes($string))));
}
 
function sQuote($string) {
    return '<div class="quote">' . stripslashes(trim($string)) . '</div>';
}
 
function sCode($string){
    $pattern =  '/\<img src=\\\"(.*?)img\/smilies\/(.*?).png\\\" alt=\\\"(.*?)\\\" \/>/s';
    $string = preg_replace($pattern, '\3', $string);
    return '<pre>' . trim($string) . '</pre>';
}
 
function sList($string) {
    $tmp = explode('[*]', stripslashes($string));
    $out = null;
    foreach($tmp as $list) {
        if(strlen(str_replace('', '', $list)) > 0) {
            $out .= '<li>' . trim($list) . '</li>';
        }
    }
    return '<ul>' . $out . '</ul>';
}
 
function imagefix($img) {
    if(substr($img, 0, 7) != 'http://') {
        $img = './images/' . $img;
    }
    return '<img src="' . $img . '" alt="' . $img . '" title="' . $img . '" />';
}
 
function urlfix($url, $title) {
    $title = stripslashes($title);
    return '<a href="' . $url . '" title="' . $title . '">' . $title . '</a>';
}
?>
 
// Utilisation:
echo bbcode($texte)

mercredi 28 juillet 2010

URLs raccourcies et encodage en base 62

De plus en plus de systèmes de raccourcissement d'URL existent, et le système est somme toute relativement simple à mettre en place. Il demande un peu de logique et l'utilisation d'un encodage en base 62: les 10 chiffres et les 26 lettres (minuscules et majuscules).

Lire la suite...

jeudi 1 juillet 2010

Générer des clefs RSA en php

Voici une fonction très simple pour générer des clefs RSA.

Elle ne prend qu'un argument, la longueur en bits de la clé privée (512, 1024 ou 2048). Elle retourne un tableau contenant la clef privée, la clef publique et un message d'erreur.

<?php
/**
 
 * Generates RSA keys
 
 * @param integer $pkbits Private key bits
 * Specifies how many bits should be used to generate a private key
 * Must be 512, 1024 or 2048
 * @return array Contains private key, public key and error message
 */
 
public function generateRsa($pkbits=512) {
 
   $rsaKey = array('private' => '', 'public' => '', 'error' => '');
   $pkbits = intval($pkbits);
   if ($pkbits != 512 && $pkbits != 1024 && $pkbits != 2048) {
      $rsaKey['error'] = 'Private key bits must be 512, 1024 or 2048';
      return $rsaKey;
   }
   $res = openssl_pkey_new(array('private_key_bits' => $pkbits));
 
   // Get private key
 
   openssl_pkey_export($res, $privkey);
 
   // Get public key
 
   $pubkey = openssl_pkey_get_details($res);
 
   $rsaKey['private'] = $privkey;
 
   $rsaKey['public'] = $pubkey['key'];
   return $rsaKey;
}
?>

jeudi 27 mai 2010

Fonction glob récursive

La fonction glob est utilisée dans de nombreux langages, elle sert à lister tous les fichiers (et répertoires) qui vérifient un masque.

La petite fonction qui suit sert à rechercher tous les fichiers qui vérifient un masque dans une arborescence.

<?php
/**
 * Recursive glob
 * @param string $pattern Masque à vérifier
 * @param string $path Répertoire initial
 * @param integer $flags Drapeaux
 * @return array list of files
 */
function rglob($pattern='*', $path='', $flags = 0) {
   $paths=glob($path.'*', GLOB_MARK|GLOB_ONLYDIR|GLOB_NOSORT);
   $files=glob($path.$pattern, $flags);
   foreach ($paths as $path) {
      $files=array_merge($files,rglob($pattern, $path, $flags));
   }
   return $files;
}
?>

Les drapeaux sont ceux utilisés par la fonction glob:

  • GLOB_MARK : Ajoute un slash final à chaque dossier retourné
  • GLOB_NOSORT : Retourne les fichiers tant l'ordre d'apparence (pas de tri)
  • GLOB_NOCHECK : Retourne le masque de recherche si aucun fichier n'a été trouvé
  • GLOB_NOESCAPE : Ne protège aucun métacaractère d'un antislash
  • GLOB_BRACE : Remplace {a,b,c} par 'a', 'b' ou 'c'
  • GLOB_ONLYDIR : Ne retourne que les dossiers qui vérifient le masque
  • GLOB_ERR : Stop lors d'une erreur (comme des dossiers non lisibles), par défaut, les erreurs sont ignorées.

jeudi 25 mars 2010

Ajax en post avec jQuery

Actuellement, jQuery possède une fonction ajax qui est getJSON et qui permet de faire des appels Ajax qui récupèrent des données au format JSON. Le seul souci est que les paramètres envoyées le sont en GET, avec toutes les contraintes que cela impose.

Pour pouvoir fonctionner en POST avec la même logique, j'ai étendu jQuery avec une fonction postJSON:

jQuery.extend({
   postJSON: function( url, data, callback) {
      return jQuery.post(url, data, callback, "json");
   }
});

Elle prend les mêmes arguments que getJSON mais fonctionne en POST.

jeudi 12 novembre 2009

Retrouver le type MIME

Lorsqu'on propose un téléchargement via une interface web, ou si on veut mettre des pièces jointes dans un mail, il faut avoir le "mime-type" (Multipurpose Internet Mail Extensions) du fichier. Une fonction PHP existe pour celà, c'est mime_content_type() malheureusement elle n'est pas toujours disponible.

Voici une petite astuce qui permet de la recréer:

<?php
if (!function_exists(mime_content_type)) {
   // Nous sommes dans le cas où elle n'existe pas
   function mime_content_type($f) {
      $ext = strtolower(substr($f,strrpos($f, ".")));
      // On ne se base que sur l'extension du fichier
      switch($ext){
         case ".gz": $mtype = "application/x-gzip"; break;
         case ".tgz": $mtype = "application/x-gzip"; break;
         case ".zip": $mtype = "application/zip"; break;
         case ".pdf": $mtype = "application/pdf"; break;
         case ".png": $mtype = "image/png"; break;
         case ".gif": $mtype = "image/gif"; break;
         case ".jpg": case "jpeg": $mtype = "image/jpeg"; break;
         // Notez le cas d'un même type avec différentes extensions
         case ".txt": $mtype = "text/plain"; break;
         case ".htm": case ".html": $mtype = "text/html"; break;
         default: $mtype = "application/octet-stream"; break;
         // Par défaut, c'est application/octet-stream
      }
      return $mtype;
   }
}
?>

samedi 10 octobre 2009

Recherche "à proximité"

Ceci est la suite logique du billet précédent et permet de faire une recherche de points géolocalisés dans un rayon autour d'un point donné.

L'explication fera intervenir quelques légères notions mathématiques et géographiques, mais uniquement pour la compréhension du fonctionnement.

Lire la suite...

lundi 5 octobre 2009

Envoyer un email html avec pièce jointe en PHP

C'est toujours un casse-tête pour envoyer un email avec des pièces jointes.

Cette classe est très simple d'utilisation et possède seulement les options basiques. Elle prépare le contenu du mail et utilise simplement la fonction mail() de php pour l'expédier. Le code ne sera quasiment pas détaillé, ci-dessous vous trouverez essentiellement l'explication de l'utilisation et l'accès aux sources.

Lire la suite...

dimanche 6 septembre 2009

Les assertions et vérification de formulaire

Cette classe abstraite permet de vérifier certaines assertions, ou en d'autres termes de vérifier qu'une valeur répond à une condition.

Les vérifications présentées ici sont très simples mais permettent de traiter la plupart des conditions requises pour un formulaire. Voici le détail des fonctionnalités actuelles.

Lire la suite...

vendredi 7 août 2009

Fonction fputcsv en PHP4

Alors que la fonction fgetcsv existe en PHP4 et en PHP5, la fonction fputcsv n'existe qu'en PHP5, ce qui est fort dommage lorsqu'on veut travailler avec des fichiers d'exports ou bien lorsqu'on veut avoir un script utilisable sur la plupart des serveurs sans connaitre leur version de PHP.

Lire la suite...

mercredi 13 mai 2009

Fonction str_split

Bien que je développe essentiellement en PHP 5, il m'arrive parfois d'avoir à travailler sur des hébergements qui sont encore en PHP 4, ce qui est parfois handicapant car des fonctions manquent.

Récemment, je me suis servi dans un script de la fonction str_split() qui permet de transformer une chaîne de caractères en un tableau. Bien entendu, je ne suis pas le seul à avoir fait cela, il y a d'autres versions sur la page officielle.

array str_split ( string string [, int split_length] ) : Convertit une chaîne de caractères en tableau. Si le paramètre optionnel split_length est spécifié, le tableau retourné sera découpé en sous-parties, chacune de taille split_length, sinon, chaque sous-partie aura la taille d'un caractère.

Cette fonction retourne FALSE si split_length est inférieur à 1. Si la longueur de split_length est supérieure à celle de string, la chaîne entière est retournée dans le premier (et seul) élément du tableau.

Fonction

<?php
if (!function_exists('str_split')) {
   /**
    * Convertit une chaine en tableau
    * Retourne false si $length est inférieur à 1, sinon un tableau
    * @param string $string Chaine à convertir
    * @param integer $length Longueur des sous-ensembles
    * @return mixed
    */
   function str_split($string, $length=1) {
      if (intval($length)<1) return false;
      if (strlen($string)<=$length) return array($string);
      $parts = array();
      while(strlen($string)>0) {
         $parts[] = substr($string, 0, $length);
         $string = substr($string, $length);
      }
      return $parts;
   }
}
?>

Utilisation

$string = 'Salut Dave';
$test = str_split($string);
print_r($test);
$test2 = str_split($string, 3);
print_r($test2);

Cet exemple va afficher:

Array (
    [0] => S
    [1] => a
    [2] => l
    [3] => u
    [4] => t
    [5] =>
    [6] => D
    [7] => a
    [8] => v
    [9] => e
)
Array(
   [0] => Sal
   [1] => ut 
   [2] => Dav
   [3] => e
)

- page 1 de 2