<?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>Développement Web Libre</title>
	<atom:link href="http://www.sbnet.fr/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.sbnet.fr</link>
	<description>xhtml, css, javascript, php et ruby</description>
	<lastBuildDate>Fri, 03 Feb 2012 11:44:49 +0000</lastBuildDate>
	<language>fr</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Chronique d&#8217;un développeur</title>
		<link>http://www.sbnet.fr/2012/02/03/chronique-dun-developpeur/</link>
		<comments>http://www.sbnet.fr/2012/02/03/chronique-dun-developpeur/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 11:44:49 +0000</pubDate>
		<dc:creator>Stéphane</dc:creator>
				<category><![CDATA[Informatique]]></category>
		<category><![CDATA[chronique]]></category>
		<category><![CDATA[developpement]]></category>
		<category><![CDATA[seo]]></category>

		<guid isPermaLink="false">http://www.sbnet.fr/?p=264</guid>
		<description><![CDATA[Je profite de ce billet pour lancer ma petite chronique de la semaine passée. Je vous présenterai ici, tous les vendredi un récapitulatif des faits et liens qui ont retenus mon attention. Développement Une mise a jour de PHP 5.3 est disponible dès aujourd&#8217;hui, elle corrige une faille de sécurité critique. Crypter des données avec [...]]]></description>
			<content:encoded><![CDATA[<p>Je profite de ce billet pour lancer ma petite chronique de la semaine passée. Je vous présenterai ici, tous les vendredi un récapitulatif des faits et liens qui ont retenus mon attention.</p>
<h3>Développement</h3>
<ul>
<li><a title="Mise a jour de php 5.3" href="http://www.php.net/index.php#id2012-02-02-1" target="_blank">Une mise a jour de PHP 5.3</a> est disponible dès aujourd&#8217;hui, elle corrige une faille de sécurité critique.</li>
<li>Crypter des données avec une clé Privée/Publique en php : <a href="http://www.joeldare.com/wiki/php:php_public_private_key_cryptography" target="_blank">www.joeldare.com/wiki/php:php_public_private_key_cryptography</a></li>
<li>Refaire la timeline de Facebook en js+css, tout est expliqué pas à pas ici  : <a href="http://www.9lessons.info/2012/01/facebook-timeline-design-using-jquery.html" target="_blank">www.9lessons.info/2012/01/facebook-timeline-design-using-jquery.html</a></li>
</ul>
<h3>SEO</h3>
<ul>
<li>Le pagerank est-il vraiment utile pour le positionnement ? <a href="http://www.lemarketingenligne.com/non-classe/dites-adieu-au-pagerank/" target="_blank">www.lemarketingenligne.com/non-classe/dites-adieu-au-pagerank</a></li>
<li>Deux logiciels de spinning gratuits : <a href="http://www.effi10.com/seo-referencement/logiciel-spinning-gratuit" target="_blank">www.effi10.com/seo-referencement/logiciel-spinning-gratuit</a> et <a href="http://lab.webimago.fr/web-imago-spin" target="_blank">lab.webimago.fr/web-imago-spin</a></li>
</ul>
<p>Voila, une petite chronique, il n&#8217;y a pas grand chose mais c&#8217;est volontaire je ne souhaite y mettre que ce qui m&#8217;a réellement marqué.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sbnet.fr/2012/02/03/chronique-dun-developpeur/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Traitements parallèles grâce a Gearman</title>
		<link>http://www.sbnet.fr/2011/06/30/traitements-paralleles-grace-a-gearman/</link>
		<comments>http://www.sbnet.fr/2011/06/30/traitements-paralleles-grace-a-gearman/#comments</comments>
		<pubDate>Thu, 30 Jun 2011 17:47:51 +0000</pubDate>
		<dc:creator>Stéphane</dc:creator>
				<category><![CDATA[Informatique]]></category>
		<category><![CDATA[gearman]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.sbnet.fr/?p=168</guid>
		<description><![CDATA[Je me suis déjà frotté au multitâche avec PHP, et il faut dire, avec un certain recul et pas mal de temps de tests, que je suis plutot déçu par la stabilité du système mis en place. J&#8217;avais développé ça sur une base de forks de process. Ça marchait bien jusqu&#8217;à un certain point, lorsque [...]]]></description>
			<content:encoded><![CDATA[<p>Je me suis déjà frotté au <a title="PHP fait du multitâche" href="http://www.sbnet.fr/2010/02/26/php-fait-du-multitache/">multitâche avec PHP</a>, et il faut dire, avec un certain recul et pas mal de temps de tests, que je suis plutot déçu par la stabilité du système mis en place. J&#8217;avais développé ça sur une base de forks de process. Ça marchait bien jusqu&#8217;à un certain point, lorsque le serveur était un peu chargé (à peine plus que d&#8217;habitude) certain de mes process plantaient aléatoirement, jamais le même process. Peut-être que j&#8217;abusais un peu, mais bon j&#8217;en ai besoin de mes 200 process moi.</p>
<p>Dans ma quête de stabilité, je me suis dit qu&#8217;utiliser <a title="Gearman" href="http://gearman.org/">Gearman</a> serait une bonne idée, il est censé être simple, scalable, stable, et tout et tout.</p>
<p><span id="more-168"></span></p>
<p>Voici la structure mise en place :</p>
<ul>
<li>Un client, qui en fait est un script PHP, qui envoie envoie des <em>jobs</em> (des tâches) au serveur gearman.</li>
<li>Un serveur gearman qui s&#8217;occupe d&#8217;empiler les jobs et de les distribuer au workers.</li>
<li>Plusieurs workers qui eux aussi sont des scripts PHP. Ils reçoivent les jobs que le client à envoyé au serveur. Une fois le job terminé, le worker qui avait le job en charge retourne le résultat au client via le serveur.</li>
</ul>
<p>On verra pas la suite que le client n&#8217;est pas obligé d&#8217;attendre le résultat de ses jobs. Dans ce cas le client ne sait pas si le job s&#8217;est bien passé et il ne connaitra pas non plus le résultat du job.</p>
<p>Dans mon cas je n&#8217;ai pas besoin du résultat, j&#8217;ai juste besoin d&#8217;empiler des jobs afin de les lancer en parallèle et ce n&#8217;est pas la peine d&#8217;attendre que chaque job ait fini son travail.</p>
<p style="text-align: center;"><img class="size-full wp-image-179 aligncenter" title="Achitecture Gearman" src="http://www.sbnet.fr/uploads/gearman.png" alt="" width="402" height="462" /></p>
<h2>Installation</h2>
<p>L&#8217;installation décrite ici est pour Linux, pour Ubuntu plus exactement, voici la démarche a suivre :</p>
<p>Il faut ajouter ce dépôt à vos sources dans le fichier <em>/etc/apt/sources.list</em> :  <a title="https://launchpad.net/~gearman-developers/+archive/ppa" href="https://launchpad.net/~gearman-developers/+archive/ppa" rel="nofollow">https://launchpad.net/~gearman-developers/+archive/ppa</a></p>
<p>On met à jour puis on installe gearman avec apt-get :</p>
<div style="overflow: auto;"><pre class="bash" id="geshi" style="color: #fff; border-left: 5px solid #900; background-color:#000;">apt-get update
apt-get upgrade
apt-get install gearman-job-server</pre></div>
<p>On installe l&#8217;extension pour PHP</p>
<div style="overflow: auto;"><pre class="bash" id="geshi" style="color: #fff; border-left: 5px solid #900; background-color:#000;">apt-get install php5-dev
apt-get install libgearman-dev
wget http://pecl.php.net/get/gearman<span class="nu0">-0.8</span><span class="nu0">.0</span>.tgz
tar xzf gearman-X.Y.tgz
<span class="kw3">cd</span> gearman-X.Y
phpize
./configure
make
make install</pre></div>
<p>Si tout se passe bien, on a juste à a jouter l&#8217;extension au fichier php.ini :</p>
<div style="overflow: auto;"><pre class="ini" id="geshi" style="color: #fff; border-left: 5px solid #900; background-color:#000;">extension=<span class="st0">&quot;gearman.so&quot;</span></pre></div>
<p>Et on n&#8217;oublie pas de recharger son serveur web pour prendre en compte la nouvelle extension.</p>
<p>Pour vérifier que tout est bien en place, on peut utiliser cette commande :</p>
<div style="overflow: auto;"><pre class="php" id="geshi" style="color: #fff; border-left: 5px solid #900; background-color:#000;"><a href="http://www.php.net/print"><span class="kw3">print</span></a> gearman_version<span class="br0">(</span><span class="br0">)</span>;</pre></div>
<h2>Le client</h2>
<p>Voila le code du client utilisé :</p>
<div style="overflow: auto;"><pre class="php" id="geshi" style="color: #fff; border-left: 5px solid #900; background-color:#000;"><span class="re0">$client</span>= <span class="kw2">new</span> GearmanClient<span class="br0">(</span><span class="br0">)</span>;
<span class="re0">$client</span>-&gt;addServer<span class="br0">(</span><span class="st0">&quot;127.0.0.1&quot;</span>, <span class="nu0">4730</span><span class="br0">)</span>;
 
<span class="re0">$task_id</span> = <span class="nu0">0</span>;
<span class="kw1">while</span><span class="br0">(</span><span class="re0">$image_id</span> = get_new_image<span class="br0">(</span><span class="br0">)</span><span class="br0">)</span>
<span class="br0">{</span>
    <span class="re0">$params</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">(</span>
        <span class="st0">&quot;db_config&quot;</span> =&gt; <span class="re0">$db_config</span><span class="br0">[</span><span class="re0">$options</span><span class="br0">[</span><span class="st0">'environment'</span><span class="br0">]</span><span class="br0">]</span>,
        <span class="st0">&quot;image_id&quot;</span> = <span class="re0">$image_id</span>,
    <span class="br0">)</span>;
 
    <span class="re0">$client</span>-&gt;addTaskBackground<span class="br0">(</span><span class="st0">&quot;process_image&quot;</span>, <a href="http://www.php.net/serialize"><span class="kw3">serialize</span></a><span class="br0">(</span><span class="re0">$params</span><span class="br0">)</span>, <span class="kw2">null</span>, <span class="st0">&quot;T&quot;</span>.<span class="re0">$task_id</span>++<span class="br0">)</span>;
<span class="br0">}</span>
<span class="re0">$client</span>-&gt;runTasks<span class="br0">(</span><span class="br0">)</span>;
<a href="http://www.php.net/exit"><span class="kw3">exit</span></a><span class="br0">(</span><span class="nu0">0</span><span class="br0">)</span>;</pre></div>
<p>On commence par créer un objet <em>GearmanClient</em>, il se connectera à notre serveur grâce au <em>addServer</em>.</p>
<p>Dans cet exemple, on empile des traitements sur des images, c&#8217;est la fonction process_image qui sera appelée par chaque job.</p>
<p>On crée aussi un tableau de paramètres qui sera sérialisé avant d&#8217;être envoyé au job. Les paramètres que j&#8217;ai mis ici sont juste des exemples, on peut y mettre ce qu&#8217;on veut pourvu que ce qu&#8217;on y met soit sérialisable.</p>
<p>Le <em>runTasks() </em>achève le travail et indique au serveur de lancer les tâches.</p>
<h2>Les workers</h2>
<p>Pour gérer les workers, j&#8217;ai fait un petit script qui en lance un certain nombre à coup de <em>fork()</em>.</p>
<div style="overflow: auto; height: 300px;"><pre class="php" id="geshi" style="color: #fff; border-left: 5px solid #900; background-color:#000;"><a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&quot;Starting {$nb_workers} workers : &quot;</span>;
<span class="kw1">for</span><span class="br0">(</span><span class="re0">$i</span>=<span class="nu0">0</span>; <span class="re0">$i</span>&lt;<span class="re0">$nb_workers</span>; <span class="re0">$i</span>++<span class="br0">)</span>
<span class="br0">{</span>
     <span class="re0">$pid</span> = pcntl_fork<span class="br0">(</span><span class="br0">)</span>;
      <span class="kw1">if</span><span class="br0">(</span><span class="re0">$pid</span> == <span class="nu0">-1</span><span class="br0">)</span>
      <span class="br0">{</span>
          <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&quot;Fork error !<span class="es0">\n</span>&quot;</span>;
      <span class="br0">}</span>
      <span class="kw1">else</span> <span class="kw1">if</span><span class="br0">(</span><span class="re0">$pid</span><span class="br0">)</span>
      <span class="br0">{</span>
         <span class="re0">$pids</span><span class="br0">[</span><span class="br0">]</span> = <span class="re0">$pid</span>;
         <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&quot;Worker pid : {$pid}<span class="es0">\n</span>&quot;</span>;
      <span class="br0">}</span>
      <span class="kw1">else</span>
      <span class="br0">{</span>
         <a href="http://www.php.net/call_user_func_array"><span class="kw3">call_user_func_array</span></a><span class="br0">(</span><span class="st0">&quot;run&quot;</span>, <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span>;
         <a href="http://www.php.net/exit"><span class="kw3">exit</span></a><span class="br0">(</span><span class="nu0">0</span><span class="br0">)</span>;
     <span class="br0">}</span>
 <span class="br0">}</span>
 
 <span class="br0">[</span>...<span class="br0">]</span>
 
 <span class="kw2">function</span> run<span class="br0">(</span><span class="br0">)</span>
 <span class="br0">{</span>
     <span class="re0">$worker</span>= <span class="kw2">new</span> GearmanWorker<span class="br0">(</span><span class="br0">)</span>;
     <span class="re0">$worker</span>-&gt;addServer<span class="br0">(</span><span class="st0">&quot;127.0.0.1&quot;</span>, <span class="nu0">4730</span><span class="br0">)</span>;
     <span class="re0">$worker</span>-&gt;addFunction<span class="br0">(</span><span class="st0">&quot;process_image&quot;</span>, <span class="st0">&quot;do_work&quot;</span><span class="br0">)</span>;
     <span class="kw1">while</span><span class="br0">(</span><span class="re0">$worker</span>-&gt;work<span class="br0">(</span><span class="br0">)</span><span class="br0">)</span>;
<span class="br0">}</span>
 
<span class="kw2">function</span> do_work<span class="br0">(</span><span class="re0">$job</span><span class="br0">)</span>
<span class="br0">{</span>
    <span class="re0">$params</span> = <a href="http://www.php.net/unserialize"><span class="kw3">unserialize</span></a><span class="br0">(</span><span class="re0">$job</span>-&gt;workload<span class="br0">(</span><span class="br0">)</span><span class="br0">)</span>;    
 
    <span class="co1">// Code du traitement de l'image</span>
<span class="br0">}</span></pre></div>
<p>A vous de l’adapter selon vos besoins, il n&#8217;y a la rien de bien compliqué.</p>
<h2>Conclusion</h2>
<p>Finalement, la mise en place d&#8217;un tel système s&#8217;avère assez simple et rapide. Il ne nous aura pas fallu plus d&#8217;une journée pour réaliser l&#8217;ensemble alors que nous n&#8217;avions jamais touché à Gearman auparavant.</p>
<p>La stabilité à l&#8217;air d&#8217;être au rendez-vous, nous n&#8217;avons eu aucun plantage de job ou autre depuis sa mise en tests et nous lançons environs 700 jobs par jours repartis sur 10 workers. C&#8217;est pas énorme mais on a prévu de charger un peu plus la bête dans un second temps.</p>
<p>Pour plus d&#8217;informations, voici quelques liens :</p>
<ul>
<li><a href="http://fr.php.net/manual/en/book.gearman.php">http://fr.php.net/manual/en/book.gearman.php</a></li>
<li><a href="http://gearman.org/">http://gearman.org/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.sbnet.fr/2011/06/30/traitements-paralleles-grace-a-gearman/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>cURL multi prend tout mon cpu !</title>
		<link>http://www.sbnet.fr/2011/04/07/curl-multi-prend-tout-mon-cpu/</link>
		<comments>http://www.sbnet.fr/2011/04/07/curl-multi-prend-tout-mon-cpu/#comments</comments>
		<pubDate>Thu, 07 Apr 2011 17:04:09 +0000</pubDate>
		<dc:creator>Stéphane</dc:creator>
				<category><![CDATA[Informatique]]></category>

		<guid isPermaLink="false">http://www.sbnet.fr/?p=155</guid>
		<description><![CDATA[Pour un projet j&#8217;utilise de façon assez intensive cURL multi dans mes scripts et je me suis rendu compte qu&#8217;il me prennait quasiment 100% de mon cpu. // Préparation des handles cURL   do { curl_multi_exec($mh, $running); }while($running&#62;0);   // Traitement des requetes C&#8217;est biensûr la boucle do &#8230; while qui est en cause ici. Pourtant [...]]]></description>
			<content:encoded><![CDATA[<p>Pour un projet j&#8217;utilise de façon assez intensive cURL multi dans mes scripts et je me suis rendu compte qu&#8217;il me prennait quasiment 100% de mon cpu.</p>
<div style="overflow: auto;"><pre class="php" id="geshi" style="color: #fff; border-left: 5px solid #900; background-color:#000;"><span class="co1">// Préparation des handles cURL</span>
 
<span class="kw1">do</span>
<span class="br0">{</span>
    curl_multi_exec<span class="br0">(</span><span class="re0">$mh</span>, <span class="re0">$running</span><span class="br0">)</span>;
<span class="br0">}</span><span class="kw1">while</span><span class="br0">(</span><span class="re0">$running</span>&gt;<span class="nu0">0</span><span class="br0">)</span>;
 
<span class="co1">// Traitement des requetes</span></pre></div>
<p>C&#8217;est biensûr la boucle<em> do &#8230; while</em> qui est en cause ici.</p>
<p><span id="more-155"></span>Pourtant il y a une méthode simple pour indiquer à cURL d&#8217;attendre tant qu&#8217;il y a de l&#8217;activité sur un handle. Méthode que je ne connaissais pas et que voici :</p>
<p>Il suffit d&#8217;utiliser <em>curl_multi_select()</em></p>
<div style="overflow: auto;"><pre class="php" id="geshi" style="color: #fff; border-left: 5px solid #900; background-color:#000;"><span class="co1">// Préparation des handles cURL</span>
 
<span class="kw1">do</span>
<span class="br0">{</span>
    curl_multi_exec<span class="br0">(</span><span class="re0">$mh</span>, <span class="re0">$running</span><span class="br0">)</span>;
    <span class="re0">$ready</span> = curl_multi_select<span class="br0">(</span><span class="re0">$mh</span><span class="br0">)</span>;
<span class="br0">}</span><span class="kw1">while</span><span class="br0">(</span><span class="re0">$running</span>&gt;<span class="nu0">0</span> &amp;&amp; <span class="re0">$ready</span>!=<span class="nu0">-1</span><span class="br0">)</span>;
 
<span class="co1">// Traitement des requetes</span></pre></div>
<p>C&#8217;est tout, mon script est passé de 100% de charge à environ 2%.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sbnet.fr/2011/04/07/curl-multi-prend-tout-mon-cpu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Associer un sous-domaine à une application symfony</title>
		<link>http://www.sbnet.fr/2010/07/02/associer-un-sous-domaine-a-une-application-symfony/</link>
		<comments>http://www.sbnet.fr/2010/07/02/associer-un-sous-domaine-a-une-application-symfony/#comments</comments>
		<pubDate>Fri, 02 Jul 2010 08:35:29 +0000</pubDate>
		<dc:creator>Stéphane</dc:creator>
				<category><![CDATA[Informatique]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://www.sbnet.fr/?p=133</guid>
		<description><![CDATA[Coté serveur web Il faut soit  créer des virtual host pour tous vos sous-domaine. Soit créer un seul virtual host en utilisant des wildcards dans le ServerAlias, du coup tous les sous-domaines pourraient correspondre à une application, plus besoin de créer autant de virtual hosts que de sous-domaine. Il doit même être possible d&#8217;utiliser les [...]]]></description>
			<content:encoded><![CDATA[<h3>Coté serveur web</h3>
<p>Il faut soit  créer des virtual host pour tous vos sous-domaine.</p>
<p>Soit créer un seul virtual host en utilisant des wildcards dans le ServerAlias, du coup tous les sous-domaines pourraient correspondre à une application, plus besoin de créer autant de virtual hosts que de sous-domaine. Il doit même être possible d&#8217;utiliser les wildcards dans la déclaration du domaine dans le gestionnaire de dns.</p>
<div style="overflow: auto;"><pre class="php" id="geshi" style="color: #fff; border-left: 5px solid #900; background-color:#000;">ServerName domain.tld
ServerAlias *.domain.tld</pre></div>
<h3>Coté symfony</h3>
<p>Il faut renommer le fichier <em>web/index.php</em> en <em>web/frontend.php</em><br />
<em> </em>Puis re-créer le fichier <em>web/index.php </em>en y mettant le code qui permettra de choisir l&#8217;application<br />
en fonction du sous domaine.<br />
Voici un exemple, il suffit de modifier le <em>switch()</em> pour l&#8217;adapter à vos besoins :</p>
<div style="overflow: auto;"><pre class="php" id="geshi" style="color: #fff; border-left: 5px solid #900; background-color:#000;"><span class="kw1">require_once</span><span class="br0">(</span><a href="http://www.php.net/dirname"><span class="kw3">dirname</span></a><span class="br0">(</span><span class="kw2">__FILE__</span><span class="br0">)</span>.<span class="st0">'/../config/ProjectConfiguration.class.php'</span><span class="br0">)</span>;
<span class="co1">// Trouve le sous-domaine</span>
<a href="http://www.php.net/list"><span class="kw3">list</span></a><span class="br0">(</span><span class="re0">$subdomain</span>, <span class="re0">$domain</span>, <span class="re0">$tld</span><span class="br0">)</span> = <a href="http://www.php.net/explode"><span class="kw3">explode</span></a><span class="br0">(</span><span class="st0">'.'</span>, <span class="re0">$_SERVER</span><span class="br0">[</span><span class="st0">'HTTP_HOST'</span><span class="br0">]</span><span class="br0">)</span>;
 
<span class="co1">// En deduit l'application</span>
<span class="kw1">switch</span><span class="br0">(</span><span class="re0">$subdomain</span><span class="br0">)</span>
<span class="br0">{</span>
    <span class="kw1">case</span> <span class="st0">&quot;documentation&quot;</span>:
        <span class="re0">$app</span> = <span class="st0">&quot;documentation&quot;</span>;
    <span class="kw1">break</span>;
 
    <span class="kw2">default</span>:
        <span class="re0">$app</span> = <span class="st0">&quot;frontend&quot;</span>;
    <span class="kw1">break</span>;
<span class="br0">}</span>
<span class="re0">$configuration</span> = ProjectConfiguration::<span class="me2">getApplicationConfiguration</span><span class="br0">(</span><span class="re0">$app</span>, <span class="st0">'prod'</span>, <span class="kw2">false</span><span class="br0">)</span>;
sfContext::<span class="me2">createInstance</span><span class="br0">(</span><span class="re0">$configuration</span><span class="br0">)</span>-&gt;dispatch<span class="br0">(</span><span class="br0">)</span>;</pre></div>
]]></content:encoded>
			<wfw:commentRss>http://www.sbnet.fr/2010/07/02/associer-un-sous-domaine-a-une-application-symfony/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHP fait du multitâche</title>
		<link>http://www.sbnet.fr/2010/02/26/php-fait-du-multitache/</link>
		<comments>http://www.sbnet.fr/2010/02/26/php-fait-du-multitache/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 15:30:52 +0000</pubDate>
		<dc:creator>Stéphane</dc:creator>
				<category><![CDATA[Informatique]]></category>
		<category><![CDATA[multitache]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.sbnet.fr/2010/02/26/threads-et-php-multitache/</guid>
		<description><![CDATA[Pour les besoins d&#8217;un projet effectuant un grand nombre de tâches répétitives, j&#8217;ai dû mettre en place un système basé sur un script PHP lancé par cron à intervalles réguliers. Il n&#8217;y a aucune difficulté particulière à réaliser ceci, là où ça commence à être intéressant c&#8217;est à partir du moment où il a fallu [...]]]></description>
			<content:encoded><![CDATA[<p>Pour les besoins d&#8217;un projet effectuant un grand nombre de tâches répétitives, j&#8217;ai dû mettre en place un système basé sur un script PHP lancé par cron à intervalles réguliers. Il n&#8217;y a aucune difficulté particulière à réaliser ceci, là où ça commence à être intéressant c&#8217;est à partir du moment où il a fallu que ce script puisse lancer plusieurs tâches en même temps.</p>
<p>On a donc un script lancé à intervalles réguliers qui lui même va lancer et gérer un certain nombre, configurable, de tâches concurrente. Voici comment j&#8217;ai procédé.</p>
<p><span id="more-131"></span>Avant de continuer, il est bon de noter que j&#8217;ai effectué tous mes tests sur une machine fonctionnant sous linux, <strike>je n&#8217;ai aucune idée de la façon dont ça peu fonctionner sous windows, si jamais ça fonctionne sous windows</strike> les fonctions pcntl ne fonctionnent pas sous windows, donc pas de multitâche, avec cette méthode en tous cas, pour cette plateforme.</p>
<p>Un petit exemple vaut mieux que de longs discours :</p>
<div style="overflow: auto;"><pre class="php" id="geshi" style="color: #fff; border-left: 5px solid #900; background-color:#000;"><span class="kw2">function</span> task<span class="br0">(</span><span class="re0">$msg</span><span class="br0">)</span>
<span class="br0">{</span>
    <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&quot;Task say $msg<span class="es0">\n</span>&quot;</span>;
<span class="br0">}</span>
 
<span class="re0">$t</span> = <span class="kw2">new</span> Task<span class="br0">(</span><span class="br0">)</span>;
<span class="re0">$t</span>-&gt;fork<span class="br0">(</span><span class="st0">'task'</span>, <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">(</span><span class="st0">&quot;hello&quot;</span><span class="br0">)</span><span class="br0">)</span>;</pre></div>
<p>On peut sans problème lancer plusieurs tâches en créant plusieurs objets <em>Task</em>.</p>
<p>Et vérifier qu&#8217;une tâche est en cours avec la méthode <em>is_running()</em></p>
<p>Ici, pour l&#8217;exemple, on lance simplement une nouvelle tâche dont l&#8217;action principale sera d&#8217;afficher du texte, mais en général on à tendance à faire des tâches pour effectuer un traitement lourd ou long. Par exemple si on doit vérifier qu&#8217;une liste sites répondent correctement (disons 10 000 sites) sans utiliser de multitâche, si on a un timeout de 5 secondes et que 10% des sites sont hs, on perdra 5000 secondes à attendre. Par contre si on lance 100 tâches, potentiellement, on divises par 100 le temps d&#8217;attente.</p>
<p>Voici le code de cette classe</p>
<div style="overflow: auto; height: 300px;"><pre class="php" id="geshi" style="color: #fff; border-left: 5px solid #900; background-color:#000;"><span class="kw2">class</span> Task
<span class="br0">{</span>
    <span class="kw2">private</span> <span class="re0">$pid</span>;
    <span class="kw2">private</span> <span class="re0">$priority</span>=<span class="nu0">0</span>;
 
    protected <span class="re0">$children_pid</span>=<a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">(</span><span class="br0">)</span>;
 
    <span class="kw2">public</span> <span class="kw2">function</span> __construct<span class="br0">(</span><span class="br0">)</span>
    <span class="br0">{</span>
        <span class="kw1">if</span><span class="br0">(</span>!<a href="http://www.php.net/function_exists"><span class="kw3">function_exists</span></a><span class="br0">(</span><span class="st0">&quot;pcntl_fork&quot;</span><span class="br0">)</span><span class="br0">)</span>
        <span class="br0">{</span>
            throw <span class="kw2">new</span> Exception <span class="br0">(</span><span class="st0">&quot;Your system does not support pcntl (thread) functions&quot;</span><span class="br0">)</span>;
        <span class="br0">}</span>
 
        <span class="co1">// Set the default signal handler</span>
        <span class="re0">$this</span>-&gt;add_signal<span class="br0">(</span>SIGTERM, <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">(</span><span class="re0">$this</span>, <span class="st0">&quot;signal_handler&quot;</span><span class="br0">)</span><span class="br0">)</span>;
        <span class="re0">$this</span>-&gt;add_signal<span class="br0">(</span>SIGINT, <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">(</span><span class="re0">$this</span>, <span class="st0">&quot;signal_handler&quot;</span><span class="br0">)</span><span class="br0">)</span>;
        <span class="re0">$this</span>-&gt;add_signal<span class="br0">(</span>SIGQUIT, <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">(</span><span class="re0">$this</span>, <span class="st0">&quot;signal_handler&quot;</span><span class="br0">)</span><span class="br0">)</span>;
    <span class="br0">}</span> 
 
    <span class="kw2">public</span> <span class="kw2">function</span> __destruct<span class="br0">(</span><span class="br0">)</span>
    <span class="br0">{</span>
        <span class="re0">$this</span>-&gt;wait_children<span class="br0">(</span><span class="br0">)</span>;
    <span class="br0">}</span> 
 
    <span class="kw2">public</span> <span class="kw2">function</span> is_running<span class="br0">(</span><span class="br0">)</span>
    <span class="br0">{</span>
        <span class="re0">$pid</span> = pcntl_waitpid<span class="br0">(</span><span class="re0">$this</span>-&gt;pid, <span class="re0">$status</span>, WNOHANG<span class="br0">)</span>;
        <span class="kw1">return</span><span class="br0">(</span><span class="re0">$pid</span> === <span class="nu0">0</span><span class="br0">)</span>;
    <span class="br0">}</span>  
 
    <span class="kw2">public</span> <span class="kw2">function</span> wait_children<span class="br0">(</span><span class="br0">)</span>
    <span class="br0">{</span>
        <span class="kw1">foreach</span><span class="br0">(</span><span class="re0">$this</span>-&gt;children_pid <span class="kw1">as</span> <span class="re0">$child_pid</span><span class="br0">)</span>
        <span class="br0">{</span>
            pcntl_waitpid<span class="br0">(</span><span class="re0">$child_pid</span>, <span class="re0">$status</span><span class="br0">)</span>;
        <span class="br0">}</span>
    <span class="br0">}</span>
 
    <span class="kw2">public</span> <span class="kw2">function</span> fork<span class="br0">(</span><span class="re0">$name</span>, <span class="re0">$params</span>=<a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span>
    <span class="br0">{</span>
        <span class="re0">$pid</span> = pcntl_fork<span class="br0">(</span><span class="br0">)</span>;
 
        <span class="kw1">if</span><span class="br0">(</span><span class="re0">$pid</span> === <span class="nu0">-1</span><span class="br0">)</span>
        <span class="br0">{</span>
            throw <span class="kw2">new</span> Exception<span class="br0">(</span><span class="st0">&quot;Unable to fork&quot;</span><span class="br0">)</span>;
        <span class="br0">}</span>
        <span class="kw1">elseif</span><span class="br0">(</span><span class="re0">$pid</span> &gt; <span class="nu0">0</span><span class="br0">)</span>
        <span class="br0">{</span>
            <span class="co1">// Parent</span>
            <span class="re0">$this</span>-&gt;children_pid<span class="br0">[</span><span class="br0">]</span> = <span class="re0">$pid</span>;
        <span class="br0">}</span>
        <span class="kw1">elseif</span><span class="br0">(</span><span class="re0">$pid</span> === <span class="nu0">0</span><span class="br0">)</span>
        <span class="br0">{</span>
            <span class="co1">// Child</span>
            <a href="http://www.php.net/call_user_func_array"><span class="kw3">call_user_func_array</span></a><span class="br0">(</span><span class="re0">$name</span>, <span class="re0">$params</span><span class="br0">)</span>;
            <a href="http://www.php.net/exit"><span class="kw3">exit</span></a><span class="br0">(</span><span class="nu0">0</span><span class="br0">)</span>;
        <span class="br0">}</span>
    <span class="br0">}</span>
 
    <span class="kw2">public</span> <span class="kw2">function</span> add_signal<span class="br0">(</span><span class="re0">$signal</span>, <span class="re0">$function_name</span><span class="br0">)</span>
    <span class="br0">{</span>
        <span class="kw1">if</span><span class="br0">(</span>!pcntl_signal<span class="br0">(</span><span class="re0">$signal</span>, <span class="re0">$function_name</span><span class="br0">)</span><span class="br0">)</span>
        <span class="br0">{</span>
            throw <span class="kw2">new</span> Exception<span class="br0">(</span><span class="st0">&quot;Can't add the signal&quot;</span><span class="br0">)</span>;
        <span class="br0">}</span>
    <span class="br0">}</span>
 
    <span class="kw2">public</span> <span class="kw2">function</span> signal_handler<span class="br0">(</span><span class="re0">$signal</span><span class="br0">)</span>
    <span class="br0">{</span>
        <span class="kw1">switch</span><span class="br0">(</span><span class="re0">$signal</span><span class="br0">)</span>
        <span class="br0">{</span>
            <span class="kw2">default</span>:
            <span class="kw1">case</span> SIGTERM:
                <a href="http://www.php.net/exit"><span class="kw3">exit</span></a><span class="br0">(</span><span class="nu0">0</span><span class="br0">)</span>;
            <span class="kw1">break</span>;
 
            <span class="kw1">case</span> SIGQUIT:
            <span class="kw1">case</span> SIGINT:
            <span class="kw1">case</span> SIGKILL:
                <a href="http://www.php.net/exit"><span class="kw3">exit</span></a><span class="br0">(</span><span class="nu0">1</span><span class="br0">)</span>;
            <span class="kw1">break</span>;
        <span class="br0">}</span>
    <span class="br0">}</span>
 
    <span class="kw2">public</span> <span class="kw2">function</span> get_pid<span class="br0">(</span><span class="br0">)</span>
    <span class="br0">{</span>
        <span class="kw1">return</span> <span class="re0">$this</span>-&gt;pid;
    <span class="br0">}</span>
 
    <span class="kw2">public</span> <span class="kw2">function</span> set_priority<span class="br0">(</span><span class="re0">$priority</span>, <span class="re0">$process_identifier</span>=PRIO_PROCESS<span class="br0">)</span>
    <span class="br0">{</span>
        <span class="kw1">if</span><span class="br0">(</span>!<a href="http://www.php.net/is_int"><span class="kw3">is_int</span></a><span class="br0">(</span><span class="re0">$priority</span><span class="br0">)</span> || <span class="re0">$priority</span> &lt; <span class="nu0">-20</span> || <span class="re0">$priority</span> &gt; <span class="nu0">20</span><span class="br0">)</span>
        <span class="br0">{</span>
            throw <span class="kw2">new</span> Exception<span class="br0">(</span><span class="st0">&quot;Invalid priority&quot;</span><span class="br0">)</span>;
        <span class="br0">}</span>
 
        <span class="kw1">if</span><span class="br0">(</span><span class="re0">$process_identifier</span> != PRIO_PROCESS || <span class="re0">$process_identifier</span> != PRIO_PGRP || <span class="re0">$process_identifier</span> != PRIO_USER<span class="br0">)</span>
        <span class="br0">{</span>
            throw <span class="kw2">new</span> Exception<span class="br0">(</span><span class="st0">&quot;Invalid process identifier type&quot;</span><span class="br0">)</span>;
        <span class="br0">}</span>
 
        <span class="kw1">if</span><span class="br0">(</span>!pcntl_setpriority<span class="br0">(</span><span class="re0">$priority</span>, <span class="re0">$this</span>-&gt;pid, <span class="re0">$process_identifier</span><span class="br0">)</span><span class="br0">)</span>
        <span class="br0">{</span>
            throw <span class="kw2">new</span> Exception<span class="br0">(</span><span class="st0">&quot;Can't set the priority&quot;</span><span class="br0">)</span>;
        <span class="br0">}</span>
 
        <span class="re0">$this</span>-&gt;priority = <span class="re0">$priority</span>;
    <span class="br0">}</span>
 
    <span class="kw2">public</span> <span class="kw2">function</span> get_priority<span class="br0">(</span><span class="br0">)</span>
    <span class="br0">{</span>
        <span class="kw1">return</span> <span class="re0">$this</span>-&gt;priority;
    <span class="br0">}</span>
 
    <span class="kw2">public</span> <span class="kw2">function</span> kill<span class="br0">(</span><span class="re0">$pid</span><span class="br0">)</span>
    <span class="br0">{</span>
        <a href="http://www.php.net/posix_kill"><span class="kw3">posix_kill</span></a><span class="br0">(</span>pid, SIGHUP<span class="br0">)</span>;
    <span class="br0">}</span>
<span class="br0">}</span></pre></div>
]]></content:encoded>
			<wfw:commentRss>http://www.sbnet.fr/2010/02/26/php-fait-du-multitache/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Zero, c&#8217;est la tête à toto</title>
		<link>http://www.sbnet.fr/2010/02/04/zero-cest-la-tete-a-toto/</link>
		<comments>http://www.sbnet.fr/2010/02/04/zero-cest-la-tete-a-toto/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 16:13:45 +0000</pubDate>
		<dc:creator>Stéphane</dc:creator>
				<category><![CDATA[Informatique]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.sbnet.fr/2010/02/04/zero-cest-la-tete-a-toto/</guid>
		<description><![CDATA[C&#8217;est pas moi qui le dit, c&#8217;est PHP. La preuve : var_dump(0 == &#34;toto&#34;); Voir ça sur codepad]]></description>
			<content:encoded><![CDATA[<p><a href="http://php.net/error_reporting" class="external text" title="http://php.net/error_reporting" rel="nofollow"></a>C&#8217;est pas moi qui le dit, c&#8217;est PHP.</p>
<p>La preuve :</p>
<div style="overflow: auto;"><pre class="php" id="geshi" style="color: #fff; border-left: 5px solid #900; background-color:#000;"><a href="http://www.php.net/var_dump"><span class="kw3">var_dump</span></a><span class="br0">(</span><span class="nu0">0</span> == <span class="st0">&quot;toto&quot;</span><span class="br0">)</span>;</pre></div>
<p><a href="http://codepad.org/AIpJjxLa" title="php ça crain">Voir ça sur codepad</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sbnet.fr/2010/02/04/zero-cest-la-tete-a-toto/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>La vie est belle</title>
		<link>http://www.sbnet.fr/2010/02/02/la-vie-est-belle/</link>
		<comments>http://www.sbnet.fr/2010/02/02/la-vie-est-belle/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 15:47:23 +0000</pubDate>
		<dc:creator>Stéphane</dc:creator>
				<category><![CDATA[autre]]></category>

		<guid isPermaLink="false">http://www.sbnet.fr/2010/02/02/la-vie-est-belle/</guid>
		<description><![CDATA[D&#8217;habitude je ne parle que technique sur ce blog, mais pas cette fois-ci. Cette dernière année à été riche en évènements pour moi, beaucoup de changements, dans l&#8217;ordre : Je me suis marié ! J&#8217;ai trouvé un travail qui me plait beaucoup dans une petite entreprise bien sympathique et dynamique. J&#8217;ai déménagé et j&#8217;ai changé [...]]]></description>
			<content:encoded><![CDATA[<p>D&#8217;habitude je ne parle que technique sur ce blog, mais pas cette fois-ci.</p>
<p><span id="more-129"></span>Cette dernière année à été riche en évènements pour moi, beaucoup de changements, dans l&#8217;ordre :</p>
<ul>
<li>Je me suis marié !</li>
<li>J&#8217;ai trouvé un travail qui me plait beaucoup dans une petite entreprise bien sympathique et dynamique.</li>
<li>J&#8217;ai déménagé et j&#8217;ai changé de région (J&#8217;ai quitté le Vaucluse pour la Savoie)</li>
<li>Et surtout, je suis l&#8217;heureux papa de la plus jolie de toutes les petites filles.<br />
<strong>Julie est née le 28 janvier 2010</strong> !</li>
</ul>
<p>Ça commence et ça termine bien non ?</p>
<p><img src="http://stephane.6degres.fr/julie/2/DSC01645.JPG" alt="julie" width="600" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sbnet.fr/2010/02/02/la-vie-est-belle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Qui veut une invitation à Google Wave ?</title>
		<link>http://www.sbnet.fr/2009/12/07/qui-veut-une-invitation-a-google-wave/</link>
		<comments>http://www.sbnet.fr/2009/12/07/qui-veut-une-invitation-a-google-wave/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 13:09:51 +0000</pubDate>
		<dc:creator>Stéphane</dc:creator>
				<category><![CDATA[Informatique]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.sbnet.fr/2009/12/07/qui-veut-une-invitation-a-google-wave/</guid>
		<description><![CDATA[Il me reste 3 invitations à Google Wave, si vous en voulez une laissez moi un commentaire ici. Faites vite, seuls les 3 premiers en auront une.]]></description>
			<content:encoded><![CDATA[<p>Il me reste 3 invitations à <a href="https://wave.google.com/wave/" title="Google Wave">Google Wave</a>, si vous en voulez une laissez moi un commentaire ici.</p>
<p>Faites vite, seuls les 3 premiers en auront une.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sbnet.fr/2009/12/07/qui-veut-une-invitation-a-google-wave/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Attention à la faille dans subversion</title>
		<link>http://www.sbnet.fr/2009/11/19/attention-a-la-faille-dans-subversion/</link>
		<comments>http://www.sbnet.fr/2009/11/19/attention-a-la-faille-dans-subversion/#comments</comments>
		<pubDate>Thu, 19 Nov 2009 10:33:17 +0000</pubDate>
		<dc:creator>Stéphane</dc:creator>
				<category><![CDATA[Informatique]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://www.sbnet.fr/2009/11/19/attention-a-la-faille-dans-subversion/</guid>
		<description><![CDATA[Enfin, c&#8217;est pas vraiment une faille, c&#8217;est juste que lorsque l&#8217;on déploie un projet à partir d&#8217;un dépôt subversion, il faut faire attention aux fichiers et répertoires .svn qui peuvent être visibles, selon  la configuration de votre serveur web. Pour empêcher ça avec apache, quelques lignes dans votre httpd.conf suffisent : &#60;Directory ~ &#34;.*\.svn&#34;&#62;   [...]]]></description>
			<content:encoded><![CDATA[<p>Enfin, c&#8217;est pas vraiment une faille, c&#8217;est juste que lorsque l&#8217;on déploie un projet à partir d&#8217;un dépôt subversion, il faut faire attention aux fichiers et répertoires <em>.svn</em> qui peuvent être visibles, selon  la configuration de votre serveur web.</p>
<p>Pour empêcher ça avec apache, quelques lignes dans votre httpd.conf suffisent :</p>
<div style="overflow: auto;"><pre class="xml" id="geshi" style="color: #fff; border-left: 5px solid #900; background-color:#000;"><span class="sc1">&lt;</span>Directory ~ &quot;.*\.svn&quot;<span class="sc1">&gt;</span>
    Order allow,deny
    Deny from all
    Satisfy All
<span class="sc1">&lt;</span>/Directory<span class="sc1">&gt;</span></pre></div>
<p>Thanks <a href="http://isaykin.ru/" target="_blank">Anton Isaykin</a> for pointing that out to us.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sbnet.fr/2009/11/19/attention-a-la-faille-dans-subversion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Magento : ajouter et enlever des produits du panier</title>
		<link>http://www.sbnet.fr/2009/03/24/magento-ajouter-et-enlever-des-produits-du-panier/</link>
		<comments>http://www.sbnet.fr/2009/03/24/magento-ajouter-et-enlever-des-produits-du-panier/#comments</comments>
		<pubDate>Tue, 24 Mar 2009 09:37:26 +0000</pubDate>
		<dc:creator>Stéphane</dc:creator>
				<category><![CDATA[Informatique]]></category>
		<category><![CDATA[magento]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.sbnet.fr/2009/03/24/magento-ajouter-et-enlever-de-produits-du-panier/</guid>
		<description><![CDATA[Magento est un système de commerce électronique assez complexe à appréhender, il est bien mieux organisé que le vieillissant Oscommerce et peut être modifié à souhait grâce à une architecture bien pensée, basée sur Zend Framework mais qui demande quand même assez de temps pour s&#8217;y habituer. Je vous propose dans ce billet de voir [...]]]></description>
			<content:encoded><![CDATA[<p>Magento est un système de commerce électronique assez complexe à appréhender, il est bien mieux organisé que le vieillissant Oscommerce et peut être modifié à souhait grâce à une architecture bien pensée, basée sur Zend Framework mais qui demande quand même assez de temps pour s&#8217;y habituer. Je vous propose dans ce billet de voir comment faire pour ajouter et enlever des produits du panier de façon automatique.</p>
<p><span id="more-124"></span></p>
<h3>Ajouter un produit</h3>
<p>C&#8217;est le plus simple, il suffit de récupérer l&#8217;id du produit puis de tout simplement l&#8217;ajouter au panier</p>
<div style="overflow: auto;"><pre class="php" id="geshi" style="color: #fff; border-left: 5px solid #900; background-color:#000;"><span class="re0">$id</span> = Mage::<span class="me2">getModel</span><span class="br0">(</span><span class="st0">'catalog/product'</span><span class="br0">)</span>-&gt;getIdBySku<span class="br0">(</span><span class="st0">&quot;product_sku&quot;</span><span class="br0">)</span>;
<span class="re0">$cart</span> = Mage::<span class="me2">getModel</span><span class="br0">(</span><span class="st0">&quot;checkout/cart&quot;</span><span class="br0">)</span>;
<span class="re0">$cart</span>-&gt;addProductsByIds<span class="br0">(</span><a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">(</span><span class="re0">$id</span><span class="br0">)</span><span class="br0">)</span>;
<span class="re0">$cart</span>-&gt;save<span class="br0">(</span><span class="br0">)</span>;</pre></div>
<h3>Enlever un produit</h3>
<p>C&#8217;est un peut plus compliqué, il faut parcourir tout le panier pour vérifier si l&#8217;id du produit à enlever est bien présent et le supprimer si c&#8217;est le cas</p>
<div style="overflow: auto;"><pre class="php" id="geshi" style="color: #fff; border-left: 5px solid #900; background-color:#000;"><span class="re0">$cart</span> = Mage::<span class="me2">getModel</span><span class="br0">(</span><span class="st0">&quot;checkout/cart&quot;</span><span class="br0">)</span>;
<span class="re0">$id</span> = Mage::<span class="me2">getModel</span><span class="br0">(</span><span class="st0">'catalog/product'</span><span class="br0">)</span>-&gt;getIdBySku<span class="br0">(</span><span class="st0">&quot;product_sku&quot;</span><span class="br0">)</span>;
 
<span class="re0">$items</span> = <span class="re0">$cart</span>-&gt;getItems<span class="br0">(</span><span class="br0">)</span>;
<span class="kw1">foreach</span><span class="br0">(</span><span class="re0">$items</span> <span class="kw1">as</span> <span class="re0">$item</span><span class="br0">)</span>
<span class="br0">{</span>
    <span class="kw1">if</span><span class="br0">(</span><span class="re0">$item</span>-&gt;getProduct<span class="br0">(</span><span class="br0">)</span>-&gt;getId<span class="br0">(</span><span class="br0">)</span> == <span class="re0">$id</span><span class="br0">)</span>
    <span class="br0">{</span>
        <span class="re0">$itemId</span> = <span class="re0">$item</span>-&gt;getItemId<span class="br0">(</span><span class="br0">)</span>;
        <span class="re0">$cart</span>-&gt;removeItem<span class="br0">(</span><span class="re0">$itemId</span><span class="br0">)</span>-&gt;save<span class="br0">(</span><span class="br0">)</span>;
    <span class="br0">}</span>
<span class="br0">}</span></pre></div>
]]></content:encoded>
			<wfw:commentRss>http://www.sbnet.fr/2009/03/24/magento-ajouter-et-enlever-des-produits-du-panier/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

