Kamelot Blog

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

mercredi 27 mai 2009

mer
27
mai '09

{$variable} (corrigé)

Note : ce post publié ce matin était complètement faux et non terminé.

${variable}s

Dans un post récent sur heredoc et newdoc

Je disais que pour HEREDOC et pour les guillemets doubles,

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

Donc

testé sur PHP_VERSION:5.2.5
<?php

echo 
'<hr />';
highlight_file __FILE__ );
echo 
'<hr />';

$salut 'hello';
$salut_fr 'bonjour';
$b_fr 'yo man';
$b'salut';

printVar(${b} . "<br />${b}<br />{$b} ",'${b} . " ${b} {$b} "'); 
printVar("${$b}<br />$$b<br />" . $$b,'${$b} $$b " . $$b'); 
printVar("$b_fr<br />" . ${"b_fr"},'"$b_fr " . ${"b_fr"}'); 
printVar("${b}_fr<br />{$b}_fr",'${b}_fr {$b}_fr'); 
printVar("${$b}_fr",'${$b}_fr'); 
printVar(${$b."_fr"},'${$b."_fr"}'); 
//printVar("{${$b}_fr}",'${b}'); 

Mais depuis php 5.0 ${uneFonction()} fonctionne aussi



function donneUnNomDeVariable()
{
   return 
'salut';
}

printVar(${donneUnNomDeVariable()},'${donneUnNomDeVariable()}'); 
// FATAL ERROR printVar("{$donneUnNomDeVariable()}",'"{$donneUnNomDeVariable()}"'); 
// FATAL ERROR printVar("${$donneUnNomDeVariable()}",'"${$donneUnNomDeVariable()}"'); 
printVar(${donneUnNomDeVariable()}."_fr",'${donneUnNomDeVariable()}."_fr"'); 
printVar(${donneUnNomDeVariable()."_fr"},'${donneUnNomDeVariable()."_fr"}'); 

/**
 * Affiche le contenu de la variable
 * 
 * @param mixed $var la variable dont il faut afficher le contenu
 * @param string $varName le label
 * @return boolean true
 */
function printVar($var$varName '@') {
  static 
$varStaticInutile '3';
  
$varStaticInutile 5;
  
$bt debug_backtrace ();
  if (
is_array $bt ))
    
$bt array_reverse $bt );
  else {
    
$bt = array (array ('line' => '' ) );
  }
  
  echo 
'<p>' "\n" '[' $varName '] (line:' $bt [0] ['line'] . ') : ' "\n" '<pre style="color:red">' "\n" var_export $var) . '</pre>' "\n" '</p>' "\n";
  return 
true;
}

?>

[${b} . " ${b} {$b} "] (line:12) :

'salut
salut
salut '

[${$b} $$b " . $$b] (line:13) :

'hello
$salut
hello'

["$b_fr " . ${"b_fr"}] (line:14) :

'yo man
yo man'

[${b}_fr {$b}_fr] (line:15) :


'salut_fr
salut_fr'

[${$b}_fr] (line:16) :

'hello_fr'

[${$b."_fr"}] (line:17) :

'bonjour'

[${donneUnNomDeVariable()}] (line:27) :

'hello'

[${donneUnNomDeVariable()}."_fr"] (line:30) :

'hello_fr'

[${donneUnNomDeVariable()."_fr"}] (line:31) :

'bonjour'

mercredi 20 mai 2009

mer
20
mai '09

PHP Tv : Magento, Mysql, Symfony VS Zend_Framework

Je vous renvoie directement vers la page de l'émission


Magento

Magento optimise ses performances et fait évoluer son offre auprès des professionnels. La communauté française organise le bargento, une rencontre autour de l'application.

MySQL / Oracle

Que va devenir MySQL avec le rachat de Sun par Oracle ? La communauté réagit.

Frameworks : Symfony ou Zend Framework ?

Le point sur les deux frameworks les plus en vus du moment par le monde professionnel.


mardi 19 mai 2009

mar
19
mai '09

PHP Scan : Exif

Plusieurs formats d'images peuvent contenir des meta données. Entre autres, on a IPTC et Exif

J'ai déjà parlé de ceux ci dans un post sur Xnview et Flickr

Pour EXIF, on a PECL::Exif et pour IPTC on utilisera GD:iptcparse ou Pear::Image_IPTC

Deux petits exemples.

EXIF

<?php
echo "test1.jpg:<br />\n";
$exif = exif_read_data('tests/test1.jpg', 'IFD0');
echo $exif===false ? "Aucun en-tête de donnés n'a été trouvé.<br />\n" : "L'image contient des en-têtes<br />\n";
 
$exif = exif_read_data('tests/test2.jpg', 0, true);
echo "test2.jpg:<br />\n";
foreach ($exif as $key => $section) {
   foreach ($section as $name => $val) {
       echo "$key.$name: $val<br />\n";
   }
}
?>

IPTC

[php]
<?php
$size = getimagesize('./test.jpg', $info);
if(isset($info['APP13']))
{
    $iptc = iptcparse($info['APP13']);
    var_dump($iptc);
}
?>

Bonus : exifTool, rien à voir avec php mais toujours bon à connaitre.

mar
19
mai '09

PHP Scan : Reflexion

Reflexion est une nouveauté de PHP 5. C'est un outil de développement plus que de production.

Ca permet d'aller plus loin que get_loaded_extensions(), get_extension_funcs(), get_defined_functions(), get_defined_vars(),... On donne au constructeur un nom de classe, d'interface, de fonction et de méthode ou bien encore d'extension et il fourni une série de méthodes pour récupérer des informations telles que le nom, le fichier où elle est déclarée, le numéro de ligne de début et de fin dans le fichier, les commentaires phpDoc, les éventuelles variables statiques, l'éventuelle ''Closure'', les références, les paramètres demandés, ...

La doc présente comme ceci :

PHP 5 introduit API de réflexion complète qui permet de faire du reverse-engineering sur les classes, les interfaces, les fonctions et les méthodes tout comme les extensions. L'API de réflexion permet également d'obtenir les commentaires de la documentation pour les fonctions, les classes et les méthodes.

On dispose d'une série de classes qu'on utilise de la sorte

[php]
<?php
 $reflexionDeMaFonction = new ReflectionFunction('MaFonction');
?>

Et là on peut utiliser l'objet $reflexionDeMaFonction, on va faire appel à une série de méthodes pour obtenir les informations sur la fonction.

[php]
<?php
    var_export $reflexionDeMaFonction->isInternal () ? 'internal' 'user-defined');
    var_export $reflexionDeMaFonction->getName ());
    var_export $reflexionDeMaFonction->getFileName ());
    var_export $reflexionDeMaFonction->getStartLine ());
    var_export $reflexionDeMaFonction->getEndline ());
?>

Notez qu'on peut aller jusqu'à récupérer les commentaires phpDoc !

[php]
<?php    var_export $reflexionDeMaFonction->getDocComment ());
?>

Ca c'était pour les fonctions. on a aussi

  • La classe ReflectionParameter pour les paramètres des fonctions ou des méthodes.
  • La classe ReflectionClass pour les classes et les interfaces.
  • La classe ReflectionException pour les Exception.
  • La classe ReflectionObject pour les objets.
  • La classe ReflectionMethod pour les méthodes des classes.
  • La classe ReflectionProperty pour les propriétés des classes.
  • La classe ReflectionExtension les extensions.

Il y a même la possibilité d'étendre ces classes pour faire votre propre reflexion.

Regardez l'article complet pour avoir un exemple sur une fonction maison, sur array_reverse et sur Zend_log. L'output est dans le premier commentaire.

à lire aussi

Lire la suite...

vendredi 15 mai 2009

ven
15
mai '09

PHP Scan : Intéressant ?

Petite prise de température.

Mes posts, PHP SCAN sont-ils intéressants ?

Moi je les écris avant tout pour moi et mon équipe, et donc tant qu'à faire je partage l'info. Mais dans l'absolu, je ne sais pas si ça passe juste pour du réchauffé ou si ça vous a appris (rappelé) quelque chose.

Notez: quelque soit la réponse, je vais continuer

jeudi 14 mai 2009

jeu
14
mai '09

PHP Scan : http_build_query

http_build_query est visiblement moins connue qu'on y penserait car beaucoup s'échinent encore à refaire son boulot en PHP.

Depuis PHP 5, http_build_query() génère une chaîne de requête en encodage URL.

http_build_query  ( array $formdata  , string $numeric_prefix  [, string $arg_separator  ] )

Le fonctionnement est assez simple et la fonction ci-dessous à utiliser pour les versions antérieures l'explique aussi assez bien.

On a un implode des couples param/valeur eux même séparé par un =.

Depuis 5.1.2, l'implode utilise $arg_separator comme glue, c'est la valeur par défaut est celle de la directive arg-separator configurée dans php.ini

Les éventuelles clés numériques dans la structure du tableau sont préfixées par le second paramètres (vide par défaut).

Un autre traitement à noter : L'ensemble des paramètres et valeurs sont urlencodés et depuis 5.1.3 Les crochets sont échappés.

Avant php 5 on avait ceci

[php]
<?php
if (!function_exists('http_build_query')) {
    function http_build_query($data, $prefix='', $sep='', $key='') {
        $ret = array();
        foreach ((array)$data as $k => $v) {
            if (is_int($k) && $prefix != null) {
                $k = urlencode($prefix . $k);
            }
            if ((!empty($key)) || ($key === 0))  $k = $key.'['.urlencode($k).']';
            if (is_array($v) || is_object($v)) {
                array_push($ret, http_build_query($v, '', $sep, $k));
            } else {
                array_push($ret, $k.'='.urlencode($v));
            }
        }
        if (empty($sep)) $sep = ini_get('arg_separator.output');
        return implode($sep, $ret);
    }// http_build_query
}//if
?>

samedi 9 mai 2009

sam
09
mai '09

piège de count et explode : count(explode(',',''))

count(explode(',',''))

Explode retourne un tableau, si je lui donne une chaine vide, alors il me retourne un tableau vide et count vaut 0.

Faux.

La doc le dit : array explode ( string $delimiter , string $string [, int $limit ] ) Si delimiter contient une valeur qui n'est pas contenue dans string (...), alors explode() retournera un tableau, contenant la chaîne string entière.

il retourne array ( 0 => '',)
donc count = 1 !!!
Voici le code pour le tester.

Lire la suite...

jeudi 7 mai 2009

jeu
07
mai '09

GeoIP PECL

L'extension GeoIP permet de localiser une adresse IP. La ville, l'état, le pays, la longitude, la latitude et d'autres informations comme l'ISP et le type de connexion peuvent être obtenus grâce à GeoIP.

C'est un package PECL. Stable depuis Août 2007, la dernière version est là 1.0.7 de 2009-03-11.

Fonctions GeoIP

<?php
$continent = geoip_continent_code_by_name('www.example.com');
if ($continent) {
    echo 'Cet hôte est situé en : ' . $continent . '<br/>;
}
 
$country = geoip_country_code_by_name('www.example.com');
if ($country) {
    echo 'Localisation de cet hôte : ' . $country . '<br/>;
}
 
 
$country = geoip_country_code3_by_name('www.example.com');
if ($country) {
    echo 'Localisation de cet hôte : ' . $country;
}
 
$country = geoip_country_name_by_name('www.example.com');
if ($country) {
    echo 'Localisation de cet hôte : ' . $country;
}
 
?>

L'exemple ci-dessus va afficher :

Cet hôte est situé en : NA
Localisation de cet hôte : US
Localisation de cet hôte : USA
Localisation de cet hôte : United States

Et il y en a d'autres, je vais juste mettre un exemple de retour

GEO-106FREE 20060801 Build 1 Copyright (c) 2006 MaxMind LLC All Rights Reserved
  • geoip_db_avail — Vérifie si la base de données GeoIP est disponible
GEO-106FREE 20080801 Build 1 Copyright (c) 2006 MaxMind LLC All Rights Reserved
  • geoip_db_filename — Retourne le nom du fichier contenant la base de données GeoIP spécifiée
/usr/share/GeoIP/GeoIP.dat
  • geoip_db_get_all_info — Retourne des informations détaillées sur tous les types de bases de données GeoIP
array(11) {
  [1]=>
  array(3) {
    ["available"]=>
    bool(true)
    ["description"]=>
    string(21) "GeoIP Country Edition"
    ["filename"]=>
    string(32) "/usr/share/GeoIP/GeoIP.dat"
  }

[ ... ]

  [11]=>
  array(3) {
    ["available"]=>
    bool(false)
    ["description"]=>
    string(25) "GeoIP Domain Name Edition"
    ["filename"]=>
    string(38) "/usr/share/GeoIP/GeoIPDomain.dat"
  }
}
GEOIP_UNKNOWN_SPEED
GEOIP_DIALUP_SPEED
GEOIP_CABLEDSL_SPEED
GEOIP_CORPORATE_SPEED
L'IP de l'hôte appartient à l'ISP : ICANN c/o Internet Assigned Numbers Authority
Nom de l'organisation : ICANN c/o Internet Assigned Numbers Authority
  • geoip_record_by_name — Récupère les informations détaillées sur un pays, trouvées dans la base de données GeoIP
Array
(
    [continent_code] => NA
    [country_code] => US
    [country_code3] => USA
    [country_name] => United States
    [region] => CA
    [city] => Marina Del Rey
    [postal_code] => 
    [latitude] => 33.9776992798
    [longitude] => -118.435096741
    [dma_code] => 803
    [area_code] => 310
)
Array('country_code' => US, 'region' => CA)
Nom de la région CA/QC: Quebec
Nom de la région JP/01: Aichi
Fuseau horaire de CA/QC : America/Montreal
Fuseau horaire de JP/01 : Asia/Tokyo

Alternatives

PEAR propose PEAR::NET_GEOIP

  • Net_GeoIP::getInstance() -- method to get an instance and avoid re-parsing the database
  • Net_GeoIP::lookupCountryName() -- returns full country name for specified IP address
  • Net_GeoIP::lookupCountryCode() -- returns 2-letter country code (e.g. CA) for specified IP address
  • Net_GeoIP::lookupRegion() -- returns the region for given IP address.
  • Net_GeoIP::lookupLocation() -- returns the location record for specified IP address
  • Net_GeoIP::lookupOrg() -- returns the name of the organization or ISP for the given IP address.

un exemple

[php]
<?php
require_once "Net/GeoIP.php";

$geoip = Net_GeoIP::getInstance("/path/to/geoipdb.dat");

try {
    echo $geoip->lookupCountryCode($_SERVER['REMOTE_ADDR']);
} catch (Exception $e) {
    // Handle exception
}
?> 

Les commentaires intéressants

GeoLiteCity

Le base de donnée libre GeoLiteCity db fonctionne et peut résoudre les noms de ville et d'autres informations.

Regardez comment l'installer ici : http://www.maxmind.com/app/installation?city=1

À l'étape 2 décompresser le fichier et déplacez-le et renommé.

Les fichiers doivent être renommé GeoIPCity.dat sinon le mod_geoip ne la trouvera pas.

dimanche 3 mai 2009

dim
03
mai '09

Zend_Loader::Zend_Loader::registerAutoload is deprecated as of 1.8.0 and will be removed with 2.0.0; use Zend_Loader_Autoloader

Notice: Zend_Loader::Zend_Loader::registerAutoload is deprecated as of 1.8.0 and will be removed with 2.0.0; use Zend_Loader_Autoloader instead in xxx

ZendFramework 1.8 déprécie l'utilisation de l'autoload que nous connaissons, ...

Pour ma part pas de problème, je ne suis toujours pas séduit par la fonctionnalité.

samedi 2 mai 2009

sam
02
mai '09

Php scan : php_strip_whitespace()

Rien d'extraordinaire mais juste le mérite d'exister et d'éviter de devoir faire un eval de php -w.

php_strip_whitespace() retourne le code source PHP fichier dont on passe le nom en paramètre mais en ayant supprimé les commentaires ainsi que les espaces.

Cela peut être utile pour comparer la quantité de code avec la quantité de commentaire dans votre code.

<?php
// Commentaire PHP ici
 
/*
 * Un autre commentaire PHP
 */
 
echo        php_strip_whitespace(__FILE__);
// Les nouvelles lignes sont considérées comme des espaces et sont donc également effacées :
do_nothing();
?>

L'exemple ci-dessus va afficher :

[output]
<?php
 echo php_strip_whitespace(__FILE__); do_nothing(); ?>

Tags