Kamelot Blog

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

jeudi 30 avril 2009

jeu
30
avr '09

Zend_View_Helper_FormRadio : Ce que ne dit pas la doc

L'autre jour je parlais d'éléments non documentés dans Zend_log_filter.

A l'instar de Zend_log_filter, Zend_View_Helper_FormRadio n'est pas complètement documenté.

Voici un post de Maxence Delannoy qui lève une partie du voile.

Au menu

  • L'argument fantôme
  • Les attributs "magiques"
  • Personnaliser les labels

mercredi 29 avril 2009

mer
29
avr '09

php scan : nowdoc

Il y a déjà peu de gens qui connaissent la notation HEREDOC.

<?php
$variables = 'hellos';
$a = <<<MONMARQUEUR
ma chaine avec des $variables
MONMARQUEUR;
echo $a;
?>

affiche

ma chaine avec des hellos

depuis php 5.3 on a en plus le NOWDOC

http://be2.php.net/manual/fr/language.types.string.php#language.types.string.syntax.nowdoc

Nowdoc

Ce que dit la doc

Nowdoc est aux chaînes entourées de guillemet simple ce qu'Heredoc est aux chaînes entourées de guillemet double.

Nowdoc est spécifié de manière similaire à Heredoc, mais aucune analyse n'est effectuée dans une syntaxe Nowdoc. La construction est idéale pour embarquer du code PHP ou d'autres larges blocs de texte, sans avoir besoin d'échapper quoi que ce soit. Cette syntaxe partage les mêmes fonctionnalités que le constructeur SGML <![CDATA ]>, en ce qu'elle déclare un bloc de texte qui ne doit pas être analysé.

Nowdoc est identifié avec la même séquence <<< utilisée par Heredoc, mais l'identifiant qui suit est entouré de guillemet simple,e.g. <<<'EOT'. Toutes les règles concernant les identifiants Heredoc sont également appliquer aux identifiants Nowdoc, et tout spécialement, celles concernant l'apparence de l'identifiant.

Donc

<?php
$variables = 'hello';
$a = <<<'MONMARQUEUR'
ma chaine avec des $variables
MONMARQUEUR;
echo $a;
?>

affiche

ma chaine avec des $variables

Notation complexe

Rappel, pour le heredoc et pour les " ,

${variable}s"; // fonctionne
{$variable}s"; // fonctionne

vendredi 24 avril 2009

ven
24
avr '09

Le FORUM PHP 2009 se prépare

Le Forum PHP 2009 qui se déroulera le 12 et 13 novembre 2009 à la cité des sciences.

Si vous avez quelque chose à dire : dites leur

Si vous avez juste envie d'écouter, les inscriptions en prévente avec un tarif préférentiel (remise de 20€ jusqu'au 30 mai 2009)

Lire la suite...

jeudi 23 avril 2009

jeu
23
avr '09

Connaissez-vous inclued et inclued_get_data ?

Une autre découverte de mon SCAN de la doc de php : inclued_get_data issu du package PECL inclued (V0.1.0/alpha/2008-02-29)

On trouve un exemple dans la doc http://www.php.net/manual/fr/inclued.examples-implementation.php mais il n'est pas super clair.

Par contre c'est mieux présenté sur GnuSquad. D'ailleurs je ne vais pas développer et juste conseiller d'aller lire ce post ansi que celui-ci en anglais.

L'extension inclued inclut un fichier PHP appelé gengraph.php qui crée un fichier DOT, qui peut être passé à la bibliothèque » graphviz. Cependant, cette approche n'est pas obligatoire.

Exemple #1 Exemple avec inclued_get_data()

<?php 
include 'x.php';
 
$clue = inclued_get_data();
 
print_r($clue);
?>

L'exemple ci-dessus va afficher quelque chose de similaire à :

[output]
Array
(
  [includes] => Array
    (
      [0] => Array
        (
          [operation] => include
          [op_type] => 2
          [filename] => x.php
          [opened_path] => /tmp/x.php
          [fromfile] => /tmp/z.php
          [fromline] => 2
        )
    )
)

mercredi 22 avril 2009

mer
22
avr '09

Scream @

C'est juste dans la documentation de php mais qui le connaissait ?

En gros cette directive permet d'ignorer les @.

Exemple : Activation et désactivation de scream, à l'exécution

<?php
// Affichage des erreurs
ini_set('display_errors', true);
error_reporting(E_ALL);
 
// Désactivation de scream : le code est silencieux
ini_set('scream.enabled', false);
echo "Opening http://example.com/not-existing-file\n";
@fopen('http://example.com/not-existing-file', 'r');
 
// Activation de scream : le code est verbeux
ini_set('scream.enabled', true);
echo "Opening http://example.com/not-existing-file\n";
@fopen('http://example.com/another-not-existing-file', 'r');
?>

L'exemple ci-dessus va afficher quelque chose de similaire à :

[Output]
Opening http://example.com/not-existing-file
Opening http://example.com/not-existing-file

Warning: fopen(http://example.com/another-not-existing-file): 
failed to open stream: HTTP request failed! HTTP/1.1 
404 Not Found in example.php on line 14

Note: Généralement, on active cette extension avec une directive de configuration php.ini, au lieu de la modifier dans le code PHP Le comportement de ces fonctions est affecté par la configuration dans le fichier php.ini.

Options de configuration de scream

mardi 21 avril 2009

mar
21
avr '09

Zend_Log_Filter_Priority : Ce que ne dit pas la doc.

http://framework.zend.com/manual/fr/zend.log.filters.html#zend.log.filters.all-writers

30.4. Filtres

Un objet Filter bloque les messages avant l'écriture dans le log.

[PHP]
<?php
$logger = new Zend_Log();

$redacteur = new Zend_Log_Writer_Stream('php://output');
$logger->addWriter($redacteur);

$filtre = new Zend_Log_Filter_Priority(Zend_Log::CRIT);
$logger->addFilter($filtre);

// bloqué
$logger->info("Message d'information");

// écrit dans le log
$logger->emerg("Message d'urgence");
?>

Avec cet exemple, on reçoit les messages de niveau 0,1 et 2

si on regarde le tableau des priorités

EMERG   = 0;  // Urgence : le système est inutilisable
ALERT   = 1;  // Alerte: une mesure corrective doit être prise immédiatement
CRIT    = 2;  // Critique : états critiques
ERR     = 3;  // Erreur: états d'erreur 
WARN    = 4;  // Avertissement: états d'avertissement
NOTICE  = 5;  // Notice: normal mais état significatif
INFO    = 6;  // Information: messages d'informations
DEBUG   = 7;  // Debug: messages de déboguages

On comprend que Zend_Log_Filter_Priority(Zend_Log::CRIT); signifie ne prendre que ce qui est inférieur ou égal à 2//CRIT

Comment faire pour avoir que les 4 ou que les 5, 6 et 7 ou que les 2 et 3 ?

Dans la doc api on peut voir pour le constructeur

Constructor __construct (line 54)
Filter logging by $priority. By default, it will accept any log event whose priority value is less than or equal to $priority.
  • throws: Zend_Log_Exception
  • access: public
Zend_Log_Filter_Priority __construct (integer $priority, [string $operator = '<='])
  • integer $priority: Priority
  • string $operator: Comparison operator

On ne parle pas encore de string $operator = '<=' dans la doc

Donc il faut savoir que

[php]
<?php

$filtre = new Zend_Log_Filter_Priority(Zend_Log::CRIT, '=');
$logger->addFilter($filtre);

?>

mon logger ne reprend que les niveaux CRITICAL

[php]
<?php

$filtre = new Zend_Log_Filter_Priority(Zend_Log::CRIT, '<=');
$logger2->addFilter($filtre);

$filtre = new Zend_Log_Filter_Priority(Zend_Log::NOTICE  , '>=');
$logger2->addFilter($filtre);

// mon logger ne reprend que les niveaux CRITICAL, ERR, WARN et NOTICE  

?>

Pour aller plus loin il faut savoir qu'il y a aussi 2 autres filtres à découvrir.

lundi 20 avril 2009

lun
20
avr '09

PHPBelgium meeting on April 22 in Ghent

Spring is in the air and PHP is ready to blossom, so join the PHPBelgium meeting on Wednesday April 22 at our bi-monthly PHPBelgium meeting. We've got two valued speakers lined up and lots of goodies to give away.

schedule:

20:00h CLI, the other SAPI - Thijs Feryn

An in depth talk about using PHP on the command line and all the benefits that go along with it. In this presentation, Thijs will tackle common problems that occur when using classic PHP via the browser and he'll show you how the PHP binary allows you to create powerfull shell applications. Thijs Feryn is the support manager at COMBELL where he constantly gets into contact with real-world hosted examples of good and bad LAMP development. Being a PHP 5 ZCE he's also a talented developer and you'll be hearing plenty more of him in the community.

21:00h Everything you always wanted to know about UTF-8 (but never dared to ask) - Juliette Reinders Folmer

Juliette is a veteran PHP developer and a well respected representative for PHPWomen in the Benelux. She has already introduced herself about a year ago at one of the first PHPBelgium meetings, but is now giving a presentation where you'll learn the ins and outs of UTF-8

22:00h Drinks, socializing and goodies time

To list a few of the goodies:

  • one copy of "Zend Framework in Action" signed by Rob Allen donated by himself
  • one free license for Zend Studio for Eclipse donated by Zend Technologies, Inc.
  • one free ticket for Dutch PHP Conference 2009 donated by Ibuildings, the PHP Professionals
  • the one and only elePHPant!

Catering and venue for this meeting are provided by Combell Internet Solutions More information can be found at http://phpbelgium.be/events/23032009/phpbelgium-meeting-april and you can sign up for this meeting at http://upcoming.yahoo.com/event/2167970

dimanche 19 avril 2009

dim
19
avr '09

Config avec Zend ou Pear

Zend_Config et Pear::config sont conçus pour simplifier l'accès et l'utilisation des données de configuration dans les applications.

Les données de configuration peuvent venir de sources variées supportant une organisation hiérarchique des données.

Actuellement Zend_Config fournit des adaptateurs pour les données de configuration qui sont stockées dans des fichier textes avec Zend_Config_Ini et Zend_Config_Xml.

De son coté Pear::config propose Apache, GenericConf, IniCommented, IniFile, PHPArray, PHPConstants, XML.

Je ne suis pas encore à l'aise ni avec l'un, ni avec l'autre.

Ce qu'il me faut c'est :

  • une possibilité de gérer plusieurs fichiers qui regroupent "sémantiquement" les valeurs de configuration.
  • Ces fichiers doivent être administrables avec auteur et versionning des modifications.
  • Il faut une gestion de staging.
  • Il faut un éditeur de config auto généré.
  • un cache transparent qui évite un reparsing des fichiers.
  • Une possibilité d'overrider une valeur au niveau applicatif.

edit : Oops c'est article a été publié inachevé.

Le fond du problème c'est de se dire qu'une config c'est avant tout une liste de valeurs variable/paramétrable dont la valeur n'est pas assignée par le développeur, mais par un utilisateur.

  • un administrateur technique (même si c'est la même personne. Ce n'est pas la même casquette. Le développeur c'est celui qui crée le code, l'administrateur technique c'est celui qui dit comment il va fonctionner.)
  • un administrateur non technique qui n'a pas à bidouiller dans un fichier de config. (même s'il prétend en être capable)

Pour ce dont j'ai besoin

  • Il faut une gestion de staging. <- existe dans Zend_config (cfr commentaire fragile)
  • un cache transparent qui évite un reparsing des fichiers. <- possible avec PEAR et ZF
  • Une possibilité d'overrider une valeur au niveau applicatif. <- possible mais il faut le prévoir soigneusement dans le code

On avait implémenté plusieurs des autres points dans Claroline mais ce dernier n'utilise ni PEAR::Config, ni Zend_Config

L'idée est d'avoir une config de config.

Avoir une liste des valeurs de config avec leur définition, contexte, type, ...

Avoir un outil d'édition des fichiers de config qui se base sur ces listes pour

  • afficher le formulaire d'édition de des fichiers de config
  • versionner les modification de config, ou tout du moins "logguer"

Pear::Config

Pear::Config aide à manipuler votre configuration qu'elle soie stockée dans des fichiers XML, des tableaux PHP ou tout autre genre de source de données. Il comporte les fonctionnalités suivantes :

  • Analyser les différents formats de configuration.
  • Manipuler les sections, directives, commentaires, blancs de la manière que vous voulez.
  • Réécrire de nouveau les données dans votre format préféré.

L'objet de Config agit en tant que conteneur pour d'autres objets de Config_Container. Il ne fait pas beaucoup mais rend la tenue des opérations de E/S plus faciles. Il contient l'objet racine de Config_Container qui contient alternativement un objet enfant de Config_Container. Les objets Config_Container stockent des références à leur parent et ont un tableau d'enfants. Cette structure permet alors d'accéder à différent les conteneurs et leur contenu.

Un objet de Config_Container peut être de différents types :

  • Section: une section contient d'autres objets Config_Container.
  • Directive: une directive ne contient aucun autre objet mais a un contenu et un nom. Voyez-les comme des paires de clef-valeur.
  • Commentaire: comme les directives, les commentaires ont un contenu mais elles n'ont pas de nom. Elles sont rendues d'une manière spéciale selon le type de configuration que vous choisissez.
  • Blanc: elles n'ont ni contenu ni nom mais sont utilisées pour indiquer les interlignes si votre _renderer_ les emploie.

En utilisant le paquet Config, la majeure partie du travail est effectuée avec les objets Config_Container .

Zend_Config

On voit donc un petit avantage à PEAR_Config c'est qu'il propose aussi l'écriture.

Pour creuser Zend_Config : Différentes approches et sa partie 2

Claroline

Les valeurs de configuration actives seront stockées dans des fichiers de config contenant de simples array php.

[php]
<?php

/* campus_name : Name of your campus */
$claro_config['platform_name'] = 'My campus';

/* platform_language : Select the default language of the platform */
$claro_config['platform_language'] = 'english';

/* claro_stylesheet : Set the stylesheet layout */
$claro_config['platform_stylesheet'] = 'default.css';

/* administrator_name : Complete name */
$claro_config['administrator_name'] = 'John Doe';

/* administrator_email : This email is the main contact address on the platform */
$claro_config['administrator_email'] = 'John@doe.net';

/* administrator_phone : Phone */
$claro_config['administrator_phone'] = "";

/* institution_name : Name displayed in the top banner */
$claro_config['institution_name'] = 'My institute';

?>

Mais ce qui est particulier est en amont.

Dans claroline, on ne distribue plus jamais les fichiers de config. mais des fichiers de définition.

L'outil d'édition de config, (et d'install et d'upgrade) lit le fichier de définition et il lit les valeurs actives si elles existent dans les fichiers de config.

Ensuite il génère le forumlaire, on peut editer comme on veut puis dire, "appliquer", "restaurer les valeur par défaut", "abandonner"

Si on utilise "appliquer" il regénère tous les fichiers de conf concernés

L'avantage c'est qu'à l'upgrade on écrase les fichiers de définition pas les valeurs actives.

voici a quoi ressemble la définition d'une valeur de config.

[php]
<?php
   $toolConfProperties['CONFVAL_LOG_CALENDAR_INSERT'] = 
   array ('label'       => 'Logguer les ajouts d\'agenda' 
         ,'default'     => 'TRUE' 
         ,'type'        => 'boolean' 
         ,'display'     => TRUE 
         ,'readonly'    => FALSE 
         ,'container'   => 'CONST' 
         ,'acceptedval' => array ('TRUE'=>'enabled' 
                                 ,'FALSE'=>'dislabed' 
                                 ) 
         ); 
?>
  • CONFVAL_LOG_CALENDAR_INSERT <- nom du conteneur
  • container => 'CONST' <- type du conteneur

donc ici il génère un define('CONFVAL_LOG_CALENDAR_INSERT', ...)

  • default => 'TRUE' <- valeur proposée par défaut
  • type => 'boolean' <- permet de définir le contrôle sur valeur recue et l'aspect du formulaire on peut mettre boolean, integer, string, enum, enum+, ereg, si boolean,'acceptedval' => array ('TRUE'=>'enabled','FALSE'=>'dislabed') perment de mettre le nom à coté des radios
  • display = TRUE;
  • readonly = FALSE;

Ces deux là permettent d'afficher ou non une valeur dans l'éditeur et de la rendre editable ou non

un autre exemple

[php]
<?php
$toolConfProperties['DEFAULT_SUFFIX_MAIL']['default'] = '@fake.zz';
$toolConfProperties['DEFAULT_SUFFIX_MAIL']['type' ]   = 'regexp';
$toolConfProperties['DEFAULT_SUFFIX_MAIL']['acceptedval'] = '@(([0-9]{1,3}\.){3}[0-9]{1,3}|([0-9a-z][0-9a-z-]*[0-9a-z]\.)+[a-z]{2,4})$';
?>

Maintenant avec Zend ou Pear on pourrait transformer une partie de l'éditeur auto généré pour utiliser Zend_Form ou PEAR::Quickform2

Conclusion

Rien Ne me convient, je suis un difficile capricieux.

Il va falloir que je planifie tout ceci.

vendredi 17 avril 2009

ven
17
avr '09

PhpMyAdmin "avancé" (partie 1)

Il existe plein d'options dans phpMyAdmin pas très connues.

Trois me plaisent plus particulièrement.

  • le regroupement de table par préfix
  • L'historique des commandes. (Partie 2)
  • la gestion des relations (Partie 2)

le regroupement de table par préfix

C'est une option liée au LeftFrameLight.

Il faut mettre à true $cfg['LeftFrameLight'] et $cfg['LeftFrameDBTree']

Puis $cfg['LeftFrameDBSeparator'] et/ou $cfg['LeftFrameTableSeparator'] doivent être modifiés pour indiquer qu'elle est le séparateur de votre convention de nommage.

Défini par défaut à '__'.

Si vous avez des tables telles que 'première__seconde__troisième' elles seront affichées comme une hiérarchie à trois niveaux telle que : premier > seconde > troisième.

Pour finaliser $cfg['LeftFrameTableLevel'] définit le nombre de sous-niveaux qui doivent être affichés quand les tables sont subdivisées par le séparateur ci-dessus.

En pratique

Dans mon cas LeftFrameTableSeparator vaut _

Si je regarde la db INFORMATION_SCHEMA , j'ai 2 tables dont le nom commence par Table_

dans le frame de gauche je ne les vois pas toutes les 2 mais j'ai

Si je clique sur le +, j'obtiens

Ca ne fait pas grand chose sur INFORMATION_SCHEMA qui ne compte que quelque tables mais quand vous en avez 400 réparties dans une 10aine de sous groupe


Partie 1 - (Partie 2)

mercredi 8 avril 2009

mer
08
avr '09

benchmark de php pour sprintf, strtr et str_replace

J'ai testé sprintf, strtr et str_replace. 100K passages sur chaque test.
Une version avec time(), une autre juste hello.
J'ai pris 4 références de comparaison pour faire le tableau. La colonne qui m'intéresse le plus est la référence 4. où le sprintf sur hello est 1.

Résultat

éxécuté 100000 fois
testchrono secondesratio
'hello'
ratio
time()
ratio
sprintf('a %s', time())
ratio
sprintf('a %s', 'hello')
$a = time();0.063431.868531.000000.314490.41980
$a = sprintf('a %s', time());0.201705.941503.179771.000001.33487
$a = str_replace('%s', time(), 'a %s');0.215586.350463.398641.068831.42675
$a = strtr('a %s', array('%s'=> time() ));0.286588.441904.517931.420841.89663
$a = str_replace('%t', time(), str_replace('%u', time(), str_replace('%s', time(), 'a %s %t %u'));0.5586716.457108.807512.769853.69740
$a = str_replace(array('%t','%u','%s'), array(time(),time(),time(),), 'a %s %t %u');0.6897120.3171210.873313.419534.56463
$a = strtr('a %s %t %u', array('%s'=> time(), '%t'=> time(), '%u'=> time(), ));0.4964314.623837.826372.461303.28552
$a = 'hello';0.033951.000000.535180.168310.22467
$a = sprintf('a %s', 'hello');0.151104.450992.382080.749141.00000
$a = str_replace('%s', 'hello', 'a %s');0.161224.749052.541600.799301.06696
$a = strtr('a %s', array('%s'=> 'hello' ));0.200345.901463.158340.993261.32588
$a = str_replace('%t', 'hello', str_replace('%u', 'hello', str_replace('%s', 'hello', 'a %s %t %u'));0.4081712.023656.434812.023672.70134
$a = str_replace(array('%t','%u','%s'), array('hello','hello','hello',), 'a %s %t %u');0.5182515.266578.170362.569483.42993
$a = strtr('a %s %t %u', array('%s'=> 'hello', '%t'=> 'hello', '%u'=> 'hello', ));0.319299.405615.033691.583032.11315

Lire la suite...

Tags