<?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>Gregwar &#187; iterable</title>
	<atom:link href="http://www.gregwar.com/tag/iterable/feed" rel="self" type="application/rss+xml" />
	<link>http://www.gregwar.com</link>
	<description>Web &#38; technologies</description>
	<lastBuildDate>Wed, 28 Dec 2011 19:24:56 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Fonctionnalités obscures de PHP</title>
		<link>http://www.gregwar.com/php/fonctionnalites-obscures-ph-25</link>
		<comments>http://www.gregwar.com/php/fonctionnalites-obscures-ph-25#comments</comments>
		<pubDate>Thu, 21 Jan 2010 18:45:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[iterable]]></category>
		<category><![CDATA[object]]></category>

		<guid isPermaLink="false">http://www.slashed.fr/?p=25</guid>
		<description><![CDATA[Un petit article pour parler des fonctionalités &#171;&#160;obscures&#160;&#187; de PHP. J&#8217;ai trouvé en effet mal documenté certains features qui me semblent intéréssant du coté des interfaces. Je vous laisse regarder la doc si vous n&#8217;avez pas envie de lire l&#8217;article en cliquant ici.
Des pseudos-tableaux
Il est en effet possible d&#8217;utiliser la syntaxe suivante (utiliser des objets [...]]]></description>
			<content:encoded><![CDATA[<p>Un petit article pour parler des fonctionalités &laquo;&nbsp;obscures&nbsp;&raquo; de PHP. J&#8217;ai trouvé en effet mal documenté certains features qui me semblent intéréssant du coté des interfaces. Je vous laisse regarder la doc si vous n&#8217;avez pas envie de lire l&#8217;article en <a href="http://fr2.php.net/manual/en/reserved.interfaces.php" target="_blank">cliquant ici</a>.</p>
<h2>Des pseudos-tableaux</h2>
<p>Il est en effet possible d&#8217;utiliser la syntaxe suivante (utiliser des objets comme des arrays):</p>
<pre class="brush: php">$m = new Machin;
$m[&quot;test&quot;] = 12</pre>
<p>Ca peut parraitre bizarre, mais c&#8217;est parfois pratique. Voici une petite description de l&#8217;utilisation de ce feature:</p>
<pre class="brush: php">class Machin implements ArrayAccess {
	//Est-ce que isset($obj[$var] ?
	public function offsetExists($var) {
		return true;
	}
	//Quelle est la valeur de $obj[$var] ?
	public function offsetGet($var) {
		return 42;
	}
	//Définition de la valeur $obj[$var]
		public function offsetSet($var, $val) {
		echo &quot;$var = $val!\n&quot;;
	}
	//Appel à unset($var[$obj])
	public function offsetUnset($var) {
		echo &quot;removing $var\n&quot;;
	}
}
$m = new Machin;
if (isset($m[&quot;toto&quot;])) { //true
	echo $m[&quot;toto&quot;].&quot;\n&quot;;   //42
	$m[&quot;truc&quot;] = &quot;bidule&quot;;  //truc = bidule!
	unset($m[&quot;blork&quot;]);     //removing blork
}</pre>
<p>Il est par exemple plus facile de créer un système de session customizées, enfin, laissez votre imagination tourner je pense que vous aurez bien plus d&#8217;idées que moi, sachant que chaque acces au tableau provoque un appel de fonction et peut donc être dynamique (pourquoi pas requêter un SGBD). Il est aussi possible de &laquo;&nbsp;mapper&nbsp;&raquo; un serveur memcache par exemple, créer une classe qui permettra d&#8217;utiliser le serveur de cache comme un simple tableau.</p>
<h2>Des objets itérables</h2>
<p>Vous qui utilisez des templates php à tour de bras vous devez apprécier fortement l&#8217;instruction <em>foreach</em>. Je vous laisse donc découvrir ce que vous pouvez faire en implémentant <em>Iterator</em>:</p>
<ul>
<li>function <em>rewind() </em>: retourne à la premiere position de l&#8217;itération</li>
<li>function <em>current()</em> : retourne l&#8217;élément courant</li>
<li>function <em>key()</em> : retourne la clé courante</li>
<li>function <em>next()</em> : passe à l&#8217;élément suivant</li>
<li>function <em>valide()</em> : retourne vrai si l&#8217;élément est valide (permet d&#8217;arrêter l&#8217;itération)</li>
</ul>
<p>Il est alors possible de faire:</p>
<pre class="brush: php">$trucs = new Trucs;
foreach ($trucs as $t) {
	//Faire quelque chose avec $t
}</pre>
<p>Ce qui peut s&#8217;avérer pratique lorsque la sémantique de votre objet est justement d&#8217;être un containers. Pour plus de détails je vous laisse consulter la <a href="http://fr2.php.net/manual/en/class.iterator.php" target="_blank">documentation</a>.</p>
<h2>Appels de méthodes enchaînés</h2>
<p>Ce n&#8217;est pas vraiment quelque chose d&#8217;obscur ou de caché mais plus une astuce. Lorsque vous souhaitez appeller plusieurs fonctions sur le même objet, et que ces fonctions ne retournent rien, rien ne coute d&#8217;ajouter un <em>return $this;</em> à la fin de la fonction en question, ce qui vous permet d&#8217;enchainer les appels sur la  même ligne. Un petit exemple:</p>
<pre class="brush: php">class Query {
	private $sql;
	public function __construct() {
		$this-&gt;sql = &quot;SELECT * FROM &quot;;
	}
	public function from($table) {
		$this-&gt;sql.= &quot;`$table` &quot;;
		return $this;
	}
	public function where($where) {
		$this-&gt;sql.= &quot;WHERE $where &quot;;
		return $this;
	}
	public function exec() {
		echo &quot;Requete: &quot;.$this-&gt;sql.&quot;\n&quot;;
	}
}

$q = new Query;
$q-&gt;from(&quot;users&quot;)-&gt;where(&quot;id=12&quot;)-&gt;exec();
//Requete: SELECT * FROM `users` WHERE id=12</pre>
<p>L&#8217;exemple est très caricatural, mais on voit vite les avantages d&#8217;un tels procedé. Cette syntaxe est largement utilsiée par certaines libs comme <a href="http://www.doctrine-project.org/" target="_blank">Doctrine</a>.</p>
<h2>Les fonctions magiques</h2>
<p>Chaque classes définit ses propres méthodes, mais peut aussi définir des méthodes dynamiquement. Lorsqu&#8217;une méthode n&#8217;existe pas, php appelle la fonction <em>__call()</em> si elle existe. un petit exemple:</p>
<pre class="brush: php">class User {
	public function __call($func, $params) {
		if (substr($func, 0, 2) == &quot;by&quot;) {
			$name = trim(strtolower(substr($func, 2)));
			$param = $params[0];
			echo &quot;SELECT * FROM users WHERE `$name`=\&quot;&quot;.$params[0].&quot;\&quot;&quot;;
		}
	}
}
$u = new User;
$u-&gt;byName(&quot;toto&quot;);
//SELECT * FROM users WHERE `name`=&quot;toto&quot;</pre>
<p>Encore très simplifié, mais je pense que le concept transparait bien, les fonctions peuvent être parfois plus parlantes que des noms d&#8217;arguments.</p>
<p>A noter qu&#8217;il existe d&#8217;autres fonctions magiques, comme celles permettant d&#8217;acceder à des pseudos-propriétés (<em>$u-&gt;name</em> par exemple) de manière dynamique (avec un appel de fonction). Là aussi, <a href="http://fr.php.net/manual/en/language.oop5.overloading.php" target="_blank">jetez un oeil au manuel</a>.</p>
<h2>Le mécanisme de réflexion</h2>
<p>Un autre aspect sur lequele je ne vais pas m&#8217;éterniser, le <a href="http://fr2.php.net/manual/en/book.reflection.php" target="_blank">mécanisme de réflexion</a>. Comme tous les langages de haut niveau, PHP peut s&#8217;analyser lui même, il est ainsi possible de savoir dynamiquement si une fonction existe, si une classe implémente telle ou telle interface, dans quel fichier elle est définie ou encore le noms et les valeurs des propriétés statiques.</p>
<p>Voila je m&#8217;arrête ici, j&#8217;éspère vous avoir donné quelques idées pour vos projets. La souplesse du langage permet de faire beaucoup de choses assez sympas qui rendent le code (celui qui utilise vos classes bizarres!) plus lisible et facile à maintenir, donc à vos claviers.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gregwar.com/php/fonctionnalites-obscures-ph-25/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

