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

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

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

Call Stack:
    0.0001     623440   1. {main}() /home/www/blog.juliencrouzet.fr/index.php:0
    0.0002     628968   2. require('/home/www/blog.juliencrouzet.fr/wp-blog-header.php') /home/www/blog.juliencrouzet.fr/index.php:17
    0.2060   38087216   3. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php') /home/www/blog.juliencrouzet.fr/wp-blog-header.php:16
    0.2069   38090136   4. do_feed() /home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php:14
    0.2069   38090416   5. do_action() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1721
    0.2069   38092440   6. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:395
    0.2069   38092496   7. do_feed_rss2() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:0
    0.2069   38092688   8. load_template() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1753
    0.2071   38154832   9. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php') /home/www/blog.juliencrouzet.fr/wp-includes/theme.php:1087
    0.2122   38165024  10. the_excerpt_rss() /home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php:46
    0.2322   38168560  11. apply_filters() /home/www/blog.juliencrouzet.fr/wp-includes/feed.php:177
    0.2324   38171184  12. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:166

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

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

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

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

Call Stack:
    0.0001     623440   1. {main}() /home/www/blog.juliencrouzet.fr/index.php:0
    0.0002     628968   2. require('/home/www/blog.juliencrouzet.fr/wp-blog-header.php') /home/www/blog.juliencrouzet.fr/index.php:17
    0.2060   38087216   3. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php') /home/www/blog.juliencrouzet.fr/wp-blog-header.php:16
    0.2069   38090136   4. do_feed() /home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php:14
    0.2069   38090416   5. do_action() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1721
    0.2069   38092440   6. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:395
    0.2069   38092496   7. do_feed_rss2() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:0
    0.2069   38092688   8. load_template() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1753
    0.2071   38154832   9. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php') /home/www/blog.juliencrouzet.fr/wp-includes/theme.php:1087
    0.2537   38184424  10. the_excerpt_rss() /home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php:46
    0.2600   38187080  11. apply_filters() /home/www/blog.juliencrouzet.fr/wp-includes/feed.php:177
    0.2602   38189544  12. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:166

]]></description>
			<content:encoded><![CDATA[<div id="attachment_461" class="wp-caption aligncenter" style="width: 114px"><a href="http://blog.juliencrouzet.fr/wp-content/uploads/2009/08/aptana.png" rel="lightbox[460]"><img class="size-full wp-image-461" title="aptana" src="http://blog.juliencrouzet.fr/wp-content/uploads/2009/08/aptana.png" alt="Retour d&quot;expérience sur Aptana Studio" width="104" height="104" /></a><p class="wp-caption-text"> Aptana Studio</p></div>
<p>Un <a href="http://fr.wikipedia.org/wiki/Environnement_de_d%C3%A9veloppement_int%C3%A9gr%C3%A9">I.D.E.</a> pour un développeur, c&#8217;est l&#8217;une des choses primordiales. C&#8217;est une façon de travailler, des habitudes de développement et souvent, c&#8217;est presque une impératif. Bien sur, certains diront qu&#8217;un vrai développeur peut travailler avec n&#8217;importe lequel et c&#8217;est souvent vrai, mais avouons-le, nous avons tous nos petites habitudes !</p>
<p>Depuis quelques années, je travaillais avec <a href="http://www.zend.com/fr/products/studio">Zend Studio</a>, que j&#8217;avais adopté plus par contrainte de mon employeur au début, mais depuis l&#8217;évolution de celui-ci vers <a href="http://fr.wikipedia.org/wiki/Eclipse_%28logiciel%29">Eclipse</a>, j&#8217;avais lâché le train en route n&#8217;ayant le temps de m&#8217;y mettre et je suis resté cloitré sur l&#8217;ancienne version (5.2), que certes je maitrisais jusqu&#8217;au bout des menus, mais commençait sérieusement à vieillir.</p>
<p>J&#8217;ai donc décidé d&#8217;essayer <a href="http://www.aptana.com/">Aptana Studio</a>, dont on me parlait en bien depuis quelque temps et qui sur le papier, me séduisait fortement.</p>
<p>Après 1 mois, voici mes retours d&#8217;expérience.</p>
<p><span id="more-460"></span></p>
<h2>Ce que j&#8217;ai aimé :</h2>
<h3>Le support de jQuery</h3>
<p>Aptana est livré avec le support prépackagé de plusieurs librairies / frameworks Javascripts, dont jQuery.</p>
<p>A la clé, des templates de codes, de la complétion, de la coloration syntaxique adaptée, et caetera.</p>
<h3>Le support de Smarty</h3>
<p>Je suis depuis plusieurs années, un gran fan de <a href="http://www.smarty.net/">Smarty </a>(non pas les bonbons, quoique), que je continues à utiliser comme Vue dans mes développements <a href="http://fr.wikipedia.org/wiki/Mod%C3%A8le-Vue-Contr%C3%B4leur">MVC </a>sur Zend Framework.</p>
<p>Et la, encore une exclusivité, Aptana Studio nous offre un complétion de code, un coloration syntaxique et tout le toutim pour les fichiers de gabarits smarty, y compris sur vos propres fonctions !</p>
<h3>En bref, les complétions multilangage</h3>
<p>En plus des deux éléments cités, Aptana Studio offre une complétion très bien faite sur tout ce qui est possible : HTML, PHP, XML, JSON, CSS, etc. Et ca marche plutôt bien !</p>
<h2>Ce que je n&#8217;ai pas aimé :</h2>
<h3>Des bugs en pagaille dans le formatage</h3>
<p>Au fur et à mesure que je configurais des fonctionnalités, j&#8217;ai eu de plus en plus de fil à retordre avec des bugs, plus ou moins génants.</p>
<p>Le plus embêtants se trouvent au niveau du formatage de code. Aptana Studio, comme la plupart des I.D.E. basés sur Eclipse vous propose de formater votre code selon les règles que vous avez configurées, comme les retour à la ligne, les indentations, les espaces après les virgules, etc.</p>
<p>Force est de constater que par exemple, les retours à la ligne dans la déclarations de tableaux (array()) ou ceux des déclarations CSS qui commencent par un identifiant (#monDiv .maClasse) ont des comportements complètement aléatoire !</p>
<h3>Des bugs aussi dans la gestion &laquo;&nbsp;remote&nbsp;&raquo;</h3>
<p>Eclipse (ce n&#8217;est qu&#8217;un point de vue&#8230;) n&#8217;est pas pratique pour développer &#8216;en remote&#8217; ; c&#8217;est à dire que vous modifiez et testez sur un serveur distant via FTP ou SFTP par exemple.</p>
<p>Un bout de scotch est malgré tout là pour parer à cette problématique dans Aptana c&#8217;est un petit script bien nommé &laquo;&nbsp;Upload file on save&nbsp;&raquo; qui est censé envoyer vos fichiers via FTP / SFTP lorsque vous les sauvegarder.</p>
<p>Première mauvaise impression : il faut modifier le script pour l&#8217;activer !</p>
<p>Deuxième : il ne marche pas une fois sur trois, et tout est désynchronisé.</p>
<h3>Des fonctionnalités mal finies</h3>
<p>J&#8217;ai été impressionné lorsque j&#8217;ai vu un onglet &laquo;&nbsp;iPhone view&nbsp;&raquo;. Pensez donc ! Un émulateur iPhone intégré à un I.D.E !</p>
<p>En fait, il ne s&#8217;agit que d&#8217;une preview HTML de votre navigateur classique rétrécie au dimensions du mobile et entourée d&#8217;une photo d&#8217;iPhone &#8230; arf !</p>
<h3>Une complétion PHP de votre projet mal pensée</h3>
<p>Si vous souhaitez avoir une complétion sur vos propre classes (évidemment !) en PHP. Beaucoup de manipulations nécessaires : il va falloir définir la nature primaire de votre projet en PHP et ajoutez les répertoires ou sont vos classes dans une liste. Et ce pour chaque projet.</p>
<p>Bien sur, il va falloir après à la main les supprimer, sinon vous atteindrez les 45 secondes à l&#8217;ouverture de chaque projet des les 5 projets (~ 1 Mo de code) atteint &#8230;</p>
<h2>Conclusion</h2>
<p>Malgré une première impression, Aptana Studio semble très utile, très prometteur, mais pas assez stable et mature pour que je l&#8217;adopte. Dommage.</p>
<p>Je vais maintenant me pencher sérieusement sur <a href="http://www.zend.com/fr/products/studio/">Zend Studio 7</a> (qui gère PHP5.3 !)&#8230; Retours dans quelques semaine, sauf incident majeur <img src='http://blog.juliencrouzet.fr/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.juliencrouzet.fr/460/aptana-studio-retour-dexperience/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP5.3 : Quelles nouveautés ?</title>
		<link>http://blog.juliencrouzet.fr/421/php-5-3-what-s-new/</link>
		<comments>http://blog.juliencrouzet.fr/421/php-5-3-what-s-new/#comments</comments>
		<pubDate>Sat, 04 Jul 2009 23:51:13 +0000</pubDate>
		<dc:creator>c2c</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[développement]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Tech]]></category>

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

Call Stack:
    0.0001     623440   1. {main}() /home/www/blog.juliencrouzet.fr/index.php:0
    0.0002     628968   2. require('/home/www/blog.juliencrouzet.fr/wp-blog-header.php') /home/www/blog.juliencrouzet.fr/index.php:17
    0.2060   38087216   3. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php') /home/www/blog.juliencrouzet.fr/wp-blog-header.php:16
    0.2069   38090136   4. do_feed() /home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php:14
    0.2069   38090416   5. do_action() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1721
    0.2069   38092440   6. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:395
    0.2069   38092496   7. do_feed_rss2() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:0
    0.2069   38092688   8. load_template() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1753
    0.2071   38154832   9. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php') /home/www/blog.juliencrouzet.fr/wp-includes/theme.php:1087
    0.2690   38189968  10. the_excerpt_rss() /home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php:46
    0.2762   38192568  11. apply_filters() /home/www/blog.juliencrouzet.fr/wp-includes/feed.php:177
    0.2764   38194968  12. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:166

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

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

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

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

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

Call Stack:
    0.0001     623440   1. {main}() /home/www/blog.juliencrouzet.fr/index.php:0
    0.0002     628968   2. require('/home/www/blog.juliencrouzet.fr/wp-blog-header.php') /home/www/blog.juliencrouzet.fr/index.php:17
    0.2060   38087216   3. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php') /home/www/blog.juliencrouzet.fr/wp-blog-header.php:16
    0.2069   38090136   4. do_feed() /home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php:14
    0.2069   38090416   5. do_action() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1721
    0.2069   38092440   6. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:395
    0.2069   38092496   7. do_feed_rss2() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:0
    0.2069   38092688   8. load_template() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1753
    0.2071   38154832   9. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php') /home/www/blog.juliencrouzet.fr/wp-includes/theme.php:1087
    0.2860   38193872  10. the_excerpt_rss() /home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php:46
    0.2975   38196448  11. apply_filters() /home/www/blog.juliencrouzet.fr/wp-includes/feed.php:177
    0.2977   38198824  12. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:166

]]></description>
			<content:encoded><![CDATA[<div id="attachment_344" class="wp-caption aligncenter" style="width: 152px"><a href="http://blog.juliencrouzet.fr/wp-content/uploads/2009/03/pr_cadenas_anse_surex_de_40mm.jpg" rel="lightbox[343]"><img class="size-thumbnail wp-image-344" title="pr_cadenas_anse_surex_de_40mm" src="http://blog.juliencrouzet.fr/wp-content/uploads/2009/03/pr_cadenas_anse_surex_de_40mm-150x150.jpg" alt="pr_cadenas_anse_surex_de_40mm" width="142" height="160" /></a><p class="wp-caption-text">Protégez votre code !</p></div>
<p style="text-align: left;">Une des failles les plus connues, les plus utilisées et les plus simples à utiliser quand on parle de sites Web, c&#8217;est évidemment les injections SQL. Même Kaskpersky, le grand nom de la sécurité informatique <a href="/2009/02/10/le-site-de-kaspersky-hacke/">y passe</a>.</p>
<p style="text-align: left;">Les requêtes préparées sont, de loin, la méthode la plus fiable et la plus performante pour se protéger.</p>
<p style="text-align: left;">Je vais essayer dans cet article de vous expliquer pourquoi et surtout comment les utiliser avec PDO (qui rappelons le va devenir le <a href="http://r.wikipedia.org/wiki/Système_de_gestion_de_base_de_données">SGBD </a>par défaut de PHP6, les fonctions mysql_*, désuettes,  seront recalées au fin fond d&#8217;une extension <a href="http://pecl.php.net">PECL</a>).</p>
<p style="text-align: left;"><span id="more-343"></span></p>
<h2 style="text-align: left;">Une injection SQL, comment ça marche ?</h2>
<p>Le fonctionnement des applications PHP / MySQL (ou autres) depuis des lustres est basé sur un principe simple : L&#8217;utilisateur envoi une requête, cette requête est interprétée, une requête SQL en découle et le résultat est mis en forme ou enregistré en base de données.</p>
<p>Pour ce faire, le développeur génère des requêtes SQL en utilisant les données envoyées par l&#8217;internaute comme paramètres, par exemple :</p>
<pre lang="php">mysql_query('UPDATE `users` SET `name`="' . $_POST['name'] . '" WHERE `id_user`=' . $user_id);</pre>
<p>Problème : L&#8217;internaute envoie ce qu&#8217;il veut, et la requête effectuée sur la base de donnée peut être dangereuse. Par exemple, dans l&#8217;exemple précédent, si l&#8217;internaute envoie</p>
<blockquote><p>&laquo;&nbsp;; DELETE from users; &#8211;</p></blockquote>
<p>vous allez envoyer comme requête à votre serveur SQL :</p>
<pre lang="sql">UPDATE `users` SET `name`=""; DELETE from users; --" WHERE `id_user`= 5</pre>
<p>Soit : Efface tous les noms de ma table puis vide là. Problématique &#8230;</p>
<h2 style="text-align: left;">L&#8217;échappement comme solution miracle &#8230;</h2>
<p>Face à ce problème évident de sécurité, les développeurs ont souvent le reflexe d&#8217;utiliser <a href="http://fr.php.net/mysql-escape-string">mysql_escape_string()</a>, ou mieux, <a href="http://fr.php.net/manual/fr/function.mysql-real-escape-string.php">mysql_real_escape_string()</a>. Ces deux fonctions de PHP ont pour but de protéger les champs envoyés par les internautes contre ces injections SQL en échappant (en ajoutant un backslash ou <strong></strong>) devant les caractères    <em>NULL</em>, <em>x00 </em>(null), <em>n </em>(saut de ligne),    <em>r</em> (retour chariot), <em></em>, <em>&#8216;</em>,    <em>&laquo;&nbsp;</em> et <em>x1a </em>(control).</p>
<p>Pour l&#8217;exemple précédent, cela donnera :</p>
<pre lang="php">mysql_query('UPDATE `users` SET `name`="' . mysql_real_escape_string($_POST['name']) . '" WHERE `id_user`=' . mysql_real_escape_string($user_id));</pre>
<p>soit la requête :</p>
<pre lang="sql">UPDATE `users` SET `name`=""; DELETE from users; --" WHERE `id_user`= 5</pre>
<p>Youpi nous voila protégé ! L&#8217;article est fini ? Non.</p>
<h2 style="text-align: left;">&#8230; ou pas !</h2>
<h3>mysql_real_escape_string() n&#8217;est pas totalement sécurisé</h3>
<p>Et oui, on nous ment, on nous spolie ! Bon, la on passe au niveau barbu du hacking (les enfants, passez au point suivant, ne refaites pas cela chez vous).</p>
<p>mysql_real_escape_string() se base sur le jeu de caractère de la connexion active (<em>SET NAMES</em>) et si celui-ci n&#8217;est pas actif, elle utilise le jeu de caractère par défaut. Il est alors facile d&#8217;utiliser la magie de &laquo;&nbsp;<em><code>chr(0xbf) . chr(0x27)</code></em><code>" pour insérer l'injection fatale.</code>Cependant, cela ne marche que pour des jeu de caractères comme GBK ou Big5, donc il est probable qu&#8217;un <em>SET NAMES</em> soit présent.</p>
<p>Vous n&#8217;avez pas compris ? Pas grave, retenez juste que malgré ce que dit le complot universel, mysql_real_escape_string() n&#8217;est pas infaillible !</p>
<h3>Alors pourquoi ne pas encoder la chaîne ?</h3>
<p>Effectivement, si l&#8217;on utilise <a href="http://fr.php.net/manual/fr/function.htmlentities.php">htmlentities()</a> qui convertit chaque caractère qui peut l&#8217;être en entité HTML (&amp;quelquechose), ou <a href="http://fr.php.net/base64-encode">base64_encode()</a>, etc. il semble que l&#8217;on sera protégés ?</p>
<p>Oui et non, déjà non, on ne sera pas <span style="text-decoration: underline;">COMPLÈTEMENT </span>protégé, pour les même raisons que le point précédent. Et puis vous allez vous compliquer la vie lorsque vous souhaiterez rechercher du texte (oui, rechercher des entités HTML c&#8217;ets pas sexy).</p>
<h3>Et puis surtout, ce n&#8217;est pas optimisé !</h3>
<p>Un des goulot d&#8217;étranglement d&#8217;une application web ou d&#8217;un site, c&#8217;est souvent la base de donnée ; alors en plus y rajouter des traitement, recherche et modifications permanents de chaîne, c&#8217;est du suicide et du massacre de cycle de processeur !</p>
<h2 style="text-align: left;">Puis vinrent les requêtes préparées !</h2>
<p>Les requêtes préparées, ou prepared queries, c&#8217;est la bonne réponse, pour la simple et bonne raison : Ce n&#8217;est pas un patch mais une refonte de la reflexion !</p>
<p>Posons nous une seconde sur le problème, la source de la faille repose sur le fait qu&#8217;un serveur SQL quel qu&#8217;il soit se base sur un concept : PHP se connecte, lui donne une requête (un ordre) qu&#8217;il execute sans broncher.Le script lui prend une donnée qui n&#8217;est pas contrôlée par le développeur et la place au milieu de l&#8217;ordre donnée.</p>
<p>Il n&#8217;y a donc qu&#8217;une solution : Séparer ce que l&#8217;on contrôle, l&#8217;ordre, de ce que l&#8217;on ne controle pas, les arguments.</p>
<p>Le principe de la requête préparée, c&#8217;est ça. On dit au serveur SQL :</p>
<blockquote><p>Tu vas modifier le champs name par une certaine valeur la table users quand le champs id sera d&#8217;un autre certaine valeur</p></blockquote>
<p>Puis, on lui précise</p>
<blockquote><p>La première valeur c&#8217;est $_POST['name'], et la seconde c&#8217;est 5</p></blockquote>
<p>La première partie fera l&#8217;objet d&#8217;un analyse du serveur SQL, la seconde ne le sera pas. Voila, on est protégé, on est optmisé la messe est dite <img src='http://blog.juliencrouzet.fr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2 style="text-align: left;">Donc, comment ça marche ?</h2>
<p>Qui dit requête préparée en PHP, dit <a href="http://fr.php.net/pdo">PDO</a> (ou <a href="http://framework.zend.com/manual/fr/zend.db.html">Zend Framework</a> qui vous simplifie la vie, voila il est placé).</p>
<p>Plutôt qu&#8217;un long discours, voici un exemple qui insere et lit des données, pour aller plus loin, je vous laisse lire la doc.</p>
<pre lang="php">/**
 * Création d'un objet PDO
 */
$object = new PDO('mysql:host=localhost;dbname=myDatabase', 'user', 'pass');
/**
 * On énonce une requête préparée
 */
$statement = $object->prepare("SELECT * FROM `user` WHERE `name`=? OR `firstname`=?");
/**
 * On éxécute l'énoncé avec une paire d'argument
 */
$statement->execute(array($_POST['name'], $_POST['firstname']));
/**
 * On récupère le résultat
 */
$result = $statement->fetchRow();
/**
 * On énonce une requête préparée d'insertion
 */
$statement = $object->prepare("INSERT INTO `users` (`name`, `firstname`, `email`) VALUES (?, ?, ?)");
/**
 * On éxécute l'énoncé pour 4 valeurs différentes
 */
$statement->execute(array('doe', 'john', 'john.doe@gmail.com'));
$statement->execute(array('gates', 'bill', 'bill@microsoft.com'));
$statement->execute(array('jobs', 'steve', 'sjobs@apple.com'));
$statement->execute(array('"; DELETE from users; --', 'blah', 'bleh'));</pre>
<h2 style="text-align: left;">D&#8217;autres intérêts ?</h2>
<p style="text-align: left;">Utiliser des requêtes préparées en PDO ne vous apportera pas que la sécurisation de vos requêtes.</p>
<p style="text-align: left;">Déjà, utiliser PDO vous apportera une vraie conception objet de la gestion de la base de données (mais encore plus avec Zend Framework <img src='http://blog.juliencrouzet.fr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ) mais j&#8217;y reviendrais avec un billet sur <a href="http://fr.wikipedia.org/wiki/Mod%C3%A8le-Vue-Contr%C3%B4leur">MVC</a>.</p>
<p>Mais en plus, si vous regardez bien l&#8217;exemple, j&#8217;ai fait 4 requêtes avec une énoncé, donc concretement, votre serveur SQL n&#8217;a analysé qu&#8217;une fois votre requête et vous n&#8217;avez fait aucune analyse des paramètres.</p>
<p>Je vous laisse méditer sur l&#8217;optimisation obtenue <img src='http://blog.juliencrouzet.fr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.juliencrouzet.fr/343/php-les-requetes-preparees/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Ce qu&#039;il faut savoir avant d&#039;envoyer des emails en masse</title>
		<link>http://blog.juliencrouzet.fr/298/ce-quil-faut-savoir-avant-denvoyer-des-emails-en-masse/</link>
		<comments>http://blog.juliencrouzet.fr/298/ce-quil-faut-savoir-avant-denvoyer-des-emails-en-masse/#comments</comments>
		<pubDate>Tue, 10 Mar 2009 09:00:45 +0000</pubDate>
		<dc:creator>c2c</dc:creator>
				<category><![CDATA[email]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[spam]]></category>
		<category><![CDATA[Tech]]></category>

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

Call Stack:
    0.0001     623440   1. {main}() /home/www/blog.juliencrouzet.fr/index.php:0
    0.0002     628968   2. require('/home/www/blog.juliencrouzet.fr/wp-blog-header.php') /home/www/blog.juliencrouzet.fr/index.php:17
    0.2060   38087216   3. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php') /home/www/blog.juliencrouzet.fr/wp-blog-header.php:16
    0.2069   38090136   4. do_feed() /home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php:14
    0.2069   38090416   5. do_action() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1721
    0.2069   38092440   6. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:395
    0.2069   38092496   7. do_feed_rss2() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:0
    0.2069   38092688   8. load_template() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1753
    0.2071   38154832   9. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php') /home/www/blog.juliencrouzet.fr/wp-includes/theme.php:1087
    0.3115   38197776  10. the_excerpt_rss() /home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php:46
    0.3205   38200336  11. apply_filters() /home/www/blog.juliencrouzet.fr/wp-includes/feed.php:177
    0.3208   38202720  12. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:166

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

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

Call Stack:
    0.0001     623440   1. {main}() /home/www/blog.juliencrouzet.fr/index.php:0
    0.0002     628968   2. require('/home/www/blog.juliencrouzet.fr/wp-blog-header.php') /home/www/blog.juliencrouzet.fr/index.php:17
    0.2060   38087216   3. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php') /home/www/blog.juliencrouzet.fr/wp-blog-header.php:16
    0.2069   38090136   4. do_feed() /home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php:14
    0.2069   38090416   5. do_action() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1721
    0.2069   38092440   6. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:395
    0.2069   38092496   7. do_feed_rss2() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:0
    0.2069   38092688   8. load_template() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1753
    0.2071   38154832   9. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php') /home/www/blog.juliencrouzet.fr/wp-includes/theme.php:1087
    0.3322   38201680  10. the_excerpt_rss() /home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php:46
    0.3475   38204312  11. apply_filters() /home/www/blog.juliencrouzet.fr/wp-includes/feed.php:177
    0.3478   38206736  12. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:166

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

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

Call Stack:
    0.0001     623440   1. {main}() /home/www/blog.juliencrouzet.fr/index.php:0
    0.0002     628968   2. require('/home/www/blog.juliencrouzet.fr/wp-blog-header.php') /home/www/blog.juliencrouzet.fr/index.php:17
    0.2060   38087216   3. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php') /home/www/blog.juliencrouzet.fr/wp-blog-header.php:16
    0.2069   38090136   4. do_feed() /home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php:14
    0.2069   38090416   5. do_action() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1721
    0.2069   38092440   6. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:395
    0.2069   38092496   7. do_feed_rss2() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:0
    0.2069   38092688   8. load_template() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1753
    0.2071   38154832   9. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php') /home/www/blog.juliencrouzet.fr/wp-includes/theme.php:1087
    0.3647   38205584  10. the_excerpt_rss() /home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php:46
    0.3807   38208192  11. apply_filters() /home/www/blog.juliencrouzet.fr/wp-includes/feed.php:177
    0.3810   38210600  12. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:166

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

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

Call Stack:
    0.0001     623440   1. {main}() /home/www/blog.juliencrouzet.fr/index.php:0
    0.0002     628968   2. require('/home/www/blog.juliencrouzet.fr/wp-blog-header.php') /home/www/blog.juliencrouzet.fr/index.php:17
    0.2060   38087216   3. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php') /home/www/blog.juliencrouzet.fr/wp-blog-header.php:16
    0.2069   38090136   4. do_feed() /home/www/blog.juliencrouzet.fr/wp-includes/template-loader.php:14
    0.2069   38090416   5. do_action() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1721
    0.2069   38092440   6. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:395
    0.2069   38092496   7. do_feed_rss2() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:0
    0.2069   38092688   8. load_template() /home/www/blog.juliencrouzet.fr/wp-includes/functions.php:1753
    0.2071   38154832   9. require_once('/home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php') /home/www/blog.juliencrouzet.fr/wp-includes/theme.php:1087
    0.3985   38209488  10. the_excerpt_rss() /home/www/blog.juliencrouzet.fr/wp-includes/feed-rss2.php:46
    0.4094   38212072  11. apply_filters() /home/www/blog.juliencrouzet.fr/wp-includes/feed.php:177
    0.4096   38214456  12. call_user_func_array() /home/www/blog.juliencrouzet.fr/wp-includes/plugin.php:166

]]></description>
			<content:encoded><![CDATA[<div id="attachment_206" class="wp-caption aligncenter" style="width: 241px"><a href="http://blog.juliencrouzet.fr/wp-content/uploads/2009/02/codemonkeysketch.jpg" rel="lightbox[205]"><img class="size-medium wp-image-206" title="codemonkeysketch" src="http://blog.juliencrouzet.fr/wp-content/uploads/2009/02/codemonkeysketch-296x300.jpg" alt="codemonkeysketch" width="231" height="166" /></a><p class="wp-caption-text">De PHP/FI à PHP6, les règles on changé</p></div>
<p>Après une dure semaine coté outils et méthodes de développement, je me lance dans une liste dont j&#8217;assume le coté très subjectif et qui n&#8217;engage que moi : les 10 choses qui permettent de séparer un développeur, un vrai qui sent la sueur, d&#8217;un webmaster.</p>
<p>Cette liste s&#8217;entend pour un développement Web et PHP &#8230;</p>
<p><span id="more-205"></span></p>
<h2><a href="http://fr.wikipedia.org/wiki/Programmation_orient%C3%A9e_objet">Programmation Orientée Objet</a></h2>
<p>Sujet sensible, si l&#8217;en est &#8230; J&#8217;ai encore du mal à comprendre qu&#8217;en 2009 on développe en <a href="http://fr.wikipedia.org/wiki/Programmation_proc%C3%A9durale">procédural </a>ma bonne dame !</p>
<h2><a href="http://fr.wikipedia.org/wiki/Framework">Utilisation d&#8217;un framework</a></h2>
<p>J&#8217;ai fait mes études à <a href="http://www.epitech.eu">{EPITECH}</a> (pas taper), ou l&#8217;on commence sa première année à réinventer la roue : se redévelopper sa propre libc, de <a href="http://www.linux-kheops.com/doc/man/manfr/man-html-0.9/man3/atoi.3.html">atoi()</a> à <a href="http://www.linux-kheops.com/doc/man/manfr/man-html-0.9/man3/malloc.3.html">malloc()</a>. Je comprenais et appréciais le principe de disséquer tout ça pour mieux le comprendre plutôt que d&#8217;en apprendre le manuel et s&#8217;en contenter.</p>
<p>Et puis est venu le stage, et la je ne comprenais plus ! Mon directeur technique s&#8217;était bricolé une librairie PHP3/PHP4 sortie d&#8217;un espace intersidéral qui était censée gérer tout, du traitement des chaînes au transferts FTP ; ce mauvais reflexe m&#8217;a poursuivi longtemps &#8230;</p>
<p>Développer un site ou une application Web, c&#8217;est utiliser une base saine, donc un Framework, pour se concentrer sur ce que l&#8217;on crée, à quoi bon <strong>mal </strong>recoder <a href="http://www.dreamincode.net/code/snippet1428.htm">une fonction</a> qui protège les champs d&#8217;une requête SQL ? Des centaines de développeurs l&#8217;ont déjà <strong>bien </strong>fait <a href="http://framework.zend.com/manual/fr/zend.db.html">pour vous</a> !</p>
<h2><a href="http://fr.wikipedia.org/wiki/Mod%C3%A8le-Vue-Contr%C3%B4leur">Utilisation d&#8217;une architecture MVC</a></h2>
<p>Un développeur qui ne respecte pas MVC :</p>
<blockquote><p>Si on veut enlever ces liens du footer, je vais devoir modifier la fonction generate_footer()</p></blockquote>
<p>L&#8217;équivalent chez son garagiste :</p>
<blockquote><p>Sur que je peux vous changer la plaque d&#8217;immatriculation, mais je vais devoir démonter la boite de vitesse</p></blockquote>
<p>L&#8217;avantage, c&#8217;est que ce point a de fortes chances d&#8217;être correlé avec le point précédent puis que la plupart des Framework PHP actuels se reposent sur une architecture MVC.</p>
<h2><a href="http://fr.wikipedia.org/wiki/Test_unitaire">Définir des tests unitaires</a></h2>
<p>Un développeur, un webmaster ou un boulanger ont une chose en commun : Ils ne sont pas infaillibles. Tout développement comporte forcément des bugs, c&#8217;est la <a href="http://fr.wikipedia.org/wiki/Loi_de_murphy">loi de murphy</a>.</p>
<p>Bien qu&#8217;aillant du mal à l&#8217;admettre, le développeur, le vrai, le poilu sait prévoir le fait qu&#8217;il oubliera ça et là de jolies erreur de conception, et il veut le savoir avant d&#8217;être montré du doigt ; il a donc inventé les <a href="http://fr.wikipedia.org/wiki/Test_unitaire">tests unitaires</a>.</p>
<p>PHP à donc aussi ses outils de tests unitaires, comme <a href="http://www.phpunit.de/">PHPUnit </a>ou <a href="http://www.simpletest.org/">SimpleTest</a>. A consommer sans modération !</p>
<h2><a href="http://fr.wikipedia.org/wiki/M%C3%A9moire_cache">Utiliser un cache</a></h2>
<p>Même si certains le pensent, les ressources sont chères et il ne faut pas les gaspiller. Le but ultime de toute application Web reste quand même, dans une grande majorité de cas, d&#8217;être utilisée par le plus de monde possible. C&#8217;est donc automatique, plus votre site est consulté, plus vous aurez besoin de processeur et de mémoire, plus cela vous coutera cher.La meilleure et la plus simple des méthodes d&#8217;économie de ressources est l&#8217;utilisation de mémoire cache.</p>
<p>Tout résultat d&#8217;une requête SQL, tout résultat d&#8217;une fonction complexe (calculs, recherches, etc.) doit ammener une question simple : Est-ce que je ne peux pas mettre ça en cache ? Si oui, action !</p>
<p>Le cache le plus simple est d&#8217;écrire ce résultat dans un fichier, mais il reste des solutions plus optimisées et simple à déployer comme <a href="http://www.danga.com/memcached">memcached</a>, <a href="http://sharedance.pureftpd.org/project/sharedance">sharedance </a>ou <a href="http://fr.php.net/apc">APC</a>. Là aussi, les Frameworks vous rendent cette tâche encore plus simple qu&#8217;elle ne l&#8217;est.</p>
<h2><a href="http://fr.wikipedia.org/wiki/Documentation_logicielle">Documenter son code</a></h2>
<p>Le meilleur conseil que l&#8217;on puisse donner à un développeur est:</p>
<blockquote><p><a class="title" href="http://www.myconfinedspace.com/watermark.php?src=wp-content/uploads/2007/06/001grg3w.jpg" rel="lightbox[205]"> Always code as if the person who will maintain your code is a maniac serial killer knows where you live</a></p></blockquote>
<p>Un des primodiaux pour ne pas vous faire éventrer par ce serial killer est de documenter ce code. Ce qui vous parait très clair aujourd&#8217;hui ne le sera plus du tout 3 jours ou 3 bières plus tard ; autant dire que cela ressemblera peut être à du bulgare pour un autre développeur 3 ans plus tard.</p>
<p>Et quitte à commenter votre code, autant bien le faire, en respectant une norme communément admise en PHP, j&#8217;ai nommé <a href="http://fr.wikipedia.org/wiki/Javadoc">JavaDoc</a>. Ce <a href="http://pear.php.net/manual/en/standards.php">document</a> est une bible, il est conseillé, sous peine de torture.</p>
<h2><a href="http://fr.wikipedia.org/wiki/Factorisation_(informatique)">Factoriser son code</a></h2>
<p>Ce point coule vraiment de source (mais rarement appliqué). Combien de fois suis-je tombé sur des projets ou la meme chose était codée dans 5 fonctions (et donc 5 fois avec des bugs, même souvent différents !) ?</p>
<p>Donc, vu qu&#8217;un développeur poilu code aussi en POO (oui, le premier point), factoriser son code c&#8217;est aussi utiliser de l&#8217;<a href="http://fr.wikipedia.org/wiki/H%C3%A9ritage_(informatique)">héritage de classe</a>.</p>
<h2><a href="http://fr.wikipedia.org/wiki/%C3%89vidence">Concentrer la configuration</a></h2>
<p>Toute configuration (j&#8217;entend par la des <a href="http://fr.php.net/define">define()</a>, des <a href="http://fr.php.net/manual/fr/language.variables.scope.php">variables globales</a>, meme si c&#8217;est très mal, ou toute variables que l&#8217;on peut modifier) doit être séparée du code et concentrer dans un fichier ou plusieurs fichiers dans un répertoire différent, la mettre en haut d&#8217;une classe est une absurdité !</p>
<p>De même, même si c&#8217;est aussi évident, ce fichier ou répertoire ne doit pas être consultable par les internautes (en dehors du htdocs).</p>
<h2><a href="http://fr.wikipedia.org/wiki/R%C3%A9gionalisation_de_logiciel">Localiser son code</a></h2>
<p>Personne ne sait de quoi demain sera fait, votre super site peut devenir demain un tel succès que des anglophones veuillent, eux aussi, profiter de cette merveille. Je pense qu&#8217;à ce jour, j&#8217;ai du assister à plus de 10 fois à un rush pour recoder tout un site en anglais.</p>
<p>Pour éviter ça, un reflexe simple, localiser son code, en utilisant des outils comme <a href="http://www.gnu.org/software/gettext/">Gettext</a>, <a href="http://developers.sun.com/dev/gadc/technicalpublications/articles/xliff.html">XLIFF</a> ou <a href="http://www.potu.com/man/doc.trolltech.com/4.0/linguist-manual.html">Qt Linguist</a>. &lt;radottage&gt;Les frameworks actuels gèrent tous ça&lt;/radottage&gt;</p>
<h2><a href="http://fr.wikipedia.org/wiki/Analyse_fonctionnelle_(conception)">Réfléchir avant de coder</a></h2>
<p>Ce point est très subjectif, je sais. Mais c&#8217;est un point essentiel du succès d&#8217;un développement. C&#8217;est très tentant de se jeter dans son éditeur, au début d&#8217;un projet, pour mettre les mains dans le camboui.</p>
<p>Résistez à la tentation et jetez sur papier ou sur <a href="http://fr.wikipedia.org/wiki/Unified_Modeling_Language">UML </a>votre réflexion &#8230; ca prend 10 minutes pour chaque classe et ca vous sauve souvent 2 heures de prise de tête !</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.juliencrouzet.fr/205/10-regles-qui-separent-un-developpeur-dun-webmaster/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
