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

<channel>
	<title>./maxime.sh &#187; PHP</title>
	<atom:link href="http://maxime.sh/category/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://maxime.sh</link>
	<description>Le blog de Maxime VALETTE : Web, Vin, Littérature, Culture outrancière.</description>
	<lastBuildDate>Mon, 26 Jul 2010 07:23:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>L&#8217;infrastructure VDM : Memcache</title>
		<link>http://maxime.sh/2010/03/linfrastructure-vdm-memcache/</link>
		<comments>http://maxime.sh/2010/03/linfrastructure-vdm-memcache/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 19:44:50 +0000</pubDate>
		<dc:creator>Maxime</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[Ma vie]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://maxime.sh/?p=2661</guid>
		<description><![CDATA[La semaine dernière, je vous annonçais la création d&#8217;une suite d&#8217;articles concernant l&#8217;infrastructure de VDM. J&#8217;ai commencé en présentant mes serveurs MySQL. Récapitulatif : L’infrastructure que j’ai montée pour VDM/FML Dans cette série de billets (normalement trois en comptant celui là), je vais vous raconter ce qui se passe derrière les URL viedemerde.fr et fmylife.com, [...]]]></description>
			<content:encoded><![CDATA[<p>La semaine dernière, je vous annonçais la création d&#8217;une suite d&#8217;articles concernant l&#8217;infrastructure de VDM. J&#8217;ai commencé en présentant mes <a href="http://maxime.sh/2010/03/linfrastructure-vdm-mysql/" target="_blank">serveurs MySQL</a>. Récapitulatif :</p>
<p class="image"><a href="http://maxime.sh/wp-content/uploads/2010/03/betacie_network1.png" target="_blank"><img src="http://maxime.sh/wp-content/uploads/2010/03/betacie_network1-500.png" border="0" alt="betacie_network.png" /></a><br />
<em>L’infrastructure que j’ai montée pour VDM/FML</em></p>
<p>Dans cette série de billets (normalement trois en comptant celui là), je vais vous raconter ce qui se passe derrière les URL viedemerde.fr et fmylife.com, qui représentent 98% du trafic de l’infrastructure d’hébergement de ma société, Beta&amp;Cie. Ces articles n’ont pas pour vocation de me vanter ou de dire au monde entier que ma solution est la meilleure, c’est juste ma solution et elle marche bien jusqu’à maintenant.</p>
<p>Aujourd&#8217;hui, parlons de <strong>Memcache</strong>.</p>
<h2>Présentation de memcached</h2>
<p>Comme nous l&#8217;avons vu la semaine dernière, les serveurs de données sont bien remplis en données diverses et variées, que ce soit des votes, des anecdotes, les informations de connexion. Beaucoup de données, dont une partie est redondante. Mais pas la totalité de la page puisque chaque anecdote est votée, impossible donc de <em>cacher</em> toute la page.</p>
<p>Un <a href="http://memcached.org/" target="_blank">serveur memcached</a> (d pour daemon) est un serveur léger qui permet de stocker temporairement des données en RAM. Si léger qu&#8217;il ne dispose d&#8217;aucun système d&#8217;identification pour accéder ou modifier ces données, donc faites bien attention à ne faire écouter le serveur qu&#8217;en local si vous installez un jour une telle solution pour votre serveur.</p>
<h2>Son utilisation sur VDM</h2>
<p>La technologie memcached permet donc de stocker n&#8217;importe quel type de données. Il sert souvent par exemple sur des clusters de serveurs Web pour centraliser les sessions PHP. On peut donc facilement en tirer profit pour mettre en cache plusieurs informations du site, et ainsi soulager de manière significative les serveurs MySQL.</p>
<p class="image border"><a href="http://maxime.sh/wp-content/uploads/2010/03/memcache.png" target="_blank"><img src="http://maxime.sh/wp-content/uploads/2010/03/memcache.png" border="0" alt="memcache.png" /></a><br />
<em>One server to rule them all.</em></p>
<p>La problématique est maintenant la mise en place de cette solution sur le code PHP existant de VDM. PHP possède une <a href="http://php.net/manual/en/ref.memcache.php" target="_blank">extension Memcache</a> qui permet d&#8217;implémenter facilement une solution de cache.</p>
<p>La solution que j&#8217;ai retenue est résumée dans le code suivant. Les requêtes SQL sont transformées en hash MD5 pour le nom de la clé, et l&#8217;objet du résultat de la requête est stockée en cache, avec un cache par défaut d&#8217;une heure (3600 secondes). De cette manière, si la clé n&#8217;existe pas sur le serveur memcached, la requête est automatiquement exécutée et le résultat stocké.</p>
<pre class="brush: php;">&lt;?php

$memcache = new Memcache();
$memcache-&gt;pconnect(&quot;127.0.0.1&quot;,&quot;9000&quot;);

function mcache($query,$timeout=3600,$force=false) {

	global $memcache;

	$hash = md5($query);

	if (!$force) {

		$value = $memcache-&gt;get($hash);

	}

	if ($force || $value === FALSE) {

		$result = mysql_query($query);
		$value = mysql_fetch_object($result);
		$memcache-&gt;set($hash,$value,NULL,$timeout);

	}

	return $value;

}

function mcache_set($query,$value,$timeout=3600) {

	global $memcache;

	$hash = md5($query);

	$value = $memcache-&gt;set($hash,$value,NULL,$timeout);

	return $value;

}

function mcache_delete($query) {

	global $memcache;

	$hash = md5($query);
	$value = $memcache-&gt;delete($hash);

	return $value;

}

?&gt;</pre>
<p>Grâce à ces fonctions nous avons conservé toutes nos requêtes, et pouvons utiliser de manière transparente soit Memcache soit MySQL. Plus pratique pour pouvoir synchroniser rapidement les données entre les deux serveurs, en plus d&#8217;avoir facilité la migration vers Memcache.</p>
<p>Exemple d&#8217;utilisation :</p>
<pre class="brush: php;">&lt;?php

/* Je suis un nul alors je mets pas de mot de passe en root */
mysql_connect(&quot;localhost&quot;,&quot;root&quot;,&quot;&quot;);
mysql_select_db(&quot;base&quot;);

/* La requête MySQL normale sans cache */
$result = mysql_query(&quot;SELECT texte FROM articles WHERE id = '1337' LIMIT 1&quot;);
$row = mysql_fetch_object($result);

/* La requête avec le cache Memcache */
$row = mcache(&quot;SELECT texte FROM articles WHERE id = '1337' LIMIT 1&quot;);

?&gt;</pre>
<p>Grâce aux fonctions <span class="code">mcache()</span> et consorts, on peut donc sans trop de difficultés alléger le travail des serveurs de bases de données. Si vous avez besoin de mettre en cache un tableau de résultats, vous pouvez utiliser la fonction suivante :</p>
<pre class="brush: php;">&lt;?php

function mcache_array($query,$timeout=3600,$force=false) {

	global $memcache;

	$hash = md5($query);

	if (!$force) {

		$value = $memcache-&gt;get($hash);

	}

	if ($force || $value === FALSE) {

		$memcache-&gt;delete($hash);

		$result = mysql_query($query);
		while ($row = mysql_fetch_object($result)) {
			$value[] = $row;
		}

		$memcache-&gt;set($hash,$value,NULL,$timeout);

	}

	if (!is_array($value)) $value = array();
	return $value;

}

?&gt;</pre>
<p>Ainsi, sur VDM et FML, nous mettons en cache principalement les données suivantes :</p>
<ul>
<li>Les données &laquo;&nbsp;statiques&nbsp;&raquo; des anecdotes (texte, auteur, etc.)</li>
<li>Les totaux des votes sur les anecdotes (mis à jour à chaque vote sans appel à MySQL)</li>
<li>Les ID des dernières anecdotes lues par les utilisateurs, pour afficher les &laquo;&nbsp;NEW&nbsp;&raquo;</li>
<li>Certains rendus XML de l&#8217;API pour les applications mobiles</li>
</ul>
<p>Au niveau des chiffres, voici des statistiques sur les 3 dernières semaines d&#8217;utilisation du serveur memcached :</p>
<ul>
<li>900 connexions simultanées en permanence</li>
<li>90 000 connexions par jour</li>
<li>14,4 Mo écrits par seconde (via 622 requêtes en moyenne)</li>
<li>1,8 Go de données stockées en ce moment</li>
<li>6,9 millions de données stockées en ce moment</li>
<li>1,3 milliard de données stockées en tout</li>
</ul>
<p>Comme d&#8217;habitude, n&#8217;hésitez pas à commenter pour plus d&#8217;informations, j&#8217;ai sûrement oublié beaucoup de choses. La semaine prochaine nous parlerons de serveurs Web.</p>
]]></content:encoded>
			<wfw:commentRss>http://maxime.sh/2010/03/linfrastructure-vdm-memcache/feed/</wfw:commentRss>
		<slash:comments>75</slash:comments>
		</item>
		<item>
		<title>L&#8217;infrastructure VDM : MySQL</title>
		<link>http://maxime.sh/2010/03/linfrastructure-vdm-mysql/</link>
		<comments>http://maxime.sh/2010/03/linfrastructure-vdm-mysql/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 16:35:14 +0000</pubDate>
		<dc:creator>Maxime</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[Ma vie]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://maxime.sh/?p=2500</guid>
		<description><![CDATA[Depuis des mois je promets une série d&#8217;articles qui ne va peut-être pas intéresser grand monde, mais qui aura le mérite d&#8217;exister et de soulager ma conscience (ma mère m&#8217;a dit que ce n&#8217;était pas joli de ne pas tenir ses promesses). Contrairement à ce que certains laissent penser, je fais quelque chose de mes [...]]]></description>
			<content:encoded><![CDATA[<p>Depuis des mois je promets une série d&#8217;articles qui ne va peut-être pas intéresser grand monde, mais qui aura le mérite d&#8217;exister et de soulager ma conscience (ma mère m&#8217;a dit que ce n&#8217;était pas joli de ne pas tenir ses promesses).</p>
<p>Contrairement à ce que certains laissent penser, je fais quelque chose de mes journées. Je suis développeur Web, mais aussi administrateur système. Créer puis s&#8217;occuper de l&#8217;hébergement de sites comme VDM et FML n&#8217;arrive pas tous les jours, et j&#8217;ai gagné beaucoup d&#8217;expérience ces 12 derniers mois en montant une infrastructure qui accueille chaque jour <em>plus de 3 millions de visiteurs</em>.</p>
<p class="image"><a href="http://maxime.sh/wp-content/uploads/2010/03/betacie_network.png" target="_blank"><img src="http://maxime.sh/wp-content/uploads/2010/03/betacie_network-500.png" alt="betacie_network.png" border="0" /></a><br /><em>L&#8217;infrastructure que j&#8217;ai montée pour VDM/FML</em></p>
<p>Dans cette série de billets (normalement trois en comptant celui là), je vais vous raconter ce qui se passe derrière les URL viedemerde.fr et fmylife.com, qui représentent 98% du trafic de l&#8217;infrastructure d&#8217;hébergement de ma société, Beta&#038;Cie. Ces articles n&#8217;ont pas pour vocation de me vanter ou de dire au monde entier que ma solution est la meilleure, c&#8217;est juste ma solution et elle marche bien jusqu&#8217;à maintenant.</p>
<p>Passons au premier sujet : <strong>Les serveurs MySQL</strong>.</p>
<h2>Réplication circulaire</h2>
<p class="image border"><a href="http://maxime.sh/wp-content/uploads/2010/03/tv8n.png" target="_blank"><img src="http://maxime.sh/wp-content/uploads/2010/03/tv8n-500.png" alt="tv8n.png" border="0" /></a><br /><em>Mes sept petits bouts de chou.</em></p>
<p>Comme le montre le schéma, mes sept serveurs sont configurés en réplication circulaire. C&#8217;est à dire que chacun est maître et esclave à la fois (pas de connotations sexuelles ici, merci !). s1 est donc maître sur s2, mais il est esclave de s7.</p>
<p>Cette configuration a l&#8217;avantage de bien fonctionner derrière un <em>load balancer</em> puisque chaque serveur a le droit d&#8217;écriture. C&#8217;est donc transparent pour le développeur qui n&#8217;a qu&#8217;à renseigner l&#8217;IP du load balancer dans sa connexion à MySQL et travailler comme s&#8217;il n&#8217;avait qu&#8217;un seul serveur.</p>
<p>L&#8217;inconvénient est un inconvénient de taille. Comme les requêtes s&#8217;exécutent comme dans une ronde, si un serveur plante, toute la ronde est cassée et plus rien ne se réplique. Il faut donc avoir du bon matériel, et au cas où ça arrive quand même, <a href="http://maxime.sh/2009/12/le-monitoring-cette-belle-activite/" target="_blank">agir très vite</a> pour éviter que les utilisateurs ne râlent :)</p>
<p>Une petite astuce pour éviter que votre réplication ne s&#8217;arrête pour des raisons connes : Je fais ignorer par mes serveurs systématiquement les erreurs 1062 (nouvelle entrée avec le même ID) et 1053 (déclenchée quand le serveur maître s&#8217;éteint ou redémarre) :</p>
<pre class="brush: plain;">slave-skip-errors=1062,1053</pre>
<p>Pour diminuer les latences de réplication il est aussi important d&#8217;avoir un bon réseau&#8230;</p>
<h2>Réseau VLAN</h2>
<p>Au delà de l&#8217;onomatopée, un VLAN est l&#8217;abréviation de Réseau Local Virtuel (RLV ça le faisait pas, hein ?). Il permet de créer un réseau indépendant du reste des machines du réseau où est hébergée l&#8217;infrastructure. Concrètement chaque serveur possède deux interfaces physiques :</p>
<pre class="brush: bash;"># ifconfig
eth0      Link encap:Ethernet  HWaddr 00:30:48:b9:42:e2
          inet addr:91.191.146.199  Bcast:91.191.146.255  Mask:255.255.255.192

eth1      Link encap:Ethernet  HWaddr 00:30:48:b9:42:e3
          inet addr:10.191.146.199  Bcast:10.191.146.255  Mask:255.255.255.0</pre>
<p>eth0 a l&#8217;adresse IP 91.191.146.199 qui est atteignable de l&#8217;extérieur du réseau, alors que eth1 a l&#8217;adresse IP 10.191.146.199 qui est interne au VLAN et qui par conséquent ne peut communiquer qu&#8217;avec ses copines du même VLAN qu&#8217;elle.</p>
<p>Avoir ses serveurs en VLAN diminue donc la latence entre les serveurs, la réplication se fait plus rapidement et avec plus de sécurité puisqu&#8217;aucun paquet ne sort de votre réseau local. Deux avantages indéniables qui devraient vous faire <s>quitter OVH</s> choisir un hébergeur qui fait du VLAN ! En effet les réseaux virtuels se configurent au niveau des routeurs/switches, il faut donc choisir un hébergeur qui puisse le prendre en charge.</p>
<h2>Disques SSD</h2>
<p>Pour économiser un certain nombre de machines dans ma réplication circulaire et ainsi réduire le nombre de défaillances matérielles, j&#8217;ai très vite décidé d&#8217;utiliser du SSD pour héberger les données de mes bases. Au début j&#8217;ai eu des X25-M chez OVH (mon ancien hébergeur), qui est le moyen de gamme du SSD, puis je suis passé récemment au X25-E, la version haut de gamme, comme le montre ce <a href="http://www.sd-france.com/news-200908/24/disques-ssd-intel-x25-e.html" target="_blank">benchmark par SD-France</a>, mon gentil hébergeur :</p>
<p class="image"><a href="http://maxime.sh/wp-content/uploads/2010/03/20090824-test-ssd-graph-ecriture.gif" target="_blank"><img src="http://maxime.sh/wp-content/uploads/2010/03/20090824-test-ssd-graph-ecriture.gif" alt="20090824-test-ssd-graph-ecriture.gif" border="0" /></a></p>
<p>Le X25-E dépasse largement tous ses concurrents en terme d&#8217;écriture et de lecture de disque. Cela assure évidemment un meilleur temps de réponse sur les requêtes, différence qui se ressent lorsque l&#8217;on traite <strong>15 000 requêtes par seconde</strong>&#8230;</p>
<p>Les deux inconvénients de cette méthode :</p>
<ul>
<li>La capacité. La plus grande taille disponible est 64 Go, ce qui peut paraître beaucoup pour de simples bases de données, mais qui se remplit vite quand le site repose sur beaucoup d&#8217;anecdotes / commentaires et surtout votes.</li>
<li>Le prix. Les disques SSD X25-E sont encore très chers, même s&#8217;ils économisent parfois de nouvelles machines, je me fais taper quand j&#8217;en demande des nouveaux :D</li>
</ul>
<h2>Optimisations</h2>
<p>Comme le disque SSD est déjà pas mal occupé à traiter les requêtes SQL, la copie des résultats de SELECT sur les bases temporaires dans <span class="code">/tmp</span> (configuration par défaut) est fortement ralentie. En parallèle la RAM n&#8217;est en général pas utilisée à fond. Il est donc judicieux d&#8217;utiliser la RAM restante comme espace pour les fichiers temporaires, grâce au système de fichier <em>tmpfs</em> :</p>
<pre class="brush: bash;">mkdir /tmpfs
mount tmpfs /tmpfs -t tmpfs</pre>
<p>Vérifiez que votre nouveau répertoire fonctionne correctement, puis modifiez la configuration de votre <span class="code">my.cnf</span> pour la valeur suivante :</p>
<pre class="brush: plain;">tmpdir = /tmpfs</pre>
<p>Ne pas oublier de rajouter le montage du tmpfs dans votre <span class="code">/etc/fstab</span>, pour éviter les problèmes au reboot :)</p>
<p>Avec tout ceci, nous arrivons à traiter <em>vaguement</em> ces quelques données :</p>
<ul>
<li>2 millions d&#8217;anecdotes, 8000 nouvelles par jour</li>
<li>1,7 million de commentaires, 5000 nouveaux par jour</li>
<li><strong>630 millions de votes</strong>, 850 000 nouveaux par jour</li>
</ul>
<p>Voilà mes petits pandas, je pense avoir couvert pas mal des aspects principaux &laquo;&nbsp;caractéristiques&nbsp;&raquo; de l&#8217;infrastructure au niveau de MySQL. Mais j&#8217;ai sûrement oublié beaucoup de choses, alors n&#8217;hésitez pas si vous avez des questions.</p>
<p>Pas de date pour le prochain article mais j&#8217;espère la semaine prochaine.</p>
]]></content:encoded>
			<wfw:commentRss>http://maxime.sh/2010/03/linfrastructure-vdm-mysql/feed/</wfw:commentRss>
		<slash:comments>83</slash:comments>
		</item>
		<item>
		<title>HipHop : L&#8217;histoire d&#8217;un mal nécessaire</title>
		<link>http://maxime.sh/2010/02/hiphop-lhistoire-dun-mal-necessaire/</link>
		<comments>http://maxime.sh/2010/02/hiphop-lhistoire-dun-mal-necessaire/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 08:03:00 +0000</pubDate>
		<dc:creator>Maxime</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://maxime.sh/?p=2122</guid>
		<description><![CDATA[Il y a quelques heures a eu lieu une conférence Facebook très attendue par la communauté de développeurs Web tels que votre serviteur. Facebook a annoncé un projet sur lequel 6 personnes travaillent en secret depuis deux ans. Cela s&#8217;appelle HipHop for PHP, et c&#8217;est un projet open-source visant à transformer du langage PHP en [...]]]></description>
			<content:encoded><![CDATA[<p>Il y a quelques heures a eu lieu une conférence Facebook très attendue par la communauté de développeurs Web tels que votre serviteur. Facebook <a href="http://www.ustream.tv/recorded/4409735" target="_blank">a annoncé</a> un projet sur lequel 6 personnes travaillent en secret depuis deux ans. Cela s&#8217;appelle <a href="http://developers.facebook.com/hiphop-php/" target="_blank">HipHop for PHP</a>, et c&#8217;est un projet open-source visant à transformer du langage PHP en langage C++, afin de le compiler pour atteindre un niveau plus bas dans l&#8217;interprétation et accélérer le calcul de ses nombreuses pages dynamiques.</p>
<p class="image"><a href="http://maxime.sh/wp-content/uploads/2010/02/HipHop_logo_white.png" target="_blank"><img src="http://maxime.sh/wp-content/uploads/2010/02/HipHop_logo_white.png" alt="HipHop_logo_white.png" border="0" /></a></p>
<p>C&#8217;est un travail gigantesque qui a été accompli par cette équipe de Facebook. Même si dans l&#8217;absolu peu de gens en auront réellement besoin pour leurs sites PHP ; la plupart du temps l&#8217;exécution des scripts en eux-même est assez rapide depuis PHP 4 et son Zend Engine. Même pour WordPress, ce qui ralentit l&#8217;affichage relève en général des requêtes à la base de données ou du serveur Web (HipHop n&#8217;utilise pas Apache, Facebook l&#8217;utilisait auparavant), puisque très peu de sites peuvent se targuer d&#8217;avoir comme Facebook des pages qui sont uniques pour <em>chaque utilisateur</em>.</p>
<p>Un autre indicateur qui montre que le développeur PHP lambda n&#8217;utilisera jamais HipHop réside dans son incompréhension complète de l&#8217;utilité voire même de la définition d&#8217;HipHop en elle-même&#8230; Morceaux choisis, pour le fun :</p>
<blockquote class="quote"><p>&laquo;&nbsp;I think the HipHop compiler should be great for WordPress users.&nbsp;&raquo; &mdash; <a href="http://twitter.com/patrickmusgrave" target="_blank">Patrick Musgrave</a></p>
</blockquote>
<p>Le script WordPress en lui-même utilise beaucoup la fonction eval(), qui a été explicitement sacrifiée par HipHop. Impossible donc.</p>
<blockquote class="quote"><p>&laquo;&nbsp;il semblerait que Facebook se soit amusé à reécrire tout ou une bonne partie de PHP. [...] un compilateur de PHP ne serait pas une idée si farfelue que ça…&nbsp;&raquo; &mdash; <a href="http://www.korben.info/facebook-va-probablement-sortir-un-compilateur-php.html" target="_blank">Korben.info</a></p>
</blockquote>
<p>Deux billets associant &laquo;&nbsp;Facebook&nbsp;&raquo; avec le terme &laquo;&nbsp;compilateur PHP&nbsp;&raquo;. Cela n&#8217;a rien d&#8217;un compilateur PHP, il en existe déjà plusieurs depuis des années, le plus connu étant <a href="http://www.phpcompiler.org/" target="_blank">phc</a>. C&#8217;est dommage qu&#8217;un blog qui se veut vulgarisateur emploie des termes erronés à longueur de journée.</p>
<blockquote class="quote"><p>&laquo;&nbsp;@Korben: hum, je me disais surtout que vu que Java est plus proche de C++ que Php, pourquoi il n’ont pas écrit Facebook en Java directement. Enfin je me trompe peut-être.&nbsp;&raquo; &mdash; <a href="http://www.tux-planet.fr/" target="_blank">Tux-planet</a></p>
</blockquote>
<p>Tu te trompes effectivement. En réfléchissant une minute il paraît évident que Facebook ne peut se permettre de re-coder tout son site, d&#8217;autant qu&#8217;un bon développeur Java se trouve plus difficilement qu&#8217;un bon développeur PHP.</p>
<p class="image border"><a href="http://maxime.sh/wp-content/uploads/2010/02/08_05_php_vikinger_elephpant.jpg" target="_blank"><img src="http://maxime.sh/wp-content/uploads/2010/02/08_05_php_vikinger_elephpant-500.jpg" alt="08_05_php_vikinger_elephpant.jpg" border="0" /></a><br /><em>Pour ceux qui se posent la question : Oui j&#8217;en ai un chez moi &lt;3</em></p>
<blockquote class="quote"><p>&laquo;&nbsp;mais si on code avec un framework genre cakePHP, est-ce que l’on va pouvoir quand même le compiler ?&nbsp;&raquo; &mdash; crevette d&#8217;@cier</p>
</blockquote>
<p>Faux problème : Avant d&#8217;en arriver au stade d&#8217;avoir besoin de compiler du PHP transformé en C++, il faudrait déjà penser à s&#8217;affranchir de son framework qui ne peut que ralentir l&#8217;exécution de son site.</p>
<blockquote class="quote"><p>&laquo;&nbsp;There’s this distinction in coding between a scripted language and a compiled language. PHP is an example of a scripted language. The computer or browser reads the program like a script, from top to bottom, and executes it in that order: anything you declare at the bottom cannot be referenced at the top.&nbsp;&raquo; &mdash; <a href="http://therumpus.net/2010/01/conversations-about-the-internet-5-anonymous-facebook-employee/?full=yes" target="_blank">Une employée de Facebook</a></p>
</blockquote>
<p>Je ne sais pas où l&#8217;auteur a récupéré cette employée de Facebook, mais je parie qu&#8217;elle s&#8217;occupe de la cantine, de la salle Guitar Hero, ou alors du ménage ; en tout cas elle ne peut pas avoir un lien avec les développeurs pour déclarer que PHP est un langage one-pass. Qu&#8217;elle demande à ses collègues, ou qu&#8217;elle se taise !</p>
<blockquote class="quote"><p>&laquo;&nbsp;Cela me parait étonnant tout de meme, je vois mal des .exe tourné pour une site web, http://truk.com/hu.exe?var=prout ??? loool&nbsp;&raquo; &mdash; krg</p>
</blockquote>
<p>J&#8217;ai gardé le meilleur pour la fin&#8230; :) Ça se passe de commentaire. A noter que deux lignes plus loin, krg nous dit qu&#8217;il est un hacker. Au moins il ne se fera pas bloquer chez Korben.</p>
<p>Pour en revenir au titre de cet article, les gens qui me connaissent un petit peu savent que je n&#8217;ai pas Facebook en particulière adoration, je pense même que plus ça va et plus ça se transforme en un Skyblog mondialisé. Mais tout comme Facebook, Skyblog participe <em>activement</em> à la communauté open-source. Si leurs projets ne sont pas mis en avant de la même manière médiatique, Frank Denis fournit un <a href="http://www.pureftpd.org/project/pure-ftpd" target="_blank">travail remarquable</a> pour la communauté PHP et open-source depuis des années.</p>
<p class="image"><a href="http://maxime.sh/wp-content/uploads/2010/02/pure-ftpd.png" target="_blank"><img src="http://maxime.sh/wp-content/uploads/2010/02/pure-ftpd.png" alt="pure-ftpd.png" border="0" /></a></p>
<p>Evidemment, tout comme HipHop, dans l&#8217;absolu ça ne servira qu&#8217;à peu de gens, mais allez dire à un administrateur système que sans Skyblog, son serveur FTP n&#8217;existerait pas, et qu&#8217;il aurait sûrement plus de mal à faire <a href="http://skycache.pureftpd.org/project/skycache" target="_blank">du cache Web</a> efficace, et il va vous rire au nez :) Et peut-être vous frapper. Donc ne le faites pas.</p>
<p>HipHop for PHP sera disponible <a href="http://github.com/facebook/hiphop-php" target="_blank">sur GitHub</a> dans les heures qui viennent.</p>
]]></content:encoded>
			<wfw:commentRss>http://maxime.sh/2010/02/hiphop-lhistoire-dun-mal-necessaire/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Génération de miniatures iPhone à la volée</title>
		<link>http://maxime.sh/2009/12/generation-de-miniatures-iphone-a-la-volee/</link>
		<comments>http://maxime.sh/2009/12/generation-de-miniatures-iphone-a-la-volee/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 00:13:29 +0000</pubDate>
		<dc:creator>Maxime</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://maxime.sh/?p=736</guid>
		<description><![CDATA[Pour mes derniers articles j&#8217;ai eu besoin d&#8217;afficher des captures d&#8217;écran issues de mon iPhone. Mais comme je ne pouvais rien faire simplement, je n&#8217;allais tout de même pas ouvrir Photoshop pour créer des miniatures ! Rendons à la machine ce qui est à la machine. Afin de créer vous aussi vos miniatures iPhone, vous [...]]]></description>
			<content:encoded><![CDATA[<p>Pour mes derniers articles j&#8217;ai eu besoin d&#8217;afficher des captures d&#8217;écran issues de mon iPhone. Mais comme je ne pouvais rien faire simplement, je n&#8217;allais tout de même pas ouvrir Photoshop pour créer des miniatures ! Rendons à la machine ce qui est à la machine.</p>
<p>Afin de créer vous aussi vos miniatures iPhone, vous aurez besoin de remplir les conditions suivantes :</p>
<ul>
<li>Posséder un blog WordPress (sans déc&#8217; ?)</li>
<li>Avoir la librairie PHP Imagick</li>
<li>Disposer d&#8217;un accès FTP sur votre blog</li>
</ul>
<p>J&#8217;ai commencé par récupérer une image d&#8217;iPhone &laquo;&nbsp;vide&nbsp;&raquo;, que j&#8217;ai réduite de moitié pour adapter à la taille de mon blog. Vous pouvez récupérer l&#8217;image en cliquant ci-dessous. Elle est à mettre dans le dossier /wp-vcon :</p>
<p class="image"><a href="http://maxime.sh/wp-content/uploads/iphone-gui.png"><img src="http://maxime.sh/wp-content/uploads/iphone-gui.png" /></a></p>
<p>La technique que j&#8217;ai adoptée pour la génération d&#8217;images à la volée est de passer par un fichier .htaccess dans /wp-content/uploads. Il sert à rediriger toutes les requêtes vers des fichiers inexistants sur un script spécifique, en l&#8217;occurrence le script pour les miniatures :</p>
<pre class="brush: plain;">Options -Indexes

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^(.*)$ /wp-content/uploads/check.php?route=$1 [L,QSA]</pre>
<p>L&#8217;image à l&#8217;intérieur de l&#8217;iPhone est la moitié d&#8217;une capture d&#8217;écran faite via l&#8217;iPhone (en appuyant simultanément sur la touche Home et la touche Power). </p>
<pre class="brush: php;">&lt;?php

$destination = $_GET['route'];

if (eregi(&quot;^(.+)-iphone\.(.+)$&quot;,$destination,$r)) {

	header(&quot;Content-type: image/&quot;.$r[2]);

	$original = $r[1].&quot;.&quot;.$r[2];

	if (file_exists($original)) {

		$or = new Imagick($original);
		$or-&gt;setCompression(Imagick::FILTER_LANCZOS);
		$or-&gt;ThumbnailImage(160,240,true);

		$im = new Imagick(dirname(__FILE__).'/iphone-gui.png');
		$im-&gt;compositeImage($or,Imagick::COMPOSITE_DEFAULT,18,60);

		$im-&gt;writeImage($destination);

		echo file_get_contents($destination);

	}

}

header(&quot;HTTP/1.0 404 Not Found&quot;); 

?&gt;</pre>
<p>Exemple concret après installation du script : Si vous avez uploadé une image nommée <em>application.png</em>, il vous suffit de rajouter &laquo;&nbsp;-iphone&nbsp;&raquo; juste avant l&#8217;extension du fichier pour avoir un aperçu iPhone, ce qui donnera <em>application-iphone.png</em>.</p>
<p>Et voilà, grâce à ces quelques fichiers, ma flemme d&#8217;ouvrir Photoshop pour avoir de jolies miniatures est entièrement comblée, j&#8217;espère que ça pourra servir à quelques personnes. Le script est très facilement adaptable sur d&#8217;autres plate-formes que WordPress, j&#8217;ai donné cette intégration pour l&#8217;exemple.</p>
]]></content:encoded>
			<wfw:commentRss>http://maxime.sh/2009/12/generation-de-miniatures-iphone-a-la-volee/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>
