<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
 xmlns:dc="http://purl.org/dc/elements/1.1/"
 xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
	<title><![CDATA[Godefroy]]></title>
	<description><![CDATA[Flux RSS des articles]]></description>
	<pubDate>Sat, 19 May 2012 13:15:04 +0200</pubDate>
	<link>http://godefroy.me</link>
	<language>fr</language>
	<generator>http://www.eklablog.com</generator>
	
	<item>
		<title><![CDATA[[MySQL] Optimisation du COUNT(*) avec des triggers]]></title>
		<link>http://godefroy.me/mysql-optimisation-du-count-avec-des-triggers-a968910</link>
		<description><![CDATA[On a souvent besoin de connaitre le nombre d'entr&eacute;es dans une table, avec certaines conditions. Par exemple le nombre d'articles par cat&eacute;gories dans le cas d'un blog. Faire un SELECT COUNT(*) peut vite devenir tr&egrave;s lourd quand le nombre d'entr&eacute;es devient significatif, surtout si le moteur...]]></description>
		<content:encoded><![CDATA[<p>On a souvent besoin de connaitre le nombre d'entr&eacute;es dans une table, avec certaines conditions. Par exemple le nombre d'articles par cat&eacute;gories dans le cas d'un blog. Faire un SELECT COUNT(*) peut vite devenir tr&egrave;s lourd quand le nombre d'entr&eacute;es devient significatif, surtout si le moteur utilis&eacute; est InnoDB.</p>
<p>En effet, on peut arriver vite &agrave; de gros probl&egrave;mes de performances avec des COUNT(*) s'ex&eacute;cutant en plusieurs secondes si vous commencez &agrave; avoir beaucoup d'entr&eacute;es (1M entr&eacute;es par exemple).</p>
<p>Je vous propose donc une astuce pour remplacer avantageusement ces disgracieux COUNT(*). On va garder ici l'exemple des articles et des cat&eacute;gories, avec une table <em>posts</em> et une table <em>categories</em>&nbsp;de structure basique :</p>
<p><div class="code"><a href="http://search.mysql.com/search?site=refman-51&amp;q=CREATE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">CREATE</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=TABLE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">TABLE</span></a> <span style="color: #008000;">`categories`</span> <span style="color: #FF00FF;">&#40;</span><br />
&nbsp;<span style="color: #008000;">`id`</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=INT&amp;lr=lang_en"><span style="color: #999900; font-weight: bold;">INT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=UNSIGNED&amp;lr=lang_en"><span style="color: #FF9900; font-weight: bold;">UNSIGNED</span></a> <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">NOT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=NULL&amp;lr=lang_en"><span style="color: #9900FF; font-weight: bold;">NULL</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=AUTO_INCREMENT&amp;lr=lang_en"><span style="color: #FF9900; font-weight: bold;">AUTO_INCREMENT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=PRIMARY%20KEY&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">PRIMARY KEY</span></a><span style="color: #000033;">,</span><br />
&nbsp;<span style="color: #008000;">`title`</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=VARCHAR&amp;lr=lang_en"><span style="color: #999900; font-weight: bold;">VARCHAR</span></a><span style="color: #FF00FF;">&#40;</span><span style="color: #008080;">200</span><span style="color: #FF00FF;">&#41;</span> CHARACTER <a href="http://search.mysql.com/search?site=refman-51&amp;q=SET&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">SET</span></a> utf8 <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">COLLATE</span></a> utf8_general_ci <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">NOT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=NULL&amp;lr=lang_en"><span style="color: #9900FF; font-weight: bold;">NULL</span></a><span style="color: #000033;">,</span><br />
&nbsp;<span style="color: #008000;">`nbposts`</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=INT&amp;lr=lang_en"><span style="color: #999900; font-weight: bold;">INT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=UNSIGNED&amp;lr=lang_en"><span style="color: #FF9900; font-weight: bold;">UNSIGNED</span></a> <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">NOT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=NULL&amp;lr=lang_en"><span style="color: #9900FF; font-weight: bold;">NULL</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=DEFAULT&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">DEFAULT</span></a> <span style="color: #008000;">'0'</span><br />
&nbsp;<span style="color: #FF00FF;">&#41;</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=ENGINE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">ENGINE</span></a> <span style="color: #CC0099;">=</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=INNODB&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">INNODB</span></a> CHARACTER <a href="http://search.mysql.com/search?site=refman-51&amp;q=SET&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">SET</span></a> utf8 <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">COLLATE</span></a> utf8_general_ci<span style="color: #000033;">;</span><br />
&nbsp;<br />
&nbsp;<a href="http://search.mysql.com/search?site=refman-51&amp;q=CREATE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">CREATE</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=TABLE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">TABLE</span></a> <span style="color: #008000;">`posts`</span> <span style="color: #FF00FF;">&#40;</span><br />
&nbsp;<span style="color: #008000;">`id`</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=INT&amp;lr=lang_en"><span style="color: #999900; font-weight: bold;">INT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=UNSIGNED&amp;lr=lang_en"><span style="color: #FF9900; font-weight: bold;">UNSIGNED</span></a> <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">NOT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=NULL&amp;lr=lang_en"><span style="color: #9900FF; font-weight: bold;">NULL</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=AUTO_INCREMENT&amp;lr=lang_en"><span style="color: #FF9900; font-weight: bold;">AUTO_INCREMENT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=PRIMARY%20KEY&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">PRIMARY KEY</span></a><span style="color: #000033;">,</span><br />
&nbsp;<span style="color: #008000;">`category<span style="color: #008080; font-weight: bold;">_</span>id`</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=INT&amp;lr=lang_en"><span style="color: #999900; font-weight: bold;">INT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=UNSIGNED&amp;lr=lang_en"><span style="color: #FF9900; font-weight: bold;">UNSIGNED</span></a> <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">NOT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=NULL&amp;lr=lang_en"><span style="color: #9900FF; font-weight: bold;">NULL</span></a><span style="color: #000033;">,</span><br />
&nbsp;<span style="color: #008000;">`title`</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=VARCHAR&amp;lr=lang_en"><span style="color: #999900; font-weight: bold;">VARCHAR</span></a><span style="color: #FF00FF;">&#40;</span><span style="color: #008080;">200</span><span style="color: #FF00FF;">&#41;</span> CHARACTER <a href="http://search.mysql.com/search?site=refman-51&amp;q=SET&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">SET</span></a> utf8 <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">COLLATE</span></a> utf8_general_ci <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">NOT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=NULL&amp;lr=lang_en"><span style="color: #9900FF; font-weight: bold;">NULL</span></a><span style="color: #000033;">,</span><br />
&nbsp;<span style="color: #008000;">`content`</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=TEXT&amp;lr=lang_en"><span style="color: #999900; font-weight: bold;">TEXT</span></a> CHARACTER <a href="http://search.mysql.com/search?site=refman-51&amp;q=SET&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">SET</span></a> utf8 <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">COLLATE</span></a> utf8_general_ci <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">NOT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=NULL&amp;lr=lang_en"><span style="color: #9900FF; font-weight: bold;">NULL</span></a><span style="color: #000033;">,</span><br />
&nbsp;<span style="color: #008000;">`time`</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=INT&amp;lr=lang_en"><span style="color: #999900; font-weight: bold;">INT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=UNSIGNED&amp;lr=lang_en"><span style="color: #FF9900; font-weight: bold;">UNSIGNED</span></a> <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">NOT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=NULL&amp;lr=lang_en"><span style="color: #9900FF; font-weight: bold;">NULL</span></a><span style="color: #000033;">,</span><br />
&nbsp;<a href="http://search.mysql.com/search?site=refman-51&amp;q=INDEX&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">INDEX</span></a> <span style="color: #FF00FF;">&#40;</span><span style="color: #008000;">`category<span style="color: #008080; font-weight: bold;">_</span>id`</span><span style="color: #FF00FF;">&#41;</span><span style="color: #000033;">,</span><br />
&nbsp;<a href="http://search.mysql.com/search?site=refman-51&amp;q=INDEX&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">INDEX</span></a> <span style="color: #FF00FF;">&#40;</span><span style="color: #008000;">`time`</span><span style="color: #FF00FF;">&#41;</span><br />
&nbsp;<span style="color: #FF00FF;">&#41;</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=ENGINE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">ENGINE</span></a> <span style="color: #CC0099;">=</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=INNODB&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">INNODB</span></a> CHARACTER <a href="http://search.mysql.com/search?site=refman-51&amp;q=SET&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">SET</span></a> utf8 <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">COLLATE</span></a> utf8_general_ci<span style="color: #000033;">;</span><br />
&nbsp;<br />
&nbsp;<a href="http://search.mysql.com/search?site=refman-51&amp;q=ALTER&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">ALTER</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=TABLE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">TABLE</span></a> <span style="color: #008000;">`posts`</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=ADD&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">ADD</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=FOREIGN%20KEY&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">FOREIGN KEY</span></a> <span style="color: #FF00FF;">&#40;</span><span style="color: #008000;">`category<span style="color: #008080; font-weight: bold;">_</span>id`</span><span style="color: #FF00FF;">&#41;</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=REFERENCES&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">REFERENCES</span></a> <span style="color: #008000;">`categories`</span> <span style="color: #FF00FF;">&#40;</span><span style="color: #008000;">`id`</span><span style="color: #FF00FF;">&#41;</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=ON&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">ON</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=DELETE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">DELETE</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=CASCADE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">CASCADE</span></a><span style="color: #000033;">;</span><div style="display:none;">[code=mysql]CREATE TABLE `categories` (<br/> `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,<br/> `title` VARCHAR(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,<br/> `nbposts` INT UNSIGNED NOT NULL DEFAULT '0'<br/> ) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_general_ci;<br/> <br/> CREATE TABLE  `posts` (<br/> `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,<br/> `category_id` INT UNSIGNED NOT NULL,<br/> `title` VARCHAR(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,<br/> `content` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,<br/> `time` INT UNSIGNED NOT NULL,<br/> INDEX (`category_id`),<br/> INDEX (`time`)<br/> ) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_general_ci;<br/> <br/> ALTER TABLE  `posts` ADD FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE;[/code]</div></div></p>
<p>Le champ&nbsp;<em>nbposts</em> va nous servir &agrave; garder en m&eacute;moire le nombre d'articles dans chaque cat&eacute;gorie. Certains diront que du coup on peut perdre de la consistance, eh bien oui... mais il faudrait avoir un sacr&eacute; coup de pas de bol ou modifier la valeur du champ &agrave; la bourrin pour fausser les valeurs.</p>
<p>Pour actualiser le champ <em>nbposts</em>, on va utiliser des triggers ("d&eacute;clencheurs" en fran&ccedil;ais), qui l'incr&eacute;menteront &agrave; chaque insertion et le d&eacute;cr&eacute;menteront &agrave; chaque suppression :</p>
<p><div class="code">DELIMITER <span style="color: #000033;">;;</span><br />
&nbsp;<a href="http://search.mysql.com/search?site=refman-51&amp;q=CREATE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">CREATE</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=TRIGGER&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">TRIGGER</span></a> <span style="color: #008000;">`posts<span style="color: #008080; font-weight: bold;">_</span>insert<span style="color: #008080; font-weight: bold;">_</span>after`</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=AFTER&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">AFTER</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=INSERT&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">INSERT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=ON&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">ON</span></a> <span style="color: #008000;">`posts`</span><br />
&nbsp;<a href="http://search.mysql.com/search?site=refman-51&amp;q=FOR%20EACH%20ROW&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">FOR EACH ROW</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=BEGIN&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">BEGIN</span></a><br />
&nbsp;<a href="http://search.mysql.com/search?site=refman-51&amp;q=UPDATE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">UPDATE</span></a> <span style="color: #008000;">`categories`</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=SET&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">SET</span></a> <span style="color: #008000;">`nbposts`</span> <span style="color: #CC0099;">=</span> <span style="color: #008000;">`nbposts`</span><span style="color: #CC0099;">+</span><span style="color: #008080;">1</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=WHERE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">WHERE</span></a> id<span style="color: #CC0099;">=</span>NEW.<span style="color: #008000;">`category<span style="color: #008080; font-weight: bold;">_</span>id`</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=LIMIT&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">LIMIT</span></a> <span style="color: #008080;">1</span><span style="color: #000033;">;</span><br />
&nbsp;<a href="http://dev.mysql.com/doc/refman/5.1/en/control-flow-functions.html"><span style="color: #009900;">END</span></a> <span style="color: #000033;">;;</span><br />
&nbsp;<a href="http://search.mysql.com/search?site=refman-51&amp;q=CREATE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">CREATE</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=TRIGGER&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">TRIGGER</span></a> <span style="color: #008000;">`posts<span style="color: #008080; font-weight: bold;">_</span>delete<span style="color: #008080; font-weight: bold;">_</span>after`</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=AFTER&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">AFTER</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=DELETE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">DELETE</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=ON&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">ON</span></a> <span style="color: #008000;">`posts`</span><br />
&nbsp;<a href="http://search.mysql.com/search?site=refman-51&amp;q=FOR%20EACH%20ROW&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">FOR EACH ROW</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=BEGIN&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">BEGIN</span></a><br />
&nbsp;<a href="http://search.mysql.com/search?site=refman-51&amp;q=UPDATE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">UPDATE</span></a> <span style="color: #008000;">`categories`</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=SET&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">SET</span></a> <span style="color: #008000;">`nbposts`</span> <span style="color: #CC0099;">=</span> <span style="color: #008000;">`nbposts`</span><span style="color: #CC0099;">-</span><span style="color: #008080;">1</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=WHERE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">WHERE</span></a> id<span style="color: #CC0099;">=</span>OLD.<span style="color: #008000;">`category<span style="color: #008080; font-weight: bold;">_</span>id`</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=LIMIT&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">LIMIT</span></a> <span style="color: #008080;">1</span><span style="color: #000033;">;</span><br />
&nbsp;<a href="http://dev.mysql.com/doc/refman/5.1/en/control-flow-functions.html"><span style="color: #009900;">END</span></a> <span style="color: #000033;">;;</span><br />
&nbsp;DELIMITER <span style="color: #000033;">;</span><div style="display:none;">[code=mysql]DELIMITER ;;<br/> CREATE TRIGGER `posts_insert_after` AFTER INSERT ON `posts`<br/> FOR EACH ROW BEGIN<br/> UPDATE `categories` SET `nbposts` = `nbposts`+1 WHERE id=NEW.`category_id` LIMIT 1;<br/> END ;;<br/> CREATE TRIGGER `posts_delete_after` AFTER DELETE ON `posts`<br/> FOR EACH ROW BEGIN<br/> UPDATE `categories` SET `nbposts` = `nbposts`-1 WHERE id=OLD.`category_id` LIMIT 1;<br/> END ;;<br/> DELIMITER ;[/code]</div></div></p>
<p>Et voil&agrave;, votre champ <em>nbposts</em> s'actualise maintenant automatiquement, plus besoin de faire des COUNT(*) !</p><br /><br /><div class="article_sharebtns"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fgodefroy.me%2Fmysql-optimisation-du-count-avec-des-triggers-a968910&amp;layout=button_count&amp;show_faces=false&amp;width=65&amp;action=like&amp;font&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:65px; height:21px;" allowTransparency="true"><br /></iframe><iframe allowtransparency="true" frameborder="0" scrolling="no" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fgodefroy.me%2Fmysql-optimisation-du-count-avec-des-triggers-a968910&amp;text=%5BMySQL%5D%20Optimisation%20du%20COUNT%28%2A%29%20avec%20des%20triggers&amp;count=none" style="width: 55px; height: 20px;"></iframe><span><g:plusone size="medium" count="true" href="http://godefroy.me/mysql-optimisation-du-count-avec-des-triggers-a968910"></g:plusone></span></div><br /><hr />Article original rédigé par Godefroy et publié sur <a href="http://skreo.eklablog.com">Godefroy</a> <br /> Reproduction interdite sans autorisation]]></content:encoded>
		<pubDate>Tue, 23 Nov 2010 17:53:00 +0100</pubDate>
		<guid isPermaLink="true">http://godefroy.me/mysql-optimisation-du-count-avec-des-triggers-a968910</guid>
		<dc:creator>Godefroy</dc:creator>
		<dc:date>2010-11-23T17:53:00+01:00</dc:date>
	</item>
	<item>
		<title><![CDATA[[MySQL] Optimisation d'une recherche avec multiples jointures]]></title>
		<link>http://godefroy.me/mysql-optimisation-d-une-recherche-avec-multiples-jointures-a860197</link>
		<description><![CDATA[J'ai &eacute;t&eacute; confront&eacute; &agrave; un probl&egrave;me de ralentissements sur EklaBlog d&ucirc;s &agrave; une requ&ecirc;te SELECT utilisant de multiples jointures . Nous allons voir dans cet article comment optimiser cela. La requ&ecirc;te en elle-m&ecirc;me n'est pas tr&egrave;s complexe et utilise uniquement des cl&eacute;s (primary et indexes),...]]></description>
		<content:encoded><![CDATA[<p>J'ai &eacute;t&eacute; confront&eacute; &agrave; un probl&egrave;me de <strong>ralentissements</strong> sur EklaBlog d&ucirc;s &agrave; une requ&ecirc;te SELECT utilisant de <strong>multiples jointures</strong>. Nous allons voir dans cet article comment <strong>optimiser</strong> cela.</p>
<p>La requ&ecirc;te en elle-m&ecirc;me n'est pas tr&egrave;s complexe et utilise uniquement des cl&eacute;s (primary et indexes), mais elle est tr&egrave;s lente pour plusieurs raisons :</p>
<ul>
<li>Jointure sur 5 tables</li>
<li>Recherche sur 4 champs chacun dans une table diff&eacute;rente</li>
<li>Tri par ORDER BY</li>
</ul>
<p>Elle ressemble en gros &agrave; ceci :</p>
<p><div class="code"><a href="http://search.mysql.com/search?site=refman-51&amp;q=SELECT&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">SELECT</span></a> a.id<span style="color: #000033;">,</span> a.blog<span style="color: #000033;">,</span> a.category_id<span style="color: #000033;">,</span> a.title<span style="color: #000033;">,</span> a.content<span style="color: #000033;">,</span> a.author<span style="color: #000033;">,</span> a.creadt<span style="color: #000033;">,</span> c.url<br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=FROM&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">FROM</span></a> mod_article a  <br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=INNER&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">INNER</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=JOIN&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">JOIN</span></a> categories b <a href="http://search.mysql.com/search?site=refman-51&amp;q=ON&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">ON</span></a> b.id<span style="color: #CC0099;">=</span>a.category_id  <br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=INNER&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">INNER</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=JOIN&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">JOIN</span></a> blogs c <a href="http://search.mysql.com/search?site=refman-51&amp;q=ON&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">ON</span></a> c.id<span style="color: #CC0099;">=</span>b.blog_id  <br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=INNER&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">INNER</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=JOIN&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">JOIN</span></a> articles_tags at <a href="http://search.mysql.com/search?site=refman-51&amp;q=ON&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">ON</span></a> at.article_id<span style="color: #CC0099;">=</span>a.id <br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=INNER&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">INNER</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=JOIN&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">JOIN</span></a> tags t <a href="http://search.mysql.com/search?site=refman-51&amp;q=ON&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">ON</span></a> t.id<span style="color: #CC0099;">=</span>at.tag_id <br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=WHERE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">WHERE</span></a> t.name<span style="color: #CC0099;">=</span><span style="color: #008000;">&quot;skreo&quot;</span> <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">AND</span></a> a.online<span style="color: #CC0099;">=</span><span style="color: #008000;">&quot;1&quot;</span> <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">AND</span></a> b.protect<span style="color: #CC0099;">=</span><span style="color: #008000;">&quot;&quot;</span> <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">AND</span></a> c.protect<span style="color: #CC0099;">=</span><span style="color: #008000;">&quot;&quot;</span>  <br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=ORDER%20BY&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">ORDER BY</span></a> a.creadt <a href="http://search.mysql.com/search?site=refman-51&amp;q=DESC&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">DESC</span></a> <br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=LIMIT&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">LIMIT</span></a> <span style="color: #008080;">10</span><div style="display:none;">[code=mysql]SELECT a.id, a.blog, a.category_id, a.title, a.content, a.author, a.creadt, c.url<br />&nbsp;&nbsp;&nbsp; FROM mod_article a&nbsp; <br />&nbsp;&nbsp;&nbsp; INNER JOIN categories b ON b.id=a.category_id&nbsp; <br />&nbsp;&nbsp;&nbsp; INNER JOIN blogs c ON c.id=b.blog_id&nbsp; <br />&nbsp;&nbsp;&nbsp; INNER JOIN articles_tags at ON at.article_id=a.id <br />&nbsp;&nbsp;&nbsp; INNER JOIN tags t ON t.id=at.tag_id <br />&nbsp;&nbsp;&nbsp; WHERE t.name="skreo" AND a.online="1" AND b.protect="" AND c.protect=""&nbsp; <br />&nbsp;&nbsp;&nbsp; ORDER BY a.creadt DESC <br />&nbsp;&nbsp;&nbsp; LIMIT 10[/code]</div></div></p>
<p>Les tables concern&eacute;es sont relativement grosses :</p>
<ul>
<li>130 000 entr&eacute;es dans <em>tags</em></li>
<li>1 400 000 entr&eacute;es dans <em>articles_tags</em></li>
<li>400 000 entr&eacute;es dans <em>articles</em></li>
<li>70 000 entr&eacute;es dans <em>categories</em></li>
<li>130 000 entr&eacute;es dans <em>tags</em></li>
<li>19 000 entr&eacute;es dans <em>blogs</em></li>
</ul>
<p>D'o&ugrave; un temps d'ex&eacute;cution de la requ&ecirc;te pouvant atteindre 30 secondes...</p>
<p>Lors d'un test en local, que je r&eacute;p&egrave;terai dans la suite de l'article, j'obtiens une ex&eacute;cution en 0.24s en moyenne quand le pc ne fait rien d'autre.</p>
<p>&nbsp;</p>
<h3>Solution possible</h3>
<p>Une solution possible que m'a indiqu&eacute; mon ami <a href="http://twitter.com/swing_arcus77">Guilhem</a> est de stocker un r&eacute;sultat interm&eacute;diaire de la requ&ecirc;te dans une table de type MEMORY (en RAM) :</p>
<p><div class="code"><a href="http://search.mysql.com/search?site=refman-51&amp;q=CREATE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">CREATE</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=TABLE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">TABLE</span></a> tags_lookup <span style="color: #FF00FF;">&#40;</span><br />
    article_id <a href="http://search.mysql.com/search?site=refman-51&amp;q=INT&amp;lr=lang_en"><span style="color: #999900; font-weight: bold;">int</span></a><span style="color: #FF00FF;">&#40;</span><span style="color: #008080;">10</span><span style="color: #FF00FF;">&#41;</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=UNSIGNED&amp;lr=lang_en"><span style="color: #FF9900; font-weight: bold;">unsigned</span></a> <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">NOT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=NULL&amp;lr=lang_en"><span style="color: #9900FF; font-weight: bold;">NULL</span></a><span style="color: #000033;">,</span><br />
    tag_id <a href="http://search.mysql.com/search?site=refman-51&amp;q=INT&amp;lr=lang_en"><span style="color: #999900; font-weight: bold;">int</span></a><span style="color: #FF00FF;">&#40;</span><span style="color: #008080;">10</span><span style="color: #FF00FF;">&#41;</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=UNSIGNED&amp;lr=lang_en"><span style="color: #FF9900; font-weight: bold;">unsigned</span></a> <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">NOT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=NULL&amp;lr=lang_en"><span style="color: #9900FF; font-weight: bold;">NULL</span></a><span style="color: #000033;">,</span><br />
    creadt <a href="http://search.mysql.com/search?site=refman-51&amp;q=INT&amp;lr=lang_en"><span style="color: #999900; font-weight: bold;">int</span></a><span style="color: #FF00FF;">&#40;</span><span style="color: #008080;">10</span><span style="color: #FF00FF;">&#41;</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=UNSIGNED&amp;lr=lang_en"><span style="color: #FF9900; font-weight: bold;">unsigned</span></a> <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">NOT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=NULL&amp;lr=lang_en"><span style="color: #9900FF; font-weight: bold;">NULL</span></a><span style="color: #000033;">,</span><br />
    blog_id <a href="http://search.mysql.com/search?site=refman-51&amp;q=INT&amp;lr=lang_en"><span style="color: #999900; font-weight: bold;">int</span></a><span style="color: #FF00FF;">&#40;</span><span style="color: #008080;">10</span><span style="color: #FF00FF;">&#41;</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=UNSIGNED&amp;lr=lang_en"><span style="color: #FF9900; font-weight: bold;">unsigned</span></a> <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">NOT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=NULL&amp;lr=lang_en"><span style="color: #9900FF; font-weight: bold;">NULL</span></a><span style="color: #000033;">,</span><br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=KEY&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">KEY</span></a> tag_id <span style="color: #FF00FF;">&#40;</span>tag_id<span style="color: #FF00FF;">&#41;</span><span style="color: #000033;">,</span><br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=KEY&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">KEY</span></a> creadt <span style="color: #FF00FF;">&#40;</span>creadt<span style="color: #FF00FF;">&#41;</span><span style="color: #000033;">,</span><br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=KEY&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">KEY</span></a> blog_id <span style="color: #FF00FF;">&#40;</span>blog_id<span style="color: #FF00FF;">&#41;</span><br />
<span style="color: #FF00FF;">&#41;</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=ENGINE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">ENGINE</span></a><span style="color: #CC0099;">=</span>MEMORY<div style="display:none;">[code=mysql]CREATE TABLE tags_lookup (<br />&nbsp;&nbsp;&nbsp; article_id int(10) unsigned NOT NULL,<br />&nbsp;&nbsp;&nbsp; tag_id int(10) unsigned NOT NULL,<br />&nbsp;&nbsp;&nbsp; creadt int(10) unsigned NOT NULL,<br />&nbsp;&nbsp;&nbsp; blog_id int(10) unsigned NOT NULL,<br />&nbsp;&nbsp;&nbsp; KEY tag_id (tag_id),<br />&nbsp;&nbsp;&nbsp; KEY creadt (creadt),<br />&nbsp;&nbsp;&nbsp; KEY blog_id (blog_id)<br />) ENGINE=MEMORY[/code]</div></div></p>
<p>Il faut ensuite remplir la remplir :</p>
<p><div class="code"><span style="color: #808080; font-style: italic;"># On vide la table</span><br />
<a href="http://search.mysql.com/search?site=refman-51&amp;q=TRUNCATE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">TRUNCATE</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=TABLE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">TABLE</span></a> tags_lookup<span style="color: #000033;">;</span><br />
<span style="color: #808080; font-style: italic;"># Puis on la remplit entièrement</span><br />
<a href="http://search.mysql.com/search?site=refman-51&amp;q=INSERT&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">INSERT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=INTO&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">INTO</span></a> tags_lookup<br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=SELECT&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">SELECT</span></a> a.id <a href="http://search.mysql.com/search?site=refman-51&amp;q=AS&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">AS</span></a> article_id<span style="color: #000033;">,</span> at.tag_id<span style="color: #000033;">,</span> a.creadt<span style="color: #000033;">,</span> c.id <a href="http://search.mysql.com/search?site=refman-51&amp;q=AS&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">AS</span></a> blog_id<br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=FROM&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">FROM</span></a> articles a<span style="color: #000033;">,</span> categories b<span style="color: #000033;">,</span> blogs c<span style="color: #000033;">,</span> articles_tags at<br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=WHERE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">WHERE</span></a> a.online<span style="color: #CC0099;">=</span><span style="color: #008000;">&quot;1&quot;</span> <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">AND</span></a> b.protect<span style="color: #CC0099;">=</span><span style="color: #008000;">&quot;&quot;</span> <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">AND</span></a> c.protect<span style="color: #CC0099;">=</span><span style="color: #008000;">&quot;&quot;</span><br />
    <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">AND</span></a> b.id<span style="color: #CC0099;">=</span>a.category_id <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">AND</span></a> c.id<span style="color: #CC0099;">=</span>a.blog_id <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span style="color: #CC0099; font-weight: bold;">AND</span></a> at.article_id<span style="color: #CC0099;">=</span>a.id<span style="color: #000033;">;</span><div style="display:none;">[code=mysql]# On vide la table<br />TRUNCATE TABLE tags_lookup;<br /># Puis on la remplit enti&egrave;rement<br />INSERT INTO tags_lookup<br />&nbsp;&nbsp;&nbsp; SELECT a.id AS article_id, at.tag_id, a.creadt, c.id AS blog_id<br />&nbsp;&nbsp;&nbsp; FROM articles a, categories b, blogs c, articles_tags at<br />&nbsp;&nbsp;&nbsp; WHERE a.online="1" AND b.protect="" AND c.protect=""<br />&nbsp;&nbsp;&nbsp; AND b.id=a.category_id AND c.id=a.blog_id AND at.article_id=a.id;[/code]</div></div></p>
<p>Il faudra ex&eacute;cuter les requ&ecirc;tes ci-dessus r&eacute;guli&egrave;rement pour mettre &agrave; jour le contenu de la table, &agrave; l'aide d'un bash par exemple.</p>
<p>Pour obtenir les informations qu'on voulait au d&eacute;but, on peut alors ex&eacute;cuter cette requ&ecirc;te :</p>
<p><div class="code"><a href="http://search.mysql.com/search?site=refman-51&amp;q=SELECT&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">SELECT</span></a> a.id<span style="color: #000033;">,</span> a.blog<span style="color: #000033;">,</span> a.category_id<span style="color: #000033;">,</span> a.title<span style="color: #000033;">,</span> a.content<span style="color: #000033;">,</span> a.author<span style="color: #000033;">,</span> a.creadt<span style="color: #000033;">,</span> c.url<br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=FROM&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">FROM</span></a> tags t <br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=INNER&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">INNER</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=JOIN&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">JOIN</span></a> tags_lookup s <a href="http://search.mysql.com/search?site=refman-51&amp;q=ON&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">ON</span></a> s.tag_id<span style="color: #CC0099;">=</span>t.id <br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=INNER&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">INNER</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=JOIN&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">JOIN</span></a> articles a <a href="http://search.mysql.com/search?site=refman-51&amp;q=ON&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">ON</span></a> a.id<span style="color: #CC0099;">=</span>s.article_id <br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=INNER&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">INNER</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=JOIN&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">JOIN</span></a> categories b <a href="http://search.mysql.com/search?site=refman-51&amp;q=ON&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">ON</span></a> b.id<span style="color: #CC0099;">=</span>a.category_id  <br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=INNER&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">INNER</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=JOIN&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">JOIN</span></a> blogs c <a href="http://search.mysql.com/search?site=refman-51&amp;q=ON&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">ON</span></a> c.id<span style="color: #CC0099;">=</span>a.blog _id<br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=WHERE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">WHERE</span></a> t.name<span style="color: #CC0099;">=</span><span style="color: #008000;">&quot;skreo&quot;</span> <br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=ORDER%20BY&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">ORDER BY</span></a> s.creadt <a href="http://search.mysql.com/search?site=refman-51&amp;q=DESC&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">DESC</span></a> <br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=LIMIT&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">LIMIT</span></a> <span style="color: #008080;">10</span><div style="display:none;">[code=mysql]SELECT a.id, a.blog, a.category_id, a.title, a.content, a.author, a.creadt, c.url<br />&nbsp;&nbsp;&nbsp; FROM tags t <br />&nbsp;&nbsp;&nbsp; INNER JOIN tags_lookup s ON s.tag_id=t.id <br />&nbsp;&nbsp;&nbsp; INNER JOIN articles a ON a.id=s.article_id <br />&nbsp;&nbsp;&nbsp; INNER JOIN categories b ON b.id=a.category_id&nbsp; <br />&nbsp;&nbsp;&nbsp; INNER JOIN blogs c ON c.id=a.blog _id<br />&nbsp;&nbsp;&nbsp; WHERE t.name="skreo" <br />&nbsp;&nbsp;&nbsp; ORDER BY s.creadt DESC <br />&nbsp;&nbsp;&nbsp; LIMIT 10[/code]</div></div></p>
<p>Lors de mon test, j'obtiens cette fois-ci 0.15s d'ex&eacute;cution en moyenne, ce qui est d&eacute;j&agrave; mieux.</p>
<p>Mais le gros avantage d'une telle structure, c'est qu'on va pouvoir faire une recherche beaucoup <strong>plus facile &agrave; comprendre pour le serveur MySQL</strong>, gr&acirc;ce &agrave; des requ&ecirc;tes imbriqu&eacute;es :</p>
<p><div class="code"><a href="http://search.mysql.com/search?site=refman-51&amp;q=SELECT&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">SELECT</span></a> a.id<span style="color: #000033;">,</span> a.blog<span style="color: #000033;">,</span> a.category_id<span style="color: #000033;">,</span> a.title<span style="color: #000033;">,</span> a.content<span style="color: #000033;">,</span> a.author<span style="color: #000033;">,</span> a.creadt<span style="color: #000033;">,</span> c.url<br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=FROM&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">FROM</span></a> <span style="color: #FF00FF;">&#40;</span><br />
        <a href="http://search.mysql.com/search?site=refman-51&amp;q=SELECT&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">SELECT</span></a> article_id<br />
        <a href="http://search.mysql.com/search?site=refman-51&amp;q=FROM&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">FROM</span></a> tags_lookup<br />
        <a href="http://search.mysql.com/search?site=refman-51&amp;q=WHERE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">WHERE</span></a> tag_id<span style="color: #CC0099;">=</span><span style="color: #FF00FF;">&#40;</span><br />
            <a href="http://search.mysql.com/search?site=refman-51&amp;q=SELECT&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">SELECT</span></a> id<br />
            <a href="http://search.mysql.com/search?site=refman-51&amp;q=FROM&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">FROM</span></a> tags<br />
            <a href="http://search.mysql.com/search?site=refman-51&amp;q=WHERE&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">WHERE</span></a> name<span style="color: #CC0099;">=</span><span style="color: #008000;">&quot;skreo&quot;</span><br />
            <a href="http://search.mysql.com/search?site=refman-51&amp;q=LIMIT&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">LIMIT</span></a> <span style="color: #008080;">1</span><br />
        <span style="color: #FF00FF;">&#41;</span><br />
        <a href="http://search.mysql.com/search?site=refman-51&amp;q=ORDER%20BY&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">ORDER BY</span></a> creadt <a href="http://search.mysql.com/search?site=refman-51&amp;q=DESC&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">DESC</span></a><br />
        <a href="http://search.mysql.com/search?site=refman-51&amp;q=LIMIT&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">LIMIT</span></a> <span style="color: #008080;">10</span><br />
    <span style="color: #FF00FF;">&#41;</span> s<br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=INNER&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">INNER</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=JOIN&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">JOIN</span></a> articles a <a href="http://search.mysql.com/search?site=refman-51&amp;q=ON&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">ON</span></a> a.id<span style="color: #CC0099;">=</span>s.article_id<br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=INNER&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">INNER</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=JOIN&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">JOIN</span></a> categories b <a href="http://search.mysql.com/search?site=refman-51&amp;q=ON&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">ON</span></a> b.id<span style="color: #CC0099;">=</span>a.category_id<br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=INNER&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">INNER</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=JOIN&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">JOIN</span></a> blogs c <a href="http://search.mysql.com/search?site=refman-51&amp;q=ON&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">ON</span></a> c.id<span style="color: #CC0099;">=</span>a.blog_id<br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=ORDER%20BY&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">ORDER BY</span></a> a.creadt <a href="http://search.mysql.com/search?site=refman-51&amp;q=DESC&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">DESC</span></a><br />
    <a href="http://search.mysql.com/search?site=refman-51&amp;q=LIMIT&amp;lr=lang_en"><span style="color: #990099; font-weight: bold;">LIMIT</span></a> <span style="color: #008080;">10</span><span style="color: #000033;">;</span><div style="display:none;">[code=mysql]SELECT a.id, a.blog, a.category_id, a.title, a.content, a.author, a.creadt, c.url<br />&nbsp;&nbsp;&nbsp; FROM (<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; SELECT article_id<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; FROM tags_lookup<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WHERE tag_id=(<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; SELECT id<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; FROM tags<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WHERE name="skreo"<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; LIMIT 1<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; )<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ORDER BY creadt DESC<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; LIMIT 10<br />&nbsp;&nbsp;&nbsp; ) s<br />&nbsp;&nbsp;&nbsp; INNER JOIN articles a ON a.id=s.article_id<br />&nbsp;&nbsp;&nbsp; INNER JOIN categories b ON b.id=a.category_id<br />&nbsp;&nbsp;&nbsp; INNER JOIN blogs c ON c.id=a.blog_id<br />&nbsp;&nbsp;&nbsp; ORDER BY a.creadt DESC<br />&nbsp;&nbsp;&nbsp; LIMIT 10;[/code]</div></div></p>
<p>Toujours avec la m&ecirc;me base de donn&eacute;es, j'obtiens cette fois-ci une <strong>ex&eacute;cution presque instantan&eacute;e</strong> : entre 0 et 0.02 secondes !</p>
<p>&nbsp;</p>
<h3>Conclusion</h3>
<p>En mettant en place une table en m&eacute;moire vive rassemblant des donn&eacute;es correspondant &agrave; une partie du traitement d'une grosse requ&ecirc;te, on peut donc &eacute;viter des jointures tr&egrave;s lourdes.</p>
<p>Cette m&eacute;thode a bien &eacute;videmment comme inconv&eacute;nient d'avoir des donn&eacute;es pas toujours ultra fraiches en m&eacute;moire, mais &ccedil;a peut &ecirc;tre un bon compromis quand on voit la rapidit&eacute; des requ&ecirc;tes qui en r&eacute;sultent.</p>
<p><em>Vous avez d'autres solutions int&eacute;ressantes ? une meilleure id&eacute;e ?</em></p><br /><br /><div class="article_sharebtns"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fgodefroy.me%2Fmysql-optimisation-d-une-recherche-avec-multiples-jointures-a860197&amp;layout=button_count&amp;show_faces=false&amp;width=65&amp;action=like&amp;font&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:65px; height:21px;" allowTransparency="true"><br /></iframe><iframe allowtransparency="true" frameborder="0" scrolling="no" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fgodefroy.me%2Fmysql-optimisation-d-une-recherche-avec-multiples-jointures-a860197&amp;text=%5BMySQL%5D%20Optimisation%20d%27une%20recherche%20avec%20multiples%20jointures&amp;count=none" style="width: 55px; height: 20px;"></iframe><span><g:plusone size="medium" count="true" href="http://godefroy.me/mysql-optimisation-d-une-recherche-avec-multiples-jointures-a860197"></g:plusone></span></div><br /><hr />Article original rédigé par Godefroy et publié sur <a href="http://skreo.eklablog.com">Godefroy</a> <br /> Reproduction interdite sans autorisation]]></content:encoded>
		<pubDate>Thu, 10 Dec 2009 16:42:07 +0100</pubDate>
		<guid isPermaLink="true">http://godefroy.me/mysql-optimisation-d-une-recherche-avec-multiples-jointures-a860197</guid>
		<dc:creator>Godefroy</dc:creator>
		<dc:date>2009-12-10T16:42:07+01:00</dc:date>
	</item>
	<item>
		<title><![CDATA[[Sécurité PHP] Toujours vérifier le Referer lors d'un envoi par POST]]></title>
		<link>http://godefroy.me/securite-php-toujours-verifier-le-referer-lors-d-un-envoi-par-post-a313986</link>
		<description><![CDATA[&copy; Photo de divarvel C'est un aspect tr&egrave;s souvent n&eacute;glig&eacute; de la s&eacute;curit&eacute; des sites web, et qui est pourtant critique . Par exemple, si Facebook n'avait pas pr&eacute;vu ce genre de s&eacute;curit&eacute;, nous pourrions partir du postulat qu'il y a une chance non n&eacute;gligeable qu'un visiteur soit connect&eacute; &agrave;...]]></description>
		<content:encoded><![CDATA[<p style="text-align: center; margin-bottom: 0;"><img src="http://data0.eklablog.com/skreo/mod_article313986_1.jpg" alt="[S&eacute;curit&eacute; PHP] Toujours v&eacute;rifier le Referer lors d'un envoi par POST"/></p>
<p style="text-align: right; margin-top: 0;"><a style="color: #999999;" href="http://www.divarvel.fr">&copy; Photo de divarvel</a></p>
<p>C'est un aspect <strong>tr&egrave;s souvent n&eacute;glig&eacute;</strong> de la s&eacute;curit&eacute; des sites web, et qui est pourtant <strong>critique</strong>.</p>
<p>Par exemple, si Facebook n'avait pas pr&eacute;vu ce genre de s&eacute;curit&eacute;, nous pourrions partir du postulat qu'il y a une chance non n&eacute;gligeable qu'un visiteur soit connect&eacute; &agrave; Facebook (par session ou cookies). Prenons alors une page web visit&eacute;e par quelques dizaines ou centaines de visiteurs par jour, un blog par exemple. Sur cette page, nous allons mettre un formulaire identique &agrave; celui permettant de modifier le profil sur Facebook. Une ligne de javascript suffira &agrave; envoyer le formulaire ( <em>$("id_form").submit()</em> ), avec tout plein de grossi&egrave;ret&eacute;s qui viendront &eacute;gayer le profil de l'utilisateur <img src="http://godefroy.me/images/emoticons/happy.gif" border="0" alt=""/></p>
<p>C'est de cette mani&egrave;re qu'Olivier Duffez s'est fait<strong> pirater son compte Gmail</strong> puis le nom de domaine Webrankinfo.com ! En effet, le pirate s'est d&eacute;brouill&eacute; pour que M. Duffez se retrouve sur une page envoyant un formulaire vers la page de cr&eacute;ation de filtre de Gmail. Et comme une session Gmail &eacute;tait ouverte sur l'ordinateur de M. Duffez, le formulaire en question a pu cr&eacute;er un filtre qui transf&eacute;rait tous les e-mails re&ccedil;us au spammeur. Le spammeur a ensuite utilis&eacute; le formulaire "Mot de passe oubli&eacute;" du registrar chez lequel est enregistr&eacute; webrankinfo.com, et a donc re&ccedil;u l'e-mail permettant de modifier le mot de passe.</p>
<p>Alors ? N'est-ce pas <strong>critique</strong> comme faille ?<br />Ce type d'attaque est appel&eacute; <a href="http://fr.wikipedia.org/wiki/Cross-Site_Request_Forgeries">Cross-Site Request Forgery</a>, et n'est pas tr&egrave;s connu en raison d'un manque de communication &agrave; ce propos.<br />Voyons comment l'&eacute;tudier concr&egrave;tement, et <strong>comment &eacute;viter ce genre de d&eacute;boires</strong>.</p>
<p>&nbsp;</p>
<p>Pour vous montrer un <strong>exemple concret</strong>, cr&eacute;ons une page affichant les donn&eacute;es re&ccedil;ues par POST :<br /><a href="http://data0.eklablog.com/skreo/perso/test_referer.php">http://data0.eklablog.com/skreo/perso/test_referer.php</a></p>
<p>Code de la page :<br /><div class="code">&lt;pre&gt;<br />
Données reçues par POST :<br />
<span style="color: #0000ff;">$_POST</span> = <span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<a href="http://www.php.net/print_r"><span style="color: #000066;">print_r</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$_POST</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span><br />
&lt;/pre&gt;<div style="display:none;">[code=php]&lt;pre&gt;<br />Donn&eacute;es re&ccedil;ues par POST :<br />$_POST = &lt;?php<br />print_r($_POST);<br />?&gt;<br />&lt;/pre&gt;[/code]</div></div></p>
<p>&nbsp;</p>
<p>Ensuite, sur un <strong>nom de domaine diff&eacute;rent</strong> (ici skreo.net), cr&eacute;ons un petit formulaire qui envoie des donn&eacute;es &agrave; cette page :</p>
<p><div class="code"><span style="color: #009900;"><a href="http://december.com/html/4/element/form.html"><span style="color: #000000; font-weight: bold;">&lt;form</span></a> <span style="color: #000066;">action</span>=<span style="color: #ff0000;">&quot;http://data0.eklablog.com/skreo/perso/test_referer.php&quot;</span> <span style="color: #000066;">method</span>=<span style="color: #ff0000;">&quot;post&quot;</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;form_test_referer&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><br />
    Variable &quot;var&quot; : <span style="color: #009900;"><a href="http://december.com/html/4/element/input.html"><span style="color: #000000; font-weight: bold;">&lt;input</span></a> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;var&quot;</span> /<span style="color: #000000; font-weight: bold;">&gt;</span></a></span><span style="color: #009900;"><a href="http://december.com/html/4/element/br.html"><span style="color: #000000; font-weight: bold;">&lt;br</span></a> /<span style="color: #000000; font-weight: bold;">&gt;</span></a></span><br />
    <span style="color: #009900;"><a href="http://december.com/html/4/element/input.html"><span style="color: #000000; font-weight: bold;">&lt;input</span></a> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;submit&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;Envoyer&quot;</span> /<span style="color: #000000; font-weight: bold;">&gt;</span></a></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/form&gt;</span></span><div style="display:none;">[code=html]&lt;form action="http://data0.eklablog.com/skreo/perso/test_referer.php" method="post" id="form_test_referer"&gt;<br />&nbsp;&nbsp;&nbsp; Variable "var" : &lt;input type="text" value="" name="var" /&gt;&lt;br /&gt;<br />&nbsp;&nbsp;&nbsp; &lt;input type="submit" value="Envoyer" /&gt;<br />&lt;/form&gt;[/code]</div></div></p>
<p>Ce qui donne ceci :</p>
<form id="form_test_referer" style="border: 1px dashed red;" action="http://data0.eklablog.com/skreo/perso/test_referer.php" method="post"> Variable "var" : <input name="var" type="text"/><br /> <input type="submit" value="Envoyer"/> </form>
<p>Vous pouvez tester ce formulaire, vous voyez bien qu'on peut envoyer n'importe quelles donn&eacute;es par POST vers un autre domaine. Un petit bout de code Javascript &agrave; la suite du formulaire permet d'envoyer le formulaire imm&eacute;diatement sans m&ecirc;me demander l'avis du visiteur :</p>
<p><div class="code"><span style="color: #009900;"><a href="http://december.com/html/4/element/script.html"><span style="color: #000000; font-weight: bold;">&lt;script</span></a> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><br />
document.getElementById(&quot;form_test_referer&quot;).submit();<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span><div style="display:none;">[code=html]&lt;script type="text/javascript"&gt;<br />document.getElementById("form_test_referer").submit();<br />&lt;/script&gt;[/code]</div></div></p>
<p>&nbsp;</p>
<p>Voyons maintenant <strong>comment emp&ecirc;cher dans la majorit&eacute; des cas ce genre de hacks</strong>, avec l'aide du <a href="http://fr.wikipedia.org/wiki/R%C3%A9f%C3%A9rant">Referer</a>. Je dis bien "dans la majorit&eacute; des cas", car parfois le visiteur r&egrave;gle son navigateur internet pour que le referer soit vide.</p>
<p>Nous allons donc comparer le Referer avec le nom de domaine de la page courante, et vider la variable $_POST s'il est diff&eacute;rent. Reprenons notre fichier test_referer.php et nommons le <a href="http://data0.eklablog.com/skreo/perso/test_referer2.php">test_referer2.php</a> :</p>
<p><div class="code"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<br />
<span style="color: #808080; font-style: italic;">// Vérification du Referer pour les variables passées en POST</span><br />
&nbsp;<span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span><a href="http://www.php.net/isset"><span style="color: #000066;">isset</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$_SERVER</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'HTTP_REFERER'</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><br />
  &amp;&amp; <span style="color: #0000ff;">$_SERVER</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'HTTP_REFERER'</span><span style="color: #66cc66;">&#93;</span>!=<span style="color: #ff0000;">''</span><br />
  &amp;&amp; <a href="http://www.php.net/substr"><span style="color: #000066;">substr</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$_SERVER</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'HTTP_REFERER'</span><span style="color: #66cc66;">&#93;</span>, <span style="color: #cc66cc;">7</span>, <a href="http://www.php.net/strlen"><span style="color: #000066;">strlen</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$_SERVER</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'SERVER_NAME'</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> != <span style="color: #0000ff;">$_SERVER</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'SERVER_NAME'</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
&nbsp;    <span style="color: #0000ff;">$_POST</span> = <a href="http://www.php.net/array"><span style="color: #000066;">array</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp;<span style="color: #66cc66;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span><br />
&lt;pre&gt;<br />
Données reçues par POST :<br />
<span style="color: #0000ff;">$_POST</span> = <span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<a href="http://www.php.net/print_r"><span style="color: #000066;">print_r</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$_POST</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span><br />
&lt;/pre&gt;<div style="display:none;">[code=php]&lt;?php<br /><br />// V&eacute;rification du Referer pour les variables pass&eacute;es en POST<br /> if(isset($_SERVER['HTTP_REFERER'])<br />&nbsp; &amp;&amp; $_SERVER['HTTP_REFERER']!=''<br />&nbsp; &amp;&amp; substr($_SERVER['HTTP_REFERER'], 7, strlen($_SERVER['SERVER_NAME'])) != $_SERVER['SERVER_NAME']){<br /> &nbsp;&nbsp;&nbsp; $_POST = array();<br /> }<br /><br />?&gt;<br />&lt;pre&gt;<br />Donn&eacute;es re&ccedil;ues par POST :<br />$_POST = &lt;?php<br />print_r($_POST);<br />?&gt;<br />&lt;/pre&gt;[/code]</div></div></p>
<p>Reprenons notre formulaire pour tester, mais cette fois vers test_referer2.php :</p>
<form style="border: 1px dashed red;" action="http://data0.eklablog.com/skreo/perso/test_referer2.php" method="post"> Variable "var" : <input name="var" type="text"/><br /> <input type="submit" value="Envoyer"/> </form>
<p>&nbsp;</p>
<p>Et <strong>le tour est jou&eacute;</strong> !<br />La page accepte toujours les envois de donn&eacute;es par POST provenant du m&ecirc;me nom de domaine, mais n'accepte pas les autres !</p>
<p>Si vous avez un site web, je vous conseille tr&egrave;s fortement de mettre en place cette s&eacute;curit&eacute;, si ce n'est pas d&eacute;j&agrave; le cas <img src="http://godefroy.me/images/emoticons/wink2.gif" border="0" alt=""/></p><br /><br /><div class="article_sharebtns"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fgodefroy.me%2Fsecurite-php-toujours-verifier-le-referer-lors-d-un-envoi-par-post-a313986&amp;layout=button_count&amp;show_faces=false&amp;width=65&amp;action=like&amp;font&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:65px; height:21px;" allowTransparency="true"><br /></iframe><iframe allowtransparency="true" frameborder="0" scrolling="no" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fgodefroy.me%2Fsecurite-php-toujours-verifier-le-referer-lors-d-un-envoi-par-post-a313986&amp;text=%5BS%C3%A9curit%C3%A9%20PHP%5D%20Toujours%20v%C3%A9rifier%20le%20Referer%20lors%20d%27un%20envoi%20par%20POST&amp;count=none" style="width: 55px; height: 20px;"></iframe><span><g:plusone size="medium" count="true" href="http://godefroy.me/securite-php-toujours-verifier-le-referer-lors-d-un-envoi-par-post-a313986"></g:plusone></span></div><br /><hr />Article original rédigé par Godefroy et publié sur <a href="http://skreo.eklablog.com">Godefroy</a> <br /> Reproduction interdite sans autorisation]]></content:encoded>
		<pubDate>Fri, 26 Dec 2008 14:27:26 +0100</pubDate>
		<guid isPermaLink="true">http://godefroy.me/securite-php-toujours-verifier-le-referer-lors-d-un-envoi-par-post-a313986</guid>
		<dc:creator>Godefroy</dc:creator>
		<dc:date>2008-12-26T14:27:26+01:00</dc:date>
	</item>
	<item>
		<title><![CDATA[Détecter les sites que vos visiteurs utilisent]]></title>
		<link>http://godefroy.me/detecter-les-sites-que-vos-visiteurs-utilisent-a196583</link>
		<description><![CDATA[Je me suis souvenu d'un article tr&egrave;s int&eacute;ressant sur lequel j'&eacute;tais tomb&eacute; il y a un ou deux mois, pr&eacute;sentant une classe javascript permettant de d&eacute;tecter quels r&eacute;seaux sociaux utilisent les visiteurs. En regardant le code de plus pr&ecirc;t, je l'ai trouv&eacute; compliqu&eacute; pour pas grand chose, avec...]]></description>
		<content:encoded><![CDATA[<p>Je me suis souvenu d&#39;un <strong><a href="http://azarask.in/blog/post/socialhistoryjs/">article</a></strong>  tr&egrave;s int&eacute;ressant sur lequel j&#39;&eacute;tais tomb&eacute; il y a un ou deux mois, pr&eacute;sentant une classe javascript permettant de d&eacute;tecter quels r&eacute;seaux sociaux utilisent les visiteurs. En regardant le code de plus pr&ecirc;t, je l&#39;ai trouv&eacute; compliqu&eacute; pour pas grand chose, avec l&#39;utilisation d&#39;une iframe et un code pas tr&egrave;s optimis&eacute;.</p><p>Voici donc un code que je viens de pondre, parce que je pense qu&#39;il pourra &ecirc;tre utile, aussi bien pour vous que pour moi <img alt=" " src="http://www.skreo.net/images/emoticons/smile.gif" /> J&#39;utilise ici le framework <strong><a href="http://mootools.net/download">Mootools 1.2</a></strong> , mais je pense que c&#39;est facilement adaptable &agrave; d&#39;autres. Le principe est simple, on utilise une &quot;faille&quot; du <abbr title="Cascading Style Sheet">CSS</abbr> qui consiste &agrave; r&eacute;cup&eacute;rer le style de liens apr&egrave;s avoir appliqu&eacute; un style particulier aux liens visit&eacute;s (&quot;a:visited&quot;).<br /></p><p>Une petite d&eacute;mo pour commencer : <strong><a href="http://data0.eklablog.com/skreo/perso/checkvisited.html">checkvisited.html</a></strong><br /><br /></p><p>On va donc commencer par faire un peu de <abbr title="Cascading Style Sheet">CSS</abbr> :</p><div class="code">a<span style="color: #6666ff;">.test_visited</span> <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">display</span>: <span style="color: #993333;">block</span>; <span style="color: #66cc66;">&#125;</span><br />
a<span style="color: #6666ff;">.test_visited</span><span style="color: #3333ff;">:visited</span> <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">display</span>: <span style="color: #993333;">none</span>; <span style="color: #66cc66;">&#125;</span><div style="display:none;">[code=css]a.test_visited { display: block; }<br />a.test_visited:visited { display: none; }[/code]</div></div><br /><p>C&#39;est tout pour le <abbr title="Cascading Style Sheet">CSS</abbr> !<br />Maintenant, le Javascript :<br /><abbr title="Cascading Style Sheet"></abbr></p><div class="code"><span style="color: #009900; font-style: italic;">// Implémentation de la fonction checkVisited</span><br />
<span style="color: #009900; font-style: italic;">// pour les chaînes de caractères (String)</span><br />
String.<span style="color: #006600;">implement</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span><br />
    checkVisited : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
        <span style="color: #003366; font-weight: bold;">var</span> e = <span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> Element<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;a&quot;</span>, <span style="color: #66cc66;">&#123;</span><br />
                href: <span style="color: #000066; font-weight: bold;">this</span>,<br />
                <span style="color: #3366CC;">&quot;class&quot;</span> : <span style="color: #3366CC;">&quot;test_visited&quot;</span><br />
            <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
            .<span style="color: #006600;">inject</span><span style="color: #66cc66;">&#40;</span>document.<span style="color: #006600;">body</span><span style="color: #66cc66;">&#41;</span>,<br />
            b = e.<span style="color: #006600;">getStyle</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;display&quot;</span><span style="color: #66cc66;">&#41;</span>==<span style="color: #3366CC;">&quot;none&quot;</span>;<br />
        e.<span style="color: #006600;">destroy</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
        <span style="color: #000066; font-weight: bold;">return</span> b;<br />
    <span style="color: #66cc66;">&#125;</span><br />
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #009900; font-style: italic;">// Implémentation de la fonction checkVisited pour</span><br />
<span style="color: #009900; font-style: italic;">// les tableaux (Array) : tester une liste d'urls</span><br />
Array.<span style="color: #006600;">implement</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span><br />
    checkVisited : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
        <span style="color: #003366; font-weight: bold;">var</span> b = <span style="color: #003366; font-weight: bold;">false</span>;<br />
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">each</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>s<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
            <span style="color: #000066; font-weight: bold;">if</span><span style="color: #66cc66;">&#40;</span>s.<span style="color: #006600;">checkVisited</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
                b = <span style="color: #003366; font-weight: bold;">true</span>;<br />
        <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span><br />
        <span style="color: #000066; font-weight: bold;">return</span> b;<br />
    <span style="color: #66cc66;">&#125;</span><br />
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;<div style="display:none;">[code=javascript]// Impl&eacute;mentation de la fonction checkVisited<br />// pour les cha&icirc;nes de caract&egrave;res (String)<br />String.implement({<br />&nbsp;&nbsp;&nbsp; checkVisited : function(){<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; var e = (new Element(&quot;a&quot;, {<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; href: this,<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &quot;class&quot; : &quot;test_visited&quot;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }))<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; .inject(document.body),<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; b = e.getStyle(&quot;display&quot;)==&quot;none&quot;;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; e.destroy();<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return b;<br />&nbsp;&nbsp;&nbsp; }<br />});<br /><br />// Impl&eacute;mentation de la fonction checkVisited pour<br />// les tableaux (Array) : tester une liste d&#39;urls<br />Array.implement({<br />&nbsp;&nbsp;&nbsp; checkVisited : function(){<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; var b = false;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; this.each(function(s){<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(s.checkVisited())<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; b = true;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; })<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return b;<br />&nbsp;&nbsp;&nbsp; }<br />});[/code]</div></div><p>Ces deux impl&eacute;mentations permettent de v&eacute;rifier une URL ou une liste d&#39;URLs.</p><p>On va reprendre l&#39;exemple des r&eacute;seaux sociaux que traite Aza Raskin dans son article. D&#39;abord, on cr&eacute;e un conteneur pour l&#39;affichage du r&eacute;sultat :<br /></p><div class="code"><span style="color: #009900;"><a href="http://december.com/html/4/element/div.html"><span style="color: #000000; font-weight: bold;">&lt;div</span></a> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;visited_sites&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><div style="display:none;">[code=html]&lt;div id=&quot;visited_sites&quot;&gt;<br />&lt;/div&gt;[/code]</div></div><p>Ensuite, on cr&eacute;e la liste et on la traite : <br /></p><div class="code"><span style="color: #808080; font-style: italic;">// Liste de réseaux sociaux</span><br />
<span style="color: #000000; font-weight: bold;">var</span> sites = <span style="color: #66cc66;">&#123;</span><br />
    <span style="color: #ff0000;">&quot;Digg&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://digg.com&quot;</span>, <span style="color: #ff0000;">&quot;http://digg.com/login&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Reddit&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://reddit.com&quot;</span>, <span style="color: #ff0000;">&quot;http://reddit.com/new/&quot;</span>, <span style="color: #ff0000;">&quot;http://reddit.com/controversial/&quot;</span>, <span style="color: #ff0000;">&quot;http://reddit.com/top/&quot;</span>, <span style="color: #ff0000;">&quot;http://reddit.com/r/reddit.com/&quot;</span>, <span style="color: #ff0000;">&quot;http://reddit.com/r/programming/&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;StumbleUpon&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://stumbleupon.com&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Yahoo Buzz&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://buzz.yahoo.com&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Facebook&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://facebook.com/home.php&quot;</span>, <span style="color: #ff0000;">&quot;http://facebook.com&quot;</span>, <span style="color: #ff0000;">&quot;https://login.facebook.com/login.php&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Del.icio.us&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;https://secure.del.icio.us/login&quot;</span>, <span style="color: #ff0000;">&quot;http://del.icio.us/&quot;</span>, <span style="color: #ff0000;">&quot;http://delicious.com&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;MySpace&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://www.myspace.com/&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Technorati&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://www.technorati.com&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Newsvine&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;https://www.newsvine.com&quot;</span>, <span style="color: #ff0000;">&quot;https://www.newsvine.com/_tools/user/login&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Songza&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://songza.com&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Slashdot&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://slashdot.org/&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Ma.gnolia&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://ma.gnolia.com/&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Blinklist&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://www.blinklist.com&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Furl&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://furl.net&quot;</span>, <span style="color: #ff0000;">&quot;http://furl.net/members/login&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Mister Wong&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://www.mister-wong.com&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Current&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://current.com&quot;</span>, <span style="color: #ff0000;">&quot;http://current.com/login.html&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Menaeme&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://meneame.net&quot;</span>, <span style="color: #ff0000;">&quot;http://meneame.net/login.php&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Oknotizie&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://oknotizie.alice.it&quot;</span>, <span style="color: #ff0000;">&quot;http://oknotizie.alice.it/login.html.php&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Diigo&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://www.diigo.com/&quot;</span>, <span style="color: #ff0000;">&quot;https://secure.diigo.com/sign-in&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Funp&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://funp.com&quot;</span>, <span style="color: #ff0000;">&quot;http://funp.com/account/loginpage.php&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Blogmarks&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://blogmarks.net&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Yahoo Bookmarks&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://bookmarks.yahoo.com&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Xanga&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://xanga.com&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Blogger&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://blogger.com&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Last.fm&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://www.last.fm/&quot;</span>, <span style="color: #ff0000;">&quot;https://www.last.fm/login/&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;N4G&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://www.n4g.com&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Faves&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://faves.com&quot;</span>, <span style="color: #ff0000;">&quot;http://faves.com/home&quot;</span>, <span style="color: #ff0000;">&quot;https://secure.faves.com/signIn&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Simpy&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://www.simpy.com&quot;</span>, <span style="color: #ff0000;">&quot;http://www.simpy.com/login&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Yigg&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://www.yigg.de&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Kirtsy&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://www.kirtsy.com&quot;</span>, <span style="color: #ff0000;">&quot;http://www.kirtsy.com/login.php&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Fark&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://www.fark.com&quot;</span>, <span style="color: #ff0000;">&quot;http://cgi.fark.com/cgi/fark/users.pl?self=1&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Mixx&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;https://www.mixx.com/login/dual&quot;</span>, <span style="color: #ff0000;">&quot;http://www.mixx.com&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Google Bookmarks&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://www.google.com/bookmarks&quot;</span>, <span style="color: #ff0000;">&quot;http://www.google.com/ig/add?moduleurl=bookmarks.xml&amp;hl=en&quot;</span><span style="color: #66cc66;">&#93;</span>,<br />
    <span style="color: #ff0000;">&quot;Subbmitt&quot;</span>: <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;http://subbmitt.com/&quot;</span><span style="color: #66cc66;">&#93;</span><br />
<span style="color: #66cc66;">&#125;</span>,<br />
    t = <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span>; <span style="color: #808080; font-style: italic;">// Variable dans laquelle on va stocker la liste de sites visités par l'utilisateur</span><br />
<br />
<span style="color: #808080; font-style: italic;">// On vérifie pour chaque site de la liste</span><br />
<span style="color: #b1b100;">for</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> i in sites<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
    <span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span>sites<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span>.checkVisited<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
        t.push<span style="color: #66cc66;">&#40;</span>i<span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #66cc66;">&#125;</span><br />
<br />
<span style="color: #808080; font-style: italic;">// On affiche le résultat</span><br />
$<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;visited_sites&quot;</span><span style="color: #66cc66;">&#41;</span>.set<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;html&quot;</span>, <span style="color: #ff0000;">&quot;&lt;strong&gt;Sites visités : &lt;/strong&gt;&quot;</span> + t.<a href="http://www.php.net/join"><span style="color: #000066;">join</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;, &quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<div style="display:none;">[code=php]// Liste de r&eacute;seaux sociaux<br />var sites = {<br />&nbsp;&nbsp;&nbsp; &quot;Digg&quot;: [&quot;http://digg.com&quot;, &quot;http://digg.com/login&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Reddit&quot;: [&quot;http://reddit.com&quot;, &quot;http://reddit.com/new/&quot;, &quot;http://reddit.com/controversial/&quot;, &quot;http://reddit.com/top/&quot;, &quot;http://reddit.com/r/reddit.com/&quot;, &quot;http://reddit.com/r/programming/&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;StumbleUpon&quot;: [&quot;http://stumbleupon.com&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Yahoo Buzz&quot;: [&quot;http://buzz.yahoo.com&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Facebook&quot;: [&quot;http://facebook.com/home.php&quot;, &quot;http://facebook.com&quot;, &quot;https://login.facebook.com/login.php&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Del.icio.us&quot;: [&quot;https://secure.del.icio.us/login&quot;, &quot;http://del.icio.us/&quot;, &quot;http://delicious.com&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;MySpace&quot;: [&quot;http://www.myspace.com/&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Technorati&quot;: [&quot;http://www.technorati.com&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Newsvine&quot;: [&quot;https://www.newsvine.com&quot;, &quot;https://www.newsvine.com/_tools/user/login&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Songza&quot;: [&quot;http://songza.com&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Slashdot&quot;: [&quot;http://slashdot.org/&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Ma.gnolia&quot;: [&quot;http://ma.gnolia.com/&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Blinklist&quot;: [&quot;http://www.blinklist.com&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Furl&quot;: [&quot;http://furl.net&quot;, &quot;http://furl.net/members/login&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Mister Wong&quot;: [&quot;http://www.mister-wong.com&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Current&quot;: [&quot;http://current.com&quot;, &quot;http://current.com/login.html&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Menaeme&quot;: [&quot;http://meneame.net&quot;, &quot;http://meneame.net/login.php&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Oknotizie&quot;: [&quot;http://oknotizie.alice.it&quot;, &quot;http://oknotizie.alice.it/login.html.php&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Diigo&quot;: [&quot;http://www.diigo.com/&quot;, &quot;https://secure.diigo.com/sign-in&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Funp&quot;: [&quot;http://funp.com&quot;, &quot;http://funp.com/account/loginpage.php&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Blogmarks&quot;: [&quot;http://blogmarks.net&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Yahoo Bookmarks&quot;: [&quot;http://bookmarks.yahoo.com&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Xanga&quot;: [&quot;http://xanga.com&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Blogger&quot;: [&quot;http://blogger.com&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Last.fm&quot;: [&quot;http://www.last.fm/&quot;, &quot;https://www.last.fm/login/&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;N4G&quot;: [&quot;http://www.n4g.com&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Faves&quot;: [&quot;http://faves.com&quot;, &quot;http://faves.com/home&quot;, &quot;https://secure.faves.com/signIn&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Simpy&quot;: [&quot;http://www.simpy.com&quot;, &quot;http://www.simpy.com/login&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Yigg&quot;: [&quot;http://www.yigg.de&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Kirtsy&quot;: [&quot;http://www.kirtsy.com&quot;, &quot;http://www.kirtsy.com/login.php&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Fark&quot;: [&quot;http://www.fark.com&quot;, &quot;http://cgi.fark.com/cgi/fark/users.pl?self=1&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Mixx&quot;: [&quot;https://www.mixx.com/login/dual&quot;, &quot;http://www.mixx.com&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Google Bookmarks&quot;: [&quot;http://www.google.com/bookmarks&quot;, &quot;http://www.google.com/ig/add?moduleurl=bookmarks.xml&amp;hl=en&quot;],<br />&nbsp;&nbsp;&nbsp; &quot;Subbmitt&quot;: [&quot;http://subbmitt.com/&quot;]<br />},<br />&nbsp;&nbsp;&nbsp; t = []; // Variable dans laquelle on va stocker la liste de sites visit&eacute;s par l&#39;utilisateur<br /><br />// On v&eacute;rifie pour chaque site de la liste<br />for(var i in sites){<br />&nbsp;&nbsp;&nbsp; if(sites[i].checkVisited())<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; t.push(i);<br />}<br /><br />// On affiche le r&eacute;sultat<br />$(&quot;visited_sites&quot;).set(&quot;html&quot;, &quot;&lt;strong&gt;Sites visit&eacute;s : &lt;/strong&gt;&quot; + t.join(&quot;, &quot;));[/code]</div></div><p>C&#39;est fini !</p><p>Chez moi, &ccedil;a fonctionne impeccablement avec Firefox 3, Op&eacute;ra 9.5, IE 6, et IE 7.<br />Si vous avez un probl&egrave;me d&#39;incompatibilit&eacute; ou une suggestion, n&#39;h&eacute;sitez pas ! Par exemple, on pourrait, comme Aza, traiter pour une URL quelconque l&#39;URL avec et sans les &quot;www&quot;.</p><p>Merci de me faire un petit lien de retour si vous utilisez ce script quelque part <img alt=" " src="http://www.skreo.net/images/emoticons/wink2.gif" /></p><br /><br /><div class="article_sharebtns"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fgodefroy.me%2Fdetecter-les-sites-que-vos-visiteurs-utilisent-a196583&amp;layout=button_count&amp;show_faces=false&amp;width=65&amp;action=like&amp;font&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:65px; height:21px;" allowTransparency="true"><br /></iframe><iframe allowtransparency="true" frameborder="0" scrolling="no" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fgodefroy.me%2Fdetecter-les-sites-que-vos-visiteurs-utilisent-a196583&amp;text=D%C3%A9tecter%20les%20sites%20que%20vos%20visiteurs%20utilisent&amp;count=none" style="width: 55px; height: 20px;"></iframe><span><g:plusone size="medium" count="true" href="http://godefroy.me/detecter-les-sites-que-vos-visiteurs-utilisent-a196583"></g:plusone></span></div><br /><hr />Article original rédigé par Godefroy et publié sur <a href="http://skreo.eklablog.com">Godefroy</a> <br /> Reproduction interdite sans autorisation]]></content:encoded>
		<pubDate>Fri, 01 Aug 2008 02:34:31 +0200</pubDate>
		<guid isPermaLink="true">http://godefroy.me/detecter-les-sites-que-vos-visiteurs-utilisent-a196583</guid>
		<dc:creator>Godefroy</dc:creator>
		<dc:date>2008-08-01T02:34:31+02:00</dc:date>
	</item>
	<item>
		<title><![CDATA[[PHP] Enlever tous les accents d'une chaîne]]></title>
		<link>http://godefroy.me/php-enlever-tous-les-accents-d-une-chaine-a192614</link>
		<description><![CDATA[Voici ma fonction pour enlever tous les accents d'une cha&icirc;ne de caract&egrave;res tout en respectant l'encodage (cette fonction traite tr&egrave;s bien les textes UTF-8 par exemple) : function removeAccents ( $txt ) { 
&nbsp;&nbsp;&nbsp; $txt = str_replace ( '&oelig;' , 'oe' , $txt ) ;
&nbsp;&nbsp;&nbsp; $txt = str_replace ( '&OElig;' ,...]]></description>
		<content:encoded><![CDATA[<p>Voici ma fonction pour enlever tous les accents d&#39;une cha&icirc;ne de caract&egrave;res tout en respectant l&#39;encodage (cette fonction traite tr&egrave;s bien les textes UTF-8 par exemple) :</p><div class="code"><span style="color: #000000; font-weight: bold;">function</span> removeAccents<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/str_replace"><span style="color: #000066;">str_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'œ'</span>, <span style="color: #ff0000;">'oe'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/str_replace"><span style="color: #000066;">str_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Œ'</span>, <span style="color: #ff0000;">'Oe'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/str_replace"><span style="color: #000066;">str_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'æ'</span>, <span style="color: #ff0000;">'ae'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/str_replace"><span style="color: #000066;">str_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Æ'</span>, <span style="color: #ff0000;">'Ae'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <a href="http://www.php.net/mb_regex_encoding"><span style="color: #000066;">mb_regex_encoding</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'UTF-8'</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ÀÁÂÃÄÅĀĂǍẠẢẤẦẨẪẬẮẰẲẴẶǺĄ]'</span>, <span style="color: #ff0000;">'A'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[àáâãäåāăǎạảấầẩẫậắằẳẵặǻą]'</span>, <span style="color: #ff0000;">'a'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ÇĆĈĊČ]'</span>, <span style="color: #ff0000;">'C'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[çćĉċč]'</span>, <span style="color: #ff0000;">'c'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ÐĎĐ]'</span>, <span style="color: #ff0000;">'D'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ďđ]'</span>, <span style="color: #ff0000;">'d'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ÈÉÊËĒĔĖĘĚẸẺẼẾỀỂỄỆ]'</span>, <span style="color: #ff0000;">'E'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[èéêëēĕėęěẹẻẽếềểễệ]'</span>, <span style="color: #ff0000;">'e'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ĜĞĠĢ]'</span>, <span style="color: #ff0000;">'G'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ĝğġģ]'</span>, <span style="color: #ff0000;">'g'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ĤĦ]'</span>, <span style="color: #ff0000;">'H'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ĥħ]'</span>, <span style="color: #ff0000;">'h'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ÌÍÎÏĨĪĬĮİǏỈỊ]'</span>, <span style="color: #ff0000;">'I'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ìíîïĩīĭįıǐỉị]'</span>, <span style="color: #ff0000;">'i'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/str_replace"><span style="color: #000066;">str_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Ĵ'</span>, <span style="color: #ff0000;">'J'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/str_replace"><span style="color: #000066;">str_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'ĵ'</span>, <span style="color: #ff0000;">'j'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/str_replace"><span style="color: #000066;">str_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Ķ'</span>, <span style="color: #ff0000;">'K'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/str_replace"><span style="color: #000066;">str_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'ķ'</span>, <span style="color: #ff0000;">'k'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ĹĻĽĿŁ]'</span>, <span style="color: #ff0000;">'L'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ĺļľŀł]'</span>, <span style="color: #ff0000;">'l'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ÑŃŅŇ]'</span>, <span style="color: #ff0000;">'N'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ñńņňŉ]'</span>, <span style="color: #ff0000;">'n'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ÒÓÔÕÖØŌŎŐƠǑǾỌỎỐỒỔỖỘỚỜỞỠỢ]'</span>, <span style="color: #ff0000;">'O'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[òóôõöøōŏőơǒǿọỏốồổỗộớờởỡợð]'</span>, <span style="color: #ff0000;">'o'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ŔŖŘ]'</span>, <span style="color: #ff0000;">'R'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ŕŗř]'</span>, <span style="color: #ff0000;">'r'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ŚŜŞŠ]'</span>, <span style="color: #ff0000;">'S'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[śŝşš]'</span>, <span style="color: #ff0000;">'s'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ŢŤŦ]'</span>, <span style="color: #ff0000;">'T'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ţťŧ]'</span>, <span style="color: #ff0000;">'t'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ÙÚÛÜŨŪŬŮŰŲƯǓǕǗǙǛỤỦỨỪỬỮỰ]'</span>, <span style="color: #ff0000;">'U'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ùúûüũūŭůűųưǔǖǘǚǜụủứừửữự]'</span>, <span style="color: #ff0000;">'u'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ŴẀẂẄ]'</span>, <span style="color: #ff0000;">'W'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ŵẁẃẅ]'</span>, <span style="color: #ff0000;">'w'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ÝŶŸỲỸỶỴ]'</span>, <span style="color: #ff0000;">'Y'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ýÿŷỹỵỷỳ]'</span>, <span style="color: #ff0000;">'y'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[ŹŻŽ]'</span>, <span style="color: #ff0000;">'Z'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$txt</span> = <a href="http://www.php.net/mb_ereg_replace"><span style="color: #000066;">mb_ereg_replace</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'[źżž]'</span>, <span style="color: #ff0000;">'z'</span>, <span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #b1b100;">return</span> <span style="color: #0000ff;">$txt</span>;<br />
<span style="color: #66cc66;">&#125;</span><div style="display:none;">[code=php]function removeAccents($txt){<br />&nbsp;&nbsp;&nbsp; $txt = str_replace(&#39;&oelig;&#39;, &#39;oe&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = str_replace(&#39;&OElig;&#39;, &#39;Oe&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = str_replace(&#39;&aelig;&#39;, &#39;ae&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = str_replace(&#39;&AElig;&#39;, &#39;Ae&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; mb_regex_encoding(&#39;UTF-8&#39;);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[&Agrave;&Aacute;&Acirc;&Atilde;&Auml;&Aring;ĀĂǍẠẢẤẦẨẪẬẮẰẲẴẶǺĄ]&#39;, &#39;A&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[&agrave;&aacute;&acirc;&atilde;&auml;&aring;āăǎạảấầẩẫậắằẳẵặǻą]&#39;, &#39;a&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[&Ccedil;ĆĈĊČ]&#39;, &#39;C&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[&ccedil;ćĉċč]&#39;, &#39;c&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[&ETH;ĎĐ]&#39;, &#39;D&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[ďđ]&#39;, &#39;d&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[&Egrave;&Eacute;&Ecirc;&Euml;ĒĔĖĘĚẸẺẼẾỀỂỄỆ]&#39;, &#39;E&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[&egrave;&eacute;&ecirc;&euml;ēĕėęěẹẻẽếềểễệ]&#39;, &#39;e&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[ĜĞĠĢ]&#39;, &#39;G&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[ĝğġģ]&#39;, &#39;g&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[ĤĦ]&#39;, &#39;H&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[ĥħ]&#39;, &#39;h&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[&Igrave;&Iacute;&Icirc;&Iuml;ĨĪĬĮİǏỈỊ]&#39;, &#39;I&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[&igrave;&iacute;&icirc;&iuml;ĩīĭįıǐỉị]&#39;, &#39;i&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = str_replace(&#39;Ĵ&#39;, &#39;J&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = str_replace(&#39;ĵ&#39;, &#39;j&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = str_replace(&#39;Ķ&#39;, &#39;K&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = str_replace(&#39;ķ&#39;, &#39;k&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[ĹĻĽĿŁ]&#39;, &#39;L&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[ĺļľŀł]&#39;, &#39;l&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[&Ntilde;ŃŅŇ]&#39;, &#39;N&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[&ntilde;ńņňŉ]&#39;, &#39;n&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[&Ograve;&Oacute;&Ocirc;&Otilde;&Ouml;&Oslash;ŌŎŐƠǑǾỌỎỐỒỔỖỘỚỜỞỠỢ]&#39;, &#39;O&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[&ograve;&oacute;&ocirc;&otilde;&ouml;&oslash;ōŏőơǒǿọỏốồổỗộớờởỡợ&eth;]&#39;, &#39;o&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[ŔŖŘ]&#39;, &#39;R&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[ŕŗř]&#39;, &#39;r&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[ŚŜŞ&Scaron;]&#39;, &#39;S&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[śŝş&scaron;]&#39;, &#39;s&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[ŢŤŦ]&#39;, &#39;T&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[ţťŧ]&#39;, &#39;t&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[&Ugrave;&Uacute;&Ucirc;&Uuml;ŨŪŬŮŰŲƯǓǕǗǙǛỤỦỨỪỬỮỰ]&#39;, &#39;U&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[&ugrave;&uacute;&ucirc;&uuml;ũūŭůűųưǔǖǘǚǜụủứừửữự]&#39;, &#39;u&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[ŴẀẂẄ]&#39;, &#39;W&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[ŵẁẃẅ]&#39;, &#39;w&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[&Yacute;Ŷ&Yuml;ỲỸỶỴ]&#39;, &#39;Y&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[&yacute;&yuml;ŷỹỵỷỳ]&#39;, &#39;y&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[ŹŻŽ]&#39;, &#39;Z&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; $txt = mb_ereg_replace(&#39;[źżž]&#39;, &#39;z&#39;, $txt);<br />&nbsp;&nbsp;&nbsp; return $txt;<br />}[/code]</div></div><p>On peut faire plus simple, certes, mais contrairement &agrave; ce qu&#39;on peut voir habituellement, cette fonction traite v&eacute;ritablement tous les accents existants, et fonctionne avec tous les encodages.<br /></p><br /><br /><div class="article_sharebtns"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fgodefroy.me%2Fphp-enlever-tous-les-accents-d-une-chaine-a192614&amp;layout=button_count&amp;show_faces=false&amp;width=65&amp;action=like&amp;font&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:65px; height:21px;" allowTransparency="true"><br /></iframe><iframe allowtransparency="true" frameborder="0" scrolling="no" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fgodefroy.me%2Fphp-enlever-tous-les-accents-d-une-chaine-a192614&amp;text=%5BPHP%5D%20Enlever%20tous%20les%20accents%20d%27une%20cha%C3%AEne&amp;count=none" style="width: 55px; height: 20px;"></iframe><span><g:plusone size="medium" count="true" href="http://godefroy.me/php-enlever-tous-les-accents-d-une-chaine-a192614"></g:plusone></span></div><br /><hr />Article original rédigé par Godefroy et publié sur <a href="http://skreo.eklablog.com">Godefroy</a> <br /> Reproduction interdite sans autorisation]]></content:encoded>
		<pubDate>Fri, 25 Jul 2008 20:46:01 +0200</pubDate>
		<guid isPermaLink="true">http://godefroy.me/php-enlever-tous-les-accents-d-une-chaine-a192614</guid>
		<dc:creator>Godefroy</dc:creator>
		<dc:date>2008-07-25T20:46:01+02:00</dc:date>
	</item>
	<item>
		<title><![CDATA[Mes conventions en programmation]]></title>
		<link>http://godefroy.me/mes-conventions-en-programmation-a181807</link>
		<description><![CDATA[On a tous nos petites habitudes de programmation : quel type d'indentation, o&ugrave; placer les accolades, notation hongroise, espacements...etc.
Je vais vous pr&eacute;senter les miennes, non pas pour tenter de les imposer (d'ailleurs tout n'est pas forc&eacute;ment bien), mais pour &eacute;changer, savoir ce que vous...]]></description>
		<content:encoded><![CDATA[<p>On a tous nos petites<strong> habitudes de programmation</strong> : quel type d&#39;indentation, o&ugrave; placer les accolades, notation hongroise, espacements...etc.<br />Je vais vous pr&eacute;senter les miennes, non pas pour tenter de les imposer (d&#39;ailleurs tout n&#39;est pas forc&eacute;ment bien), mais pour &eacute;changer, savoir ce que vous en pensez, et savoir quelles sont les v&ocirc;tres. Je ne parlerai ici que de l&#39;<strong>aspect visuel</strong> de la programmation, pas de la structure des fichiers, des frameworks...<br /></p><p>Avant tout, un petit exemple en PHP pour illustrer mes conventions :<br /><div class="code"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #0000ff;">$monTableau</span> = <a href="http://www.php.net/array"><span style="color: #000066;">array</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'H'</span>, <span style="color: #ff0000;">'e'</span>, <span style="color: #ff0000;">'l'</span>, <span style="color: #ff0000;">'l'</span>, <span style="color: #ff0000;">'o'</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #0000ff;">$txt</span> = <span style="color: #ff0000;">''</span>;<br />
<span style="color: #0000ff;">$n</span> = <span style="color: #cc66cc;">2</span>;<br />
<span style="color: #b1b100;">for</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$i</span>=<span style="color: #cc66cc;">0</span>; <span style="color: #0000ff;">$i</span>&lt;count<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$monTableau</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #0000ff;">$i</span>++<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
    <span style="color: #0000ff;">$txt</span> .= <span style="color: #0000ff;">$monTableau</span><span style="color: #66cc66;">&#91;</span><span style="color: #0000ff;">$i</span><span style="color: #66cc66;">&#93;</span>;<br />
    <span style="color: #0000ff;">$n</span> = <a href="http://www.php.net/pow"><span style="color: #000066;">pow</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$n</span>, <span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #66cc66;">&#125;</span><br />
<span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$n</span> % <span style="color: #66cc66;">&#40;</span><a href="http://www.php.net/strlen"><span style="color: #000066;">strlen</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$txt</span><span style="color: #66cc66;">&#41;</span><span style="color: #cc66cc;">+1</span><span style="color: #66cc66;">&#41;</span>==<span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><br />
    <span style="color: #0000ff;">$txt</span> .= <span style="color: #ff0000;">' World'</span>;<br />
<a href="http://www.php.net/echo"><span style="color: #000066;">echo</span></a> <span style="color: #0000ff;">$txt</span>;<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span><div style="display:none;">[code=php]&lt;?php<br />$monTableau = array(&#39;H&#39;, &#39;e&#39;, &#39;l&#39;, &#39;l&#39;, &#39;o&#39;);<br />$txt = &#39;&#39;;<br />$n = 2;<br />for($i=0; $i&lt;count($monTableau); $i++){<br />&nbsp;&nbsp;&nbsp; $txt .= $monTableau[$i];<br />&nbsp;&nbsp;&nbsp; $n = pow($n, 2);<br />}<br />if($n % (strlen($txt)+1)==0)<br />&nbsp;&nbsp;&nbsp; $txt .= &#39; World&#39;;<br />echo $txt;<br />?&gt;[/code]</div></div><br /></p><p><span style="font-weight: bold">Notation :<br /></span>J&#39;utilise la notation <a href="http://fr.wikipedia.org/wiki/LowerCamelCase">lowerCamelCase</a>  pour nommer mes variables, fonctions, classes, et m&eacute;thodes.<br /></p><p><span style="font-weight: bold">Indentation :</span><br />Tabulation de la largeur de 4 espace.<br />Je prends soin de bien indenter tout les blocs. Logique diront certains, mais ce n&#39;est pas le cas partout...</p><p><span style="font-weight: bold">Accolades :</span><br />Accolade ouvrante &agrave; la fin de la ligne de d&eacute;finition de la boucle. Accolade fermante sur une nouvelle ligne, au m&ecirc;me niveau que la d&eacute;finition de la boucle.<br />Pas d&#39;accolades pour un bloc mono-ligne. (par exemple un <em>if</em> suivi d&#39;une seule instruction).<br /></p><p><span style="font-weight: bold">Espaces :</span><br />Pour les virgules et les point-virgules : pas d&#39;espace avant, un espace apr&egrave;s.<br />Pas d&#39;espace entre les noms de fonction et la parenth&egrave;se ouvrante. Idem pour les boucles.<br />Pas d&#39;espace entre la parenth&egrave;se fermante et l&#39;accolade ouvrante dans les boucles.<br />Pas d&#39;espace entre le <span style="font-style: italic">else</span> et le <span style="font-style: italic">if</span> dans les <span style="font-style: italic">else if</span>.<br />Un espace de part et d&#39;autre des op&eacute;rateurs de modification (=, +=, *=, ...).<br />Pas d&#39;espace pour les op&eacute;rateurs de comparaison (==, &lt;=, &gt;=) et pour les op&eacute;rateurs de modification dans les boucles (for, while, if), sauf pour les longues expressions.<br /></p><p><span style="font-weight: bold">Guillemets</span><br />En php, j&#39;utilise uniquement les guillemets simples (apostrophe), sauf pour afficher des caract&egrave;res sp&eacute;ciaux (\r, \n ...).<br />Dans les autres langages, des guillemets doubles.<br /></p><p><span style="font-weight: bold">Commentaires</span><br />En moyenne un commentaire mono-ligne toutes les 10 lignes, avant un bloc, pour expliquer ce qu&#39;on fait. Je pense qu&#39;ils sont important pour la compr&eacute;hension g&eacute;n&eacute;rale du code, mais qu&#39;il ne faut pas en abuser.<br />Pas de bloc de 30 lignes au d&eacute;but des pages, au pire 2 ou 3 lignes.<br /></p><p>&nbsp;</p><p>Allez j&#39;ai envie de faire mon chieur, je cr&eacute;e une cha&icirc;ne ! Je tague <a href="http://www.divarvel.fr/">divarvel</a>, <a href="http://blog.darklg.fr/">Darklg</a>, <a href="http://www.travailleursduweb.com/">Babozor</a>, et <a href="http://blog.tomclarks.net/">TomClarks</a> qui seront <span style="text-decoration: line-through">oblig&eacute;s</span> convi&eacute;s &agrave; d&eacute;crire &agrave; leur tour leurs conventions sur leur blog et faire suivre la cha&icirc;ne <img alt=" " src="http://www.skreo.net/images/emoticons/mdr.gif" /><br /></p><br /><br /><div class="article_sharebtns"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fgodefroy.me%2Fmes-conventions-en-programmation-a181807&amp;layout=button_count&amp;show_faces=false&amp;width=65&amp;action=like&amp;font&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:65px; height:21px;" allowTransparency="true"><br /></iframe><iframe allowtransparency="true" frameborder="0" scrolling="no" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fgodefroy.me%2Fmes-conventions-en-programmation-a181807&amp;text=Mes%20conventions%20en%20programmation&amp;count=none" style="width: 55px; height: 20px;"></iframe><span><g:plusone size="medium" count="true" href="http://godefroy.me/mes-conventions-en-programmation-a181807"></g:plusone></span></div><br /><hr />Article original rédigé par Godefroy et publié sur <a href="http://skreo.eklablog.com">Godefroy</a> <br /> Reproduction interdite sans autorisation]]></content:encoded>
		<pubDate>Fri, 11 Jul 2008 19:40:41 +0200</pubDate>
		<guid isPermaLink="true">http://godefroy.me/mes-conventions-en-programmation-a181807</guid>
		<dc:creator>Godefroy</dc:creator>
		<dc:date>2008-07-11T19:40:41+02:00</dc:date>
	</item>
	<item>
		<title><![CDATA[Internationalisation d'un site web]]></title>
		<link>http://godefroy.me/internationalisation-d-un-site-web-a179180</link>
		<description><![CDATA[Je me suis demand&eacute; il y a quelques temps quelle serait la meilleure solution pour traduire facilement un site web en plusieurs langues, tout en gardant une facilit&eacute; de mise &agrave; jour, une accessibilit&eacute; optimale, et des urls correctes pour le r&eacute;f&eacute;rencement. Le sujet a certes beaucoup &eacute;t&eacute;...]]></description>
		<content:encoded><![CDATA[<p>Je me suis demand&eacute; il y a quelques temps quelle serait la <strong>meilleure solution pour traduire</strong> facilement un site web en plusieurs langues, tout en gardant une facilit&eacute; de mise &agrave; jour, une accessibilit&eacute; optimale, et des urls correctes pour le r&eacute;f&eacute;rencement. Le sujet a certes beaucoup &eacute;t&eacute; trait&eacute;, mais j&#39;ai trouv&eacute; tr&egrave;s peu de solutions pratiques, jolies et <strong>performantes</strong> sur le web.<br /></p><p>Certains webmasters recopient simplement l&#39;int&eacute;gralit&eacute; de leur site dans un autre dossier ou sur un autre domaine, puis le traduisent. Oublions tout de suite cette solution... Il faut donc opter pour une solution dynamique, que je traiterai ici en php.<br /><br /></p><h4>URL et d&eacute;tection de la langue</h4><p>Avant de traduire le site, il faut &ecirc;tre capable de <strong>d&eacute;tecter la langue</strong> du visiteur, de lui proposer de changer de langue, et de m&eacute;moriser son choix :</p><p><div class="code"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<a href="http://www.php.net/session_start"><span style="color: #000066;">session_start</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #808080; font-style: italic;">// Démarrage de la session pour la sauvegarde du choix de la langue</span><br />
<span style="color: #0000ff;">$langs</span> = <a href="http://www.php.net/array"><span style="color: #000066;">array</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'en'</span>, <span style="color: #ff0000;">'fr'</span>, <span style="color: #ff0000;">'it'</span><span style="color: #66cc66;">&#41;</span>;  <span style="color: #808080; font-style: italic;">// Liste des langues</span><br />
<br />
<span style="color: #808080; font-style: italic;">// Si la langue a été changée par get ou cookie, on enregistre la modif</span><br />
<span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span><a href="http://www.php.net/isset"><span style="color: #000066;">isset</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$_GET</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'lang'</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> &amp;&amp; <a href="http://www.php.net/in_array"><span style="color: #000066;">in_array</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$_GET</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'lang'</span><span style="color: #66cc66;">&#93;</span>, <span style="color: #0000ff;">$langs</span><span style="color: #66cc66;">&#41;</span> &amp;&amp; <span style="color: #66cc66;">&#40;</span>!<a href="http://www.php.net/isset"><span style="color: #000066;">isset</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$_SESSION</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'lang'</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> || <span style="color: #0000ff;">$_SESSION</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'lang'</span><span style="color: #66cc66;">&#93;</span>!=<span style="color: #0000ff;">$_GET</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'lang'</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
    <span style="color: #0000ff;">$_SESSION</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'lang'</span><span style="color: #66cc66;">&#93;</span> = <span style="color: #0000ff;">$_GET</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'lang'</span><span style="color: #66cc66;">&#93;</span>;<br />
<span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span><a href="http://www.php.net/isset"><span style="color: #000066;">isset</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$_COOKIE</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'lang'</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> &amp;&amp; <a href="http://www.php.net/in_array"><span style="color: #000066;">in_array</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$_COOKIE</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'lang'</span><span style="color: #66cc66;">&#93;</span>, <span style="color: #0000ff;">$langs</span><span style="color: #66cc66;">&#41;</span> &amp;&amp; <span style="color: #66cc66;">&#40;</span>!<a href="http://www.php.net/isset"><span style="color: #000066;">isset</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$_SESSION</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'lang'</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> || <span style="color: #0000ff;">$_SESSION</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'lang'</span><span style="color: #66cc66;">&#93;</span>!=<span style="color: #0000ff;">$_COOKIE</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'lang'</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
    <span style="color: #0000ff;">$_SESSION</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'lang'</span><span style="color: #66cc66;">&#93;</span> = <span style="color: #0000ff;">$_COOKIE</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'lang'</span><span style="color: #66cc66;">&#93;</span>;<br />
<br />
<span style="color: #808080; font-style: italic;">// Si aucune langue n'est définie, on prend celle du navigateur du visiteur</span><br />
<span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span>!<a href="http://www.php.net/isset"><span style="color: #000066;">isset</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$_SESSION</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'lang'</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
    <span style="color: #0000ff;">$lang</span> = <a href="http://www.php.net/strtolower"><span style="color: #000066;">strtolower</span></a><span style="color: #66cc66;">&#40;</span><a href="http://www.php.net/substr"><span style="color: #000066;">substr</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$_SERVER</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'HTTP_ACCEPT_LANGUAGE'</span><span style="color: #66cc66;">&#93;</span>, <span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
    <span style="color: #0000ff;">$_SESSION</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'lang'</span><span style="color: #66cc66;">&#93;</span> = <a href="http://www.php.net/in_array"><span style="color: #000066;">in_array</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$lang</span>, <span style="color: #0000ff;">$langs</span><span style="color: #66cc66;">&#41;</span> ? <span style="color: #0000ff;">$lang</span> : <span style="color: #0000ff;">$langs</span><span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span>;<br />
<span style="color: #66cc66;">&#125;</span><br />
<br />
<span style="color: #808080; font-style: italic;">// Si le cookie de la langue n'est pas défini ou est différent de la var de session, on le définit</span><br />
<span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span>!<a href="http://www.php.net/isset"><span style="color: #000066;">isset</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$_COOKIE</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'lang'</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> || <span style="color: #0000ff;">$_SESSION</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'lang'</span><span style="color: #66cc66;">&#93;</span>!=<span style="color: #0000ff;">$_COOKIE</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'lang'</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><br />
    <a href="http://www.php.net/setcookie"><span style="color: #000066;">setcookie</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'lang'</span>, <span style="color: #0000ff;">$_SESSION</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'lang'</span><span style="color: #66cc66;">&#93;</span>, <a href="http://www.php.net/time"><span style="color: #000066;">time</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #cc66cc;">+60</span>*<span style="color: #cc66cc;">24</span>*<span style="color: #cc66cc;">3600</span>, <span style="color: #ff0000;">'/'</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #808080; font-style: italic;">// Variable $lang locale que nous utiliserons plus loin</span><br />
<span style="color: #0000ff;">$lang</span> = <span style="color: #0000ff;">$_SESSION</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'lang'</span><span style="color: #66cc66;">&#93;</span>;<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span><div style="display:none;">[code=php]&lt;?php<br />session_start(); // D&eacute;marrage de la session pour la sauvegarde du choix de la langue<br />$langs = array(&#39;en&#39;, &#39;fr&#39;, &#39;it&#39;);&nbsp; // Liste des langues<br /><br />// Si la langue a &eacute;t&eacute; chang&eacute;e par get ou cookie, on enregistre la modif<br />if(isset($_GET[&#39;lang&#39;]) &amp;&amp; in_array($_GET[&#39;lang&#39;], $langs) &amp;&amp; (!isset($_SESSION[&#39;lang&#39;]) || $_SESSION[&#39;lang&#39;]!=$_GET[&#39;lang&#39;]))<br />&nbsp;&nbsp;&nbsp; $_SESSION[&#39;lang&#39;] = $_GET[&#39;lang&#39;];<br />else if(isset($_COOKIE[&#39;lang&#39;]) &amp;&amp; in_array($_COOKIE[&#39;lang&#39;], $langs) &amp;&amp; (!isset($_SESSION[&#39;lang&#39;]) || $_SESSION[&#39;lang&#39;]!=$_COOKIE[&#39;lang&#39;]))<br />&nbsp;&nbsp;&nbsp; $_SESSION[&#39;lang&#39;] = $_COOKIE[&#39;lang&#39;];<br /><br />// Si aucune langue n&#39;est d&eacute;finie, on prend celle du navigateur du visiteur<br />if(!isset($_SESSION[&#39;lang&#39;])){<br />&nbsp;&nbsp;&nbsp; $lang = strtolower(substr($_SERVER[&#39;HTTP_ACCEPT_LANGUAGE&#39;], 0, 2));<br />&nbsp;&nbsp;&nbsp; $_SESSION[&#39;lang&#39;] = in_array($lang, $langs) ? $lang : $langs[0];<br />}<br /><br />// Si le cookie de la langue n&#39;est pas d&eacute;fini ou est diff&eacute;rent de la var de session, on le d&eacute;finit<br />if(!isset($_COOKIE[&#39;lang&#39;]) || $_SESSION[&#39;lang&#39;]!=$_COOKIE[&#39;lang&#39;])<br />&nbsp;&nbsp;&nbsp; setcookie(&#39;lang&#39;, $_SESSION[&#39;lang&#39;], time()+60*24*3600, &#39;/&#39;);<br /><br />// Variable $lang locale que nous utiliserons plus loin<br />$lang = $_SESSION[&#39;lang&#39;];<br />?&gt;[/code]</div></div></p><p>Ce code devra &ecirc;tre appel&eacute; au tout d&eacute;but de chaque page du site. Nous avons maintenant notre moyen de d&eacute;tection et de m&eacute;morisation de la langue.<br /><br /></p><p>Ensuite, nous allons prendre l&#39;exemple d&#39;URLs du type <em>http://www.monsite.com/lang/page.html</em>, ce qui a l&#39;avantage de bien r&eacute;f&eacute;rencer toutes les pages dans toutes les langues traduites. Mais nous pourrions tout aussi bien garder des URLs classiques dans le cas d&#39;un service accessible uniquement aux utilisateurs connect&eacute;s : par exemple Twitter. La langue serait alors enregistr&eacute;e dans les param&egrave;tres de l&#39;utilisateur.</p><p>Pour cela, mettons en place un .htaccess avec de l&#39;URL Rewriting &agrave; la racine :<br /><div class="code"><span style="color: #00007f;">RewriteEngine</span> <span style="color: #0000ff;">On</span><br />
<span style="color: #00007f;">RewriteRule</span>    ^<span style="color: #66cc66;">&#40;</span>en|fr|it<span style="color: #66cc66;">&#41;</span>/<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>^\?<span style="color: #66cc66;">&#93;</span>+<span style="color: #66cc66;">&#41;</span>?<span style="color: #66cc66;">&#40;</span>\?<span style="color: #66cc66;">&#40;</span>.*<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>?$    /$<span style="color: #ff0000;">2</span>?$<span style="color: #ff0000;">4</span>&amp;lang=$<span style="color: #ff0000;">1</span>    <span style="color: #66cc66;">&#91;</span>QSA,L<span style="color: #66cc66;">&#93;</span><div style="display:none;">[code=apache]RewriteEngine On<br />RewriteRule&nbsp;&nbsp;&nbsp; ^(en|fr|it)/([^\?]+)?(\?(.*))?$ &nbsp;&nbsp; /$2?$4&amp;lang=$1&nbsp;&nbsp;&nbsp; [QSA,L][/code]</div></div><br />Et voil&agrave;, d&eacute;somais, un acc&egrave;s &agrave; la page <em>http://www.monsite.com/fr/page.php</em> appellera la page <em>page.php</em> &agrave; la racine du site en lui passant la variable GET lang=fr, ce qui aura pour effet avec le script pr&eacute;c&eacute;dent d&#39;enregistrer &quot;fr&quot; comme langue dans le cookie et la variable de session du visiteur.<br /><br /></p><p>Proposons maintenant au visiteur de choisir sa langue tout en restant sur la m&ecirc;me page, au cas o&ugrave; elle aurait &eacute;t&eacute; mal d&eacute;tect&eacute; (navigateur en anglais pour un fran&ccedil;ais par exemple) :<br /><div class="code"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <br />
<span style="color: #0000ff;">$URI</span> = <span style="color: #0000ff;">$_SERVER</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'REQUEST_URI'</span><span style="color: #66cc66;">&#93;</span>; <br />
<span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$URI</span>==<span style="color: #ff0000;">'/'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #0000ff;">$URI</span> = <span style="color: #ff0000;">'/'</span>.<span style="color: #0000ff;">$lang</span>.<span style="color: #ff0000;">'/'</span>; <br />
<span style="color: #000000; font-weight: bold;">?&gt;</span><br />
&lt;a href=<span style="color: #ff0000;">&quot;&lt;?php echo preg_replace('#^/[a-z]{2}#', '/en', $URI); ?&gt;&quot;</span>&gt;&lt;img src=<span style="color: #ff0000;">&quot;/images/en.png&quot;</span> alt=<span style="color: #ff0000;">&quot;English&quot;</span> /&gt;&lt;/a&gt;  <br />
&nbsp;&lt;a href=<span style="color: #ff0000;">&quot;&lt;?php echo preg_replace('#^/[a-z]{2}#', '/fr', $URI); ?&gt;&quot;</span>&gt;&lt;img src=<span style="color: #ff0000;">&quot;/images/fr.png&quot;</span> alt=<span style="color: #ff0000;">&quot;Français&quot;</span> /&gt;&lt;/a&gt;  <br />
&lt;a href=<span style="color: #ff0000;">&quot;&lt;?php echo preg_replace('#^/[a-z]{2}#', '/it', $URI); ?&gt;&quot;</span>&gt;&lt;img src=<span style="color: #ff0000;">&quot;/images/it.png&quot;</span> alt=<span style="color: #ff0000;">&quot;Italiano&quot;</span> /&gt;&lt;/a&gt;<div style="display:none;">[code=php]&lt;?php <br />$URI = $_SERVER[&#39;REQUEST_URI&#39;]; <br />if($URI==&#39;/&#39;) $URI = &#39;/&#39;.$lang.&#39;/&#39;; <br />?&gt;<br />&lt;a href=&quot;&lt;?php echo preg_replace(&#39;#^/[a-z]{2}#&#39;, &#39;/en&#39;, $URI); ?&gt;&quot;&gt;&lt;img src=&quot;/images/en.png&quot; alt=&quot;English&quot; /&gt;&lt;/a&gt;&nbsp; <br /> &lt;a href=&quot;&lt;?php echo preg_replace(&#39;#^/[a-z]{2}#&#39;, &#39;/fr&#39;, $URI); ?&gt;&quot;&gt;&lt;img src=&quot;/images/fr.png&quot; alt=&quot;Fran&ccedil;ais&quot; /&gt;&lt;/a&gt;&nbsp; <br />&lt;a href=&quot;&lt;?php echo preg_replace(&#39;#^/[a-z]{2}#&#39;, &#39;/it&#39;, $URI); ?&gt;&quot;&gt;&lt;img src=&quot;/images/it.png&quot; alt=&quot;Italiano&quot; /&gt;&lt;/a&gt;[/code]</div></div><br />Vous trouverez plein de super ic&ocirc;nes de drapeaux <strong><a href="http://www.famfamfam.com/lab/icons/flags/">ici</a></strong>.<br /><br /></p><h4>Stockage des traductions</h4><p>On peut imaginer deux solutions de stockage pour les textes traduits. J&#39;ai retenu la deuxi&egrave;me :<br /></p><p><strong>1- Premi&egrave;re solution :</strong> Une fonction getText choisissant entre plusieurs textes propos&eacute;s. Par exemple<br /><div class="code"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<br />
<span style="color: #000000; font-weight: bold;">function</span> <a href="http://www.php.net/gettext"><span style="color: #000066;">getText</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$en</span>, <span style="color: #0000ff;">$fr</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
    <a href="http://www.php.net/global"><span style="color: #000066;">global</span></a> <span style="color: #0000ff;">$lang</span>;<br />
    <span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$lang</span>==<span style="color: #ff0000;">'fr'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">return</span> <span style="color: #0000ff;">$fr</span>;<br />
    <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">return</span> <span style="color: #0000ff;">$en</span>;<br />
<span style="color: #66cc66;">&#125;</span><br />
<br />
<span style="color: #808080; font-style: italic;">// Affichage d'un texte traduit :</span><br />
<a href="http://www.php.net/echo"><span style="color: #000066;">echo</span></a> <a href="http://www.php.net/gettext"><span style="color: #000066;">getText</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Text in english'</span>, <span style="color: #ff0000;">'Texte en français'</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span><div style="display:none;">[code=php]&lt;?php<br /><br />function getText($en, $fr){<br />&nbsp;&nbsp;&nbsp; global $lang;<br />&nbsp;&nbsp;&nbsp; if($lang==&#39;fr&#39;) return $fr;<br />&nbsp;&nbsp;&nbsp; else return $en;<br />}<br /><br />// Affichage d&#39;un texte traduit :<br />echo getText(&#39;Text in english&#39;, &#39;Texte en fran&ccedil;ais&#39;);<br />?&gt;[/code]</div></div><br />Ce n&#39;est pas tr&egrave;s pratique, et pas tr&egrave;s lisible d&egrave;s que les textes deviennent un peu gros et le nombre de langues grand.<br /><br /></p><p><strong>2- Deuxi&egrave;me solution :</strong> Le stockage des textes dans divers fichiers : un fichier par langue. L&#39;avantage ici est qu&#39;on peut traduire (ou faire traduire) le site en ajoutant simplement un seul fichier. Nous stockerons les fichiers <em>en.php</em>, <em>fr.php</em>, et <em>it.php</em> dans un dossiers <em>langs</em>. Il suffira d&#39;ajouter cette ligne apr&egrave;s la d&eacute;tection de la langue :<br /><div class="code"><span style="color: #b1b100;">require_once</span> <span style="color: #ff0000;">'langs/'</span>.<span style="color: #0000ff;">$lang</span>.<span style="color: #ff0000;">'.php'</span>;<div style="display:none;">[code=php]require_once &#39;langs/&#39;.$lang.&#39;.php&#39;;[/code]</div></div></p><p>Ensuite, nous avons encore le choix entre <strong>plusieurs m&eacute;thodes</strong> de stockage. Les deux principalement utilis&eacute;es consistent soit &agrave; cr&eacute;er une <strong>constante</strong> par texte, soit un grand <strong>tableau</strong> avec une entr&eacute;e par texte. La m&eacute;thode des constantes a l&#39;avantage d&#39;&ecirc;tre performante mais n&#39;est vraiment pas propre. Celle du tableau n&#39;est pas non plus des plus performantes. Je parle bien s&ucirc;r ici pour une grande &eacute;chelle : pr&eacute;voyons 15 000 entr&eacute;es pour voir r&eacute;ellement les diff&eacute;rences entre les m&eacute;thodes.</p><p>Je vais vous proposer une autre m&eacute;thode, une sorte de compromis, mais performante, pratique, et plus lisible. Elle consiste &agrave; utiliser une classe pour stocker les textes sous forme de constantes. Ces constantes restent dans la classe, c&#39;est donc propre, l&#39;acc&egrave;s y est tr&egrave;s facile, et les performances sont tr&egrave;s bonnes (j&#39;avais fait un benchmark il y a quelques mois, mais je ne l&#39;ai plus sous la main...). Nous allons donner un nom tr&egrave;s court &agrave; cette classe, par exemple &quot;_&quot;. Voici un exemple pour le fichier <em>fr.php</em>, il suffit ensuite de copier le fichier et de le traduire pour les autres langues :<br /><div class="code"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #808080; font-style: italic;">// Classe de stockage :</span><br />
final <span style="color: #000000; font-weight: bold;">class</span> <a href="http://www.php.net/_"><span style="color: #000066;">_</span></a> <span style="color: #66cc66;">&#123;</span><br />
    const TEXT1 = <span style="color: #ff0000;">'Mon premier texte en français'</span>;<br />
    const EXEMPLE = <span style="color: #ff0000;">'Ceci est un exemple'</span>;<br />
    const NUM = <span style="color: #ff0000;">'un, deux, trois'</span>;<br />
<span style="color: #66cc66;">&#125;</span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span><div style="display:none;">[code=php]&lt;?php<br />// Classe de stockage :<br />final class _ {<br />&nbsp;&nbsp;&nbsp; const TEXT1 = &#39;Mon premier texte en fran&ccedil;ais&#39;;<br />&nbsp;&nbsp;&nbsp; const EXEMPLE = &#39;Ceci est un exemple&#39;;<br />&nbsp;&nbsp;&nbsp; const NUM = &#39;un, deux, trois&#39;;<br />}<br />?&gt;[/code]</div></div></p><p>Puis pour afficher le texte :<br /><div class="code"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #808080; font-style: italic;">// Affichage du texte :</span><br />
<a href="http://www.php.net/echo"><span style="color: #000066;">echo</span></a> <a href="http://www.php.net/_"><span style="color: #000066;">_</span></a>::<span style="color: #006600;">TEXT1</span> . <span style="color: #ff0000;">'&lt;strong&gt;'</span>. <a href="http://www.php.net/_"><span style="color: #000066;">_</span></a>::<span style="color: #006600;">EXEMPLE</span> . <span style="color: #ff0000;">'&lt;/strong&gt;&lt;br /&gt;'</span>. <a href="http://www.php.net/_"><span style="color: #000066;">_</span></a>::<span style="color: #006600;">NUM</span>;<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span><div style="display:none;">[code=php]&lt;?php<br />// Affichage du texte :<br />echo _::TEXT1 . &#39;&lt;strong&gt;&#39;. _::EXEMPLE . &#39;&lt;/strong&gt;&lt;br /&gt;&#39;. _::NUM;<br />?&gt;[/code]</div></div><br /></p><p>&nbsp;</p><p>Et voil&agrave;, j&#39;esp&egrave;re que ce tuto pourra servir &agrave; quelqu&#39;un. Qu&#39;en pensez-vous ? Quelles solutions utilisez-vous ?<br /></p><br /><br /><div class="article_sharebtns"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fgodefroy.me%2Finternationalisation-d-un-site-web-a179180&amp;layout=button_count&amp;show_faces=false&amp;width=65&amp;action=like&amp;font&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:65px; height:21px;" allowTransparency="true"><br /></iframe><iframe allowtransparency="true" frameborder="0" scrolling="no" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fgodefroy.me%2Finternationalisation-d-un-site-web-a179180&amp;text=Internationalisation%20d%27un%20site%20web&amp;count=none" style="width: 55px; height: 20px;"></iframe><span><g:plusone size="medium" count="true" href="http://godefroy.me/internationalisation-d-un-site-web-a179180"></g:plusone></span></div><br /><hr />Article original rédigé par Godefroy et publié sur <a href="http://skreo.eklablog.com">Godefroy</a> <br /> Reproduction interdite sans autorisation]]></content:encoded>
		<pubDate>Wed, 09 Jul 2008 02:03:29 +0200</pubDate>
		<guid isPermaLink="true">http://godefroy.me/internationalisation-d-un-site-web-a179180</guid>
		<dc:creator>Godefroy</dc:creator>
		<dc:date>2008-07-09T02:03:29+02:00</dc:date>
	</item>
	<item>
		<title><![CDATA[Framework Mootools pour EklaBlog]]></title>
		<link>http://godefroy.me/framework-mootools-pour-eklablog-a81701</link>
		<description><![CDATA[J'ai d&eacute;cid&eacute; il y a un peu plus d'une semaine de refaire toute la partie javascript d'EklaBlog pour repartir sur une base solide. Jusqu'&agrave; maintenant, j'utilisais la librairie Tool-man qui n'avais pas &eacute;t&eacute; mise &agrave; jour depuis 2005... J'y avais apport&eacute; beaucoup de modifications, notamment pour...]]></description>
		<content:encoded><![CDATA[<img src="http://data0.eklablog.com/skreo/mod_article81701.jpg" width="200" alt="Framework Mootools pour EklaBlog" style="float: left; padding-right: 5px;" />J&#39;ai d&eacute;cid&eacute; il y a un peu plus d&#39;une semaine de refaire toute la partie javascript d&#39;EklaBlog pour repartir sur une base solide. Jusqu&#39;&agrave; maintenant, j&#39;utilisais la librairie Tool-man qui n&#39;avais pas &eacute;t&eacute; mise &agrave; jour depuis 2005... J&#39;y avais apport&eacute; beaucoup de modifications, notamment pour supporter des multi-listes triables (pour passer un &eacute;l&eacute;ment d&#39;une liste &agrave; une autre). A partir de maintenant, EklaBlog utlisera <a href="http://mootools.net">Mootools</a>, une framework fiable, mise &agrave; jour en permanence et relativement l&eacute;g&egrave;re.<br /><br /><br /><div class="article_sharebtns"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fgodefroy.me%2Fframework-mootools-pour-eklablog-a81701&amp;layout=button_count&amp;show_faces=false&amp;width=65&amp;action=like&amp;font&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:65px; height:21px;" allowTransparency="true"><br /></iframe><iframe allowtransparency="true" frameborder="0" scrolling="no" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fgodefroy.me%2Fframework-mootools-pour-eklablog-a81701&amp;text=Framework%20Mootools%20pour%20EklaBlog&amp;count=none" style="width: 55px; height: 20px;"></iframe><span><g:plusone size="medium" count="true" href="http://godefroy.me/framework-mootools-pour-eklablog-a81701"></g:plusone></span></div><br /><hr />Article original rédigé par Godefroy et publié sur <a href="http://skreo.eklablog.com">Godefroy</a> <br /> Reproduction interdite sans autorisation]]></content:encoded>
		<pubDate>Sun, 24 Feb 2008 17:43:44 +0100</pubDate>
		<guid isPermaLink="true">http://godefroy.me/framework-mootools-pour-eklablog-a81701</guid>
		<dc:creator>Godefroy</dc:creator>
		<dc:date>2008-02-24T17:43:44+01:00</dc:date>
	</item>
	<item>
		<title><![CDATA[WaSP café]]></title>
		<link>http://godefroy.me/wasp-cafe-a70367</link>
		<description><![CDATA[Ce soir j'&eacute;tais au WaSP caf&eacute; , un &eacute;v&eacute;nement ax&eacute; sur les standards du web, et donc l'accessibilit&eacute;, le javascript, et le css. Apr&egrave;s un court ap&eacute;ro au brownies, coca et jus de fruits, nous avons eu le droit &agrave; une pr&eacute;sentation par Tristan Nitot (Pr&eacute;sident de Mozilla Europe) de l'actualit&eacute;...]]></description>
		<content:encoded><![CDATA[<p>Ce soir j&#39;&eacute;tais au <a href="http://waspcafefrance.webstandards.org/">WaSP caf&eacute;</a> , un &eacute;v&eacute;nement ax&eacute; sur les standards du web, et donc l&#39;accessibilit&eacute;, le javascript, et le css.</p><p>Apr&egrave;s un court ap&eacute;ro au brownies, coca et jus de fruits, nous avons eu le droit &agrave; une pr&eacute;sentation par <a href="http://standblog.org/blog/">Tristan Nitot</a>  (Pr&eacute;sident de Mozilla Europe) de l&#39;actualit&eacute; des standards web, des navigateurs et de leurs enjeux. Il a parl&eacute; par exemple des plugins propri&eacute;taires visant &agrave; obliger progressivement les utilisateurs &agrave; migrer vers un OS pr&eacute;cis, comme pourrait le faire SilverLight.</p><p>Nous nous sommes ensuite s&eacute;par&eacute;s dans nos ateliers respectifs que nous avions choisis &agrave; notre inscription parmi &quot;Accessibilit&eacute;&quot;, &quot;Javascript&quot;, &quot;CSS&quot;. Pour ma part, j&#39;avais choisi Accessibilit&eacute;, mais ce n&#39;est pas exactement ce &agrave; quoi je m&#39;attendais. Je pensais plut&ocirc;t qu&#39;on allait aborder l&#39;aspect technique, avec les probl&egrave;mes que posent le javascript (Ajax...), les animations flash...etc. Mais le principal th&egrave;me abord&eacute; fut la mise en place de l&#39;application d&#39;une loi visant &agrave; rendre totalement accessible tous les sites de la fonction publique, notamment avec le <abbr title="R&eacute;f&eacute;rentiel G&eacute;n&eacute;ral d&#39;Accessibilit&eacute; des Administrations">RGAA</abbr> et <a href="http://www.accessiweb.org">AccessiWeb</a> .</p><p>A part &ccedil;a, j&#39;ai eu l&#39;occasion de rencontrer <a href="http://www.fairytells.net/">Aur&eacute;lien Levy</a> , Fr&eacute;d&eacute;ric Petit et K&eacute;vin Chanteclair. C&#39;&eacute;tait une soir&eacute;e bien sympathique, et je pense que j&#39;y retournerai la prochaine fois (dans 2 mois il parait).<br />Merci &agrave; toute l&#39;&eacute;quipe organisant le WaSP caf&eacute; <img alt=" " src="http://www.skreo.net/images/emoticons/wink2.gif" /></p><br /><br /><div class="article_sharebtns"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fgodefroy.me%2Fwasp-cafe-a70367&amp;layout=button_count&amp;show_faces=false&amp;width=65&amp;action=like&amp;font&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:65px; height:21px;" allowTransparency="true"><br /></iframe><iframe allowtransparency="true" frameborder="0" scrolling="no" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fgodefroy.me%2Fwasp-cafe-a70367&amp;text=WaSP%20caf%C3%A9&amp;count=none" style="width: 55px; height: 20px;"></iframe><span><g:plusone size="medium" count="true" href="http://godefroy.me/wasp-cafe-a70367"></g:plusone></span></div><br /><hr />Article original rédigé par Godefroy et publié sur <a href="http://skreo.eklablog.com">Godefroy</a> <br /> Reproduction interdite sans autorisation]]></content:encoded>
		<pubDate>Mon, 28 Jan 2008 23:55:43 +0100</pubDate>
		<guid isPermaLink="true">http://godefroy.me/wasp-cafe-a70367</guid>
		<dc:creator>Godefroy</dc:creator>
		<dc:date>2008-01-28T23:55:43+01:00</dc:date>
	</item>
	<item>
		<title><![CDATA[Classe de gestion de CSS]]></title>
		<link>http://godefroy.me/classe-de-gestion-de-css-a24198</link>
		<description><![CDATA[Je me suis lanc&eacute; hier matin (vers 15h ) dans le d&eacute;veloppement d'une classe de gestion de code CSS , &agrave; vrai dire sans m&ecirc;me avoir regard&eacute; sur internet si &ccedil;a existait d&eacute;j&agrave;. Apr&egrave;s quelques heures de programmation intensive, je me suis quand m&ecirc;me pos&eacute; la question et j'ai fait une petite...]]></description>
		<content:encoded><![CDATA[<img src="http://data0.eklablog.com/skreo/mod_article24198.png" width="48" alt="Classe de gestion de CSS" style="float: left; padding-right: 5px;" /><p>Je me suis lanc&eacute; hier matin (vers 15h <img alt=" " src="http://www.skreo.net/images/emoticons/he.gif" />) dans le d&eacute;veloppement d&#39;une classe de gestion de code <abbr title="Cascading Style Sheet">CSS</abbr>, &agrave; vrai dire sans m&ecirc;me avoir regard&eacute; sur internet si &ccedil;a existait d&eacute;j&agrave;. Apr&egrave;s quelques heures de programmation intensive, je me suis quand m&ecirc;me pos&eacute; la question et j&#39;ai fait une petite recherche sur Google. Je n&#39;ai pas trouv&eacute; exactement ce que je cherchais : tout ce que j&#39;ai trouv&eacute;, c&#39;est des classes php, certes bien cod&eacute;es, mais qui se contentent de parser le css, et de recr&eacute;er enti&egrave;rement le code &agrave; la fin des modification. <em>&quot;H&eacute; ben quoi t&#39;es pas content ?&quot;</em>, me direz-vous. Bah non ! Parce que je chipote encore, et <ins>moua</ins> je veux que la forme de mon CSS ne change pas du tout m&ecirc;me avec des modifications. Je veux que les commentaires restent en place, l&#39;ordre des &eacute;l&eacute;ments...etc.</p> <p><em>&quot;Et &agrave; quoi &ccedil;a servirait ??&quot;</em>, me demanderez-vous encore. Cette classe pourrait avoir plusieurs applications pour EklaBlog (mais elle peut &ecirc;tre utile pour d&#39;autres sites) : Le syst&egrave;me de th&egrave;mes personnalisables l&#39;utilisera, et elle me permettra de modifier facilement le CSS de tous les th&egrave;mes &agrave; la vol&eacute;e. Par exemple, si je veux modifier la couleur de fond de tous les blogs et ajouter un &eacute;l&eacute;ment parce que j&#39;ai rajout&eacute; un module,&nbsp; je peux faire un script qui ira chercher les fichiers CSS de tous les th&egrave;mes, modifiera la couleur de fond (propri&eacute;t&eacute; &quot;background-color&quot; de l&#39;&eacute;l&eacute;ment &quot;body&quot;), et ajoutera un &eacute;l&eacute;ment (par exemple &quot;machin {border: 1px solid dark;}&quot;)<br /> </p>     <p>J&#39;ai fini cette classe il y a 10 min, elle fait exactement tout ce que j&#39;ai dit pr&eacute;c&eacute;demment <img alt=" " src="http://www.skreo.net/images/emoticons/intello.gif" /> Et elle g&egrave;re tr&egrave;s bien les listes d&#39;&eacute;l&eacute;ments (par exemple : &quot;input, textarea:hover, select&quot;)<br />   Et comment elle marche ? Avec plein de masques <abbr title="Perl Compatible Regular Expression">PCRE</abbr> et des tableaux associatifs contenant les noms et positions des &eacute;l&eacute;ments (trouv&eacute;s par PCRE). Vive le PCRE !</p> <p>Par contre d&eacute;sol&eacute;, je ne donne pas la source de la classe, mais si elle vous int&eacute;resse, demandez la moi en postant un commentaire (sans oublier de mettre votre adresse e-mail), et je vous r&eacute;pondrai par mail <img alt=" " src="http://www.skreo.net/images/emoticons/wink2.gif" /> </p>  <br /><br /><div class="article_sharebtns"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fgodefroy.me%2Fclasse-de-gestion-de-css-a24198&amp;layout=button_count&amp;show_faces=false&amp;width=65&amp;action=like&amp;font&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:65px; height:21px;" allowTransparency="true"><br /></iframe><iframe allowtransparency="true" frameborder="0" scrolling="no" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fgodefroy.me%2Fclasse-de-gestion-de-css-a24198&amp;text=Classe%20de%20gestion%20de%20CSS&amp;count=none" style="width: 55px; height: 20px;"></iframe><span><g:plusone size="medium" count="true" href="http://godefroy.me/classe-de-gestion-de-css-a24198"></g:plusone></span></div><br /><hr />Article original rédigé par Godefroy et publié sur <a href="http://skreo.eklablog.com">Godefroy</a> <br /> Reproduction interdite sans autorisation]]></content:encoded>
		<pubDate>Fri, 20 Jul 2007 01:32:37 +0200</pubDate>
		<guid isPermaLink="true">http://godefroy.me/classe-de-gestion-de-css-a24198</guid>
		<dc:creator>Godefroy</dc:creator>
		<dc:date>2007-07-20T01:32:37+02:00</dc:date>
	</item>
</channel>
</rss><!--mdp=-->
