Mon Dieu, les billets techniques refleuriraient-ils au printemps ? Si vous désirez récupérer des informations géographiques à partir de l’adresse IP (ou du hostname) d’un utilisateur, vous pouvez utiliser les fonctions fournies par l’extension PECL GeoIP.
Voici la procédure d’installation sur une Ubuntu 8.04:
$ sudo -s # apt-get install build-essential php5-dev php5-cli libgeoip-dev libgeoip1 php-pear # pecl install geoip
Si toiut s’est bien passé :
# echo "extension=geoip.so" >> /etc/php5/cli/php.ini
Si vous utilisez Apache comme serveur :
# echo "extension=geoip.so" >> /etc/php5/apache2/php.ini
Il faut également installer la base GeoIPCity de Maxmind :
# wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz # gunzip GeoLiteCity.dat.gz # mv GeoLiteCity.dat /usr/share/GeoIP/GeoIPCity.dat
Vous pouvez maintenant tester l’extension avec une ligne du genre[1] :
$ echo "<?php var_dump(geoip_record_by_name('209.202.168.**'));"|php
Ça donne ici :
array(11) { ["continent_code"]=>
string(2) "NA"
["country_code"]=>
string(2) "US"
["country_code3"]=>
string(3) "USA"
["country_name"]=>
string(13) "United States"
["region"]=>
string(2) "NC"
["city"]=>
string(4) "Cary"
["postal_code"]=>
string(5) "27511"
["latitude"]=>
float(35.7********)
["longitude"]=>
float(-78.7*******)
["dma_code"]=>
int(560)
["area_code"]=>
int(919)
}
Enjoy.
[1] J’ai volontairement masqué certaines informations pour d’évidentes raisons de confidentialité.
Ce billet intitulé Utiliser les fonctions GeoIP de PHP sous Ubuntu a été rédigé par Nicolas Perriault et publié sur le blog Prendre un Café sous licence Creative Commons BY-NC-SA.
Avec le beau jour, il est temps de revenir aux sources.... Sortir, voir autre chose qu'un ordinateur.
c'est pourquoi
Un PHP Apéro est prévu en juin à Paris.
Tout le monde est invité
Pour plus d'informations : http://www.aperophp.net/apero.php?id=392
La première conférence francophone entièrement consacrée à Symfony se déroulera les 11 et 12 juin prochains à la Cité Universitaire , à Paris. Cet événement, très attendu au sein de la communauté PHP, est organisé par Sensio Labs en partenariat avec l’AFUP.
Je serais présent pour cet évènement car cela vaut le détour...
Pour plus d'informations rendez-vous sur http://www.symfony-live.com.
Le mercredi 24 juin 2009 de 9:30 à 22:50 à Mons
Les détails : http://phpbelgium.be/events/08062009/phpbelgium-meeting-june
Google Page Speed (la presque copie conforme de YSlow) est sorti il y a quelques jours. Ces deux outils permettent de vérifier différents critères ayant un impact sur le temps de chargement ressenti par l'utilisateur. En utilisant Google Page Speed sur ma dernière création, Bioutifoul Photos, j'ai remarqué que les miniatures des photos générées par eZ Publish via ImageMagick n'étaient pas optimisées, en effet elles contiennent toutes les informations EXIF de l'image originale ce qui est rarement utile (a priori GD ne sait pas conserver les informations EXIF donc le problème ne se pose pas).
Pour remédier à cela, il est possible de configurer un filtre spécifique (par exemple nommé optimize) qui va rajouter l'option -strip à convert lors de la création des variations pour supprimer un maximum de choses dans l'image puis à rajouter ce filtre dans les filtres utilisés pour créer une variation donnée. Cette opération est faisable en écrivant les lignes suivantes dans settings/override/image.ini.append.php :
[ImageMagick] IsEnabled=true ExecutablePath=/usr/bin Executable=convert Filters[]=optimize=-strip [mini] Filters[] Filters[]=geometry/scalewidthdownonly=200 Filters[]=optimize
Dans cet exemple, la seules les images générées en format mini seront optimisées. Une autre solution plus globale consiste à ajouter l'option -strip pour toutes les variations en utilisant le paramètre PreParameters dans le même fichier de configuration.
Dans les deux cas, pour que les images existantes soient régénérées, il faut lancer la commande suivante :
$ php bin/php/ezcache.php --clear-tag=imageAttention, sur un site avec beaucoup d'images et un peu d'audience, la régénération des variations peut être extrêmement gourmande en ressources.
Cette année, la VIP va fêter ses 10 ans d'existance et cette année, je serais bien sur présent à cet évènement qui va se dérouler du 10 au 12 juillet à Thoissey dans l'Ain au nord de Lyon, sur pré-inscription, dont j'aurais la joie d'effectuer une conférence
La VIP, c'est une rencontre qui sera le lieu de prédilection de la création numérique. La demoparty comporte différents concours informatiques dans lesquels les créateurs peuvent s'affronter, s'évaluer, en laissant une grande part de liberté dans la création et l'imagination. Chaque participant amène son propre matériel. Mais la demoparty n'est pas une lanparty, nous affectionnons plus particulièrement les esprits créateurs que les gamers (les joueurs spécialistes des jeux en réseaux), et même si nous ne les rejetons pas, ils ne seront pas acceptés lors de notre festival faute de place.
Le sujet de ma conférence n'est pas encore déterminé, mais des orientations me font penser qu'ils vont tourner autour de Web, et peut être même PHP.
Le site officiel : http://www.popsyteam.org/vip2009/
Symfony Live c'est terminé.... Et de nombreux articles ont été publiés parlant de cet évènement...
Les magazines internet.... comme nexen.net les magazines Programmez et PHP solutions, etc...
Les médias : PHPTV... Prochainement
Et voici le liens des photos pour ceux qui ne les ont pas envore vus
Voilà quelques semaines que je pestais sur sur mon ZendStudio4Eclipse à propos de SVN.
En effet, plus moyen d'utiliser les fonctionnalités de SVN fournie avec cet éditeur.
J'ai remarqué récemment que mes projets n'étaient plus dans un "workspace".
J'ai recréé un workspace et ca a commencé à rentrer dans l'ordre.
PHPBelgium June Meeting, c'est demain à Mons.
Si c'est en lisant mon blog que vous l'apprenez, alors vite découvrir phpPlanet fr, et découvrez du coup plein de bon blogs.
Moi ce qui m'intéresse de montrer cette fois, ce n'est pas ce qui arrive mais ce qui part.
Alors préparez votre code....
et les ereg à remplacer par pcre
La ça peut être moins compliqué puisque c'est en PECL, il suffit de le réintégrer soit même.
__toStringne prend plus d'argument.
__callreçoit maintenant les appels sur les méhodes privée et protégée.
__get,
__set,
__isset,
__unset,
__calldoivent toujours être publique et plus jamais être statique.
La nouvelle version du Zend Framework est disponible depuis Mardi.
Cette version corrige plus d'une cinquantaine de bugs couvrant 20 composants différents. Plus de détails sur le changelog.
Une autre information annoncée en même temps que cette sortie est la mise à disposition des roadmaps. Cela permettra aux utilisateurs d'avoir un aperçu des changements effectués sur les futures versions de Zend Framework. A noter que pour le moment, seules les modifications apportées à la version 1.9.0 y sont répertoriées, mais cela devrait s'étoffer avec le temps.
Enfin, nous apprenons aussi une date de sortie potentielle pour cette version 1.9.0, qui serait prévue pour la fin Juillet 2009. Mais comme l'auteur le signale, il est difficile de prévoir avec exactitude ces dates quand cela dépend de la disponibilité d'une multitude de contributeurs différents.
uploadprogress est un package PECL en gestation. stable depuis le 15 mars 2009 mais sans documentation
La dernière version à dater de cet article est la 1.01 : uploadprogress-1.0.1.tgz (8.3kB)
Vous pouvez tester ca ici
Voici un exemple d'info qu'on reçoit "pendant" l'upload
Date : 2009-06-23T13:45:20+02:00
ID : eb68198b81ae7c656cfc0588a23ae3dd
var_dump($info):
array(11) {
["upload_id"]=> string(32) "eb68198b81ae7c656cfc0588a23ae3dd"
["fieldname"]=> string(4) "file"
["filename"]=> string(12) "Anniversaire"
["time_start"]=> string(10) "1245757519"
["time_last"]=> string(10) "1245757520"
["speed_average"]=> string(5) "36130"
["speed_last"]=> string(5) "30874"
["bytes_uploaded"]=> string(5) "36130"
["bytes_total"]=> string(6) "155082"
["files_uploaded"]=> string(1) "0"
["est_sec"]=> string(1) "3"
}
la demo affiche pendant l'envoi
Download started since 22.791 seconds. 51% done, 20 seconds to go
et à la fin
Upload succeeded, it took 42.255 seconds. You had 32 updates from the progress meter, looks like it's working fine
J'ai extrait les exemples
http://cvs.php.net/viewvc.cgi/pecl/uploadprogress/examples/
/* +--+ | Uploadprogress extension | +--+ | Copyright (c) 2006-2008 The PHP Group | +--+ | Author: Christian Stocker (chregu@php.net) | +--+ */
index.php
[php]
<?php
$id = md5(microtime() . rand());
function return_bytes($val) {
$val = trim($val);
$last = strtolower($val[strlen($val)-1]);
switch($last) {
// The 'G' modifier is available since PHP 5.1.0
case 'g':
$val *= 1024;
case 'm':
$val *= 1024;
case 'k':
$val *= 1024;
}
return $val;
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="generator" content="HTML Tidy for Linux/x86 (vers 1 September 2005), see www.w3.org" />
<script type="text/javascript">
var UP = function() {
/* private variables */
var ifr = null;
var startTime = null;
var upload_max_filesize = <?php echo return_bytes(ini_get('upload_max_filesize'));?>;
var infoUpdated = 0;
var writeStatus = function(text,color) {
var statDiv = document.getElementById("status");
if (color == 1 ) {
statDiv.style.backgroundColor = "green";
} else if (color == 2 ) {
statDiv.style.backgroundColor = "orange";
} else if (color == 3 ) {
statDiv.style.backgroundColor = "red";
} else {
statDiv.style.backgroundColor = "white";
}
statDiv.innerHTML = text;
}
return {
start: function() {
ifr = document.getElementById("ifr");
startTime = new Date();
infoUpdated = 0;
this.requestInfo();
},
stop: function(files) {
if (typeof files == 'undefined' || files) {
var secs = (new Date() - startTime)/1000;
var statusText = "Upload succeeded, it took " + secs + " seconds. <br/> ";
if (infoUpdated > 0) {
writeStatus(statusText + "You had " + infoUpdated + " updates from the progress meter, looks like it's working fine",1);
} else {
statusText += "BUT there were no progress meter updates<br/> ";
if (secs < 3) {
writeStatus(statusText + "Your upload was maybe too short, try with a bigger file or a slower connection",2);
} else {
writeStatus(statusText + "Your upload should have taken long enough to have an progress update. Maybe it really does not work...",3);
}
}
} else {
writeStatus('PHP did not report any uploaded file, maybe it was too large, try a smaller one (post_max_size: <?php echo ini_get('post_max_size');?>)',3);
}
startTime = null;
},
requestInfo: function() {
ifr.src="info.php?ID=<?php echo $id;?>&"+new Date();
},
updateInfo: function(uploaded, total, estimatedSeconds) {
if (startTime) {
if (uploaded) {
infoUpdated++;
if (total > upload_max_filesize) {
writeStatus("The file is too large and won't be available for PHP after the upload<br/> You file size is " + total + " bytes. Allowed is " + upload_max_filesize + " bytes. That's " + Math.round (total / upload_max_filesize * 100) + "% too large<br/> Download started since " + (new Date() - startTime)/1000 + " seconds. " + Math.floor(uploaded / total * 100) + "% done, " + estimatedSeconds + " seconds to go",2);
} else {
writeStatus("Download started since " + (new Date() - startTime)/1000 + " seconds. " + Math.floor(uploaded / total * 100) + "% done, " + estimatedSeconds + " seconds to go");
}
} else {
writeStatus("Download started since " + (new Date() - startTime)/1000 + " seconds. No progress info yet");
}
window.setTimeout("UP.requestInfo()",1000);
}
}
}
}()
</script>
<title> php5.2 uploadprogress Meter - Simple Demo</title>
</head>
<body>
<form onsubmit="UP.start()" target="ifr2" action="server.php" enctype="multipart/form-data" method="post">
<input type="hidden" name="UPLOAD_IDENTIFIER" value="<?php echo $id;?>" />
<label>Select File:</label>
<input type="file" name="file" />
<br/>
<label>Select File:</label>
<input type="file" name="file2" />
<br/>
<label>Upload File:</label>
<input type="submit" value="Upload File" />
<br/>
('upload_max_filesize' is <?php echo ini_get('upload_max_filesize');?> per file)<br/>
('post_max_size' is <?php echo ini_get('post_max_size');?> per submit)<br/>
<?php
$templateini = ini_get("uploadprogress.file.filename_template");
$testid = "thisisjustatest";
$template = sprintf($templateini,$testid);
$templateerror = false;
if ($template && $template != $templateini && @touch ($template) && file_exists($template)) {
// print '('.$templateini.' is writable. The realpath is ' . str_replace($testid,"%s",realpath($template)) .')';
unlink($template);
} else {
$templateerror = true;
}
?>
</form>
<div id="status" style="border: 1px black solid;<?php
if (function_exists("uploadprogress_get_info")) {
if ($templateerror) {
print 'background-color: red;"';
print ">Problem. ";
if ($template == $templateini) {
print "uploadprogress.file.filename_template ($templateini) doesn't have an %s in it for making unique temporary files. Please adjust.<br/>";
} else {
print "$templateini is NOT writable. <br/>Please make sure the directory exists and is writable for the webserver. <br/>
Or adjust the ini setting 'uploadprogress.file.filename_template' to a correct path.";
}
} else {
print 'background-color: green;">The uploadprogress extension is installed and initial checks show everything is good';
}
} else { ?>
background-color: red;">The uploadprogress extension is not installed.
<?php } ?>
</div>
<div>The info during the upload will be displayed here:</div>
<iframe id="ifr" src="info.php?ID=<?php echo $id;?>" width="500px" height="350px" name="ifr"></iframe>
<div>
The actual file upload happens here (and displays info, when it's finished):
</div>
<iframe name="ifr2" width="500px" height="300px" id="ifr2"></iframe>
</body>
</html>
info.php
[php]
<?php
if (function_exists("uploadprogress_get_info")) {
$info = uploadprogress_get_info($_GET['ID']);
} else {
$info = false;
}
?>
<html>
<head>
<script type="text/javascript">
<?php
if ($info !== null) {
print "parent.UP.updateInfo(".$info['bytes_uploaded'].",".$info['bytes_total'].",".$info['est_sec'].")";
} else {
print "parent.UP.updateInfo()";
}
?>
</script>
</head>
<body>
<pre>
<?php
print "Date : " . date("c",time())."\n";
print "ID : ". $_GET['ID'] ."\n";
print 'var_dump($info): '. "\n";
var_dump($info);
?>
</pre>
</body>
server.php
[php]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="generator" content="HTML Tidy for Linux/x86 (vers 1 September 2005), see www.w3.org" />
<script type="text/javascript">
<?php
if (count($_FILES) > 0) {
echo "parent.UP.stop(true);";
} else {
echo "parent.UP.stop(false);";
}
?>
</script>
<title></title>
</head>
<body>
File uploaded:
<pre>
<?php
var_dump($_FILES);
?>
</pre>
</body>
</html>
eZ Feed Parse est une extension eZ Publish fournissant une fonction fetch permettant d'accéder dans un template aux données publiées dans un flux RSS ou ATOM. Cette extension interface le composant Feed des eZ Components et donc tous les formats supportés par ezcFeed sont accessibles.
Plusieurs autres extensions du même genre sont disponibles dans les contributions sur ez.no, mais il semble qu'elles utilisent toutes la classe eZXML qui a été retirée avec la sortie de la version 4.1 d'eZ Publish. Je l'utilise notamment dans la colonne de droite de ce site pour afficher quelques photos issues de Bioutifoul Photos.