<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Tech Guy FR &#187; geek</title>
	<atom:link href="http://blog.juliencrouzet.fr/tag/geek/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.juliencrouzet.fr</link>
	<description>Le blog de Julien CROUZET</description>
	<lastBuildDate>Thu, 01 Jul 2010 19:38:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Zoom sur les méthodes magiques de PHP</title>
		<link>http://blog.juliencrouzet.fr/565/les-methodes-magiques-de-php/</link>
		<comments>http://blog.juliencrouzet.fr/565/les-methodes-magiques-de-php/#comments</comments>
		<pubDate>Wed, 23 Jun 2010 01:03:11 +0000</pubDate>
		<dc:creator>c2c</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.juliencrouzet.fr/?p=565</guid>
		<description><![CDATA[
Warning: call_user_func_array() expects parameter 1 to be a valid callback, first array member is not a valid class name or object in /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php on line 166

Call Stack:
    0.0001     623440   1. {main}() /home/www/blog.juliencrouzet.fr/index.php:0
    0.0002     628968   2. require('/home/www/blog.juliencrouzet.fr/wp-blog-header.php') /home/www/blog.juliencrouzet.fr/index.php:17
    0.1948   38153848   3. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php') /home/www/blog.juliencrouzet.fr/wp-blog-header.php:16
    0.1957   38156768   4. do_feed() /home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php:14
    0.1957   38157048   5. do_action() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1721
    0.1957   38159072   6. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:395
    0.1957   38159128   7. do_feed_rss2() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:0
    0.1957   38159320   8. load_template() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1753
    0.1959   38221464   9. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php') /home/www/blog.juliencrouzet.fr/wp-includes/theme.php:1087
    0.2010   38223144  10. the_excerpt_rss() /home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php:46
    0.2209   38226680  11. apply_filters() /home/www/blog.juliencrouzet.fr/wp-includes/feed.php:177
    0.2211   38229304  12. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:166

]]></description>
			<content:encoded><![CDATA[<div id="attachment_567" class="wp-caption aligncenter" style="width: 150px"><a href="http://blog.juliencrouzet.fr/wp-content/uploads/2010/06/025-magician-01.png" rel="lightbox[565]"><img class="size-full wp-image-567" title="025-magician-01" src="http://blog.juliencrouzet.fr/wp-content/uploads/2010/06/025-magician-01.png" alt="" width="140" height="140" /></a><p class="wp-caption-text">Abracadabra...</p></div>
<p style="text-align: center;">
<p>Les objets en PHP possèdent 14 méthodes « magiques », reconnaissables à leurs noms qui commencent par deux <em>underscores</em> « __ » : __construct, __destruct, __call, __callStatic, __get, __set, __isset, __unset, __sleep, __wakeup, __toString, __invoke, __set_state, __clone.</p>
<p>Une méthode « magique » en PHP, c’est une méthode dont le nom est réservé (vous ne pouvez pas utiliser ces noms pour appeler vos propres méthodes, d’une manière générale, ne nommez jamais une méthode avec un nom qui commence par « __ »), que le moteur PHP va tenter d’appeler dans lors de certains évènements propres à votre classe si celles-ci existe.</p>
<p>Par exemple, si vous avez une méthode appelée « __construct » dans votre classe, celle-ci sera appelée lorsque l’on instancie une instance de votre classe : <em>new MaClasse().</em></p>
<p>Dans la plupart des cas (sauf si précisé), ces méthodes doivent être définie comme publique et non statiques (ex : <em>public function __construct()</em>).</p>
<p>Voyons-les en détails …</p>
<p><span id="more-565"></span><br />
<h3>__construct</h3>
<p>La plus connue d’entre elles ; beaucoup l’utilisent sans savoir qu’il s’agit d’une méthode « magique ». __construct est ce qui s’apparente à un constructeur en C++, c’est-à-dire qu’elle est appelée à  chaque instanciation de votre objet. Par exemple, si j’appelle <em>new MaClasse(</em><code><em>"test"</em></code><em>, 5 ) ;</em>, la méthode __construct de MaClasse va être appelée avec comme argument <code>"test"</code> et 5. Il est inutile de retourner une valeur dans cette méthode, ce retour serait ignoré.</p>
<p>Par convention, on place dans la méthode __construct toutes les initialisations nécessaires à l’utilisation d’un objet, comme par exemple la connexion à une base de données, les valeurs par défaut des variables, etc.</p>
<p>A noter qu’en cas d’instanciation d’une classe fille (qui hérite de la classe), __construct ne sera pas appelé, si la classe fille (ou une des classe dans l’héritage) implémente une fonction __construct ; il faudra alors appeler <em>parent::__construct(…)</em> dans la méthode __construct de cette classe fille.</p>
<h3>__destruct</h3>
<p>__destruct est appelé lorsque qu’une instance de notre classe est détruite (elle n’est plus utilisée, ou la fin du script est arrivée par exemple), elle n’a aucun argument.</p>
<p>A l’inverse de __construct, on place dans cette méthode tout ce qui est nécessaire à la fin de vie de notre objet, comme par exemple la déconnexion d’une socket, la libération de mémoire cache, etc.</p>
<p>Attention, l’utilisation de cette méthode est souvent très sensible :</p>
<ul>
<li>Souvent, celle-ci est appelée en fin de script, c’est-à-dire à un moment ou les en-têtes (headers) sont déjà envoyés ;</li>
<li>Si une exception est levée pendant l’exécution de cette méthode, une erreur fatale PHP est levée et le reste (de la fin) du script ne sera pas exécuté ;</li>
<li>Beaucoup de ressources (instances d’autres classes, connexion à des bases de données) dont probablement déjà plus disponibles.</li>
</ul>
<h3>__call</h3>
<p>__call est appelé lorsque l’on essaye d’appeler une méthode qui n’existe pas dans la classe. Par exemple, si j’essayer d’appeler <em>$objet-&gt;fooBar(</em><code><em>"test"</em></code><em>, 5) ;</em> que <em>fooBar</em> n’est pas une méthode définie dans ma classe et que j’ai une méthode __call définie, celle-ci va être appelée avec comme arguments  <code><em>"fooBar"</em></code><code> (</code>le nom de la méthode appelée) et un tableau contenant <code><em>"test"</em></code> et<em> 5</em> (les arguments).</p>
<h3>__callStatic</h3>
<p>__callStatic fait la même chose que __call, mais est appelée lorsque l’on essaye d’appeler une méthode statique qui n’existe pas ; par exemple <em>MaClasse::fooBar(</em><code><em>"test"</em></code><em>, 5) ;</em> appellera __callStatic  avec comme arguments  <code><em>"fooBar"</em></code><code> (</code>le nom de la méthode appelée) et un tableau contenant <code><em>"test"</em></code> et<em> 5</em> (les arguments).</p>
<p>Attention, comme callStatic est appelé dans un contexte statique, il faut définir la méthode de manière publique et statique (<em>public static function __callStatic($name, $args) { </em>).</p>
<h3>__set</h3>
<p>__set est appelé lorsque l’on essaye de définir une propriété qui n’existe pas.</p>
<p>Par exemple <em>$object-&gt;fooBar = 5;</em> appellera __set  avec comme arguments  <code><em>"fooBar"</em></code><code> (</code>le nom de la propriété) et un <em>5</em> (la nouvelle valeur). Cependant, cette propriété ne sera pas créée pour autant !</p>
<p>A noter que __set est appelée lorsque l’on essaye de modifier la valeur d’une propriété privée ou protégée depuis l’extérieur de la classe.</p>
<h3>__get</h3>
<p>__get est appelé lorsque l’on essaye de récupérer la valeur d’une propriété qui n’existe pas.</p>
<p>Par exemple echo <em>$object-&gt;fooBar;</em> appellera __get  avec comme argument  <code><em>"fooBar"</em></code>. La valeur alors retournée par la méthode __get sera retournée à l’appel (<em>echo</em> dans l’exemple).</p>
<p>A noter que __get est appelée lorsque l’on essaye de récupérer la valeur d’une propriété privée ou protégée depuis l’extérieur de la classe.</p>
<h3>__isset</h3>
<p>__isset est appelé lorsque l’on essaye de savoir si une propriété qui n’existe pas est définie, avec <em>isset()</em> par exemple.</p>
<p>Par exemple  isset(<em>$object-&gt;fooBar)</em> appellera __isset  avec comme argument  <code><em>"fooBar"</em></code>. La valeur alors retournée par la méthode __get sera retournée à l’appel, celle-ci doit donc de préférence retourner <em>true</em> ou <em>false</em>.</p>
<p>A noter que __isset est appelée lorsque l’on essaye de savoir si la valeur d’une propriété privée ou protégée est définie depuis l’extérieur de la classe.</p>
<h3>__unset</h3>
<p>__unset fait à peu près la même chose que __isset, donc vous avez tout deviné … J</p>
<p><strong>__sleep et __wakeup</strong></p>
<p>Ces anciennes méthodes permettent de linéariser et délinéariser des objets d’une classe. La linéarisation permet à un objet d’être enregistré (comme par exemple dans une base de données ou une mémoire cache) dans un état défini (comprendre les valeurs des méthodes par exemple). Ceci peut être très utile par exemple si l’on veut enregistrer un objet de session.</p>
<p>Par défaut, les objets linéarisés le sont à l’aide de la fonction serialize() de PHP, mais cela peut s’avérer insuffisant, comme par exemple si l’on doit avant se déconnecter d’une base de données ou faire du nettoyage.</p>
<p>Deux méthodes magiques existent pour cela, __sleep et __wakeup, mais il est fortement déconseillé de les utiliser car il est impossible alors d’accéder au nom des propriétés privées ou protégées des classes parentes, il faut alors utiliser l’interface Serializable. Ce n’est pas une méthode magique, mais elle les « remplace », je vais donc en parler ici.</p>
<p>Serializable définit deux méthodes : serialize et unserialize :</p>
<ul>
<li>serialize() est appelé lorsque l’on appelle la fonction PHP <em>serialize($objet)</em> ;. Elle doit alors retourner une chaîne qui pourra être récupérée pour réinitialiser l’objet dans l’état actuel ;</li>
<li>unserialize($string) est appelé lorsque l’on appelle la fonction PHP $object = <em>unserialize($string)</em> ;. Elle doit alors récupérer la chaîne $string pour réinitialiser l’objet dans l’état décrit par celle-ci. Dans ce cas, $object sera alors une instance de la classe réinitialisé, mais <em>__construct()</em> ne sera pas appelé. Elle doit modifier l’objet mais ne rien retourner (comme __construct).</li>
</ul>
<p>Voici un exemple de classe pour être plus clair :</p>
<pre name="code" class="php">
/**
 * Classe mere
 */
class					Compteur {
	/**
	 * Somme
	 *
	 * @var	int
	 */
	protected			$_sum;
}
/**
 * Une classe tout bête qui compte le nombre de fois
 * qu'on l'a appelée et fait une somme
 */
class					CompteurBete extends Compteur implements Serializable {
	/**
	 * Nombre de fois qu'on l'a appellé
	 *
	 * @var	int
	 */
	private				$_calls;	

	/**
	 * Constructeur
	 */
	public function		__construct() {
		$this->_sum = 0;
		$this->_calls = 0;
		echo "Constructeur appellé !\n";
	}
	/**
	 * On ajoute un nombre a la somme
	 *
	 * @param	int			Nombre
	 */
	public function			add($number) {
		$this->_sum += intval($number);
		$this->_calls++;
	}
	/**
	 * Quelle est la somme ?
	 *
	 * @return	int
	 */
	public function			getSum() {
		return($this->_sum);
	}
	/**
	 * Combien de fois ai-je été appelé
	 *
	 * @return	int
	 */
	public function			getCalls() {
		return($this->_calls);
	}
	/**
	 * La méthode qui fait la sérialisation
	 *
	 * @return	string		Chaîne qui représente l'état de l'objet
	 */
	public function			serialize() {
		return("{$this->_sum}|{$this->_calls}");
	}
	/**
	 * La méthode qui réinitialise l'objet dans l'état sérialisé
	 *
	 * @param	string		Chaîne retournée par serialize()
	 */
	public function			unserialize($serialized) {
		if (preg_match("/^([\-\d]+)\|([\-\d]+)$/", $serialized, $parts)) {
			$this->_sum = intval($parts[1]);
			$this->_calls = intval($parts[2]);
		} else {
			throw new Exception("La chaîne ne représente pas une instance de CompteurBete : " . $serialized);
		}
	}
}
</pre>
<p>Si on exécute le code suivant :</p>
<pre name="code" class="php">
/**
 * On cree notre objet
 */
$object = new CompteurBete();
/**
 * On joue avec
 */
$object->add(5);
$object->add(10);
$object->add(-25);
/**
 * On le serialize
 */
$serialized = serialize($object);

echo "Nombre d'appels : " . $object->getCalls() . "\n";
echo "Somme : " . $object->getSum() . "\n";
echo "Chaîne sérialisée : " . $serialized . "\n";
</pre>
<p>On obtient le résultat :</p>
<pre name="code" class="php">
Constructeur appellé !
Nombre d'appels : 3
Somme : -10
Chaîne sérialisée : C:12:"CompteurBete":5:{-10|3}
</pre>
<p>La chaîne « <em>C:12:&nbsp;&raquo;CompteurBete&nbsp;&raquo;:5:{-10|3}</em> » peut être traduite par « Une instance de la classe &laquo;&nbsp;CompteurBete&nbsp;&raquo; que l’on peut désérialiser avec la chaîne  &laquo;&nbsp;{-10|3}&nbsp;&raquo; ».</p>
<p>Donc si l’on exécute maintenant le code :</p>
<pre name="code" class="php">
/**
 * On passe la chaîne récupérée
 */
$newObject = unserialize('C:12:"CompteurBete":5:{-10|3}');
echo "Nombre d'appels : " . $object->getCalls() . "\n";
echo "Somme : " . $object->getSum() . "\n";
</pre>
<p>On obtient :</p>
<pre name="code" class="php">
Nombre d'appels : 3
Somme : -10
Magnifique ! Le même résultat ! Notre objet est donc bien réinitialisé !
</pre>
<p>Vous noterez que j’ai « implémenté » un système maison de sérialisation/désérialisation maison mais il est souvent préférable de se baser sur des systèmes tels que <em>serialize()/unserialize()</em> de PHP…</p>
<h3>__toString</h3>
<p>__toString est appelé lorsque l’on essaye d’utiliser une classe comme une chaîne de caractères, par exemple lorsque l’on appelle <em>echo $object ;</em>.La méthode __toString est alors appelée, sans argument, et doit retourner une chaîne qui sera à son tour retournée à l’appelant.</p>
<p>C’est très utile lorsque l’on crée des classes qui représentent des balises HTML, on peut alors travailler avec ces classes avec des appels du type :</p>
<pre name="code" class="php">
$tag = new HTMLTag('ul');
$tag->setClass('maClasse')->setId('monId')->html('Hello');
echo $tag;  // Va afficher
<ul class="maClasse" id="monId">Hello</ul>
</pre>
<h3>__invoke</h3>
<p>__invoke est appelé lorsque l’on essaye d’appeler un objet comme une fonction. Par exemple, si l’on effectue <em>$object(&laquo;&nbsp;buuum&nbsp;&raquo;) ;</em>, la méthode __invoke va être appelée avec comme argument <em>&laquo;&nbsp;buuum&nbsp;&raquo;</em>.</p>
<p>Cela peut être utile notamment lorsque l’on souhaite utiliser une fonction de PHP qui utilise une fonction comme argument, comme <em>usort()</em>, à laquelle on peut passer comme argument l’objet.</p>
<p>A noter, pour tester si une instance d’une classe implémente __invoke, on peut utiliser <em>is_callable()</em>.</p>
<h3>__set_state</h3>
<p>__set_state est un peu complexe à définir, et à mon avis pas très utile, mais essayons quand même. Pour comprendre __set_state, il faut d’abord connaitre la fonction PHP <em>var_export()</em>.<em>var_export()</em> c’est le même principe que <em>var_dump()</em>, c’est-à-dire afficher des informations sur une variable, mais avec deux différences :</p>
<ul>
<li>· var_export peut retourner les infos plutôt que de les afficher si on précise <em>true</em> en deuxième argument ;</li>
<li>· var_export retourne du code PHP valide.</li>
</ul>
<p>Si l’on prend le code suivant par exemple :</p>
<pre name="code" class="php">
$number = 5;
$string = "ouech";
$array = array(1, "t'as vu", false);
class test {
	public				$property = 5;
	private				$_property = "ok";
	public function		method() { /**/ }
}
$object = new test();
echo var_export($number) . "\n";
echo var_export($string) . "\n";
echo var_export($array) . "\n";
echo var_export($object) . "\n";
</pre>
<p>On obtient le résultat suivant :</p>
<pre name="code" class="php">
5
'ouech'
array (
	0 =&gt; 1,
	1 =&gt; 't\'as vu',
	2 =&gt; false,
)
test::__set_state(array(
	'property' =&gt; 5,
	'_property' =&gt; 'ok',
))
</pre>
<p>Penchons-nous donc sur le dernier résultat, concernant l’objet. <em>var_export()</em> retourne un code qui est un appel à une méthode __set_state sur la classe <em>test</em>. On y est dont, à cette méthode.</p>
<p>En fait, cette méthode prend en argument un tableau qui représente la liste des propriétés de l’instance de la classe. La méthode doit normalement récupérer créer une instance de la classe, assigner les propriétés récupérées et retourner cet objet, afin de pouvoir faire quelque chose comme <em>eval(‘$newInstance =’ . var_export($oldInstance, true) . ‘;’) ;</em></p>
<p>Donc :</p>
<ul>
<li>· La méthode __set_state est une méthode publique statique, on a donc pas accès aux propriétés protégées et publique de l’objet qu’on doit réinitialiser, il faut donc faire des méthodes « setter » ;</li>
<li>· C’est ignoble, immonde et lent comme code (et oui eval()…) ;</li>
<li>· C’est pas très sécurisé, voire pas du tout (et oui eval()…) ;</li>
<li>· La méthode peut en fait faire n’importe quoi et retourner n’importe quoi…</li>
</ul>
<p>Si quelqu’un à compris quelle est l’utilité de __set_state, donc, qu’il se manifeste !</p>
<h3>__clone</h3>
<p>__clone est appelé lorsque l’on souhaite cloner une instance de la classe avec la fonction PHP <em>clone()</em>. En effet, on peut dans certains cas vouloir contrôler le clonage d’une instance de notre classe pour par exemple partager des ressources (base de données, etc.), voir l’empecher.</p>
<p>Lorsque l’on appelle clone() sur un objet et que la méthode __clone est implémentée, celle-ci sera invoquée alors sur le nouvel objet cloné juste après sa création.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.juliencrouzet.fr/565/les-methodes-magiques-de-php/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>redis : Le système de cache parfait</title>
		<link>http://blog.juliencrouzet.fr/484/redis-le-systeme-de-cache-parfait/</link>
		<comments>http://blog.juliencrouzet.fr/484/redis-le-systeme-de-cache-parfait/#comments</comments>
		<pubDate>Sat, 29 Aug 2009 17:11:14 +0000</pubDate>
		<dc:creator>c2c</dc:creator>
				<category><![CDATA[cache]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://blog.juliencrouzet.fr/?p=484</guid>
		<description><![CDATA[
Warning: call_user_func_array() expects parameter 1 to be a valid callback, first array member is not a valid class name or object in /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php on line 166

Call Stack:
    0.0001     623440   1. {main}() /home/www/blog.juliencrouzet.fr/index.php:0
    0.0002     628968   2. require('/home/www/blog.juliencrouzet.fr/wp-blog-header.php') /home/www/blog.juliencrouzet.fr/index.php:17
    0.1948   38153848   3. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php') /home/www/blog.juliencrouzet.fr/wp-blog-header.php:16
    0.1957   38156768   4. do_feed() /home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php:14
    0.1957   38157048   5. do_action() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1721
    0.1957   38159072   6. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:395
    0.1957   38159128   7. do_feed_rss2() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:0
    0.1957   38159320   8. load_template() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1753
    0.1959   38221464   9. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php') /home/www/blog.juliencrouzet.fr/wp-includes/theme.php:1087
    0.2419   38242640  10. the_excerpt_rss() /home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php:46
    0.2477   38245256  11. apply_filters() /home/www/blog.juliencrouzet.fr/wp-includes/feed.php:177
    0.2480   38247672  12. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:166

]]></description>
			<content:encoded><![CDATA[<div id="attachment_485" class="wp-caption aligncenter" style="width: 171px"><a href="http://blog.juliencrouzet.fr/wp-content/uploads/2009/08/bolt.jpg" rel="lightbox[484]"><img class="size-medium wp-image-485" title="bolt" src="http://blog.juliencrouzet.fr/wp-content/uploads/2009/08/bolt-300x243.jpg" alt="Il les surpasse tous !" width="161" height="131" /></a><p class="wp-caption-text">Il les surpasse tous !</p></div>
<p>Après 3 ans d&#8217;une histoire d&#8217;amour fidèle avec <a href="http://www.danga.com/memcached/">Memcached</a> ; le serveur de cache notamment utilisé par <a href="http://www.facebook.com/note.php?note_id=39391378919">Facebook</a>, <a href="http://video.google.com/videoplay?docid=-6304964351441328559">Youtube</a> ou <a href="http://blog.twitter.com/2008/05/its-not-rocket-science-but-its-our-work.html">Twitter </a>; je suis au bord de la rupture après avoir rencontré <a href="http://code.google.com/p/redis/">redis</a>.<br />
<span id="more-484"></span></p>
<h2>redis, A persistent key-value <em>database</em></h2>
<p>Oui, <strong>database</strong>. En fait, redis, c&#8217;est les avantage d&#8217;un système de cache sans les inconvénients.</p>
<p>D&#8217;habitude avec les systèmes de caches comme Memcached, les données mises en cache sont volatiles. Elles sont stockées en mémoire pendant un certain temps ; passé ce délais elles sont supprimées.</p>
<p>Ce point n&#8217;est pas bloquant, une données mise en cache doit pouvoir être recalculée ou récupérée à tout moment, mais cela consomme des ressources en plus (pour récupérer cette donnée, justement).</p>
<p><a href="http://code.google.com/p/redis/">redis</a> est conçu sur un autre modèle. Les données sont dans un premier temps stockées en mémoire de la même manière que les autres, mais elles sont de manière cycliques (tout les X écritures ou après X temps) écrites sur le disque dur. On peut donc stocker une donnée de manière permanente !</p>
<p>A noter cependant que Memcache existe en version persistante (<a href="http://memcachedb.org/">MemcachedDB</a>), cependant on il ne fait QUE du stockage persistant, on perd donc en performance.</p>
<h2>Des performances impressionnantes</h2>
<p>Afin de comparer les performances de Memcached, réputé et reconnu pour sa rapidité, et celles de redis, j&#8217;ai fait un simple test pour Memcache :</p>
<p>Et pour redis :</p>
<p>Résultat : Avec redis on est en moyenne à 2,507 secondes pour 10 000 itérations, pour Memcached on est à 3,669 secondes.</p>
<p>redis est donc plus rapides que Memcached sur des opérations de bases (écriture, lecture) il fallait le faire !</p>
<p>Sinon pour être un peu plus complet, une page de <a href="http://code.google.com/p/redis/wiki/Benchmarks">benchmark </a>est présente sur le site.</p>
<h2>Au delà du stockage <em>&laquo;&nbsp;clé-chaîne&nbsp;&raquo;</em></h2>
<p>Un autre inconvénient de Memcached ou d&#8217;autres système de cache, c&#8217;est qu&#8217;il fonctionne sur un modèle &laquo;&nbsp;<em>clé-chaîne de caractère</em>&laquo;&nbsp;, il ne peut donc stocker que des combinaisons du type (&#8216;clé de cache&#8217;, &#8216;valeur à stocker&#8217;).</p>
<p>Lorsque l&#8217;on doit enregistrer des données plus complexes comme des tableaux, on est alors obligé de passer par une mécanique de <a href="http://fr.wikipedia.org/wiki/S%C3%A9rialisation">sérialisation des données ou Mashalling</a>, comme <a href="http://fr3.php.net/serialize">serialize</a>() en PHP.</p>
<p>redis permet en plus du mode de stockage &laquo;&nbsp;<em>clé-chaîne</em>&nbsp;&raquo; un mode de stockage &laquo;&nbsp;<em>clé-liste</em>&nbsp;&raquo; qui permet de stocker des listes. Il est donc possible, au delà de stocker et récupérer des valeurs, d&#8217;utiliser les fonctions classiques de listes, comme changer une valeur dans cette liste, récupérer une valeur ou un ensemble de valeur dans la liste, la modifier etc. et ce sans avoir à récupérer la liste, la modifier et la renvoyer comme c&#8217;est le cas avec les autres systèmes.</p>
<p>Ceci est un gain énorme de ressources système et de temps tout en simplifiant la gestion du cache !</p>
<h2>Multiple bases de donnée</h2>
<p>Un même serveur de cache peut être utilisé par plusieurs systèmes de cache. Souvent cela est problématique car les données ne sont pas séparées par application. On utilise alors souvent un système de préfixage des clés, par exemple la clé &#8216;UsersCount&#8217; sera nommée &#8216;MyApplication_UsersCount&#8217; pour éviter d&#8217;écraser une clé d&#8217;une autre application.</p>
<p>redis offre une gestion par &laquo;&nbsp;base de donnée&nbsp;&raquo; comme le font les base de données classiques ; ce qui permet entre autre de vider le cache d&#8217;une application sans effacer les autres données ou de lister rapidement les données en cache d&#8217;une application donnée.</p>
<h2>Implémentation langages</h2>
<p>Pour utiliser redis il existe des libraries ou classe en Ruby, Python, PHP, Perl, Java, etc. ; la liste est présente sur le <a href="http://code.google.com/p/redis/">site du projet</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.juliencrouzet.fr/484/redis-le-systeme-de-cache-parfait/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Microsoft assurera le support d’Internet Explorer 6 jusqu’en 2014</title>
		<link>http://blog.juliencrouzet.fr/480/microsoft-assurera-le-support-d%e2%80%99internet-explorer-6-jusqu%e2%80%99en-2014/</link>
		<comments>http://blog.juliencrouzet.fr/480/microsoft-assurera-le-support-d%e2%80%99internet-explorer-6-jusqu%e2%80%99en-2014/#comments</comments>
		<pubDate>Sun, 16 Aug 2009 12:17:48 +0000</pubDate>
		<dc:creator>c2c</dc:creator>
				<category><![CDATA[geek]]></category>
		<category><![CDATA[ie6]]></category>
		<category><![CDATA[internet explorer]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://blog.juliencrouzet.fr/?p=480</guid>
		<description><![CDATA[
Warning: call_user_func_array() expects parameter 1 to be a valid callback, first array member is not a valid class name or object in /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php on line 166

Call Stack:
    0.0001     623440   1. {main}() /home/www/blog.juliencrouzet.fr/index.php:0
    0.0002     628968   2. require('/home/www/blog.juliencrouzet.fr/wp-blog-header.php') /home/www/blog.juliencrouzet.fr/index.php:17
    0.1948   38153848   3. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php') /home/www/blog.juliencrouzet.fr/wp-blog-header.php:16
    0.1957   38156768   4. do_feed() /home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php:14
    0.1957   38157048   5. do_action() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1721
    0.1957   38159072   6. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:395
    0.1957   38159128   7. do_feed_rss2() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:0
    0.1957   38159320   8. load_template() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1753
    0.1959   38221464   9. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php') /home/www/blog.juliencrouzet.fr/wp-includes/theme.php:1087
    0.2564   38246544  10. the_excerpt_rss() /home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php:46
    0.2586   38249176  11. apply_filters() /home/www/blog.juliencrouzet.fr/wp-includes/feed.php:177
    0.2588   38251608  12. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:166

]]></description>
			<content:encoded><![CDATA[<div id="attachment_481" class="wp-caption aligncenter" style="width: 154px"><a href="http://blog.juliencrouzet.fr/wp-content/uploads/2009/08/ie6-no-more.jpg" rel="lightbox[480]"><img class="size-full wp-image-481" title="ie6-no-more" src="http://blog.juliencrouzet.fr/wp-content/uploads/2009/08/ie6-no-more.jpg" alt="IE6 ? No more !" width="144" height="143" /></a><p class="wp-caption-text">IE6 ? No more !</p></div>
<p>Après avoir hésité quelque temps, Microsoft à craqué face au lobby des D.S.I. aussi vieillissant que leur navigateur préféré : <a href="http://www.zdnet.fr/actualites/internet/0,39020774,39704568,00.htm">Le support d&#8217;Internet Explorer 6 sera maintenu jusqu&#8217;en 2014</a>.</p>
<p><span id="more-480"></span></p>
<p>Amy Barzdukas, la directrice de l&#8217;activité IE chez Microsoft, à même des arguments chocs :</p>
<blockquote><p>Il est difficile d&#8217;être cavalier avec cette économie en disant &laquo;&nbsp;oh il est temps de se mettre à jour&nbsp;&raquo;</p></blockquote>
<p>Mais elle est consciente quand même que :</p>
<blockquote><p>Si les gens qui sont frustrés par cette expérience commencent à dire &laquo;&nbsp;Microsoft craint et IE craint&nbsp;&raquo; en se basant sur une technologie vieille de bientôt 10 ans alors cela devient effectivement préoccupant</p></blockquote>
<p>Si l&#8217;on résume donc :  Microsoft, pour ne pas froisser quelques D.S.I. à décidé de maintenir IE6, et donc, par la même légitimer un choix suicidaire de continuer à exploiter et même développer des intranets et applications Web pour Internet Explorer 6, quitte à s&#8217;exposer à une perte de crédibilité et une baisse d&#8217;image auprès &laquo;&nbsp;des gens&nbsp;&raquo;.</p>
<p>Je ne reviendrais pas sur <a href="http://blog.juliencrouzet.fr/2009/03/13/ie6-est-il-une-faute-professionnelle/">les raisons</a> qui font que IE6 doit immédiatement mourir de sa belle mort après presque 10 ans d&#8217;activité&#8230; Je constate juste qu&#8217;il est dommage de voir que Microsoft, qui semblait petit à petit adopter une stratégie plus réfléchie à propos des navigateurs (plus d&#8217;efforts pour adopter des standards, ballot screen, etc.) revient donc à ses origines.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.juliencrouzet.fr/480/microsoft-assurera-le-support-d%e2%80%99internet-explorer-6-jusqu%e2%80%99en-2014/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP5.3 : Quelles nouveautés ?</title>
		<link>http://blog.juliencrouzet.fr/421/php-5-3-what-s-new/</link>
		<comments>http://blog.juliencrouzet.fr/421/php-5-3-what-s-new/#comments</comments>
		<pubDate>Sat, 04 Jul 2009 23:51:13 +0000</pubDate>
		<dc:creator>c2c</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[développement]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://blog.juliencrouzet.fr/?p=421</guid>
		<description><![CDATA[
Warning: call_user_func_array() expects parameter 1 to be a valid callback, first array member is not a valid class name or object in /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php on line 166

Call Stack:
    0.0001     623440   1. {main}() /home/www/blog.juliencrouzet.fr/index.php:0
    0.0002     628968   2. require('/home/www/blog.juliencrouzet.fr/wp-blog-header.php') /home/www/blog.juliencrouzet.fr/index.php:17
    0.1948   38153848   3. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php') /home/www/blog.juliencrouzet.fr/wp-blog-header.php:16
    0.1957   38156768   4. do_feed() /home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php:14
    0.1957   38157048   5. do_action() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1721
    0.1957   38159072   6. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:395
    0.1957   38159128   7. do_feed_rss2() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:0
    0.1957   38159320   8. load_template() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1753
    0.1959   38221464   9. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php') /home/www/blog.juliencrouzet.fr/wp-includes/theme.php:1087
    0.2638   38251264  10. the_excerpt_rss() /home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php:46
    0.2710   38253864  11. apply_filters() /home/www/blog.juliencrouzet.fr/wp-includes/feed.php:177
    0.2712   38256264  12. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:166

]]></description>
			<content:encoded><![CDATA[<div id="attachment_422" class="wp-caption aligncenter" style="width: 209px"><a href="http://blog.juliencrouzet.fr/wp-content/uploads/2009/07/800px-PHP-n_logo.svg1_2.png" rel="lightbox[421]"><img class="size-medium wp-image-422" title="PHP5.3 est sorti le 30 Juin" src="http://blog.juliencrouzet.fr/wp-content/uploads/2009/07/800px-PHP-n_logo.svg1_2-300x157.png" alt="PHP5.3 est sorti le 30 Juin" width="199" height="104" /></a><p class="wp-caption-text">Les nouveautés de PHP5.3</p></div>
<p style="text-align: left;">Le 30 Juin dernier est sorti PHP5.3, discrètement&#8230; Pourtant c&#8217;est une évolution majeure, qui ne comprends pas que des corrections de bugs (140 corrections quand même).</p>
<p style="text-align: left;">Quoi de neuf alors dans cette version ?</p>
<p style="text-align: left;"><span id="more-421"></span></p>
<h2 style="text-align: left;">Les namespaces</h2>
<p>Annoncé comme l&#8217;une des évolutions majeures du légendaire PHP6 (sortie en 2087, peut être), les namespaces ou espaces de nommages sont l&#8217;une des dernières étapes de la route vers un vrai langage objet.</p>
<p>Alors qu&#8217;est ce que c&#8217;est &laquo;&nbsp;simplement&nbsp;&raquo; ? C&#8217;est un moyen de faire cohabiter ensemble plusieurs librairies de manière simple et d&#8217;organiser simplement son code.</p>
<p>Le but premier est de pouvoir nommer <strong>simplement </strong>des classes, constantes et fonctions sans risquer le conflit avec du code existant. Jusqu&#8217;ici, on utilisait des techniques, comme par exemple nommer ses classes en respectant des règles comme  <em>NomDuFramework_NomDeLaLibrairie_NomDeLaClasse</em>. Avec les namespaces, il est simple de compartimenter son code et ne pas se soucier des conflits.</p>
<p>Un exemple, qui j&#8217;espère, sera parlant :</p>
<pre name="code" class="php">

/**
 * On execute du code dans le deuxièmme espace
 */
namespace				Espace2 {
	echo "On est dans le deuxièmme espace :\n";
	var_dump(CONSTANTE);
	fonction();
	$objet = new Classe();
	$objet-&gt;test();
	echo "\n\n";
}
/**
 * On execute du code dans l'espace global
 */
namespace {
	echo "On est dans l'espace global :\n";
	echo "Est-ce que la constante CONSTANTE est définie ?\n";
	var_dump(defined('CONSTANTE'));
	echo "Est-ce que la fonction fonction() est définie ?\n";
	var_dump(function_exists('fonction'));
	echo "Est-ce que la classe 'Classe' est définie ?\n";
	var_dump(class_exists('Classe'));
}
?&gt;</pre>
<p>Avec cette évolution, on fait un pas de plus vers les lettres de noblesse de PHP dans le monde des langages objets, à plus d&#8217;un point.</p>
<p>Aujourd&#8217;hui, beaucoup de gens pensent leur code comme une accumulation de fonctions (souvent un copier-coller de <a href="http://phpfonctions.fr/">sites</a>). Utiliser des namespaces pousse le développeur à s&#8217;imposer une certaine rigueur et à bien séparer son code de manière logique.</p>
<p>J&#8217;attends avec impatience la 2.0 de <a href="http://framework.zend.com">Zend Framework</a> qui utilisera les namespaces <img src='http://blog.juliencrouzet.fr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Les fonctions anonymes</h2>
<p>Les fonctions anonymes (ou <em>closures</em>) sont des blocs de codes exécutables (donc des fonctions) mais qui ne possèdent pas de noms pour être rappelées plus tard. La première fois cela peut paraitre déroutant et on peut ne pas comprendre l&#8217;utilité, mais par exemple, si vous utilisez jQuery, vous saisissez immédiatement l&#8217;opportunité !</p>
<p>Prenons par exemple la fonction PHP <a href="http://fr2.php.net/manual/fr/function.array-walk.php">array_walk()</a> qui permet d&#8217;appliquer une fonction sur chaque élément d&#8217;un tableau. Avant on définissait une fonction, on la nommait et on passait le nom de la fonction en argument, comme ceci :</p>
<pre name="code" class="php">
function cmp($a, $b) {
    if ($a == $b) {
        return 0;
    }
    return ($a < $b) ? -1 : 1;
}
uasort($array, 'cmp');
</pre>
<p>Maintenant, on peut directement passer une fonction anonyme comme argument sans avoir à créer de fonction au préalable :</p>
<pre name="code" class="php">
uasort($array, function($a, $b) {
    if ($a == $b) {
        return 0;
    }
    return ($a < $b) ? -1 : 1;
});
</pre>
<h2>"late static binding"</h2>
<p>Le late static binding ou la "Résolution statique à la volée" est un concept assez théorique au premier abord mais qui solutionne une importante limitations de PHP.</p>
<p>Dans le cadre de méthodes statiques d'une classe, le mot clé <em>self </em>ou la constante <em>__CLASS__</em> qui font référence à la classe "courante" sont assignées par PHP lors de l'analyse du code et non au moment de l'exécution, donc en cas d'héritage, elles font référence à la classe parente et non à la classe courante.</p>
<p>Cela peut paraitre compliqué, alors prenons un exemple, le code suivant :</p>
<p>affichera "Je suis la classe Papa".</p>
<p>PHP5.3 étend donc le mot-clé <em>static</em>, pour l'utiliser comme une référence à la classe courante <strong>pendant l'exécution</strong> et non pendant la compilation. On peut donc écrire le code suivant :</p>
<pre name="code" class="php">
class		Papa {
	public static function	jeSuis() {
		return (__CLASS__);
	}

	public static function	annonceToi() {
		echo 'Je suis la classe ' . static::jeSuis() . "\n";
	}
}
class		Filston extends Papa {
	public static function	jeSuis() {
		return (__CLASS__);
	}
}

Filston::annonceToi();
</pre>
<p>qui affichera bien "Je suis la classe Filston".</p>
<h2>Le contrôle du garbage collector</h2>
<p>Pour ceux qui ne serait pas à l'aise, consultez l'article <a href="http://fr.wikipedia.org/wiki/Ramasse-miettes_%28informatique%29">Garbage Collector</a> sur Wikipedia.</p>
<p>N'ayant eu le temps de tester encore en détail, je vous conseille la lecture de ce <a href="http://blog.pascal-martin.fr/post/php-5.3-garbage-collector-vs-consommation-memoire">très bon billet</a>.</p>
<h2>L'opérateur ternaire simplifié</h2>
<pre name="code" class="php">
$valeur = ($valeur) ?: $default;
</pre>
<p>à la place de </p>
<pre name="code" class="php">
$valeur = ($valeur) ? $valeur : $default;
</pre>
<h2>Et puis aussi ...</h2>
<p>D'autres <a href="http://fr3.php.net/manual/en/migration53.php">petits changements</a> que je vous laisse consulter... <img src='http://blog.juliencrouzet.fr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Bonne lecture et bon tests !</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.juliencrouzet.fr/421/php-5-3-what-s-new/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>IE6 est il une faute professionnelle ?</title>
		<link>http://blog.juliencrouzet.fr/313/ie6-est-il-une-faute-professionnelle/</link>
		<comments>http://blog.juliencrouzet.fr/313/ie6-est-il-une-faute-professionnelle/#comments</comments>
		<pubDate>Fri, 13 Mar 2009 22:36:48 +0000</pubDate>
		<dc:creator>c2c</dc:creator>
				<category><![CDATA[geek]]></category>
		<category><![CDATA[ie6]]></category>
		<category><![CDATA[internet explorer]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://blog.juliencrouzet.fr/?p=313</guid>
		<description><![CDATA[
Warning: call_user_func_array() expects parameter 1 to be a valid callback, first array member is not a valid class name or object in /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php on line 166

Call Stack:
    0.0001     623440   1. {main}() /home/www/blog.juliencrouzet.fr/index.php:0
    0.0002     628968   2. require('/home/www/blog.juliencrouzet.fr/wp-blog-header.php') /home/www/blog.juliencrouzet.fr/index.php:17
    0.1948   38153848   3. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php') /home/www/blog.juliencrouzet.fr/wp-blog-header.php:16
    0.1957   38156768   4. do_feed() /home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php:14
    0.1957   38157048   5. do_action() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1721
    0.1957   38159072   6. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:395
    0.1957   38159128   7. do_feed_rss2() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:0
    0.1957   38159320   8. load_template() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1753
    0.1959   38221464   9. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php') /home/www/blog.juliencrouzet.fr/wp-includes/theme.php:1087
    0.2808   38255168  10. the_excerpt_rss() /home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php:46
    0.2893   38257744  11. apply_filters() /home/www/blog.juliencrouzet.fr/wp-includes/feed.php:177
    0.2895   38260120  12. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:166

]]></description>
			<content:encoded><![CDATA[<div id="attachment_314" class="wp-caption aligncenter" style="width: 160px"><a href="http://blog.juliencrouzet.fr/wp-content/uploads/2009/03/ie6-300x263.png" rel="lightbox[313]"><img class="size-thumbnail wp-image-314" title="ie6-300x263" src="http://blog.juliencrouzet.fr/wp-content/uploads/2009/03/ie6-300x263-150x150.png" alt="Meurs IE6, meurs" width="150" height="150" /></a><p class="wp-caption-text">Meurs IE6, meurs</p></div>
<p>Tout développeur, et même plus largement, toute personne travaillant dans le Web sait que IE6 est de nos jours uniquement synonyme de problèmes, de temps perdu et de régression. Alors que des initiatives comme <a href="http://www.stopie6.org/">Stop IE6</a> et l&#8217;ensemble de la communauté des développeurs essaye de le faire disparaitre de la planète Web (<a href="http://www.clubic.com/actualite-259480-microsoft-norvege-eradiquer-ie6.html">avec le soutien de Microsoft</a>), Internet Explorer 6 représente encore presque <a href="http://www.w3counter.com/globalstats.php">26%</a> du parc des navigateurs !</p>
<p>Dans ces 26%, une énorme partie représente le parc informatique des sociétés ou beaucoup de D.S.I. insistent à garder IE6 dans les installations.</p>
<p><span id="more-313"></span></p>
<h2>Le problème c&#8217;est 6, pas Internet Explorer</h2>
<p>Entendons nous bien, le problème n&#8217;est pas une simple guerre des navigateurs ou une croisade anti microsoft. Internet Explorer en est aujourd&#8217;hui à la version 8 (beta) et beaucoup de personnes admettent que la mouture IE8 est très correcte.</p>
<p>Non, le problème c&#8217;est que Internet Explorer 6 est un logiciel de 2001 dont Microsoft n&#8217;assure plus le support. A titre de comparaison, c&#8217;est comme si on demandait aux employés de travailler avec Word 2000 (celui ou le support du presse-papier a été ajouté !).</p>
<h2>Le travail d&#8217;un DSI, c&#8217;est quoi ?</h2>
<p>Si l&#8217;on en croit <a href="http://fr.wikipedia.org/wiki/Directeur_des_syst%C3%A8mes_d%27information">Wikipedia</a>, <a href="http://www.01net.com/article/220682.html">01Net</a> ou <a href="http://www-935.ibm.com/services/fr/cio/changeleader/index.html">IBM</a> parmis les rôles premiers d&#8217;un DSI, on a :</p>
<ul>
<li>Anticiper et suivre les évolutions sur le système informatique de la stratégie de l&#8217;entreprise ;</li>
<li>Assurer la sécurité et la pérennité des données et du travail des collaborateurs ;</li>
<li>Optimiser la performance de la société grâce à l&#8217;outil informatique ;</li>
<li>Commander les achats informatiques et opmtimiser leur cout.</li>
</ul>
<h2>Et une faute professionnelle ?</h2>
<blockquote><p>Je ne suis ni juriste ni spécialiste du droit du travail, donc cette définition n&#8217;est ni précise, ni complète.</p></blockquote>
<p>Une faute professionnelle est un acte, une erreur ou un manquement, qui de graves conséquences humaines, matérielles ou financières commis dans l&#8217;exercice de ses fonctions.</p>
<p>Parmi les critère d&#8217;appréciation de la faute, il y a bien évidemment des critères comme l&#8217;intention de nuire, des conséquences corporelles sur des collègues ou des notions de vols, agressions, etc.</p>
<p>Mais les critères qui nous intéressent ici sont une absence d&#8217;exécution des tâches premières demandées au salarié et son niveau hierarchique dans l&#8217;entreprise.</p>
<h2>Quelles sont les conséquences de vouloir conserver IE6 ?</h2>
<h3>La sécurité de l&#8217;entreprise</h3>
<p>Comme nous l&#8217;avons rappelé, Internet Explorer 6 est un logiciel de 2001. Il n&#8217;est ni plus mauvais, ni meilleur qu&#8217;un autre navigateur par essence, il est juste un outil qui a été développé pour un Internet qui n&#8217;a strictement rien à voir avec celui que l&#8217;on connait aujourd&#8217;hui.</p>
<p>Faire utiliser IE6 par ses employés revient aujourd&#8217;hui à exposer les postes à <a href="http://secunia.com/advisories/product/11/">150 failles connues</a> (et combien à découvrir &#8230;) et qui ne seront pas résolues !</p>
<p>De plus, la majorité des navigateurs actuels (IE7 compris) intègre un <a href="http://www.microsoft.com/canada/fr/athome/security/online/phishing_filter.mspx">filtre anti-hameçonnage</a> qui constituent aujourd&#8217;hui les attaques les plus fréquentes sur le Web.</p>
<p><strong>Un DSI qui impose IE6 impose l&#8217;utilisation d&#8217;un outil communément connus pour sa faible sécurité</strong></p>
<h3>La rentabilité de l&#8217;entreprise</h3>
<p>Il subsiste aujourd&#8217;hui très peu de métier dans le secteur tertiaire qui ne nécessite pas une utilisation intensive d&#8217;Internet et c&#8217;était beaucoup moins le cas en 2001.</p>
<p>Afin d&#8217;optimiser la navigation de chacun, les navigateurs se sont adaptés. A titre d&#8217;exemple, voici des fonctions présentes dans IE7 qui ne sont pas dans IE6 :</p>
<ul>
<li>La navigation par onglet qui permet de consulter plusieurs sites en même temps ;</li>
<li>La mosaïque &laquo;&nbsp;Quick Tabs&nbsp;&raquo; qui permet de voir tous les onglets ouvert afin de retrouver la page que l&#8217;on chercher ;</li>
<li>Une intégration du moteur de recherche a côté de la barre d&#8217;adresse pour effectuer une recherche rapidement ;</li>
<li>La possibilité de mettre en page avant d&#8217;imprimer ;</li>
<li>La possibilité de trier et de rechercher parmi son historique</li>
</ul>
<p><strong>Un DSI qui impose IE6 ralentit la productivité de son entreprise.</strong></p>
<h3>L&#8217;optimisation des coûts d&#8217;achat</h3>
<p>Le développement d&#8217;un site (y compris un intranet) compatible avec Internet Explorer 6 est une tâche ardue car la mise en page est rendu compliquée à cause de la faiblesse du support de <a href="http://fr.wikipedia.org/wiki/Feuilles_de_style_en_cascade">CSS. </a>La programmation est aussi rendue compliquée à cause de la gestion hasardeuse du <a href="http://fr.wikipedia.org/wiki/DOM">DOM </a>et de <a href="http://fr.wikipedia.org/wiki/Javascript">Javascript.</a></p>
<p>Conséquence : Soit les éditeurs de solutions intranet nécessitent des temps de développement plus important et donc des prix plus élévés, soit leur solution n&#8217;est pas compatible avec IE6 et donc inutilisable dans l&#8217;entreprise ;  le choix est donc plus limité.</p>
<p><strong>Un DSI qui impose IE6 augmente inutilement le coût des achats informatique dans l&#8217;entreprise.</strong></p>
<h2>Conclusion</h2>
<p>Je suis d&#8217;accord, la <strong>faute professionnelle</strong> en elle même est difficilement applicable et un petit peu tirée par les cheveux. Mais &#8230; quand même.</p>
<p>Le fait de vouloir conserver Internet Explorer 6 comme navigateur dans un système d&#8217;information est contraire à la définition même du travail d&#8217;un DSI.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.juliencrouzet.fr/313/ie6-est-il-une-faute-professionnelle/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Ce qu&#039;il faut savoir avant d&#039;envoyer des emails en masse</title>
		<link>http://blog.juliencrouzet.fr/298/ce-quil-faut-savoir-avant-denvoyer-des-emails-en-masse/</link>
		<comments>http://blog.juliencrouzet.fr/298/ce-quil-faut-savoir-avant-denvoyer-des-emails-en-masse/#comments</comments>
		<pubDate>Tue, 10 Mar 2009 09:00:45 +0000</pubDate>
		<dc:creator>c2c</dc:creator>
				<category><![CDATA[email]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[spam]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://blog.juliencrouzet.fr/?p=298</guid>
		<description><![CDATA[
Warning: call_user_func_array() expects parameter 1 to be a valid callback, first array member is not a valid class name or object in /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php on line 166

Call Stack:
    0.0001     623440   1. {main}() /home/www/blog.juliencrouzet.fr/index.php:0
    0.0002     628968   2. require('/home/www/blog.juliencrouzet.fr/wp-blog-header.php') /home/www/blog.juliencrouzet.fr/index.php:17
    0.1948   38153848   3. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php') /home/www/blog.juliencrouzet.fr/wp-blog-header.php:16
    0.1957   38156768   4. do_feed() /home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php:14
    0.1957   38157048   5. do_action() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1721
    0.1957   38159072   6. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:395
    0.1957   38159128   7. do_feed_rss2() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:0
    0.1957   38159320   8. load_template() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1753
    0.1959   38221464   9. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php') /home/www/blog.juliencrouzet.fr/wp-includes/theme.php:1087
    0.3004   38259072  10. the_excerpt_rss() /home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php:46
    0.3096   38261632  11. apply_filters() /home/www/blog.juliencrouzet.fr/wp-includes/feed.php:177
    0.3098   38264008  12. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:166

]]></description>
			<content:encoded><![CDATA[<div id="attachment_299" class="wp-caption aligncenter" style="width: 221px"><a href="http://blog.juliencrouzet.fr/wp-content/uploads/2009/03/spam.jpg" rel="lightbox[298]"><img class="size-full wp-image-299" title="spam" src="http://blog.juliencrouzet.fr/wp-content/uploads/2009/03/spam.jpg" alt="Mangez du spam, ne l'envoyez plus" width="211" height="189" /></a><p class="wp-caption-text">Mangez du spam, ne l&#39;envoyez plus</p></div>
<p>Tout bon site avec une gestion des utilisateurs envoie des mails, c&#8217;est incontournable, mais pour bien le faire ; et par la même être sur qu&#8217;ils seront bien reçus et lus ; il faut respecter quelques points.</p>
<p><span id="more-298"></span></p>
<h2>Ne pas utiliser <a href="http://fr.php.net/manual/fr/function.mail.php">mail()</a> &#8230;</h2>
<p>Comment ça ? Oui !</p>
<ol>
<li>mail() fonctionne différement selon les OS</li>
<li>mail() ouvre une socket à chaque envoi de mail dans une boucle</li>
<li>mail() ne protège pas les en-tête (et donc permet le spam via votre site)</li>
<li>mail() complique la gestion du <a href="http://fr.wikipedia.org/wiki/Multipurpose_Internet_Mail_Extensions">MIME</a></li>
<li>mail() ça craint <img src='http://blog.juliencrouzet.fr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ol>
<h2>&#8230; et utiliser une librairie ou un Framework à la place</h2>
<p><a href="http://pear.php.net/package/Mail_Mime">Pear::Mail_Mime</a>, <a href="http://www.swiftmailer.org/">Swift Mailer</a>, <a href="http://phpmailer.codeworxtech.com/">PHP Mailer</a> ou &#8230; (je touche un € a chaque fois que je le cite <img src='http://blog.juliencrouzet.fr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ) <a href="http://framework.zend.com/manual/fr/zend.mail.html">Zend Framework</a> sont vos amis, n&#8217;hésitez pas à en user et abuser.</p>
<p>Si vous êtes du genre à vouloir recoder la roue, au moins, inspirez vous en plutôt que d&#8217;utiliser une classe d&#8217;abstraction de mail() !</p>
<h2>Offrir un alternative texte</h2>
<p>Vous avez passé des heures a intégrer un joli mail HTML, très graphique et qui marche sous <a href="http://www.campaignmonitor.com/css/">tous les clients mail</a> (et oui, c&#8217;est autant le bordel que pour les navigateurs). C&#8217;est bien, et très utile, la majorité des gens apprécieront.</p>
<p>Mais on est sur Internet, et il y a toujours des gens qui ralent ; d&#8217;autres qui ont des outils différents. Ceux-la sont aussi de potentiels clients ou abonnés.</p>
<p>Offrez dont toujours une alternative texte à vos mails, les librairies et framework cités ci-dessus le gèrent tous !</p>
<h2>Offrir un lien de désabonnement</h2>
<p>Assez explicite, et indispensable.</p>
<p>Tous vos mails doivent avoir au moins un lien qui permet au destinataire de vous dire &laquo;&nbsp;Je ne veux plus recevoir de mail de toi !&nbsp;&raquo;, c&#8217;est son droit le plus strict.</p>
<p>Et un vrai lien, hein, qui désabonne vraiment ! Ou un adresse, qui est vraiment lue ou vous désabonnez vraiment.</p>
<p>De toute façon, si vous ne respectez pas ça, vous serez listé comme spammeur, tôt ou tard !</p>
<h2>Bien configurer son serveur d&#8217;envoi de mail</h2>
<h3>Avoir un reverse</h3>
<p>Un <a href="http://en.wikipedia.org/wiki/Reverse_DNS_lookup">reverse DNS</a>, c&#8217;est (soyons le plus simple possible) &laquo;&nbsp;quelque chose&nbsp;&raquo; qui permet de traduire une I.P. (11.22.33.44) en nom d&#8217;hôte (hostname, ex: <em>mail.domain.com</em>).</p>
<p>Il doit être mis en place sur l&#8217;IP de vos serveurs d&#8217;envoi de mail (tous les hébergeurs vous le permettent) sous peine de voir ses mails tous mis dans la boite &laquo;&nbsp;SPAM&nbsp;&raquo;.</p>
<h3>Vérifier que l&#8217;on est pas &laquo;&nbsp;Open Relay&nbsp;&raquo;</h3>
<p>Si tout le monde peut envoyer des mails sur votre serveur, vous êtes <a href="http://en.wikipedia.org/wiki/Open_mail_relay">Open Relay</a>.</p>
<p>C&#8217;est tout d&#8217;abord embétant pour vous pour des raisons de sécurité et de responsabilité. Mais en plus, il y a des Zoros du spam, comme <a href="http://www.dnsbl.com/">DNSBL</a> ou <a href="http://www.au.sorbs.net/">SORBS</a> qui sont des black-list d&#8217;IP de serveurs qui, entre autre, sont Open Relay.</p>
<p>Si un de ces système le détecte chez vous, pareil, =&gt; SPAM.</p>
<h3>Paramétrer votre SPF</h3>
<p>Tout est <a href="http://fr.wikipedia.org/wiki/Sender_Policy_Framework">là</a>. Si vous ne le faîtes pas, vous serez en SPAM sous Hotmail, GMail, etc.</p>
<h3>Et aussi Domain Keys / DKIM</h3>
<p>Idem que précédement, mais pour Yahoo!. Ca se passe <a href="http://fr.docs.yahoo.com/mail/spamguard_domainkeys.html">ici</a>.</p>
<h2>Cadencez vos envois</h2>
<p>Vous avez une newletter à envoyer à 25.000 membres ?</p>
<p>Évitez d&#8217;envoyer ça d&#8217;un coup, sous peine de blacklistage immédiat par GMail, Yahoo! ou AOL. Préférez un envoi modéré, par exemple, 1000 par heure.</p>
<h2>Utilisez un return-path</h2>
<p>Si l&#8217;adresse à laquelle vous envoyez un email ne peut le recevoir (souvent un mail sur trois &#8230;) pour diverses raisons (faute de frappe, quota dépassé, compte supprimé), il sera retourné à l&#8217;adresse spécifiée par le <a href="http://en.wikipedia.org/wiki/Variable_envelope_return_path">Return-Path</a>.</p>
<p>Utilisez cette variable pour détecter les emails qui n&#8217;ont pu arriver et supprimez-les de votre base de données. Si vous essayez plusieurs fois d&#8217;envoyer un email à une adresse en erreur, toujours la même chose, vous serez identifié comme Spammer !</p>
<h2>N&#8217;utilisez pas d&#8217;adresse d&#8217;images dynamiques</h2>
<p>Pour savoir qui avait ouvert notre email, en 1998, on utilisait une astuce de sioux, on utilisait des images du type &laquo;&nbsp;http://www.monsite.com/newsletter/image.php?email=toto@aol.com&nbsp;&raquo;. Les spammeurs aussi &#8230;</p>
<p>De nos jours, c&#8217;est tellement connu et mal apprécié que même outlook sait le détécter !</p>
<p>Premièrement, vous n&#8217;avez pas à savoir qui à lu votre email, c&#8217;est indiscret !</p>
<p>Deuxièmement, vous voulez savoir, et c&#8217;est légitime, COMBIEN de personne ont ouvert votre mail. Insérez donc juste vos images de manière simple (http://www.monsite.com/newsletter/logo.gif) et <strong>la même pour tout le monde</strong> puis comptez dans votre log Apache (ou autre).</p>
<p>Souvenez vous juste que ce chiffre n&#8217;est pas le reflet de la réalité, et loin s&#8217;en faut :</p>
<ol>
<li>Beaucoup de gens ne cliquent pas sur &laquo;&nbsp;Afficher les images du mail&nbsp;&raquo;</li>
<li>Les 300 personnes de chez EDF qui ont lu votre mail n&#8217;ont fait qu&#8217;une requête dans vos logs, le reste l&#8217;ont lu depuis le cache du proxy d&#8217;EDF&#8230;</li>
<li>Certains lisent la version texte du mail, sans les images</li>
</ol>
<h2>Hébergez une version &laquo;&nbsp;html&nbsp;&raquo; de votre mail</h2>
<p>Vous voyez surement de quoi je veux parler, le fameux lien &laquo;&nbsp;Cliquez ici si vous ne pouvez lire cet email&nbsp;&raquo;.</p>
<p>Beaucoup de gens ont des clients Email psychotiques (Lotus, Outlook Express de 2001, iPhone, etc.).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.juliencrouzet.fr/298/ce-quil-faut-savoir-avant-denvoyer-des-emails-en-masse/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Le DOM, c&#039;est le bordel !</title>
		<link>http://blog.juliencrouzet.fr/277/le-dom-cest-le-bordel/</link>
		<comments>http://blog.juliencrouzet.fr/277/le-dom-cest-le-bordel/#comments</comments>
		<pubDate>Mon, 09 Mar 2009 11:13:09 +0000</pubDate>
		<dc:creator>c2c</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://blog.juliencrouzet.fr/?p=277</guid>
		<description><![CDATA[
Warning: call_user_func_array() expects parameter 1 to be a valid callback, first array member is not a valid class name or object in /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php on line 166

Call Stack:
    0.0001     623440   1. {main}() /home/www/blog.juliencrouzet.fr/index.php:0
    0.0002     628968   2. require('/home/www/blog.juliencrouzet.fr/wp-blog-header.php') /home/www/blog.juliencrouzet.fr/index.php:17
    0.1948   38153848   3. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php') /home/www/blog.juliencrouzet.fr/wp-blog-header.php:16
    0.1957   38156768   4. do_feed() /home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php:14
    0.1957   38157048   5. do_action() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1721
    0.1957   38159072   6. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:395
    0.1957   38159128   7. do_feed_rss2() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:0
    0.1957   38159320   8. load_template() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1753
    0.1959   38221464   9. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php') /home/www/blog.juliencrouzet.fr/wp-includes/theme.php:1087
    0.3212   38262976  10. the_excerpt_rss() /home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php:46
    0.3238   38265544  11. apply_filters() /home/www/blog.juliencrouzet.fr/wp-includes/feed.php:177
    0.3241   38267840  12. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:166

]]></description>
			<content:encoded><![CDATA[<p>Une super présentation par John Resig (le jeune créateur de jQuery, entre autres) qui nous explique avec le sourire pourquoi le DOM, c&#8217;est le bordel <img src='http://blog.juliencrouzet.fr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p style="text-align: center;"><object width="425" height="355" data="http://static.slideshare.net/swf/ssplayer2.swf?doc=yahoodom-1233608138666908-3&amp;stripped_title=the-dom-is-a-mess-yahoo" type="application/x-shockwave-flash"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=yahoodom-1233608138666908-3&amp;stripped_title=the-dom-is-a-mess-yahoo" /><param name="allowfullscreen" value="true" /></object></p>
<div id="__ss_981615" style="width: 425px; text-align: left;"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" title="The DOM is a Mess @ Yahoo" href="http://www.slideshare.net/jeresig/the-dom-is-a-mess-yahoo?type=presentation">The DOM is a Mess @ Yahoo</a></div>
<div id="__ss_981615" style="width: 425px; text-align: left;"></div>
<p><span id="more-277"></span></p>
<p style="text-align: center;"><object width="512" height="322" data="http://d.yimg.com/static.video.yahoo.com/yep/YV_YEP.swf?ver=2.2.34" type="application/x-shockwave-flash"><param name="allowFullScreen" value="true" /><param name="AllowScriptAccess" value="always" /><param name="bgcolor" value="#000000" /><param name="flashVars" value="id=11812238&amp;vid=4403981&amp;lang=en-us&amp;intl=us&amp;thumbUrl=http%3A//l.yimg.com/a/p/i/bcst/videosearch/899/79387316.jpeg&amp;embed=1" /><param name="src" value="http://d.yimg.com/static.video.yahoo.com/yep/YV_YEP.swf?ver=2.2.34" /><param name="flashvars" value="id=11812238&amp;vid=4403981&amp;lang=en-us&amp;intl=us&amp;thumbUrl=http%3A//l.yimg.com/a/p/i/bcst/videosearch/899/79387316.jpeg&amp;embed=1" /><param name="allowfullscreen" value="true" /></object></p>
<p style="text-align: left;">
<div><a href="http://video.yahoo.com/watch/4403981/11812238">John Resig: &laquo;&nbsp;The DOM Is a  Mess&nbsp;&raquo;</a> @ <a href="http://video.yahoo.com">Yahoo! Video</a></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.juliencrouzet.fr/277/le-dom-cest-le-bordel/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[PHP] Les sessions</title>
		<link>http://blog.juliencrouzet.fr/263/php-les-sessions/</link>
		<comments>http://blog.juliencrouzet.fr/263/php-les-sessions/#comments</comments>
		<pubDate>Mon, 09 Mar 2009 09:00:32 +0000</pubDate>
		<dc:creator>c2c</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://blog.juliencrouzet.fr/?p=263</guid>
		<description><![CDATA[
Warning: call_user_func_array() expects parameter 1 to be a valid callback, first array member is not a valid class name or object in /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php on line 166

Call Stack:
    0.0001     623440   1. {main}() /home/www/blog.juliencrouzet.fr/index.php:0
    0.0002     628968   2. require('/home/www/blog.juliencrouzet.fr/wp-blog-header.php') /home/www/blog.juliencrouzet.fr/index.php:17
    0.1948   38153848   3. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php') /home/www/blog.juliencrouzet.fr/wp-blog-header.php:16
    0.1957   38156768   4. do_feed() /home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php:14
    0.1957   38157048   5. do_action() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1721
    0.1957   38159072   6. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:395
    0.1957   38159128   7. do_feed_rss2() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:0
    0.1957   38159320   8. load_template() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1753
    0.1959   38221464   9. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php') /home/www/blog.juliencrouzet.fr/wp-includes/theme.php:1087
    0.3291   38266920  10. the_excerpt_rss() /home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php:46
    0.3444   38269552  11. apply_filters() /home/www/blog.juliencrouzet.fr/wp-includes/feed.php:177
    0.3446   38271984  12. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:166

]]></description>
			<content:encoded><![CDATA[<div id="attachment_264" class="wp-caption aligncenter" style="width: 188px"><a href="http://blog.juliencrouzet.fr/wp-content/uploads/2009/03/800px-php-n_logosvg1_2.png" rel="lightbox[263]"><img class="size-medium wp-image-264" title="800px-php-n_logosvg1_2" src="http://blog.juliencrouzet.fr/wp-content/uploads/2009/03/800px-php-n_logosvg1_2-300x157.png" alt="Les sessions PHP" width="178" height="93" /></a><p class="wp-caption-text">Les sessions PHP</p></div>
<p>Les <a href="http://fr.php.net/manual/fr/book.session.php">sessions</a> sont présentes dans PHP depuis PHP4 (1998) et font partie des première choses que l&#8217;ont apprend à utiliser, cependant, elles sont souvent très mal utilisées car mal comprises ; l&#8217;occasion de revenir sur ce sujet et me lancer dans un premier article &laquo;&nbsp;pédagogique&nbsp;&raquo;.</p>
<p><span id="more-263"></span></p>
<h2>Pourquoi utiliser des sessions</h2>
<p>Comprendre ce point, c&#8217;est éviter pas mal de bourdes. Qu&#8217;est-ce qu&#8217;une session exactement ?</p>
<p>Une session, comme son nom l&#8217;indique, représente un temps <strong>défini</strong> d&#8217;utilisation d&#8217;un site par un internaute donné. Cette session à donc un début et une fin et représente un temps logique d&#8217;utilisation.</p>
<p>Les sites Web reposent sur un protocole : <a href="http://fr.wikipedia.org/wiki/Hypertext_Transfer_Protocol">HTTP</a>, qui est de nature très volatile =&gt; <strong>Je me connecte, j&#8217;envoi une requête, le serveur me répond, je me déconnecte.</strong> Impossible de savoir qui vous êtes !Pour pallier à ce problème ont été inventés les <a href="http://fr.wikipedia.org/wiki/Cookie_(informatique)">cookies</a>. Un cookie est un &laquo;&nbsp;témoin&nbsp;&raquo; que laisse un serveur Web dans votre navigateur, cela permet de mettre en place un historique de la communication.</p>
<p>Les sessions ont le même but, garder un historique des communications entre le serveur Web et votre navigateur. Ce n&#8217;est ni un espace de stockage temporaire, ni une base de données.</p>
<h2>Comment fonctionnent les sessions</h2>
<p>Côté PHP, rien de plus simple :</p>
<pre lang="PHP">/**
 * Création de la session
 */
session_start();
/**
 * Créer / Modifier une donnée de session
 */
$_SESSION['user_id'] = 125;
/**
 * Supprimer une donnée de session
 */
unset($_SESSION['user_id']);
/**
 * Détruire une session
 */
session_destroy();</pre>
<p>Je vous laisse consulter <a href="http://fr2.php.net/manual/fr/ref.session.php">la liste des fonctions</a> complète &#8230;</p>
<p>Mais comment cela fonctionne-t-il concrètement ? Analysons le fonctionnement <strong>par défaut</strong> :</p>
<p>Lors du premier appel à <em>session_create()</em>, PHP va créer un fichier temporaire dont le nom est un <a href="http://fr2.php.net/uniqid">identifiant unique</a>. Cet identifiant est également l&#8217;identifiant de le session. Il va également envoyer un cookie au navigateur nommé <em>PHPSESSID</em> contenant cet identifiant unique.</p>
<p>Une fois ce fichier créé, PHP va alors rendre disponible un variable <a href="http://fr2.php.net/manual/fr/language.variables.superglobals.php">superglobale</a> (disponible quel que soit le contexte) <em>$_SESSION</em>. Le développeur peut alors utiliser ce tableau comme n&#8217;importe lequel pour y stocker, lire et supprimer des données.</p>
<p>A la fin de l&#8217;execution du script, PHP va écrire dans le fichier temporaire créé lors de la première étape le contenu du tableau <em>$_SESSION</em> <a href="http://fr2.php.net/serialize">linéarisé</a>.</p>
<p>Lors des prochaines requêtes, le navigateur va envoyer l&#8217;identifiant de la session (stocké dans le cookie <em>PHPSESSID</em>), <em>session_create()</em> ne créera pas alors de fichier mais <a href="http://fr2.php.net/unserialize">délinéarisera</a> le contenu de ce fichier et le stockera dans <em>$_SESSION</em>, le développeur pourra alors récupérer les données stockées lors de la requête précédente et les modifier à nouveau. Ce jusqu&#8217;a l&#8217;appel de <em>session_destroy()</em> qui effacera le fichier temporaire et le cookie.</p>
<p>Comme l&#8217;on vient de le voir, le système des sessions est basé sur les cookies. Un cookie est donné du serveur Web au navigateur par une <a href="http://fr.wikipedia.org/wiki/Header_(informatique)">en-tête </a>HTTP. Il est donc impératif de placer l&#8217;appel à <em>session_start()</em> le plus haut possible dans votre script, car toute information envoyée (<a href="http://fr2.php.net/echo">echo()</a>, <a href="http://fr2.php.net/imagejpeg">imagejpeg()</a>, &#8230;) provoquera l&#8217;envoi définif des en-tête standard et il sera trop tard pour envoyer le cookie de session !</p>
<h2>Ce qu&#8217;une session doit contenir</h2>
<p>Maintenant que nous avons une nouvelle opportunité, à savoir stocker des données entre deux requête d&#8217;un utilisateur, on pourrait avoir le reflexe d&#8217;y enregistrer tout un tas de chose, comme l&#8217;historique de navigation de l&#8217;internaute sur le site, ses précédents achats, etc.</p>
<p>STOP.</p>
<p>Une session n&#8217;est pas un espace de stockage ou une mémoire cache. Le fonctionnement décrit ci-dessus est très pratique mais très gourmand en ressources :</p>
<ul>
<li>Les données sont à chaque requête <a href="http://fr2.php.net/serialize">linéarisée</a> et <a href="http://fr2.php.net/unserialize">délinéarisées</a>. Si cette fonction est très pratique pour enregistrer une données complexe facilement (transformée en une chaîne), elle est très couteuse en ressources</li>
<li>Les données linéarisées sont stockées sur un fichier. Il y a donc pour chaque requête une écriture et une lecture sur le disque dur. Les opérations sur le disque dur sont les première opérations à minimiser si l&#8217;on veut optimiser son site</li>
<li>Le tableau <em>$_SESSION</em> est une superglobale, ce qui veut dire qu&#8217;il sera accessible de partout mais aussi qu&#8217;il sera présent en mémoire tout au long de l&#8217;execution du script. Garder beaucoup d&#8217;informations en mémoire quand elles ne sont pas utilisées est un non sens. Celles-ci doivent être présente que lorsqu&#8217;on l&#8217;utilise est déchargées dès que possible.</li>
</ul>
<p>Une session ne doit donc contenir qu&#8217;une chose : Des informations sur la session en cours, typiquement peut s&#8217;agir :</p>
<ul>
<li>D&#8217;un identifiant utilisateur</li>
<li>Un email</li>
<li>Une clef unique</li>
<li>La date de création de la session</li>
</ul>
<h2>Configuration et scaling</h2>
<p>Le fonctionnement des sessions vu ci-dessus n&#8217;est pas gravé dans le marbre. Et heureusement.Si il a le mérité d&#8217;être simple à utiliser, il est totalement inutilisable sur des sites à gros traffic.</p>
<h3>Configurer le cookie</h3>
<p>Le nom par défaut du cookie des sessions est <em>PHPSESSID</em>. Simple, clair, on sait de quoi il s&#8217;agit. Un peu trop même. Cela peut être changé en utilisant la fonction <a href="http://fr2.php.net/session-name"><em>session_name()</em></a> ou la variable de configuration <a href="http://fr2.php.net/manual/fr/session.configuration.php#ini.session.name"><em>session.name</em></a>.</p>
<p>Mais il y a plus grave, ce cookie est défini par défaut comme ceci :</p>
<ul>
<li>Il n&#8217;est valable que pour le domaine (VHOST) en cours (donc si vous changez de domaine =&gt; en.monsite.com vers fr.monsite.com, il n&#8217;est plus valable)</li>
<li>Il est valable des la racine &#8216;/&#8217; (Si votre site est www.site.com/monsite/, vous le partagez avec www.site.com/autresite/)</li>
<li>C&#8217;est un cookie de session (Des que le navigateur est fermé, il n&#8217;est plus valable)</li>
<li>Il est valable qu&#8217;on soit en HTTP ou HTTPS</li>
</ul>
<p>Pour configurer ça, nous avons la méthode</p>
<pre lang="PHP">session_set_cookie_params($lifetime, $path, $domain, $secure, $httponly);</pre>
<ul>
<li><strong>$lifetime</strong> : Si 0, cookie de session, sinon, le nombre de secondes pendant lequel il sera valable [Default: 0]</li>
<li><strong>$path</strong> : Définit la racine du chemin a partir duquel le cookie sera valide (Ex: &#8216;/monsite&#8217;) [Default: '/']</li>
<li><strong>$domain</strong> : Domaine pour lequel le cookie sera valable. Pour tous les domaines se terminant par &#8216;juliencrouzet.fr&#8217;, utilisez &#8216;<span style="text-decoration: underline;"><strong>.</strong></span>juliencrouzet.fr&#8217; [Default: Le VHOST en cours]</li>
<li><strong>$secure</strong> : Si true, le cookie ne sera envoyé que si l&#8217;on est en HTTPS [Default: false]</li>
<li><strong>$httponly</strong> : Si true, le cookie ne sera envoyé que si le protocole est HTTP (Pas dans le cas d&#8217;une demande de script ou de feuille CSS, comme c&#8217;est le cas sur les attaques <a href="http://fr.wikipedia.org/wiki/Cross_site_scripting">XSS</a>) [Default: false]</li>
</ul>
<h3>Modifier la gestion des cookie</h3>
<p>PHP est livré avec le système de session géré par fichier temporaire comme décrit plus haut.  Cependant, comme nous l&#8217;avons rappelé, ce système est couteux en ressources et inadapté à des sites professionnels à forts traffic.</p>
<p>Heureusement, tout à été prévu ! La fonction <a href="http://fr2.php.net/manual/fr/function.session-set-save-handler.php"><em>session_set_save_handler()</em></a> vous permet de gérer vous même la création, la destruction est la manipulation des sessions et ainsi les stocker dans :</p>
<ul>
<li>Une base de données MySQL, SQLite, etc.</li>
<li>Un système de cache (Attention cependant, un cache est volatile et peut disparaitre, vos sessions aussi !)</li>
<li>Ce que vous voulez !</li>
</ul>
<h3>Scaling de votre application</h3>
<p>Si modifier la gestion des sessions peut paraitre un best practice si l&#8217;on a qu&#8217;un serveur, elle devient indispensable si l&#8217;on a plusieurs serveurs !</p>
<p>Une session est propre à un site Internet, pas à une machine, et si la session est stockée sur le disque dur de la première machine ou l&#8217;a fait une requête, elle aura disparue des que l&#8217;on change de serveur !</p>
<h2>Sécuriser des sessions</h2>
<p>Les sessions servant essentiellement à authentifier un internaute, il est primordial de vérifier leur sécurité. Une des première faille du système repose sur le fait qu&#8217;il suffise de connaitre l&#8217;identifiant de la session d&#8217;un internaute pour usurper son identité. C&#8217;est moche.</p>
<p>Une des premières idées que l&#8217;on peut avoir est de couplé cet identifiant à une adresse I.P., mais quid des utilisateurs en entreprise qui sont souvent derrière un pool de proxy et donc qui changent régulierement d&#8217;I.P. ?</p>
<p>La plus importante règle de sécurité à appliquer est en fait de regénérer l&#8217;identifiant de session à chaque requête. Certes, le cookie change à chaque fois et cela peut être un peu gourmand en ressources, mais si quelqu&#8217;un arrive à récupérer votre identifiant, cela ne lui sert a rien, il aura déjà changé lors de la prochaine requête.</p>
<p>Il suffit pour cela d&#8217;utiliser <a href="http://fr2.php.net/session-regenerate-id"><em>session_regenerate_id()</em></a> &#8211; ou &#8211; utiliser Zend Framework ! (oui je sais c&#8217;est récurrent ça)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.juliencrouzet.fr/263/php-les-sessions/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>10 outils qui séparent un développeur d’un webmaster</title>
		<link>http://blog.juliencrouzet.fr/252/10-outils-qui-separent-un-devloppeur-d-un-webmaster/</link>
		<comments>http://blog.juliencrouzet.fr/252/10-outils-qui-separent-un-devloppeur-d-un-webmaster/#comments</comments>
		<pubDate>Sun, 08 Mar 2009 14:57:14 +0000</pubDate>
		<dc:creator>c2c</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://blog.juliencrouzet.fr/?p=252</guid>
		<description><![CDATA[
Warning: call_user_func_array() expects parameter 1 to be a valid callback, first array member is not a valid class name or object in /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php on line 166

Call Stack:
    0.0001     623440   1. {main}() /home/www/blog.juliencrouzet.fr/index.php:0
    0.0002     628968   2. require('/home/www/blog.juliencrouzet.fr/wp-blog-header.php') /home/www/blog.juliencrouzet.fr/index.php:17
    0.1948   38153848   3. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php') /home/www/blog.juliencrouzet.fr/wp-blog-header.php:16
    0.1957   38156768   4. do_feed() /home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php:14
    0.1957   38157048   5. do_action() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1721
    0.1957   38159072   6. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:395
    0.1957   38159128   7. do_feed_rss2() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:0
    0.1957   38159320   8. load_template() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1753
    0.1959   38221464   9. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php') /home/www/blog.juliencrouzet.fr/wp-includes/theme.php:1087
    0.3617   38270824  10. the_excerpt_rss() /home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php:46
    0.3777   38273432  11. apply_filters() /home/www/blog.juliencrouzet.fr/wp-includes/feed.php:177
    0.3780   38275840  12. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:166

]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.juliencrouzet.fr/wp-content/uploads/2009/02/codemonkeysketch.jpg" rel="lightbox[252]"><img class="aligncenter size-medium wp-image-206" title="codemonkeysketch" src="http://blog.juliencrouzet.fr/wp-content/uploads/2009/02/codemonkeysketch-296x300.jpg" alt="codemonkeysketch" width="144" height="146" /></a></p>
<p>Suite au <a href="http://blog.juliencrouzet.fr/2009/02/28/10-regles-qui-separent-un-developpeur-dun-webmaster/comment-page-1/#comment-49">commentaire de Fred</a>, je me lance dans une nouvelle liste, plus ou moins la même, mais concernant cette fois les outils utilisés dans le cadre d&#8217;un développement PHP. Pour d&#8217;autres langages, la plupart du temps, les mêmes outils existent, n&#8217;hésitez pas à commenter.</p>
<p><span id="more-252"></span></p>
<h2><a href="http://www.getfirefox.com">Firefox</a></h2>
<p>Je pense qu&#8217;il est pas nécessaire de s&#8217;étendre sur Firefox&#8230;</p>
<p><span style="text-decoration: underline;">Alternatives</span> : Vous savez &#8230;</p>
<h2><a href="http://www.getfirebug.com"> Firebug et ses modules</a></h2>
<p><a href="http://www.getfirebug.com">Firebug</a> est tellement incontournable qu&#8217;il devrait faire l&#8217;objet de cours dans les écoles d&#8217;informatique qui touchent au développement Web !Régulièrement, je me pose la question : Combien de temps aurais-je eu besoin pour débugguer ça sans Firebug ? Et en général c&#8217;est des jours &#8230;</p>
<p>Firebug, c&#8217;est une <a href="http://getfirebug.com/logging.html">console</a> de débug, un <a href="http://getfirebug.com/dom.html">explorateur DOM</a>, un <a href="http://getfirebug.com/js.html">profiler Javascript</a>, un <a href="http://getfirebug.com/html.html">inspecteur HTML</a>, un <a href="http://getfirebug.com/net.html">sniffer HTTP</a>, <a href="http://www.evotech.net/blog/2007/06/introduction-to-firebug/">etc</a>.</p>
<p>Mais pas seulement &#8230;</p>
<p>Petit à petit des extensions de Firebug (oui des extensions d&#8217;un extension &#8230; c&#8217;est magique Firefox) on poussé. En voila 3 qui me parraissent tout simplement indispensable à votre santé mentale :</p>
<h3><a href="http://addons.mozilla.org/en-US/firefox/addon/6683">Firecookie</a></h3>
<p>Permet d&#8217;avoir un log de toutes les créations, modifications et expirations des cookies, de les gérer (création, edition, supression, &#8230;) et de configurer les autorisations.</p>
<h3><a href="http://fireunit.org/">Fireunit</a></h3>
<p>Permet de créer et d&#8217;exécuter des tests unitaires en Javascript.</p>
<h3><a href="http://developer.yahoo.com/yslow/">YSlow</a></h3>
<p>Crée un rapport de performance sur votre site (connection, rapidité, etc.) en utilisant Firebug. Développé par Yahoo!.</p>
<p>Au passage, ça <a href="http://getfirebug.com/lite.html">marche sous les autres navigateurs</a> !</p>
<p><span style="text-decoration: underline;">Alternatives</span> : Aucune ! Des petits bouts dans <a href="http://addons.mozilla.org/fr/firefox/addon/60">Web Developper</a>, ou <a href="http://addons.mozilla.org/addon/216">Javascript Debugger</a> mais on en est loin.</p>
<h2><a href="http://fr.wikipedia.org/wiki/Git">GIT</a></h2>
<p>GIT (connard, en anglais) est outil de <a href="http://fr.wikipedia.org/wiki/Syst%C3%A8me_de_gestion_de_versions">versionning</a> développé par Linus Torvalds (le créateur de Linux).</p>
<p>Comme tout outil de versionning, il permet de gérer les évolutions de fichiers dans une architecture ; cependant; il a quelques avantages :</p>
<ul>
<li>Un système <a href="http://fr.wikipedia.org/wiki/Gestion_de_version_d%C3%A9centralis%C3%A9e">décentralisé</a></li>
<li>Une gestion des droits plus poussée</li>
<li>Une vraie gestion des branches</li>
<li>Un besoin d&#8217;espace disque réduit</li>
<li>Une performance (rapidité, fiabilité) à toute épreuve</li>
</ul>
<p><span style="text-decoration: underline;">Alternatives</span> : <a href="http://subversion.tigris.org/">SVN</a>, <a href="http://bazaar-vcs.org/">Bazaar</a>, <a href="http://www.bitkeeper.com/">BitKeeper </a>(propriétaire)</p>
<h2><a href="http://validator.w3.org/">W3C Validator</a></h2>
<p>Valider son code (X)HTML peut parfois paraitre un long et inutile processus. Surtout que le sus nommé validateur est très pointilleux ; mais croyez-moi ; vous gagnez en fait de loooongues heures de débuggage.</p>
<p>Une source XHTML valide à 100% a de très très fortes chances de s&#8217;afficher correctement sous tous les navigateurs et qui plus est, plus rapidement.</p>
<p><span style="text-decoration: underline;">Alternatives</span> : <a href="http://www.htmlhelp.com/tools/validator/">WDG Validator</a>, <a href="https://addons.mozilla.org/fr/firefox/addon/249">HTML Validator for Firefox</a></p>
<h2><a href="http://www.jslint.com/">JSLint</a> &amp; <a href="http://www.icosaedro.it/phplint/">PHPLint</a></h2>
<p>Ceux qui ont fait du <a href="http://fr.wikipedia.org/wiki/C_(langage)">C</a>, du vrai, du costaud, du barbu connaissent <a href="http://docs.sun.com/source/806-3567/lint.html">lint</a>. lint c&#8217;était un peu le vieux monsieur du batiment qui arrivent sur un chantier qui apparement est fini et vous dit &laquo;&nbsp;Votre mur là, c&#8217;est du béton pauvre en ciment, ca va tomber dans 2 ans !&nbsp;&raquo;.</p>
<p>Les fonctions de lint sont aujourd&#8217;hui intégrées aux compilateurs (gcc &amp; co), et lint est plutôt un terme génrérique (<a href="http://www.jslint.com/">JSLint,</a> <a href="http://www.icosaedro.it/phplint/">PHPLint</a>, <a href="http://www.sureshotsoftware.com/javalint/">JAVALint</a>, etc.) qui décrit un outil analysant votre code afin d&#8217;y trouver les incohérences ou bugs potentiels. Ils permettent, entre autres, de détécter :</p>
<ul>
<li>Les variables non utilisées, non instanciées ou mal typées</li>
<li>Les partie de code qui ne seront jamais utilisées</li>
<li>Les potentielles boucles infinies</li>
<li>Les confusions possibles dues à de mauvais noms de variables ou fonctions</li>
</ul>
<p><span style="text-decoration: underline;">Alternatives</span> : <a href="http://yasca.org/">YASCA</a>, <a href="http://seclab.tuwien.ac.at/projects/pixy/">Pixy</a>, <a href="http://www.fortify.com/">Fortify</a> (commercial)</p>
<h2><a href="http://www.zend.com/fr/products/studio/">Zend Studio</a></h2>
<p>Je suis d&#8217;habitude du genre à préférer les solutions open source, mais je n&#8217;ai pas trouvé d&#8217;équivalent pour l&#8217;intant. C&#8217;est en suite un question d&#8217;habitude&#8230;</p>
<p>Quoi qu&#8217;il en soit, il est inconcevable de coder de manière optimale sans un IDE ou au moins un éditeur spécialisé.</p>
<p>Ce que j&#8217;aime dans Zend Studio :</p>
<ul>
<li>La complétion de code intelligente (parsing de votre code, typage, etc)</li>
<li>Les gabarits (templates) facilement éditables avec support de variables</li>
<li>Intégration de Zend Framework native</li>
<li>Support de CVS, SVN, Git (pour la version Eclipse) et SFTP/FTP</li>
<li>L&#8217;interface de Zend Studio 5 (pas celle d&#8217;Eclipse)</li>
<li>Gestion du XHTML et de Javascript</li>
</ul>
<p><span style="text-decoration: underline;">Alternatives</span> : <a href="http://www.php-editors.com/">Tout est là</a></p>
<h2><a href="http://www.softpedia.com/get/Internet/Browsers/Internet-Explorer-Collection.shtml">Internet Explorer Collection</a></h2>
<p>Quiconque a déjà développé un site <a href="http://blogs.zdnet.com/Berlind/?p=565">le sait</a>. Le support de Internet Explorer (surtout 6) est une vraie plaie qui ralentit le développement de manière considérable.Plus on vérifie tôt, plus souvent on le fait, plus on gagnera de temps.</p>
<p>IE Collection installe sur votre machine (Windows) toute les versions de Internet Explorer de la 1 (ouch !) à la 8, de manière native.</p>
<p><span style="text-decoration: underline;">Alternatives</span> : <a href="http://tredosoft.com/Multiple_IE">MultipleIE</a>, <a href="http://www.my-debugbar.com/wiki/IETester/HomePage">IETester</a></p>
<h2><a href="http://framework.zend.com/">Zend Framework</a></h2>
<p>Pas de débat. La chose est tranchée <img src='http://blog.juliencrouzet.fr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Zend Framework EST le Framework le plus <a href="http://framework.zend.com/community/partners">soutenu</a>, le plus <a href="http://framework.zend.com/build">maintenu</a>, le plus <a href="http://framework.zend.com/about/components">complet</a>, le mieux <a href="http://framework.zend.com/docs/overview">documenté</a>, le plus <a href="http://framework.zend.com/about/casestudies">utilisé </a>et le <a href="http://ordinarywebguy.wordpress.com/2008/04/22/i-love-zend-framework-it-really-rocks/">plus mieux du monde</a>.</p>
<p><span style="text-decoration: underline;">Alternatives (si vous cherchez moin bien <img src='http://blog.juliencrouzet.fr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> )</span> : <a href="http://www.symfony-project.org/">Symphony</a>, <a href="http://www.blueshoes.org/">Blue Shoes</a>,  <a href="http://cakephp.org/">CakePHP</a></p>
<h2><a href="http://trac.edgewall.org">Trac</a></h2>
<p>Trac est un outil de gestion de projet open source qui démoule son poney (Copyright <a href="http://www.korben.info/edito-du-dernier-vendredi-de-janvier.html">Korben</a>). Véritable couteau suisse, il gère pour vous de base :</p>
<ul>
<li>Le Wiki du projet</li>
<li>La roadmap (feuille de route)</li>
<li>La gestion des tickets (bugs, tâches, amélioration, points à trancher, etc.)</li>
<li>L&#8217;exploration de votre outils de versionning (SVN)</li>
</ul>
<p>Après un tour dans le <a href="http://trac-hacks.org/">répertoire de plugins</a>, il gérera pour vous des miliers d&#8217;autres choses, comme la gestion du temps, le support de Git ou autres, s&#8217;intégrera à Zend Studio ou ira vous chercher un Grande Late chez Starbucks (enfin je crois)</p>
<p><span style="text-decoration: underline;">Alternatives</span> : <a href="http://www.mantisbt.org/">Mantis</a>, <a href="http://www.bugzilla.org">Bugzilla</a>, <a href="http://www.phprojekt.com/features.php">PHProjekt</a></p>
<h2><a href="http://www.jquery.com">jQuery</a></h2>
<p>Last but not least &#8230; jQuery est LA bibliothèque Javascript qu&#8217;il vous faut. Décrire tout ce que jQuery peut vous apporter prendrait des heures et des heures &#8230; Alors certes, d&#8217;autres librairies existent, et presque aussi complètes, mais voilà  :</p>
<p><a href="http://blog.juliencrouzet.fr/wp-content/uploads/2009/03/jquery_mootools_prototype.jpg" rel="lightbox[252]"><img class="aligncenter size-medium wp-image-259" title="jquery_mootools_prototype" src="http://blog.juliencrouzet.fr/wp-content/uploads/2009/03/jquery_mootools_prototype-235x300.jpg" alt="jquery_mootools_prototype" width="235" height="300" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.juliencrouzet.fr/252/10-outils-qui-separent-un-devloppeur-d-un-webmaster/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Keygen Music &#8211; Parce que y&#039;a pas que le mp3 dans la vie</title>
		<link>http://blog.juliencrouzet.fr/217/keygen-music-parce-que-ya-pas-que-le-mp3-dans-la-vie/</link>
		<comments>http://blog.juliencrouzet.fr/217/keygen-music-parce-que-ya-pas-que-le-mp3-dans-la-vie/#comments</comments>
		<pubDate>Sat, 28 Feb 2009 18:00:06 +0000</pubDate>
		<dc:creator>c2c</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[keygen]]></category>
		<category><![CDATA[musique]]></category>

		<guid isPermaLink="false">http://blog.juliencrouzet.fr/?p=217</guid>
		<description><![CDATA[
Warning: call_user_func_array() expects parameter 1 to be a valid callback, first array member is not a valid class name or object in /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php on line 166

Call Stack:
    0.0001     623440   1. {main}() /home/www/blog.juliencrouzet.fr/index.php:0
    0.0002     628968   2. require('/home/www/blog.juliencrouzet.fr/wp-blog-header.php') /home/www/blog.juliencrouzet.fr/index.php:17
    0.1948   38153848   3. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php') /home/www/blog.juliencrouzet.fr/wp-blog-header.php:16
    0.1957   38156768   4. do_feed() /home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php:14
    0.1957   38157048   5. do_action() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1721
    0.1957   38159072   6. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:395
    0.1957   38159128   7. do_feed_rss2() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:0
    0.1957   38159320   8. load_template() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1753
    0.1959   38221464   9. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php') /home/www/blog.juliencrouzet.fr/wp-includes/theme.php:1087
    0.3955   38276368  10. the_excerpt_rss() /home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php:46
    0.3966   38278896  11. apply_filters() /home/www/blog.juliencrouzet.fr/wp-includes/feed.php:177
    0.3968   38281224  12. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:166

]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;">
<div id="attachment_357" class="wp-caption aligncenter" style="width: 160px"><a href="http://blog.juliencrouzet.fr/wp-content/uploads/2009/02/2009-02-28_10201.png" rel="lightbox[217]"><img class="size-thumbnail wp-image-357" title="2009-02-28_10201" src="http://blog.juliencrouzet.fr/wp-content/uploads/2009/02/2009-02-28_10201-150x150.png" alt="La musique des Keygens, de l'art !" width="150" height="150" /></a><p class="wp-caption-text">La musique des Keygens, de l&#39;art !</p></div>
<p style="text-align: left;">Toute personne qui à utilisé au moins une fois un crack ou un keygen (c&#8217;est mal !) sait les reconnaitre très rapidement : Un zip avec un fichier .nfo, un design souvent noir et qui se fait un plaisir à ne pas utiliser les fenêtres classiques de Windows et surtout, une musique .mod !</p>
<p style="text-align: left;">Si vous aussi vous avez trippé sur le générique kitch de l&#8217;Agence Tout Risque de Aol Deco (oui, sacré coup de vieux) ou sur la musique de Marios Bros d&#8217;un keygen, vous aimerez <a href="http://www.keygenmusic.net/?lang=fr">KeyGen Music</a> !</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.juliencrouzet.fr/217/keygen-music-parce-que-ya-pas-que-le-mp3-dans-la-vie/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
