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

  <title><![CDATA[mtdowling]]></title>
  <link href="http://mtdowling.com/atom.xml" rel="self"/>
  <link href="http://mtdowling.com/"/>
  <updated>2015-05-06T10:17:16-07:00</updated>
  <id>http://mtdowling.com/</id>
  <author>
    <name><![CDATA[Michael Dowling]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Transducers in PHP]]></title>
    <link href="http://mtdowling.com/blog/2014/12/04/transducers-php/"/>
    <updated>2014-12-04T00:00:00-08:00</updated>
    <id>http://mtdowling.com/blog/2014/12/04/transducers-php</id>
    <content type="html"><![CDATA[<p>Rich Hickey recently announced that <a href="http://clojure.org/transducers">transducers</a> are going to be added to Clojure, and it prompted <a href="http://www.reddit.com/r/haskell/comments/2kro78/typesafe_transducers_in_clojure_scala_and_haskell/">quite</a> <a href="http://www.reddit.com/r/haskell/comments/2cv6l4/clojures_transducers_are_perverse_lenses/cjjyay7">a bit</a> <a href="https://news.ycombinator.com/item?id=8143905">of  discussion</a>. After a somewhat <a href="http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming">brief announcement</a>, Hickey followed up with a couple videos that describe transducers in much more detail: <em><a href="https://www.youtube.com/watch?v=6mTbuzafcII">Transducers</a></em> and <em><a href="https://www.youtube.com/watch?v=4KqUvG8HPYo">Inside Transducers + more.async</a></em></p>

<p>Transducers are a very powerful concept that can be utilized in almost any language. In fact, they have been ported to various other languages including JavaScript
(<a href="https://github.com/jlongster/transducers.js">1</a> and <a href="https://github.com/cognitect-labs/transducers-js">2</a>), <a href="https://github.com/cognitect-labs/transducers-python">Python</a>, <a href="https://github.com/cognitect-labs/transducers-ruby">Ruby</a>,
<a href="transducers-java">Java</a>, and
<a href="https://github.com/sdboyer/transducers-go">Go</a>.</p>

<p>And now&hellip;transducers are available in PHP via <a href="https://github.com/mtdowling/transducers.php">transducers.php</a>!</p>

<h2>So, erm&hellip; What&rsquo;s a transducer?</h2>

<p><img style="float:right" src="http://mtdowling.com/images/burrito.png" /></p>

<p>From the Clojure documentation:</p>

<blockquote><p>Transducers are composable algorithmic transformations. They are independent from the context of their input and output sources and specify only the essence of the transformation in terms of an individual element. Because transducers are decoupled from input or output sources, they can be used in many different processes &ndash; collections, streams, channels, observables, etc. Transducers compose directly, without awareness of input or creation of intermediate aggregates.</p></blockquote>

<p>This is a fancy way of saying that you can use functions like <code>map</code> and <code>filter</code> on basically any type of data source (not just sequences), and by using a step function, transducers can directly output to any type of data structure like iterators, filling an array, writing to a stream, or even invoking a custom function.</p>

<h2>Eager evaluation</h2>

<p>Transducers can be applied <a href="http://en.wikipedia.org/wiki/Eager_evaluation">eagerly</a>.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">Transducers</span> <span class="k">as</span> <span class="nx">t</span><span class="p">;</span>

<span class="nv">$xf</span> <span class="o">=</span> <span class="nx">t\map</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="nv">$x</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$x</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="p">};</span>
<span class="nv">$result</span> <span class="o">=</span> <span class="nx">t\xform</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="nv">$xf</span><span class="p">);</span>
<span class="c1">//&gt; [2, 3, 4]</span>
</code></pre></div>


<p>The above example creates a transformation function in <code>$xf</code> that increments each value passed through the transducer by 1. <code>$xf</code> is then applied to an array <code>[1, 2, 3]</code> using the <code>transducers\xform()</code> function. This returns the same type of supplied data structure with the transducer applied to it (so given an array it returns an array, given a string it returns a string, given a stream it returns a stream with an applied filter, etc.).</p>

<p>Eager transformations are kinda like this (you consume and emit <strong>all</strong> of the data):</p>

<p><img style="margin: 0 auto 1em auto; display: block;" src="http://mtdowling.com/images/finn_barf.gif" /></p>

<h2>Lazy evaluation</h2>

<p>We can also use transducers to <a href="http://en.wikipedia.org/wiki/Lazy_evaluation">lazily</a> transform data.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="nv">$forever</span> <span class="o">=</span> <span class="k">function</span> <span class="p">()</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="mi">1</span><span class="p">)</span> <span class="nx">yield</span> <span class="nv">$i</span><span class="o">++</span><span class="p">;</span>
<span class="p">};</span>

<span class="c1">// Create a transformation function that multiplies each</span>
<span class="c1">// value by two and takes ony 100 values.</span>
<span class="nv">$xf</span> <span class="o">=</span> <span class="nx">t\comp</span><span class="p">(</span>
    <span class="nx">t\map</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="nv">$value</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$value</span> <span class="o">*</span> <span class="mi">2</span><span class="p">;</span> <span class="p">}),</span>
    <span class="nx">t\take</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span>
<span class="p">);</span>

<span class="c1">// Lazily transform the given generator using t\xform()</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nx">t\xform</span><span class="p">(</span><span class="nv">$forever</span><span class="p">(),</span> <span class="nv">$xf</span><span class="p">)</span> <span class="k">as</span> <span class="nv">$value</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="nv">$value</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>


<p>The above example lazily applied a transducer to a generator by creating another generator that applies a reducing step to each value yielded by the generator.</p>

<h2>Transducers are composable</h2>

<p>Transducers are <em>composable</em>, allowing you to create a transformation pipeline of data. Take the following example:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">Transducers</span> <span class="k">as</span> <span class="nx">t</span><span class="p">;</span>

<span class="nv">$xf</span> <span class="o">=</span> <span class="nx">t\comp</span><span class="p">(</span>
    <span class="nx">t\drop</span><span class="p">(</span><span class="mi">2</span><span class="p">),</span>
    <span class="nx">t\map</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="nv">$x</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$x</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="p">},</span>
    <span class="nx">t\filter</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="nv">$x</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$x</span> <span class="o">%</span> <span class="mi">2</span><span class="p">;</span> <span class="p">},</span>
    <span class="nx">t\take</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="p">);</span>

<span class="nv">$data</span> <span class="o">=</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="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">10</span><span class="p">];</span>
<span class="nv">$result</span> <span class="o">=</span> <span class="nx">t\xform</span><span class="p">(</span><span class="nv">$data</span><span class="p">,</span> <span class="nv">$xf</span><span class="p">);</span> <span class="c1">//&gt; [5, 7, 9]</span>
</code></pre></div>


<p>We just used the <code>transducers\comp()</code> to compose multiple transducers together into a single function. This composed function applies each transducer function, in the order they are defined, to a series of data. Each transducer performs its operation before deciding whether and how many times to call the next transducer in the pipeline. This means that the <code>t\drop()</code> transducer skips the first two elements of the input series and does not bother calling the subsequent transducers for the elements it skips.</p>

<p><em>To be clear, this means the pipeline order is as follows: <code>drop -&gt; map -&gt; filter -&gt; take</code></em></p>

<h2>Available transducers</h2>

<p>transducers.php comes with a number of built-in transducer functions.</p>

<table class="bordered-table">
  <thead>
    <tr>
      <th>
        function
      </th>
      <th>
        description
      </th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>
        <code>
          map(callable $f)
        </code>

      </td>
      <td>
        Applies a map function
        <code>
          $f
        </code>
        to each value in a collection.
      </td>
    </tr>
    <tr>
      <td>
        <code>
          filter(callable $pred)
        </code>

      </td>
      <td>
        Filters values that do not satisfy the predicate function
        <code>
          $pred
        </code>
        .
      </td>
    </tr>
    <tr>
      <td>
        <code>
          remove(callable $pred)
        </code>

      </td>
      <td>
        Removes anything from a sequence that satisfied
        <code>
          $pred
        </code>
        .
      </td>
    </tr>
    <tr>
      <td>
        <code>
          cat()
        </code>

      </td>
      <td>
        Transducer that concatenates items from nested lists.
      </td>
    </tr>
    <tr>
      <td>
        <code>
          mapcat(callable $f)
        </code>

      </td>
      <td>
        Applies a map function to a collection and concats them into one less level of nesting.
      </td>
    </tr>
    <tr>
      <td>
        <code>
          flatten()
        </code>

      </td>
      <td>
        Takes any nested combination of sequential things and returns their contents as a single, flat sequence.
      </td>
    </tr>
    <tr>
      <td>
        <code>
          partition($size)
        </code>

      </td>
      <td>
        Partitions the source into arrays of size
        <code>
          $size
        </code>
        .
      </td>
    </tr>
    <tr>
      <td>
        <code>
          partition_by(callable $pred)
        </code>

      </td>
      <td>
        Split inputs into lists by starting a new list each time the predicate passed in evaluates to a different condition (true/false) than what holds for the present list.
      </td>
    </tr>
    <tr>
      <td>
        <code>
          take($n)
        </code>

      </td>
      <td>
        Takes
        <code>
          $n
        </code>
        number of values from a collection.
      </td>
    </tr>
    <tr>
      <td>
        <code>
          take_while(callable $pred)
        </code>

      </td>
      <td>
        Takes from a collection while the predicate function
        <code>
          $pred
        </code>
        returns true.
      </td>
    </tr>
    <tr>
      <td>
        <code>
          take_nth($nth)
        </code>

      </td>
      <td>
        Takes every nth item from a sequence of values.
      </td>
    </tr>
    <tr>
      <td>
        <code>
          drop($n)
        </code>

      </td>
      <td>
        Drops
        <code>
          $n
        </code>
        items from the beginning of the input sequence.
      </td>
    </tr>
    <tr>
      <td>
        <code>
          drop_while(callable $pred)
        </code>

      </td>
      <td>
        Drops values from a sequence so long as the predicate function
        <code>
          $pred
        </code>
        returns true.
      </td>
    </tr>
    <tr>
      <td>
        <code>
          replace(array $smap)
        </code>

      </td>
      <td>
        Given a map of replacement pairs and a collection, returns a sequence where any elements equal to a key in
        <code>
          $smap
        </code>
        are replaced with the corresponding
        <code>
          $smap
        </code>
        value.
      </td>
    </tr>
    <tr>
      <td>
        <code>
          keep(callable $f)
        </code>

      </td>
      <td>
        Keeps
        <code>
          $f
        </code>
        items for which
        <code>
          $f
        </code>
        does not return null.
      </td>
    </tr>
    <tr>
      <td>
        <code>
          keep_indexed(callable $f)
        </code>

      </td>
      <td>
        Returns a sequence of the non-null results of
        <code>
          $f($index, $input)
        </code>
        .
      </td>
    </tr>
    <tr>
      <td>
        <code>
          dedupe()
        </code>

      </td>
      <td>
        Removes duplicates that occur in order (keeping the first in a sequence of duplicate values).
      </td>
    </tr>
    <tr>
      <td>
        <code>
          interpose($separator)
        </code>

  </td>
  <td>
    Adds a separator between each item in the sequence.
  </td>
  </tr>
  <tr>
    <td>
      <code>
        tap(callable $interceptor)
      </code>

    </td>
    <td>
      Invokes interceptor with each result and item, and then steps through unchanged.
    </td>
  </tr>
  <tr>
    <td>
      <code>
        compact()
      </code>

    </td>
    <td>
      Trim out all falsey values.
    </td>
  </tr>
  <tr>
    <td>
      <code>
        words($maxBuffer = 4096)
      </code>

    </td>
    <td>
      Splits the input by words.
    </td>
  </tr>
  <tr>
    <td>
      <code>
        lines($maxBuffer = 10240000)
      </code>

    </td>
    <td>
      Splits the input by lines.
    </td>
  </tr>
  </tbody>
</table>


<p>Please consult the <a href="https://github.com/mtdowling/transducers.php#available-transducers">README</a> for a full list of transducers and their descriptions.</p>

<h2>Applying transducers</h2>

<p>transducers.php offers several built-in ways of applying transducers to common data structures.</p>

<ul>
<li><code>function transduce(callable $xf, array $step, $coll, $init = null)</code> &ndash; Transform and reduce $coll by applying <code>$xf($step)['step']</code> to each value.</li>
<li><code>function into($target, $coll, callable $xf)</code> &ndash; Transduces items from $coll into the given $target, in essence &ldquo;pouring&rdquo; transformed data from one source into another data type.</li>
<li><code>function to_iter($coll, callable $xf)</code> &ndash; Creates an iterator that lazily applies the transducer $xf to the $input iterator.</li>
<li><code>function to_array($iterable, callable $xf)</code> &ndash; Converts a value to an array and applies a transducer function. $iterable is passed through vec() in order to convert the input value into an array.</li>
<li><code>function to_assoc($iterable, callable $xf)</code> &ndash; Creates an associative array using the provided input while applying $xf to each value. Values are converted to arrays that contain the array key in the first element and the array value in the second.</li>
<li><code>function to_string($iterable, callable $xf)</code> &ndash; Converts a value to a string and applies a transducer function to each character. $iterable is passed through vec() in order to convert the input value into an array.</li>
<li><code>function xform($coll, callable $xf)</code> &ndash; Returns the same data type passed in as $coll with $xf applied.</li>
</ul>


<p>Each of these functions apply transducers and provide results in different ways. You can find more information and examples in the <a href="https://github.com/mtdowling/transducers.php#using-transducers">README</a>.</p>

<h3>Applying to streams of data</h3>

<p>Remember when we were talking about how transducers don&rsquo;t know anything about the data source or the output destination?</p>

<p>Here&rsquo;s a great example of where this comes into play: transducers can be applied to PHP streams using <a href="http://php.net/manual/en/stream.filters.php">stream filters</a>.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">transducers</span> <span class="k">as</span> <span class="nx">t</span><span class="p">;</span>

<span class="nv">$f</span> <span class="o">=</span> <span class="nb">fopen</span><span class="p">(</span><span class="s1">&#39;php://temp&#39;</span><span class="p">,</span> <span class="s1">&#39;w+&#39;</span><span class="p">);</span>
<span class="nb">fwrite</span><span class="p">(</span><span class="nv">$f</span><span class="p">,</span> <span class="s1">&#39;testing. Can you hear me?&#39;</span><span class="p">);</span>
<span class="nb">rewind</span><span class="p">(</span><span class="nv">$f</span><span class="p">);</span>

<span class="nv">$xf</span> <span class="o">=</span> <span class="nx">t\comp</span><span class="p">(</span>
    <span class="c1">// Split by words</span>
    <span class="nx">t\words</span><span class="p">(),</span>
    <span class="c1">// Uppercase/lowercase every other word.</span>
    <span class="nx">t\keep_indexed</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="nv">$i</span><span class="p">,</span> <span class="nv">$v</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nv">$i</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">?</span> <span class="nx">strtoupper</span><span class="p">(</span><span class="nv">$v</span><span class="p">)</span> <span class="o">:</span> <span class="nx">strtolower</span><span class="p">(</span><span class="nv">$v</span><span class="p">);</span>
    <span class="p">}),</span>
    <span class="c1">// Combine words back together into a string separated by &#39; &#39;.</span>
    <span class="nx">t\interpose</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">)</span>
<span class="p">);</span>

<span class="c1">// Apply a transducer stream filter.</span>
<span class="nv">$filter</span> <span class="o">=</span> <span class="nx">t\append_stream_filter</span><span class="p">(</span><span class="nv">$f</span><span class="p">,</span> <span class="nv">$xf</span><span class="p">,</span> <span class="nx">STREAM_FILTER_READ</span><span class="p">);</span>
<span class="k">echo</span> <span class="nb">stream_get_contents</span><span class="p">(</span><span class="nv">$f</span><span class="p">);</span>

<span class="c1">// Be sure to remove the filter to flush out any buffers.</span>
<span class="nb">stream_filter_remove</span><span class="p">(</span><span class="nv">$filter</span><span class="p">);</span>
<span class="k">echo</span> <span class="nb">stream_get_contents</span><span class="p">(</span><span class="nv">$f</span><span class="p">);</span>
<span class="nb">fclose</span><span class="p">(</span><span class="nv">$f</span><span class="p">);</span>

<span class="c1">// Outputs: &quot;testing. CAN you HEAR me?&quot;</span>
</code></pre></div>


<p>Because transducers don&rsquo;t know anything about the sequence of data being transformed, you can apply transducers in any way you want.</p>

<h2>Creating transducers</h2>

<p>To create a transducer, you need to create a function that returns the transducer (a transformation function). This function then returns another function that is the actual transducer. Let&rsquo;s take a look at how <code>map()</code> is implemented.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">function</span> <span class="nf">map</span><span class="p">(</span><span class="nx">callable</span> <span class="nv">$f</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">return</span> <span class="k">function</span> <span class="p">(</span><span class="k">array</span> <span class="nv">$xf</span><span class="p">)</span> <span class="k">use</span> <span class="p">(</span><span class="nv">$f</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="p">[</span>
            <span class="s1">&#39;init&#39;</span>   <span class="o">=&gt;</span> <span class="nv">$xf</span><span class="p">[</span><span class="s1">&#39;init&#39;</span><span class="p">],</span>
            <span class="s1">&#39;result&#39;</span> <span class="o">=&gt;</span> <span class="nv">$xf</span><span class="p">[</span><span class="s1">&#39;result&#39;</span><span class="p">],</span>
            <span class="s1">&#39;step&#39;</span>   <span class="o">=&gt;</span> <span class="k">function</span> <span class="p">(</span><span class="nv">$result</span><span class="p">,</span> <span class="nv">$input</span><span class="p">)</span> <span class="k">use</span> <span class="p">(</span><span class="nv">$xf</span><span class="p">,</span> <span class="nv">$f</span><span class="p">)</span> <span class="p">{</span>
                <span class="k">return</span> <span class="nv">$xf</span><span class="p">[</span><span class="s1">&#39;step&#39;</span><span class="p">](</span><span class="nv">$result</span><span class="p">,</span> <span class="nv">$f</span><span class="p">(</span><span class="nv">$input</span><span class="p">));</span>
            <span class="p">}</span>
        <span class="p">];</span>
    <span class="p">};</span>
<span class="p">}</span>
</code></pre></div>


<p>Notice that <code>map</code> is a function that returns a transducer. A <em>transducer</em> is a function that accepts a <em>reducing function array</em> and returns a new reducing function array with added behavior. The above map function decorates the provided reducing function array step function by calling a map function on each value as it passes through.</p>

<p>Instead of using a 3 arity function like Clojure, transducers.php uses an associative array of functions for speed and clarity.</p>

<h3>Reducing function array</h3>

<p>Reducing function arrays are PHP associative arrays that contain a &lsquo;init&rsquo;,
&lsquo;step&rsquo;, and &lsquo;result&rsquo; key that maps to a function.</p>

<table class="bordered-table">
  <thead>
    <tr>
      <th>
        key
      </th>
      <th>
        arguments
  </th>
  <th>
    Description
  </th>
  </tr>
  </thead>
  <tbody>
    <tr>
      <td>
        init
      </td>
      <td>
        none
      </td>
      <td>
        Invoked to initialize a transducer. This function should call the ‘init’ function on the nested reducing function array
        <code>
          $xf
        </code>
        , which will eventually call out to the transducing process. This function is only called when an initial value is not provided while transducing.
      </td>
    </tr>
    <tr>
      <td>
        step
      </td>
      <td>

        <code>
          $result
        </code>
        ,
        <code>
          $input
        </code>

      </td>
      <td>
        This is a standard reduction function but it is expected to call the
        <code>
          $xf['step']
        </code>
        function 0 or more times as appropriate in the transducer. For example,
        <code>
          filter
        </code>
        will choose (based on the predicate) whether to call
        <code>
          $xf
        </code>
        or not.
        <code>
          map
        </code>
        will always call it exactly once.
        <code>
          cat
        </code>
        may call it many times depending on the inputs.
      </td>
    </tr>
    <tr>
      <td>
        result
      </td>
      <td>

        <code>
          $result
        </code>

      </td>
      <td>
        Some processes will not end, but for those that do (like transduce), the ‘result’ function is used to produce a final value and/or flush state. This function must call the
        <code>
          $xf['result']
        </code>
        function exactly once.
      </td>
    </tr>
  </tbody>
</table>


<h2>Transducers vs generators</h2>

<p>You might be thinking that generators in PHP offer similar functionality to transducers&mdash; and you&rsquo;d be right! However, transducers offer a number of benefits over just decorating iterators with generators.</p>

<h3>Transducers are more composable than generators</h3>

<p><img style="display: block; margin: 0 0 12px 12px; float: right" src="http://mtdowling.com/images/cup-stacking.gif" /></p>

<p>When composing generators, you need to wrap iterators from the inside out, which can lead to code that&rsquo;s hard to read and deeply nested. Let&rsquo;s compare transducer composition vs generator compositon (using to nikic&rsquo;s <a href="https://github.com/nikic/iter">iter library</a>).</p>

<p>The following composed transducer is a function that creates a pipeline for transforming data: it skips the first two elements of a collection, adds 1 to each value, filters out even numbers, then takes 3 elements from the collection. This new transformation function can be used with various transducer application functions, including <code>to_iter</code>.</p>

<p><em>Assume both examples have access to a <code>$data</code> variable that is traversable.</em></p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="nv">$iter</span> <span class="o">=</span> <span class="nx">t\to_iter</span><span class="p">(</span><span class="nv">$data</span><span class="p">,</span> <span class="nx">t\comp</span><span class="p">(</span>
    <span class="nx">t\drop</span><span class="p">(</span><span class="mi">2</span><span class="p">),</span>
    <span class="nx">t\map</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="nv">$x</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$x</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="p">},</span>
    <span class="nx">t\filter</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="nv">$x</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$x</span> <span class="o">%</span> <span class="mi">2</span><span class="p">;</span> <span class="p">},</span>
    <span class="nx">t\take</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="p">));</span>
</code></pre></div>


<p><em>Note: <code>to_iter()</code> uses a generator under the hood to lazily apply the transducer</em></p>

<p>Here&rsquo;s the same transformation using generators (notice it&rsquo;s awkwardly composed from the inside out):</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="nv">$iter</span> <span class="o">=</span> <span class="nx">iter\take</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="nx">iter\filter</span><span class="p">(</span>
    <span class="k">function</span><span class="p">(</span><span class="nv">$x</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$x</span> <span class="o">%</span> <span class="mi">2</span><span class="p">;</span> <span class="p">},</span>
    <span class="nx">iter\map</span><span class="p">(</span>
        <span class="k">function</span> <span class="p">(</span><span class="nv">$x</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$x</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="p">},</span>
        <span class="nx">iter\drop</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="nv">$data</span><span class="p">)</span>
    <span class="p">)</span>
<span class="p">));</span>
</code></pre></div>


<h3>Transducers are more generic than generators</h3>

<p>Using generators to transform a sequence of data requires that your input data is iterable and that your output is iterable. Generators have knowledge of the traversal, transformation, and building up of a result. Transducers on the other hand are only concerned with transforming data and as such can transform any type of data source including <strong>but not limited to</strong> iterable data. Transducers can perform an action on each item in a series of data (like writing to a stream) without creating an intermediate sequence whereas a generator would require you to <code>foreach</code> over an iterator and then perform the action. This flexibility is demonstrated in the transducer <a href="https://github.com/mtdowling/transducers.php/blob/b43b43583f8d5726072627b9c36b0bb43d799c85/src/transducers.php#L1119">stream filter</a>.</p>

<h2>Try it out!</h2>

<p>Transducers are an exciting new innovation from the Clojure community that is now <a href="https://github.com/mtdowling/transducers.php">available to the PHP community</a>. Give it a try and let me know what you think.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Managing Changelogs with Chag]]></title>
    <link href="http://mtdowling.com/blog/2014/10/26/managing-changelogs-with-chag/"/>
    <updated>2014-10-26T00:00:00-07:00</updated>
    <id>http://mtdowling.com/blog/2014/10/26/managing-changelogs-with-chag</id>
    <content type="html"><![CDATA[<p>Open source projects often include some kind of changelog file that helps
consumers of the project to be aware of any important changes that have been
made between versions. The format and filename of a changelog typically varies
from project to project; however, there&rsquo;s some promising news&hellip;
<a href="http://keepachangelog.com">http://keepachangelog.com</a> hopes to standardize
how open source projects represent changelog files. I&rsquo;ve recently begun
modifying the changelog files of all of my projects to conform to this new
changelog standard.</p>

<p>I often need to re-publish the contents of a changelog entry to various other mediums to help keep users of my projects up to date. For example, I often use
<a href="https://github.com/blog/1547-release-your-software">GitHub Releases</a> to
notify users of a new release via email, provide users an
<a href="https://github.com/guzzle/guzzle/releases.atom">atom feed</a> for updates to a
project, and provide
<a href="https://github.com/guzzle/guzzle/releases">historical builds</a> of each release.
One of the nice things about keepachangelog.com is that it makes it easier to
parse changelog files.</p>

<h2>Chag</h2>

<p>I created <a href="https://github.com/mtdowling/chag">chag</a>, short for &ldquo;changelog tag&rdquo;,
in order to automate the process of extracting changelog information from a
project&rsquo;s changelog file.</p>

<p>Installing chag is simple:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>curl -s https://raw.githubusercontent.com/mtdowling/chag/master/install.sh | bash</span></code></pre></td></tr></table></div></figure>


<p>Chag has several features that helps to automate various aspects of a managing
a changelog file.</p>

<h3>chag contents</h3>

<p>Extract the contents of a changelog entry (either the latest entry or a
specific entry by version).</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Usage: chag contents [--help] [--file &lt;path&gt;] [--tag &lt;tag&gt;]
</span><span class='line'>
</span><span class='line'>Outputs the contents of a changelog entry from a changelog file. If no
</span><span class='line'>--tag option is provided, then the top-most entry in the changelog is
</span><span class='line'>parsed.
</span><span class='line'>
</span><span class='line'>Options:
</span><span class='line'>--file     Path to changelog. Defaults to CHANGELOG.md
</span><span class='line'>--tag      Tag version string to parse. Defaults to the latest.
</span><span class='line'>--help     Displays this message.</span></code></pre></td></tr></table></div></figure>


<h3>chag entries</h3>

<p>Get a list of versions available in a changelog file.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Usage: chag entries [--help] [--file &lt;path&gt;]
</span><span class='line'>
</span><span class='line'>Lists all of the version numbers in a changelog file, separated by new lines.
</span><span class='line'>
</span><span class='line'>Options:
</span><span class='line'>--file    Path to changelog. Defaults to CHANGELOG.md
</span><span class='line'>--help    Displays this message.</span></code></pre></td></tr></table></div></figure>


<h3>chag latest</h3>

<p>Get the latest version in a changelog file.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Usage: chag latest [--help] [--file &lt;path&gt;]
</span><span class='line'>
</span><span class='line'>Get the latest changelog entry version from a CHANGELOG.
</span><span class='line'>
</span><span class='line'>Options:
</span><span class='line'>--file    Path to changelog. Defaults to CHANGELOG.md
</span><span class='line'>--help    Displays this message.</span></code></pre></td></tr></table></div></figure>


<h3>chag update</h3>

<p>Update a WIP changelog heading to a new version number and date.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Usage: chag contents [--help] [--file &lt;path&gt;] [--tag &lt;tag&gt;]
</span><span class='line'>
</span><span class='line'>Outputs the contents of a changelog entry from a changelog file. If no
</span><span class='line'>--tag option is provided, then the top-most entry in the changelog is
</span><span class='line'>parsed.
</span><span class='line'>
</span><span class='line'>Options:
</span><span class='line'>--file     Path to changelog. Defaults to CHANGELOG.md
</span><span class='line'>--tag      Tag version string to parse. Defaults to the latest.
</span><span class='line'>--help     Displays this message.</span></code></pre></td></tr></table></div></figure>


<p>This command allows you maintain an <code>## Unreleased</code> changelog entry and append
content to the entry as you develop a new version. When the new version is
ready to tag, you simply call <code>chag update X.Y.Z</code>, where <code>X.Y.Z</code> is the
version that you will use when the next release is tagged. Chag will modify
the WIP changelog entry to use the new version and will add today&rsquo;s date to
the entry.</p>

<h3>chag tag</h3>

<p>Create an annotated Git tag using the latest changelog entry.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Usage: chag tag [--help] [--file &lt;path&gt;] [--addv] [-s|--sign] [-f|--force]
</span><span class='line'>
</span><span class='line'>Parses a changelog entry for the given tag and creates an annotated git
</span><span class='line'>tag based on the changelog entry.
</span><span class='line'>
</span><span class='line'>Options:
</span><span class='line'>--file      Path to changelog. Defaults to CHANGELOG.md
</span><span class='line'>--addv      Pass to prepend a "v" to the git tag (e.g., "v2.0.1")
</span><span class='line'>--sign|-s   Make a GPG-signed tag, using the default git e-mail address key.
</span><span class='line'>--force|-f  Delete an existing tag if present.
</span><span class='line'>--help      Displays this message.</span></code></pre></td></tr></table></div></figure>


<h2>GitHub Releases</h2>

<p><a href="https://developer.github.com/v3/repos/releases/">GitHub Releases</a> provides
a really nice way to release open source software hosted on GitHub. Releases
allows your users to list the available versions of a project, download builds,
of specific versions, and subscribe to an atom feed that contains release
information.</p>

<p>For example, the releases for chag can be found at
<a href="https://github.com/mtdowling/chag/releases.">https://github.com/mtdowling/chag/releases.</a> Chag&rsquo;s release atom feed can be
found at <a href="https://github.com/mtdowling/chag/releases.atom">https://github.com/mtdowling/chag/releases.atom</a>.
In fact, every project on GitHub provides a release atom feed. Simply substitute
<code>mtdowling/chag</code> in the above URL with a project owner and repo name:
<code>https://github.com/{owner}/{repo}/releases.atom</code>. Included in each atom feed
entry is changelog information&mdash; information that can be extracted using chag.</p>

<p>Each time a release is published, any developer that is &ldquo;watching&rdquo; the repo
will receive an email that lets them know about the release. Included in this
email is a description of the changes made in the version&mdash; again, information
that can be extracted with chag.</p>

<p>GitHub releases can be created using the GitHub API or using a
<a href="http://docs.travis-ci.com/user/deployment/">Travis CI deployment provider</a>.</p>

<h2>Travis Releases</h2>

<p><a href="https://travis-ci.org/">Travis CI</a> is a continuous integration service used to
build and test projects. Most open source projects utilize Travis, and if they
don&rsquo;t, they should. One of the many features offered by Travis CI is the
ability to deploy your project after a successful build. Travis CI offers
various <a href="http://docs.travis-ci.com/user/deployment/">deployment providers</a>, one
of which is
<a href="http://docs.travis-ci.com/user/deployment/releases/">GitHub Releases</a>.</p>

<p>I use GitHub releases in several of my open source projects (for example,
<a href="http://guzzlephp.org">Guzzle</a>). Utilizing Travis CI to deploy a release means
that all I need to do to cut a release is push a tag to GitHub. Travis then
sees the new tag, builds my assets, and makes an API call to GitHub Releases
to create a new release with the built assets. All you need to do to utilize
GitHub releases in your project is modify your
<a href="https://github.com/guzzle/guzzle/blob/83ad35d31c75c4f7241c383c6c2ea8f233849dc5/.travis.yml#L28">.travis.yml file</a>. This can be done rather easily using the
<a href="https://github.com/travis-ci/travis.rb">travis command line tools</a>.</p>

<h3>Configure Travis</h3>

<p>First you need to install the Travis CLI:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>gem install travis</span></code></pre></td></tr></table></div></figure>


<p>Next use the Travis CLI to interactively configure your project for GitHub
releases.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>travis setup releases</span></code></pre></td></tr></table></div></figure>


<p><em><strong>Note:</strong> You should configure the deploy provider to only deploy on new
tags. There is also currently a bug in Travis that requires you to specify
<code>all_branches</code> as <code>true</code> in order to build only on tags. See:
<a href="https://github.com/travis-ci/travis-ci/issues/1675#issuecomment-37851765">https://github.com/travis-ci/travis-ci/issues/1675#issuecomment-37851765</a></em></p>

<p>Here&rsquo;s what the deploy section of a configured project&rsquo;s .travis.yml might look
like:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='yaml'><span class='line'><span class="l-Scalar-Plain">language</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">bash</span>
</span><span class='line'>
</span><span class='line'><span class="l-Scalar-Plain">before_install</span><span class="p-Indicator">:</span>
</span><span class='line'><span class="p-Indicator">-</span> <span class="l-Scalar-Plain">do some install commands...</span>
</span><span class='line'>
</span><span class='line'><span class="l-Scalar-Plain">script</span><span class="p-Indicator">:</span>
</span><span class='line'><span class="p-Indicator">-</span> <span class="l-Scalar-Plain">script used to run your tests...</span>
</span><span class='line'>
</span><span class='line'><span class="l-Scalar-Plain">deploy</span><span class="p-Indicator">:</span>
</span><span class='line'>  <span class="l-Scalar-Plain">provider</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">releases</span>
</span><span class='line'>  <span class="l-Scalar-Plain">api_key</span><span class="p-Indicator">:</span>
</span><span class='line'>    <span class="l-Scalar-Plain">secure</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">long-encrypted-token</span>
</span><span class='line'>  <span class="l-Scalar-Plain">file</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">chag</span>
</span><span class='line'>  <span class="l-Scalar-Plain">on</span><span class="p-Indicator">:</span>
</span><span class='line'>    <span class="l-Scalar-Plain">repo</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">mtdowling/chag</span>
</span><span class='line'>    <span class="l-Scalar-Plain">tags</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">true</span>
</span><span class='line'>    <span class="l-Scalar-Plain">all_branches</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">true</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Publish a Release</h3>

<p>Now that Travis is configured, any time you push a new tag to GitHub, Travis
will create a new GitHub Release. You&rsquo;ll need to use chag in order for your
changelog information to show up in your releases. Chag uses annotated Git tags
that contains the latest entry in your changelog as the tag annotation.</p>

<p>Given the following changelog file:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='yaml'><span class='line'><span class="c1"># CHANGELOG</span>
</span><span class='line'>
</span><span class='line'><span class="c1">## 1.0.0 - 2014-10-26</span>
</span><span class='line'>
</span><span class='line'><span class="l-Scalar-Plain">Bugfix release</span>
</span><span class='line'>
</span><span class='line'><span class="l-Scalar-Plain">- Addressed issue</span> <span class="c1">#12.</span>
</span><span class='line'><span class="p-Indicator">-</span> <span class="l-Scalar-Plain">Fixed a bug.</span>
</span></code></pre></td></tr></table></div></figure>


<p>You can tag the <code>1.0.0</code> release using the corresponding changelog contents
using chag:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='yaml'><span class='line'><span class="l-Scalar-Plain">chag tag</span>
</span></code></pre></td></tr></table></div></figure>


<p>This command will parse the contents of the latest changelog entry and create a
new annotated Git tag that uses the contents as the tag annotation. The command
identifies the version to tag as <code>1.0.0</code> and extracts the changelog entry
contents from the file so that it is used in the tag annotation. This annotated
tag is then used by Travis when pushing the release to GitHub releases.</p>

<p><em><strong>Note:</strong> GitHub currently uses the first line of a changelog entry as
part of the title in a release.</em></p>

<h2>Thanks</h2>

<p>I hope that you find chag useful when managing your changelog files. If you&rsquo;re
not managing a changelog for your project, then I hope that you start, and
I hope that you use the format described by <a href="http://keepachangelog.com.">http://keepachangelog.com.</a></p>

<p><em><strong>P.S.:</strong> Chag uses a uses a tool called
<a href="https://github.com/sstephenson/bats">Bats</a> for automated testing. It made
testing a semi-complicated Bash script as painless as possible. If you&rsquo;re
developing a Bash script, then I highly recommend it.</em></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Guzzle 5 and RingPHP]]></title>
    <link href="http://mtdowling.com/blog/2014/10/13/guzzle-5/"/>
    <updated>2014-10-13T00:00:00-07:00</updated>
    <id>http://mtdowling.com/blog/2014/10/13/guzzle-5</id>
    <content type="html"><![CDATA[<p><a href="https://github.com/guzzle/guzzle/blob/master/CHANGELOG.md#500-2014-10-12">Guzzle 5</a>
has been officially released. Guzzle 5 now utilizes <a href="http://ringphp.readthedocs.org">RingPHP</a>
as the transport layer, making it significantly easier to bind Guzzle to
existing networking libraries (e.g., sockets, event loop libraries, etc.).
Guzzle 5 can now send both synchronous and asynchronous requests using a
consistent interface.</p>

<p>With RingPHP, Guzzle does not require cURL and can be used with any HTTP
transport mechanism. I&rsquo;d love to help anyone who is interested in creating
RingPHP adapters to bind Guzzle to another library. For example, WyriHaximus
on Github is working on <a href="https://github.com/WyriHaximus/ReactGuzzleRing">binding Guzzle to ReactPHP</a>.
(In fact, Guzzle 4 did not require cURL, though it was much harder to use an
alternate transport.)</p>

<h2>RingPHP</h2>

<p><a href="http://ringphp.readthedocs.org">RingPHP</a> is a new PHP library that abstracts
away the HTTP protocol into simple hashes and PHP functions. RingPHP handlers
are implemented using PHP callables that accept an associative array of request
data and return a future array of response data that can be used synchronously
as an array or asynchronously using a <a href="https://github.com/reactphp/promise">promise</a>.
While Guzzle only uses RingPHP  as a HTTP client, it can also be used to power
HTTP servers.</p>

<p>The use of RingPHP now allows Guzzle to send HTTP redirects and retries
concurrently (Guzzle previously performed blocking redirects and retries).</p>

<h2>Promises and Futures</h2>

<p>Guzzle 5 now utilizes future values to represent asynchronous response objects.
These response objects (<code>GuzzleHttp\Message\FutureResponse</code>) can be used as a
normal response to use them synchronously, or utilized asynchronously using the
<code>promise()</code> method of the response.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="nv">$response</span> <span class="o">=</span> <span class="nv">$client</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s1">&#39;http://httpbin.org&#39;</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;future&#39;</span> <span class="o">=&gt;</span> <span class="k">true</span><span class="p">]);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Use the response asynchronously</span>
</span><span class='line'><span class="nv">$response</span><span class="o">-&gt;</span><span class="na">then</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="nv">$response</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">echo</span> <span class="nv">$response</span><span class="o">-&gt;</span><span class="na">getStatusCode</span><span class="p">();</span> <span class="c1">// 200</span>
</span><span class='line'><span class="p">});</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Use the response synchronously</span>
</span><span class='line'><span class="k">echo</span> <span class="nv">$response</span><span class="o">-&gt;</span><span class="na">getStatusCode</span><span class="p">();</span> <span class="c1">// 200</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Explicitly block on the response to be ready</span>
</span><span class='line'><span class="nv">$actualResponse</span> <span class="o">=</span> <span class="nv">$response</span><span class="o">-&gt;</span><span class="na">wait</span><span class="p">();</span>
</span></code></pre></td></tr></table></div></figure>


<h2>PSR-7 Compatibility</h2>

<p>As of today, Guzzle 5 is now completely compatible with the current draft of the
<a href="https://github.com/php-fig/fig-standards/blob/master/proposed/http-message.md">PSR-7 message proposal</a>
(which didn&rsquo;t require many changes considering PSR-7 is very similar to
Guzzle&rsquo;s existing interfaces). This includes the newly released
<a href="https://github.com/guzzle/streams/blob/master/CHANGELOG.rst#300-2014-10-12">guzzlehttp/streams 3.0</a>.</p>

<h2>Iterable and Callable Streams</h2>

<p>Guzzle streams can now be created for PHP iterators and callables, making it
much easier to generate streams of data on the fly using PHP generators.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="nv">$gen</span> <span class="o">=</span> <span class="k">function</span> <span class="p">(</span><span class="nv">$size</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">while</span> <span class="p">(</span><span class="nv">$size</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">yield</span> <span class="s1">&#39;.&#39;</span><span class="p">;</span>
</span><span class='line'>        <span class="nv">$size</span><span class="o">--</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="nv">$stream</span> <span class="o">=</span> <span class="nx">GuzzleHttp\Stream\Stream</span><span class="o">::</span><span class="na">factory</span><span class="p">(</span><span class="nv">$gen</span><span class="p">(</span><span class="mi">1000</span><span class="p">));</span>
</span><span class='line'>
</span><span class='line'><span class="k">echo</span> <span class="nv">$stream</span><span class="o">-&gt;</span><span class="na">read</span><span class="p">(</span><span class="mi">5</span><span class="p">);</span>
</span><span class='line'><span class="c1">// Outputs: .....</span>
</span></code></pre></td></tr></table></div></figure>


<h2>New Events</h2>

<p>The event system in Guzzle got several upgrades.</p>

<ol>
<li>There is a new <a href="http://docs.guzzlephp.org/en/latest/events.html#progress">&ldquo;progress&rdquo; event</a>
that can be used to get the progress of HTTP uploads and downloads.</li>
<li>There is a new <a href="http://docs.guzzlephp.org/en/latest/events.html#end">&ldquo;end&rdquo; event</a>
that is a terminal event that is triggered once per HTTP request. The &ldquo;end&rdquo;
event is triggered for both successful and failed requests.</li>
<li>There is now a <code>retry()</code> function on <code>GuzzleHttp\Event\ErrorEvent</code> and
<code>GuzzleHttp\Event\CompleteEvent</code> that allows you to retry a request without
emitting multiple &ldquo;end&rdquo; events. The <code>retry()</code> method accepts an optional
delay argument that specifies how long to wait before retrying. When using a
non-blocking adapter, this delay can happen concurrently while other
requests are transferred.</li>
</ol>


<p>In addition to using promises for asynchronous response handling, Guzzle&rsquo;s
signal slot event system can also be used for handling asynchronous responses
and makes it easy to create sharable event subscribers that can be used across
projects (like the <a href="https://github.com/guzzle/log-subscriber">log subscriber</a>,
<a href="https://github.com/guzzle/retry-subscriber">retry subscriber</a>, etc.).</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="k">use</span> <span class="nx">GuzzleHttp\Event\EndEvent</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="nv">$request</span> <span class="o">=</span> <span class="nv">$client</span><span class="o">-&gt;</span><span class="na">createRequest</span><span class="p">(</span><span class="s1">&#39;GET&#39;</span><span class="p">,</span> <span class="s1">&#39;http://httpbin.org/get&#39;</span><span class="p">);</span>
</span><span class='line'><span class="nv">$request</span><span class="o">-&gt;</span><span class="na">getEmitter</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">on</span><span class="p">(</span><span class="s1">&#39;end&#39;</span><span class="p">,</span> <span class="k">function</span> <span class="p">(</span><span class="nx">EndEvent</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nv">$e</span><span class="o">-&gt;</span><span class="na">getException</span><span class="p">())</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">echo</span> <span class="s1">&#39;Got an error! &#39;</span> <span class="o">.</span> <span class="nv">$e</span><span class="o">-&gt;</span><span class="na">getException</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">getMessage</span><span class="p">();</span>
</span><span class='line'>    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>       <span class="k">echo</span> <span class="s1">&#39;Got a response: &#39;</span> <span class="o">.</span> <span class="nv">$e</span><span class="o">-&gt;</span><span class="na">getResponse</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">getStatusCode</span><span class="p">();</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">});</span>
</span><span class='line'>
</span><span class='line'><span class="nv">$client</span><span class="o">-&gt;</span><span class="na">send</span><span class="p">(</span><span class="nv">$request</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>Signal slot events should be used when creating event subscribers that modify
the request or response before it is returned. These signal slot events will
complete before any promises are resolved. Other than the &ldquo;end&rdquo; event, signal
slot events can be triggered multiple times for a single request transfer,
whereas a promise is resolved or rejected only once per transfer.</p>

<h2>Upgrading to Guzzle 5</h2>

<p>Upgrading your application to Guzzle 5 should be relatively painless and won&rsquo;t
require changes for most users. Please see the
<a href="https://github.com/guzzle/guzzle/blob/master/CHANGELOG.md#500-2014-10-12">changelog</a>
and <a href="https://github.com/guzzle/guzzle/blob/master/UPGRADING.md#4x-to-50">upgrading guide</a>
for more information.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[RingPHP and Future Responses]]></title>
    <link href="http://mtdowling.com/blog/2014/09/28/guzzle-ring/"/>
    <updated>2014-09-28T00:00:00-07:00</updated>
    <id>http://mtdowling.com/blog/2014/09/28/guzzle-ring</id>
    <content type="html"><![CDATA[<p>Guzzle 4 has been out for a little over six months. It has proven to be
leaps and bounds better than Guzzle 3, and I&rsquo;ve been very happy with the design
so far. However, after the release of Guzzle 4, I&rsquo;ve received feedback from
numerous members of the PHP community that can be boiled down to
&ldquo;Guzzle needs async support.&rdquo; While Guzzle has always had the ability to send
requests concurrently using a pool of requests, there was not a way to send
asynchronous requests.</p>

<p>After a couple months of work and borrowing concepts from Clojure, I&rsquo;ve created
<a href="https://github.com/guzzle/ringphp">RingPHP</a>, an extremely simple
handler and middleware library for PHP (not just Guzzle) that can power both
clients and servers for both synchronous and asynchronous requests. Along with
creating RingPHP, I created a branch of Guzzle itself that now utilizes
RingPHP: <a href="https://github.com/guzzle/guzzle/tree/ring.">https://github.com/guzzle/guzzle/tree/ring.</a></p>

<p>This branch has now been merged and Guzzle 5 has</p>

<h2>Problem Statement</h2>

<p><a href="https://github.com/guzzle/guzzle/tree/4.2.2/src/Adapter">Guzzle 4&rsquo;s adapter system</a>
was overly complex and required different interfaces for adapters that could
send requests concurrently and adapters that could only send requests serially.
Neither of these adapter implementations were able to implement asynchronous
requests. <a href="https://github.com/guzzle/guzzle/blob/4.2.2/src/Adapter/ParallelAdapterInterface.php">&ldquo;Parallel&rdquo; adapters</a>
were a special form of adapters that that could send requests concurrently
while popping requests off a an iterator. Sending a single request using the
<code>send()</code> method of a client meant that clients would send requests using the
<code>"adapter"</code> associated with a client, while sending requests concurrently
using the <code>sendAll()</code> method of a client meant that clients would send
requests using the <code>"parallel_adapter"</code> of a client. In hindsight, I consider
whether or not an adapter can transfer a request serially or concurrently an
implementation detail of the adapter. This implementation detail did not
warrant a separate interface or separate configuration settings in a client
constructor.</p>

<p>Guzzle 4&rsquo;s adapter layer pushed a great deal of complexity onto the adapter
layer. Handler implementations had far too much intimate knowledge about the
lifecycle of a request and how event listeners could interact with a
transaction. This resulted in overly complex (yet somehow still vague)
documentation about implementing an adapter (e.g.,
<a href="https://github.com/guzzle/guzzle/blob/4.2.2/docs/adapters.rst">https://github.com/guzzle/guzzle/blob/4.2.2/docs/adapters.rst</a>).</p>

<p>Finally, adapters, when invoked, would not return until the request had
completed. This fundamental limitation of the Guzzle 4 adapter system prevented
adapters from being able to send requests asynchronously. This caused a fairly
significant performance problem in Guzzle when
<a href="https://github.com/guzzle/guzzle/issues/804">redirects were encountered</a> or if
Guzzle was retrying failed requests using the <a href="https://github.com/guzzle/retry-subscriber">retry-subscriber</a>.</p>

<p>In order to address these concerns, I created RingPHP.</p>

<h2>RingPHP</h2>

<p>RingPHP will be the new handler system in Guzzle 5 (release date TBD).
RingPHP gives Guzzle the ability to send asynchronous requests, greatly
reduces the complexity of creating new handlers, and yields much simpler and
more explicit <a href="https://github.com/guzzle/guzzle/blob/ring/src/RequestFsm.php">request state transitions</a>
in Guzzle.</p>

<p>RingPHP is heavily influenced by <a href="http://clojure.org/">Clojure</a>, Clojure&rsquo;s
<a href="https://github.com/ring-clojure/ring">Ring</a>, and Clojure&rsquo;s <a href="http://http-kit.org/">HTTP Kit</a>,
and as such, it utilizes various functional programming concepts and uses PHP
associative arrays as the main data structure. The use of functional
composition and simple associative arrays allows RingPHP to be easy to
understand, fast, and simple to add behavior to at runtime via middleware.</p>

<p>Implementing RingPHP handlers is as simple as creating a function that
accepts a request array and returns a response array. The full specification
on what key value pairs can be in the request and response arrays can be found
in the RingPHP specification: <a href="http://RingPHP.readthedocs.org/en/latest/spec.html">http://RingPHP.readthedocs.org/en/latest/spec.html</a></p>

<p>Here&rsquo;s an example of using a CurlHandler that transfers HTTP requests using
cURL easy handles.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">GuzzleHttp\Ring\Client\CurlHandler</span><span class="p">;</span>

<span class="c1">// Create a CurlHandler that uses cURL to send requests.</span>
<span class="nv">$handler</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">CurlHandler</span><span class="p">();</span>

<span class="c1">// Requests are simple associative arrays.</span>
<span class="nv">$request</span> <span class="o">=</span> <span class="p">[</span>
    <span class="s1">&#39;http_method&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;GET&#39;</span><span class="p">,</span>
    <span class="s1">&#39;headers&#39;</span>     <span class="o">=&gt;</span> <span class="p">[</span><span class="s1">&#39;host&#39;</span> <span class="o">=&gt;</span> <span class="p">[</span><span class="s1">&#39;example.com&#39;</span><span class="p">]],</span>
    <span class="s1">&#39;client&#39;</span>      <span class="o">=&gt;</span> <span class="p">[</span><span class="s1">&#39;curl&#39;</span> <span class="o">=&gt;</span> <span class="p">[</span><span class="nx">CURLOPT_LOW_SPEED_LIMIT</span> <span class="o">=&gt;</span> <span class="mi">10</span><span class="p">]]</span>
<span class="p">];</span>

<span class="c1">// The handler is a PHP callable (implemented using PHP&#39;s __invoke method)</span>
<span class="nv">$response</span> <span class="o">=</span> <span class="nv">$handler</span><span class="p">(</span><span class="nv">$request</span><span class="p">);</span>

<span class="c1">// The response is a simple associative array of data.</span>
<span class="k">echo</span> <span class="nv">$response</span><span class="p">[</span><span class="s1">&#39;status&#39;</span><span class="p">];</span>
<span class="k">echo</span> <span class="nv">$response</span><span class="p">[</span><span class="s1">&#39;reason&#39;</span><span class="p">];</span>
<span class="nb">var_dump</span><span class="p">(</span><span class="nv">$response</span><span class="p">[</span><span class="s1">&#39;headers&#39;</span><span class="p">]);</span>
<span class="nb">var_dump</span><span class="p">(</span><span class="k">echo</span> <span class="nv">$response</span><span class="p">[</span><span class="s1">&#39;body&#39;</span><span class="p">]);</span>
</code></pre></div>


<h3>Futures</h3>

<p>Borrowing heavily from Clojure (and Java), RingPHP uses <em>futures</em>
(and promises) to implement asynchronous responses. Futures represent a value or
calculation that may have not yet completed. When a future is dereferenced
(meaning you use the future), the future blocks until the operation has
completed. Futures provide all of the power of asynchronous programming while
still allowing you to use the same objects for synchronous programming.</p>

<p>Because PHP doesn&rsquo;t has a built-in concept of futures, RingPHP provides
various primitives that are used to implement futures in PHP.</p>

<p><code>GuzzleHttp\Ring\FutureInterface</code>: A primitive future representation. This
future interface is used throughout RingPHP, and can be used in other
projects as well that could benefit from futures.</p>

<ul>
<li><code>waitf()</code>: Returns the result of the future. If the result has already
completed then it is returned immediately. If it has not completed, then the
future blocks until a result can be returned.</li>
<li><code>cancel()</code>: Attempts to cancel the future.</li>
</ul>


<p><code>GuzzleHttp\Ring\Future\FutureValue</code>: A basic implementation of FutureInterface that
returns a value when the future is dereferenced.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">React\Promise\Deferred</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">GuzzleHttp\Ring\Future\FutureValue</span><span class="p">;</span>

<span class="nv">$deferred</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Deferred</span><span class="p">();</span>

<span class="nv">$future</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">FutureValue</span><span class="p">(</span>
    <span class="nv">$deferred</span><span class="o">-&gt;</span><span class="na">promise</span><span class="p">();</span>
    <span class="k">function</span> <span class="p">()</span> <span class="k">use</span> <span class="p">(</span><span class="nv">$deferred</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="s1">&#39;Dereferencing!&#39;</span><span class="p">;</span>
        <span class="nv">$deferred</span><span class="o">-&gt;</span><span class="na">resolve</span><span class="p">(</span><span class="s1">&#39;foo&#39;</span><span class="p">);</span>
    <span class="p">},</span>
    <span class="k">function</span> <span class="p">()</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="s1">&#39;Cancelling!&#39;</span><span class="p">;</span>
        <span class="c1">// Attempt to cancel the future.</span>
    <span class="p">}</span>
<span class="p">);</span>

<span class="k">echo</span> <span class="nv">$future</span><span class="o">-&gt;</span><span class="na">wait</span><span class="p">();</span> <span class="c1">// &quot;foo&quot;</span>
</code></pre></div>


<p><code>GuzzleHttp\Ring\Future\RingFutureInterface</code>: A future implementation that can be
returned by a RingPHP handler. This future implementation acts exactly like
a PHP associative array, but the data contained in the array is populated
asynchronously. This interface is used by RingPHP handlers that support
asynchronous requests (e.g., CurlMultiHandler).</p>

<p>You can find other future primitives, including traits that make it trivial to
implement futures, in the RingPHP repo: <a href="https://github.com/guzzle/RingPHP">https://github.com/guzzle/RingPHP</a></p>

<h3>Middleware</h3>

<p>RingPHP middleware augments the functionality of handlers by invoking them
in the process of generating responses. Middleware is typically implemented as
a higher-order function or callable that takes one or more handlers as
arguments followed by an optional associative array of options as the last
argument, returning a new handler with the desired compound behavior.</p>

<p>Because RingPHP uses a function to send HTTP requests, creating middleware
is as simple as wrapping one function with another. For example, let&rsquo;s say you
wanted to add a header to every request before it&rsquo;s sent over the wire. This
can be implemented by creating a function that accepts another function (or
handler) and an array of headers to add and returns the composed function.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">GuzzleHttp\Ring\Client\CurlHandler</span><span class="p">;</span>

<span class="nv">$handler</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">CurlHandler</span><span class="p">();</span>

<span class="nv">$addHeaderHandler</span> <span class="o">=</span> <span class="k">function</span> <span class="p">(</span><span class="nx">callable</span> <span class="nv">$handler</span><span class="p">,</span> <span class="k">array</span> <span class="nv">$headers</span> <span class="o">=</span> <span class="p">[])</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">function</span> <span class="p">(</span><span class="k">array</span> <span class="nv">$request</span><span class="p">)</span> <span class="k">use</span> <span class="p">(</span><span class="nv">$handler</span><span class="p">,</span> <span class="nv">$headers</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// Add our custom headers</span>
        <span class="k">foreach</span> <span class="p">(</span><span class="nv">$headers</span> <span class="k">as</span> <span class="nv">$key</span> <span class="o">=&gt;</span> <span class="nv">$value</span><span class="p">)</span> <span class="p">{</span>
            <span class="nv">$request</span><span class="p">[</span><span class="s1">&#39;headers&#39;</span><span class="p">][</span><span class="nv">$key</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$value</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="c1">// Send the request using the handler and return the response.</span>
        <span class="k">return</span> <span class="nv">$handler</span><span class="p">(</span><span class="nv">$request</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">};</span>

<span class="c1">// Create a new handler that adds headers to each request.</span>
<span class="nv">$handler</span> <span class="o">=</span> <span class="nv">$addHeaderHandler</span><span class="p">(</span><span class="nv">$handler</span><span class="p">,</span> <span class="p">[</span>
    <span class="s1">&#39;X-AddMe&#39;</span>       <span class="o">=&gt;</span> <span class="s1">&#39;hello&#39;</span><span class="p">,</span>
    <span class="s1">&#39;Authorization&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;Basic xyz&#39;</span>
<span class="p">]);</span>

<span class="nv">$response</span> <span class="o">=</span> <span class="nv">$handler</span><span class="p">([</span>
    <span class="s1">&#39;http_method&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;GET&#39;</span><span class="p">,</span>
    <span class="s1">&#39;headers&#39;</span>     <span class="o">=&gt;</span> <span class="p">[</span><span class="s1">&#39;Host&#39;</span> <span class="o">=&gt;</span> <span class="p">[</span><span class="s1">&#39;httpbin.org&#39;</span><span class="p">]</span>
<span class="p">]);</span>
</code></pre></div>


<h2>Updates to Guzzle</h2>

<p>Replacing the Guzzle handler system is a breaking change, so it will require
a new major version tag. The number and scope of the breaking changes in the
next major version of Guzzle will be very minimal, so I believe most
applications will be able to migrate to Guzzle 5 without requiring any changes.
See the <a href="https://github.com/guzzle/guzzle/blob/ring/CHANGELOG.md#500-tbd">CHANGELOG</a>
for a full list of changes as it currently stands.</p>

<p>Because higher level concerns like the event system and error handling are
removed from the handler layer, it&rsquo;s much easier to integrate Guzzle with
more HTTP transports (e.g., React, Sockets, other clients, etc.). In fact,
I took a stab at implementing a very rudimentary <a href="https://gist.github.com/mtdowling/47da5eab54337cdc7ecc">proof of concept handler to
integrate Guzzle and React</a>.
This proof of concept shows how Guzzle can be integrated with asynchronous
handlers while still providing a synchronous interface when needed (thanks
to futures). This example handler also illustrates some upcoming changes
to the guzzle/streams project, including the new
<a href="https://github.com/guzzle/streams/blob/3.0/src/AsyncReadStream.php">AsyncReadStream</a>.</p>

<h3>Future Responses in Guzzle</h3>

<p>RingPHP handlers gives Guzzle the ability to create asynchronous future
responses. Let&rsquo;s say you&rsquo;re interacting with a web service that takes a while
to respond. With RingPHP, you can now create a request that returns future
responses that are fulfilled asynchronously, allowing you to do other
stuff while the response is completing.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">GuzzleHttp\Client</span><span class="p">;</span>

<span class="nv">$client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Client</span><span class="p">();</span>

<span class="c1">// Create a future response that sends a request and does not block.</span>
<span class="c1">// This returns a GuzzleHttp\Message\FutureResponse object.</span>
<span class="nv">$response</span> <span class="o">=</span> <span class="nv">$client</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s1">&#39;http://slow.api.com&#39;</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;future&#39;</span> <span class="o">=&gt;</span> <span class="k">true</span><span class="p">]);</span>

<span class="c1">// Do some other stuff while the response is being fulfilled and buffered</span>
<span class="c1">// at the socket level.</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">10000</span><span class="p">;</span> <span class="nv">$i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// stuff</span>
<span class="p">}</span>

<span class="c1">// When you&#39;re done with your calculations, you can use the future response.</span>
<span class="c1">// If the future response has not yet completed, it will block until the</span>
<span class="c1">// response is ready to use.</span>
<span class="k">echo</span> <span class="nv">$response</span><span class="o">-&gt;</span><span class="na">getStatusCode</span><span class="p">();</span>
</code></pre></div>


<h3>Sending Requests Concurrently</h3>

<p>Guzzle will now use a Pool object for sending a pool of requests concurrently.
The Pool object accepts an iterator that yields requests and transfers the
requests as efficiently as possible. As one request completes, the next request
is added to the pool in order to maintain a fixed pool size. Each request that
is transferred by the pool is automatically dereferenced as it completes.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">GuzzleHttp\Client</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">GuzzleHttp\Pool</span><span class="p">;</span>

<span class="nv">$client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Client</span><span class="p">();</span>

<span class="c1">// Create a generator that yields N number of requests.</span>
<span class="nv">$gen</span> <span class="o">=</span> <span class="k">function</span> <span class="p">(</span><span class="nv">$total</span><span class="p">)</span> <span class="k">use</span> <span class="p">(</span><span class="nv">$client</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="nv">$total</span><span class="p">;</span> <span class="nv">$i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">yield</span> <span class="nv">$client</span><span class="o">-&gt;</span><span class="na">createRequest</span><span class="p">(</span><span class="s1">&#39;GET&#39;</span><span class="p">,</span> <span class="s1">&#39;http://example.com&#39;</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// Send 1000 requests concurrently using a pool size of 10</span>
<span class="nv">$pool</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Pool</span><span class="p">(</span><span class="nv">$client</span><span class="p">,</span> <span class="nv">$gen</span><span class="p">(</span><span class="mi">1000</span><span class="p">),</span> <span class="p">[</span><span class="s1">&#39;pool_size&#39;</span> <span class="o">=&gt;</span> <span class="mi">10</span><span class="p">]);</span>

<span class="c1">// A Pool is actually a future, so you can deref() or cancel() it</span>
<span class="c1">// at any time.</span>
<span class="nv">$pool</span><span class="o">-&gt;</span><span class="na">deref</span><span class="p">();</span>
</code></pre></div>


<h2>RingPHP Server Handlers</h2>

<p>Clojure&rsquo;s Ring library is first and foremost a library for implementing web
servers. So far I&rsquo;ve discussed RingPHP as a client, but it can also
be used as a <a href="http://RingPHP.readthedocs.org/en/latest/spec.html#server-specific-options">server-side library</a>
as well.</p>

<p>There is a very simple proof of concept RingPHP server handler that can be
used to serve HTTP requests: <a href="https://github.com/guzzle/RingPHP-server.">https://github.com/guzzle/RingPHP-server.</a> As
you can see, implementing a RingPHP server or client is strikingly similar.
This is a powerful similarity that allows middleware created for RingPHP
clients to also work with RingPHP servers.</p>

<h2>New Events</h2>

<p>Guzzle 4 had no concept of &ldquo;terminal events&rdquo;. You could subscribe to the
&ldquo;error&rdquo; and &ldquo;complete&rdquo; events, but those events could potentially be
invoked multiple times while transferring a single request. The next
version of Guzzle introduces an &ldquo;end&rdquo; event that is invoked once and
only once for a single request. The &ldquo;end&rdquo; event is invoked for both
errors and successful responses, and makes it easier to know the
ultimate end-result of sending an HTTP request.</p>

<p>In addition to the &ldquo;end&rdquo; event, the next version of Guzzle now
introduces the <code>retry()</code> method on the &ldquo;complete&rdquo; and &ldquo;error&rdquo; events
that allows event listeners to trigger a retry of a request without
creating a new &ldquo;before&rdquo; event or triggering multiple &ldquo;end&rdquo; events.</p>

<h2>Summary</h2>

<p>RingPHP provides a new middleware based PHP framework for both clients and
servers that is going to be used in the next major version of Guzzle in the
handler layer. RingPHP will provide Guzzle the ability to send requests
asynchronously while still providing the same synchronous interface thanks
to its use of Futures that block until a request is complete. As a result
of these updates, Guzzle can now retry requests and perform redirects
in a non-blocking manner, resulting in significant performance gains.</p>

<p>Before tagging the next major version of Guzzle, I&rsquo;d love feedback on
the RingPHP library and the updates I&rsquo;ve made to Guzzle. What do
you think?</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A Case for Higher Level PHP Streams in PSR-7]]></title>
    <link href="http://mtdowling.com/blog/2014/07/03/a-case-for-higher-level-php-streams/"/>
    <updated>2014-07-03T00:00:00-07:00</updated>
    <id>http://mtdowling.com/blog/2014/07/03/a-case-for-higher-level-php-streams</id>
    <content type="html"><![CDATA[<p>There&rsquo;s been a lot of talk lately about the <a href="https://github.com/php-fig/fig-standards/blob/master/proposed/http-message.md">PSR HTTP message  proposal</a>, PSR-7. The purpose of the proposal is to create a shared interface that  can be used by projects to interact with HTTP messages for both clients and  servers.</p>

<p>When I created the proposal, I envisioned the purpose is not to say projects that utilize HTTP messages need to make breaking changes to use the proposed interfaces, but rather give projects an interface for which they can create an adapter. For example, if there are swaths of changes to the proposal before it is accepted, then it is very unlikely for <a href="http://guzzlephp.org">Guzzle</a> (a very popular PHP HTTP client that I created) to utilize the interfaces directly. I also very much doubt that projects like Symfony or Zend Framework would update their HTTP message interfaces to match (at least in the near future).</p>

<h2>Message Bodies</h2>

<p>The biggest point of contention with the proposal so far has been deciding on  how the body of an HTTP message will be represented. In the current proposal,  the body of an HTTP message is exposed using a StreamInterface that provides the  following methods:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Psr\Http\Message</span><span class="p">;</span>

<span class="k">interface</span> <span class="nx">StreamInterface</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">__toString</span><span class="p">();</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">close</span><span class="p">();</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">detach</span><span class="p">();</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">getSize</span><span class="p">();</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">tell</span><span class="p">();</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">eof</span><span class="p">();</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">isSeekable</span><span class="p">();</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">seek</span><span class="p">(</span><span class="nv">$offset</span><span class="p">,</span> <span class="nv">$whence</span> <span class="o">=</span> <span class="nx">SEEK_SET</span><span class="p">);</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">isWritable</span><span class="p">();</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">write</span><span class="p">(</span><span class="nv">$string</span><span class="p">);</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">isReadable</span><span class="p">();</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">read</span><span class="p">(</span><span class="nv">$length</span><span class="p">);</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">getContents</span><span class="p">(</span><span class="nv">$maxLength</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div>


<p>As you can see, the StreamInterface provides methods that describe the stream&rsquo;s  capabilities (<code>isReadable()</code>, <code>isWritable()</code>, <code>isSeekable()</code>), can be cast to a  string, and provides methods that allow you to read and write to the stream  without having to load the entire stream into memory. Using the StreamInterface also consolidates all of the functions you need to interact with the data source in one easy to find place.</p>

<p>There are several other options that could have been utilized to represent an  HTTP message:</p>

<ul>
<li>string</li>
<li>iterators</li>
<li>PHP streams</li>
</ul>


<p>Utilizing a string would have required that the entire contents of the message  be loaded into memory. This won&rsquo;t work when you&rsquo;re interacting with web services  like Amazon S3 where it is common to download objects storing gigabytes of data.</p>

<p>Utilizing iterators <em>could</em> work, but it would likely cause a significant  performance penalty due to the fact that each call to <code>next()</code> would return only  a single byte, resulting in a huge number of method calls to download large  files. Furthermore, it would provide a read-only representation of a message  body.</p>

<h2>PHP Streams</h2>

<p>PHP streams offer pretty powerful abstraction over streams of data. They allow  you to implement custom stream protocols so that you can interact with various  data sources as well as stream filters which allow you to add customizations to  the way in which data is read or written to streams at runtime. In theory, it&rsquo;s  the obvious choice to use when representing HTTP message bodies. In practice, it  suffers from various problems that make it an impractical choice as the data  source for PSR-7.</p>

<h3>No Auto-registering of stream protocols and filters</h3>

<p>One of the great things about the StreamInterface approach is that you can easily implement StreamInterface to create stream decorators to add behavior to streams at runtime. This is an approach that I&rsquo;ve utilized heavily in Guzzle:</p>

<ul>
<li><a href="https://github.com/guzzle/streams/blob/master/src/CachingStream.php">Cache previously read bytes</a></li>
<li><a href="https://github.com/guzzle/streams/blob/master/src/LimitStream.php">Limit the data to be read to a subset of a large stream</a>. This requires <code>getSize()</code>, <code>tell()</code>, and various other methods to be decorated to limit the wrapped stream to only a subset of the larger stream.</li>
<li><a href="https://github.com/guzzle/streams/blob/master/src/NoSeekStream.php">Prevent seeking of a stream</a></li>
<li><a href="https://github.com/guzzle/message-integrity-subscriber/blob/master/src/ReadIntegrityStream.php">Implement message integrity checks</a>. This will throw an exception if a calculated rolling checksum of stream data as it is read does not match the expected checksum.</li>
<li><a href="https://github.com/guzzle/progress-subscriber/blob/master/src/UploadProgressStream.php">Provide progress information</a></li>
</ul>


<p>To add behavior like this to PHP streams, you&rsquo;d need to implement custom PHP stream wrappers and/or stream filters for each of the above decorators. The problem here is that you would need some kind of bootstrap script to register your named stream wrappers and filters before they can be utilized. There&rsquo;s no way in PHP to automatically register stream filters or wrappers before they are used. However, PHP has long offered autoloading of classes, which is the method in which StreamInterface decorators would be implemented.</p>

<h3>Exceptions cause warnings in stream wrappers and filters</h3>

<p>I&rsquo;ve been thinking lately that creating PHP resource stream decorators like I&rsquo;ve listed above would be possible, and could be implemented relatively painlessly using PHP stream wrappers. It turns out it is!</p>

<p>I started a GitHub repository that makes it easy to create PHP stream wrapper decorators that can implement what I&rsquo;ve listed above:  <a href="https://github.com/mtdowling/streamer">https://github.com/mtdowling/streamer</a>.  It acts as a decorator over an existing PHP stream resource.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">GuzzleHttp\Streamer\Utils</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">GuzzleHttp\Streamer\BaseWrapper</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">GuzzleHttp\Streamer\NoSeek</span><span class="p">;</span>

<span class="c1">// Prevents an underlying stream from being seeked</span>
<span class="k">class</span> <span class="nc">NoSeek</span> <span class="k">extends</span> <span class="nx">\GuzzleHttp\Streamer\BaseWrapper</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">stream_seek</span><span class="p">(</span><span class="nv">$offset</span><span class="p">,</span> <span class="nv">$whence</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="k">false</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="nv">$base</span> <span class="o">=</span> <span class="nx">Utils</span><span class="o">::</span><span class="na">create</span><span class="p">(</span><span class="s1">&#39;foobar&#39;</span><span class="p">);</span>
<span class="nv">$f</span> <span class="o">=</span> <span class="nx">NoSeek</span><span class="o">::</span><span class="na">wrap</span><span class="p">(</span><span class="nv">$base</span><span class="p">);</span>
<span class="k">echo</span> <span class="nb">fread</span><span class="p">(</span><span class="nv">$f</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span> <span class="c1">// Outputs &quot;foobar&quot;</span>
<span class="nb">fseek</span><span class="p">(</span><span class="nv">$f</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="k">echo</span> <span class="nb">fread</span><span class="p">(</span><span class="nv">$f</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span> <span class="c1">// Outputs &quot;&quot;</span>
</code></pre></div>


<p>That&rsquo;s awesome!</p>

<p>The problem with this approach is that PHP streams suffer from PHP&rsquo;s legacy of  emitting errors and warnings. Let&rsquo;s say you wanted to implement a message integrity check that creates a rolling checksum as data is read from a stream. When the last byte of data is read, the checksum is computed and validated against an expected value. If the checksums do not match, then you&rsquo;d throw an exception.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="k">class</span> <span class="nc">ThrowDecorator</span> <span class="k">extends</span> <span class="nx">\GuzzleHttp\Streamer\BaseWrapper</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">stream_read</span><span class="p">(</span><span class="nv">$count</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="c1">// Assume it&#39;s the last byte and there is a mismatch</span>
        <span class="k">throw</span> <span class="k">new</span> <span class="nx">\RuntimeException</span><span class="p">(</span><span class="s1">&#39;Checksum mismatch!&#39;</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="nv">$base</span> <span class="o">=</span> <span class="nx">Utils</span><span class="o">::</span><span class="na">create</span><span class="p">(</span><span class="s1">&#39;foobar&#39;</span><span class="p">);</span>
<span class="nv">$f</span> <span class="o">=</span> <span class="nx">ThrowDecorator</span><span class="o">::</span><span class="na">wrap</span><span class="p">(</span><span class="nv">$base</span><span class="p">);</span>
<span class="nb">fread</span><span class="p">(</span><span class="nv">$f</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>
</code></pre></div>


<p>Running the above example will always emit the following PHP warning followed by throwing the exception:</p>

<pre><code>PHP Warning:  fread(): ThrowDecorator::stream_eof is not implemented! Assuming EOF in test.php
</code></pre>

<p>So even though <code>stream_eof()</code> is implemented, throwing an exception inside of <code>stream_read()</code> will always emit the above warning.</p>

<p>&ldquo;This should be implemented as a stream filter!&rdquo; you might say. Ok, let&rsquo;s try that:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">class</span> <span class="nc">ThrowFilter</span> <span class="k">extends</span> <span class="k">php_user_filter</span>
<span class="p">{</span>
    <span class="k">function</span> <span class="nf">filter</span><span class="p">(</span><span class="nv">$in</span><span class="p">,</span> <span class="nv">$out</span><span class="p">,</span> <span class="o">&amp;</span><span class="nv">$consumed</span><span class="p">,</span> <span class="nv">$closing</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="c1">// Just throw immediately as an example</span>
        <span class="k">throw</span> <span class="k">new</span> <span class="nx">\RuntimeException</span><span class="p">(</span><span class="s1">&#39;Checksum mismatch!&#39;</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="nb">stream_filter_register</span><span class="p">(</span><span class="s1">&#39;throws&#39;</span><span class="p">,</span> <span class="s1">&#39;ThrowFilter&#39;</span><span class="p">);</span>
<span class="nv">$fp</span> <span class="o">=</span> <span class="nb">fopen</span><span class="p">(</span><span class="s1">&#39;/tmp/foo&#39;</span><span class="p">,</span> <span class="s1">&#39;r&#39;</span><span class="p">);</span>
<span class="nb">stream_filter_append</span><span class="p">(</span><span class="nv">$fp</span><span class="p">,</span> <span class="s1">&#39;throws&#39;</span><span class="p">);</span>
<span class="nb">fread</span><span class="p">(</span><span class="nv">$fp</span><span class="p">,</span> <span class="s2">&quot;Line1</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">);</span>
</code></pre></div>


<p>When the above example is run it emits a PHP warning before throwing the exception:</p>

<pre><code>PHP Warning:  fread(): Unprocessed filter buckets remaining on input brigade in test.php on line 20
</code></pre>

<p>The fact that PHP streams do not allow you to throw exceptions in the various abstractions poses a huge usability issue that basically renders them useless if you were wanting to decorate the behavior at runtime without resorting to emitting PHP warnings and errors rather than utilizing PHP exceptions.</p>

<h3>Cannot be cast to a string</h3>

<p>Because it implements <code>__toString()</code>, the StreamInterface approach allows the convenience of being able to treat a stream of data as a string while still allowing for the flexibility of not loading a bunch of data all into memory. This feature will make libraries implementing this proposal much more accessible to new users without making any tradeoffs in terms of encapsulation or flexibility.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="c1">// Outputs the string representation</span>
<span class="k">echo</span> <span class="nv">$message</span><span class="o">-&gt;</span><span class="na">getBody</span><span class="p">();</span>
</code></pre></div>


<p>On the other hand, using PHP streams directly would require boilerplate code each time you want to convert a message body to a string:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="nv">$resource</span> <span class="o">=</span> <span class="nv">$message</span><span class="o">-&gt;</span><span class="na">getBody</span><span class="p">();</span>
<span class="nb">rewind</span><span class="p">(</span><span class="nv">$resource</span><span class="p">);</span>
<span class="k">echo</span> <span class="nb">stream_get_contents</span><span class="p">(</span><span class="nv">$resource</span><span class="p">);</span>
</code></pre></div>


<h3>Functionality is spread over many functions</h3>

<p>To interact with PHP streams and get the same level of usability as the StreamInterface, you&rsquo;d need to interact with many different methods that aren&rsquo;t always easy to find (especially for a new user).</p>

<p>What if you wanted to know the amount of data in a PHP stream? When using the StreamInterface, it&rsquo;s a simple call to <code>getSize()</code>. When using PHP streams, it requires the following code:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="nv">$stats</span> <span class="o">=</span> <span class="nb">fstat</span><span class="p">(</span><span class="nv">$resource</span><span class="p">);</span>

<span class="k">if</span> <span class="p">(</span><span class="nb">isset</span><span class="p">(</span><span class="nv">$stats</span><span class="p">[</span><span class="s1">&#39;size&#39;</span><span class="p">]))</span> <span class="p">{</span>
    <span class="nv">$size</span> <span class="o">=</span> <span class="nv">$stats</span><span class="p">[</span><span class="s1">&#39;size&#39;</span><span class="p">];</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="nv">$size</span> <span class="o">=</span> <span class="k">null</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>


<p>What if you wanted to know whether or not a stream is seekable? Using the StreamInterface, it&rsquo;s a simple call to <code>isSeekable()</code>. When using PHP streams, you need the following code:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="nv">$meta</span> <span class="o">=</span> <span class="nb">stream_get_meta_data</span><span class="p">(</span><span class="nv">$resource</span><span class="p">);</span>
<span class="nv">$seekable</span> <span class="o">=</span> <span class="nv">$meta</span><span class="p">[</span><span class="s1">&#39;seekable&#39;</span><span class="p">];</span>
</code></pre></div>


<p>That wasn&rsquo;t too bad. But what if you wanted to know whether or not a stream is readable? Using the StreamInterface: <code>isReadable()</code>. Using PHP streams:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="nv">$meta</span> <span class="o">=</span> <span class="nb">stream_get_meta_data</span><span class="p">(</span><span class="nv">$resource</span><span class="p">);</span>
<span class="nv">$mode</span> <span class="o">=</span> <span class="nv">$meta</span><span class="p">[</span><span class="s1">&#39;mode&#39;</span><span class="p">];</span>
<span class="nv">$readableModes</span> <span class="o">=</span> <span class="p">[</span>
    <span class="s1">&#39;r&#39;</span><span class="p">,</span> <span class="s1">&#39;w+&#39;</span><span class="p">,</span> <span class="s1">&#39;r+&#39;</span><span class="p">,</span> <span class="s1">&#39;x+&#39;</span><span class="p">,</span> <span class="s1">&#39;c+&#39;</span><span class="p">,</span> <span class="s1">&#39;rb&#39;</span><span class="p">,</span> <span class="s1">&#39;w+b&#39;</span><span class="p">,</span> <span class="s1">&#39;r+b&#39;</span><span class="p">,</span> 
    <span class="s1">&#39;x+b&#39;</span><span class="p">,</span> <span class="s1">&#39;c+b&#39;</span><span class="p">,</span> <span class="s1">&#39;rt&#39;</span><span class="p">,</span> <span class="s1">&#39;w+t&#39;</span><span class="p">,</span> <span class="s1">&#39;r+t&#39;</span><span class="p">,</span> <span class="s1">&#39;x+t&#39;</span><span class="p">,</span> <span class="s1">&#39;c+t&#39;</span><span class="p">,</span> <span class="s1">&#39;a+&#39;</span>
<span class="p">];</span>
<span class="nv">$isReadable</span> <span class="o">=</span> <span class="nb">in_array</span><span class="p">(</span><span class="nv">$mode</span><span class="p">,</span> <span class="nv">$readableModes</span><span class="p">);</span>
</code></pre></div>


<p>A similar approach would need to be taken to know if a stream is writable. As you can see attempting to get the same functionality of a StreamInterface using native PHP streams would require quite a bit of boilerplate code.</p>

<p>Just for reference, here are links to PHP stream related functions and filesystem functions that can be used with PHP streams:</p>

<ul>
<li>Filesystem functions: <a href="http://php.net/manual/en/ref.filesystem.php">http://php.net/manual/en/ref.filesystem.php</a></li>
<li>Stream functions: <a href="http://php.net/manual/en/ref.stream.php">http://php.net/manual/en/ref.stream.php</a></li>
</ul>


<h2>StreamInterface concerns</h2>

<p>Even with the all of the problems that come with using PHP streams directly, various members of the mailing list has raised concerns about the StreamInterface approach. The most common concern is that there is no way to get a native PHP stream from a StreamInterface.</p>

<pre><code>The biggest thing I'm missing from the stream api, is to get to the
underlying stream.

--

We have to ensure that the common case is performant, and that it's
possible to take advantage of PHP's (fairly robust) stream handling
capabilities when feasible.  I totally get the portability and
simplicity benefits of abstracting it away from stream API, but there
needs to be a way to use, well, PHP, and do so performantly.
</code></pre>

<p>You want a way to represent a stream abstraction that does not necessarily  actually wrap a PHP stream to be able to be used like a PHP stream. This can be  achieved in a number of different ways.</p>

<h3>Creating a PHP stream from a StreamInterface</h3>

<p>When using Guzzle streams (a 1:1 implementation of the proposed  StreamInterface), you can convert any StreamInterface instance to a PHP stream  using a custom PHP stream wrapper:  <a href="https://github.com/guzzle/streams/blob/master/src/GuzzleStreamWrapper.php:">https://github.com/guzzle/streams/blob/master/src/GuzzleStreamWrapper.php:</a></p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">GuzzleHttp\Stream</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">GuzzleHttp\Stream\GuzzleStreamWrapper</span><span class="p">;</span>

<span class="c1">// Create a Guzzle stream</span>
<span class="nv">$stream</span> <span class="o">=</span> <span class="nx">Stream\create</span><span class="p">(</span><span class="s1">&#39;this is a string body&#39;</span><span class="p">);</span>

<span class="c1">// Create a PHP stream from the Guzzle stream that just wraps the Guzzle stream</span>
<span class="nv">$resource</span> <span class="o">=</span> <span class="nx">GuzzleStreamWrapper</span><span class="o">::</span><span class="na">getResource</span><span class="p">(</span><span class="nv">$stream</span><span class="p">);</span>
<span class="k">echo</span> <span class="nb">fread</span><span class="p">(</span><span class="nv">$resource</span><span class="p">,</span> <span class="mi">4</span><span class="p">);</span>
<span class="c1">// Outputs &quot;this&quot;</span>

<span class="c1">// Notice that the original stream is still in a consistent state</span>
<span class="k">echo</span> <span class="nv">$stream</span><span class="o">-&gt;</span><span class="na">tell</span><span class="p">();</span> <span class="c1">// 4</span>
<span class="k">echo</span> <span class="nb">ftell</span><span class="p">(</span><span class="nv">$resource</span><span class="p">);</span> <span class="c1">// 4</span>
</code></pre></div>


<p>The great thing about this approach is that it does not break the abstraction of  StreamInterface. For example, if you&rsquo;ve decorated the stream to add various  capabilities (e.g., checksum validation when the last byte is read), those same  capabilities will still be utilized when using the native PHP stream resource  that wraps the Guzzle stream. This would be the ideal approach to utilize when trying to use a StreamInterface as a native PHP stream.</p>

<h3>Getting the underlying PHP stream from a StreamInterface</h3>

<p>While there&rsquo;s no requirement that a StreamInterface actually wraps a PHP stream  resource (e.g., reading from strings, reading mocked data, etc.), it will often  be the case when interacting with things like files on disks or remote sockets.  In these cases, you might want to get the actual underlying stream resource from  the StreamInterface.</p>

<p>If the StreamInterface were able to return an underlying resources that can be mutated, then you would be breaking the abstraction by abandoning any decorators  and you would be leaving the StreamInterface in an inconsistent state. Because of this, the only way that the StreamInterface should return an actual underlying PHP stream resource should be when the <code>detach()</code> method is called (a method that already promises to leave a StreamInterface in an inconsistent state). Calling <code>StreamInterface::detach()</code> would return <code>null</code> if the StreamInterface doesn&rsquo;t  actually wrap an underlying resource, or would return a PHP stream resource if  one is utilized.</p>

<p>As a matter of fact, I recently pushed a change to Guzzle&rsquo;s streams API that  implements this change:  <a href="https://github.com/guzzle/streams/commit/368ee042ef5d88ffbc19632e0c114a54a3ac45b2.">https://github.com/guzzle/streams/commit/368ee042ef5d88ffbc19632e0c114a54a3ac45b2.</a> While detaching the underlying resource will not utilize any decorators that have been attached to the StreamInterface, it will provide a native PHP stream resource that does not need to utilize a custom Guzzle stream wrapper.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">GuzzleHttp\Stream</span><span class="p">;</span>

<span class="nv">$stream</span> <span class="o">=</span> <span class="nx">Stream\create</span><span class="p">(</span><span class="nb">fopen</span><span class="p">(</span><span class="s1">&#39;/tmp/foo&#39;</span><span class="p">,</span> <span class="s1">&#39;r&#39;</span><span class="p">));</span>
<span class="nv">$resource</span> <span class="o">=</span> <span class="nv">$stream</span><span class="o">-&gt;</span><span class="na">detach</span><span class="p">();</span>
</code></pre></div>


<p>I think that a similar change to the StreamInterface proposed in in PSR-7 should be made.</p>

<h2>Summary</h2>

<p>I&rsquo;ve outlined the different approaches that can be taken to represent HTTP message bodies in PSR-7 and provided more motiviation as to why I proposed the StreamInterface solution. Using PHP streams directly does not allow for a robust stream decoration strategy due to the fact that PHP streams suffers from legacy PHP warnings and errors. By showing how you can use a custom stream wrapper to convert a StreamInterface to a PHP stream and by returning the underlying PHP stream resource when the <code>StreamInterface::detach()</code> method is called, I&rsquo;ve addressed the concern that you cannot utilize native PHP streams when using a StreamInterface abstraction.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Guzzle 4.0]]></title>
    <link href="http://mtdowling.com/blog/2014/03/29/guzzle4/"/>
    <updated>2014-03-29T00:00:00-07:00</updated>
    <id>http://mtdowling.com/blog/2014/03/29/guzzle4</id>
    <content type="html"><![CDATA[<p>Guzzle 4.0 has arrived! The new version of <a href="https://github.com/guzzle/guzzle">Guzzle</a> is now simpler, faster, more flexible, and more powerful than ever.</p>

<p>You can install Guzzle 4 using Composer:</p>

<div class="highlight"><pre><code class="javascript"><span class="p">{</span>
    <span class="s2">&quot;require&quot;</span><span class="o">:</span> <span class="p">{</span>
        <span class="s2">&quot;guzzlehttp/guzzle&quot;</span><span class="o">:</span> <span class="s2">&quot;4.*&quot;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div>


<ul>
<li>View the documentation at <a href="http://guzzlephp.org">http://guzzlephp.org</a></li>
<li>View the source and contribute at <a href="https://github.com/guzzle/guzzle">https://github.com/guzzle/guzzle</a></li>
</ul>


<h2>What&rsquo;s Guzzle?</h2>

<p>Guzzle is a PHP HTTP client that makes it easy to work with HTTP/1.1 and takes the pain out of consuming web services. Here&rsquo;s a simple example of using Guzzle to interact with the GitHub API:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="nv">$client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">GuzzleHttp\Client</span><span class="p">();</span>
<span class="nv">$res</span> <span class="o">=</span> <span class="nv">$client</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s1">&#39;https://api.github.com/user&#39;</span><span class="p">,</span> <span class="p">[</span>
    <span class="s1">&#39;auth&#39;</span> <span class="o">=&gt;</span>  <span class="p">[</span><span class="s1">&#39;user&#39;</span><span class="p">,</span> <span class="s1">&#39;pass&#39;</span><span class="p">]</span>
<span class="p">]);</span>
<span class="k">echo</span> <span class="nv">$res</span><span class="o">-&gt;</span><span class="na">getStatusCode</span><span class="p">();</span>           <span class="c1">// 200</span>
<span class="k">echo</span> <span class="nv">$res</span><span class="o">-&gt;</span><span class="na">getHeader</span><span class="p">(</span><span class="s1">&#39;content-type&#39;</span><span class="p">);</span> <span class="c1">// &#39;application/json; charset=utf8&#39;</span>
<span class="k">echo</span> <span class="nv">$res</span><span class="o">-&gt;</span><span class="na">getBody</span><span class="p">();</span>                 <span class="c1">// {&quot;type&quot;:&quot;User&quot;...&#39;</span>
<span class="nb">var_export</span><span class="p">(</span><span class="nv">$res</span><span class="o">-&gt;</span><span class="na">json</span><span class="p">());</span>             <span class="c1">// Outputs the JSON decoded data</span>
</code></pre></div>


<h2>What&rsquo;s Changed?</h2>

<ul>
<li>Requires PHP 5.4 or Greater</li>
<li>Swappable HTTP adapters</li>
<li>Improved Performance</li>
<li>Simpler Interfaces</li>
<li>Smaller Core Library</li>
<li>A More Coherent Event System</li>
<li>More Straightforward Error Handling</li>
<li>Batching is Replaced by Async and Rolling Queues</li>
<li>Better POST File Support</li>
<li>No More Exception Markers</li>
</ul>


<p>You can find out more about the changes that were made by reading the blog post about the release candidate: <a href="http://mtdowling.com/blog/2014/03/15/guzzle-4-rc/">http://mtdowling.com/blog/2014/03/15/guzzle-4-rc/</a></p>

<p>You can view a list of changes and the upgrade guide to help you migrate from Guzzle 3 to 4 here: <a href="https://github.com/guzzle/guzzle/blob/master/UPGRADING.md#3x-to-40">https://github.com/guzzle/guzzle/blob/master/UPGRADING.md#3x-to-40</a></p>

<p>The Guzzle 4.0 repository is available at <a href="https://github.com/guzzle/guzzle">https://github.com/guzzle/guzzle</a>. Guzzle 3.x development has moved to <a href="https://github.com/guzzle/guzzle3">https://github.com/guzzle/guzzle3</a>. Please post issues for Guzzle 3 on the Guzzle 3 specific repository.</p>

<p>Because Guzzle 4.x was basically a rewrite of the library, I&rsquo;ve updated Guzzle 4 to use a different namespace and a different Composer package name so that you can use Guzzle 3 and 4 in the same project and slowly migrate pieces of you applications over time as needed.</p>

<h2>Plugins and companion libraries</h2>

<p>In addition to launching Guzzle 4.0, I&rsquo;ve also tagged a 1.0 release of the following packages:</p>

<ul>
<li><a href="https://github.com/guzzle/streams">Guzzle Streams</a></li>
<li><a href="https://github.com/guzzle/progress-subscriber">Progress Subscriber</a></li>
<li><a href="https://github.com/guzzle/log-subscriber">Log Subscriber</a></li>
</ul>


<p>The following libraries do not yet have a 1.0 release, but are available for use:</p>

<ul>
<li><a href="https://github.com/guzzle/oauth-subscriber">OAuth Subscriber</a></li>
<li><a href="https://github.com/guzzle/retry-subscriber">Retry Subscriber</a></li>
<li><a href="https://github.com/guzzle/message-integrity-subscriber">Message Integrity Subscriber</a></li>
<li><a href="https://github.com/guzzle/command">Guzzle Commands</a></li>
<li><a href="https://github.com/guzzle/guzzle-services">Guzzle Services</a></li>
</ul>


<h2>Service Descriptions</h2>

<p>Guzzle service descriptions (previously found under the <code>Guzzle\Service</code> namespace) have been moved into their own library at <a href="https://github.com/guzzle/guzzle-services">https://github.com/guzzle/guzzle-services</a>. This library is mostly complete but needs some additional testing and documentation.</p>

<h2>Documentation</h2>

<p>The documentation has been completely rewritten and updated for Guzzle 4.0:  <a href="http://guzzlephp.org">http://guzzlephp.org</a>. The Guzzle 3.0 documentation is still available online at <a href="http://guzzle3.readthedocs.org">http://guzzle3.readthedocs.org</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Favor Hash Lookups Over Array Searches]]></title>
    <link href="http://mtdowling.com/blog/2014/03/17/hash-lookups-over-array-search/"/>
    <updated>2014-03-17T00:00:00-07:00</updated>
    <id>http://mtdowling.com/blog/2014/03/17/hash-lookups-over-array-search</id>
    <content type="html"><![CDATA[<p>A common programming requirement is to match a string against a set of known
strings. For example, let&rsquo;s say you were iterating over the words in a forum post and testing to see if a word is in a list of prohibited words. A common approach to this problem is to create an array of the known prohibited words and then use PHP&rsquo;s <code>in_array()</code> function to test if the string is found in the list. However, there&rsquo;s a simple optimization you can make to significantly improve the performance of the algorithm.</p>

<h2>Searching an Array</h2>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="nv">$words</span> <span class="o">=</span> <span class="nx">get_all_words_in_text</span><span class="p">(</span><span class="nv">$text</span><span class="p">);</span>
<span class="nv">$badWords</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;$$$$&#39;</span><span class="p">,</span> <span class="s1">&#39;@#$%&#39;</span><span class="p">,</span> <span class="s1">&#39;crud&#39;</span> <span class="sd">/** ... */</span> <span class="p">];</span>

<span class="k">foreach</span> <span class="p">(</span><span class="nv">$words</span> <span class="k">as</span> <span class="nv">$word</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="nb">in_array</span><span class="p">(</span><span class="nx">strtolower</span><span class="p">(</span><span class="nv">$word</span><span class="p">),</span> <span class="nv">$badWords</span><span class="p">))</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="s1">&#39;Found bad word: &#39;</span> <span class="o">.</span> <span class="nv">$word</span> <span class="o">.</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div>


<p>This approach solves the problem, but it&rsquo;s inefficient. As we iterate over each word, we then test each word against each word in the bad word list using <code>in_array()</code>. PHP&rsquo;s <code>in_array()</code> function runs in <a href="http://en.wikipedia.org/wiki/Time_complexity#Linear_time">linear time</a>, meaning that as the size of the bad words array increases, the amount of time it takes to search the array proportionally increases. We can do much better than this.</p>

<h2>Hash Lookups</h2>

<p>Because the list of bad words is known up front, we can easily restructure our program to run in <a href="http://en.wikipedia.org/wiki/Time_complexity#Constant_time">constant time</a> by utilizing a PHP associative array. Like most hash tables, a key lookup on a PHP associative array is O(1) (except when a <a href="http://stackoverflow.com/a/2484455/151504">collision occurs</a> which isn&rsquo;t a concern for our use case).</p>

<p>If we restructure our PHP array to become an associative array where the words we are looking for are the keys and each value is <code>true</code>, then we can use PHP&rsquo;s <code>isset()</code> function and greatly speed things up:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="nv">$words</span> <span class="o">=</span> <span class="nx">get_all_words_in_text</span><span class="p">(</span><span class="nv">$text</span><span class="p">);</span>
<span class="nv">$badWords</span> <span class="o">=</span> <span class="p">[</span>
    <span class="s1">&#39;$$$$&#39;</span> <span class="o">=&gt;</span> <span class="k">true</span><span class="p">,</span>
    <span class="s1">&#39;@#$%&#39;</span> <span class="o">=&gt;</span> <span class="k">true</span><span class="p">,</span>
    <span class="s1">&#39;crud&#39;</span> <span class="o">=&gt;</span> <span class="k">true</span>
    <span class="c1">// ...</span>
<span class="p">];</span>

<span class="k">foreach</span> <span class="p">(</span><span class="nv">$words</span> <span class="k">as</span> <span class="nv">$word</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="nb">isset</span><span class="p">(</span><span class="nv">$badWords</span><span class="p">[</span><span class="nx">strtolower</span><span class="p">(</span><span class="nv">$word</span><span class="p">)]))</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="s1">&#39;Found bad word: &#39;</span> <span class="o">.</span> <span class="nv">$word</span> <span class="o">.</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div>


<h2>Benchmark</h2>

<p>Let&rsquo;s put this to the test. I&rsquo;ve written up a simple test to show the amount of time it takes to run each of the above implementations using some canned data.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="nv">$total</span> <span class="o">=</span> <span class="mi">10000</span><span class="p">;</span>
<span class="nv">$paragraph</span> <span class="o">=</span> <span class="s1">&#39;this is a sentence. Crud! $$$$!&#39;</span><span class="p">;</span>
<span class="nv">$words</span> <span class="o">=</span> <span class="nb">explode</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="nv">$paragraph</span><span class="p">);</span>
<span class="nv">$badWordList</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;$$$$&#39;</span><span class="p">,</span> <span class="s1">&#39;@#$%&#39;</span><span class="p">,</span> <span class="s1">&#39;crud&#39;</span><span class="p">,</span> <span class="s1">&#39;fud&#39;</span><span class="p">,</span> <span class="s1">&#39;fudd&#39;</span><span class="p">,</span> <span class="s1">&#39;dud&#39;</span><span class="p">];</span>

<span class="nv">$s</span> <span class="o">=</span> <span class="nb">microtime</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="nv">$j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nv">$j</span> <span class="o">&lt;</span> <span class="nv">$total</span><span class="p">;</span> <span class="nv">$j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">foreach</span> <span class="p">(</span><span class="nv">$words</span> <span class="k">as</span> <span class="nv">$word</span><span class="p">)</span> <span class="p">{</span>
        <span class="nb">in_array</span><span class="p">(</span><span class="nx">strtolower</span><span class="p">(</span><span class="nv">$word</span><span class="p">),</span> <span class="nv">$badWordList</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
<span class="k">echo</span> <span class="s2">&quot;in_array: &quot;</span> <span class="o">.</span> <span class="p">(</span><span class="nb">microtime</span><span class="p">(</span><span class="k">true</span><span class="p">)</span> <span class="o">-</span> <span class="nv">$s</span><span class="p">)</span> <span class="o">.</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>

<span class="nv">$badWordHash</span> <span class="o">=</span> <span class="p">[</span>
    <span class="s1">&#39;$$$$&#39;</span> <span class="o">=&gt;</span> <span class="k">true</span><span class="p">,</span>
    <span class="s1">&#39;@#$%&#39;</span> <span class="o">=&gt;</span> <span class="k">true</span><span class="p">,</span>
    <span class="s1">&#39;crud&#39;</span> <span class="o">=&gt;</span> <span class="k">true</span><span class="p">,</span>
    <span class="s1">&#39;fud&#39;</span>  <span class="o">=&gt;</span> <span class="k">true</span><span class="p">,</span>
    <span class="s1">&#39;fudd&#39;</span> <span class="o">=&gt;</span> <span class="k">true</span><span class="p">,</span>
    <span class="s1">&#39;dud&#39;</span>  <span class="o">=&gt;</span> <span class="k">true</span>
<span class="p">];</span>

<span class="nv">$s</span> <span class="o">=</span> <span class="nb">microtime</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="nv">$j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nv">$j</span> <span class="o">&lt;</span> <span class="nv">$total</span><span class="p">;</span> <span class="nv">$j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">foreach</span> <span class="p">(</span><span class="nv">$words</span> <span class="k">as</span> <span class="nv">$word</span><span class="p">)</span> <span class="p">{</span>
        <span class="nb">isset</span><span class="p">(</span><span class="nv">$badWordHash</span><span class="p">[</span><span class="nx">strtolower</span><span class="p">(</span><span class="nv">$word</span><span class="p">)]);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">echo</span> <span class="s2">&quot;hash:     &quot;</span> <span class="o">.</span> <span class="p">(</span><span class="nb">microtime</span><span class="p">(</span><span class="k">true</span><span class="p">)</span> <span class="o">-</span> <span class="nv">$s</span><span class="p">)</span> <span class="o">.</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
</code></pre></div>


<p>Here are the results of running the perf script 10,000 times:</p>

<pre><code>in_array: 0.033491134643555
hash:     0.0069370269775391
</code></pre>

<p>As you can see, converting the algorithm to use a hash lookup is <strong>480% faster</strong> than using in_array(). And that was using a small list of words.</p>

<p>It&rsquo;s important to understand that as the size of the array of prohibited words grows, so does the amount of time it takes to call <code>in_array()</code>. Conversely, the amount of time taken to run the <code>isset()</code> implementation will remain at a constant time. Let me show you what I mean. The following example uses a list of 10,000 words in our prohibited word list, and the results are quite different.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="nv">$total</span> <span class="o">=</span> <span class="mi">10000</span><span class="p">;</span>
<span class="nv">$paragraph</span> <span class="o">=</span> <span class="s1">&#39;this is a sentence. Crud! $$$$!&#39;</span><span class="p">;</span>
<span class="nv">$words</span> <span class="o">=</span> <span class="nb">explode</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="nv">$paragraph</span><span class="p">);</span>

<span class="c1">// Create a bunch of letter entries</span>
<span class="nv">$sequence</span> <span class="o">=</span> <span class="p">[];</span>
<span class="k">for</span> <span class="p">(</span><span class="nv">$j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nv">$j</span> <span class="o">&lt;</span> <span class="mi">10000</span><span class="p">;</span> <span class="nv">$j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="nv">$sequence</span><span class="p">[]</span> <span class="o">=</span> <span class="s1">&#39;a&#39;</span> <span class="o">.</span> <span class="nv">$j</span><span class="p">;</span>
<span class="p">}</span>

<span class="nv">$s</span> <span class="o">=</span> <span class="nb">microtime</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="nv">$j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nv">$j</span> <span class="o">&lt;</span> <span class="nv">$total</span><span class="p">;</span> <span class="nv">$j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">foreach</span> <span class="p">(</span><span class="nv">$words</span> <span class="k">as</span> <span class="nv">$word</span><span class="p">)</span> <span class="p">{</span>
        <span class="nb">in_array</span><span class="p">(</span><span class="nx">strtolower</span><span class="p">(</span><span class="nv">$word</span><span class="p">),</span> <span class="nv">$sequence</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
<span class="k">echo</span> <span class="s2">&quot;in_array: &quot;</span> <span class="o">.</span> <span class="p">(</span><span class="nb">microtime</span><span class="p">(</span><span class="k">true</span><span class="p">)</span> <span class="o">-</span> <span class="nv">$s</span><span class="p">)</span> <span class="o">.</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>

<span class="c1">// Convert the array to a hash</span>
<span class="nv">$hash</span> <span class="o">=</span> <span class="nb">array_fill_keys</span><span class="p">(</span><span class="nv">$sequence</span><span class="p">,</span> <span class="k">true</span><span class="p">);</span>
<span class="nv">$s</span> <span class="o">=</span> <span class="nb">microtime</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="nv">$j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nv">$j</span> <span class="o">&lt;</span> <span class="nv">$total</span><span class="p">;</span> <span class="nv">$j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">foreach</span> <span class="p">(</span><span class="nv">$words</span> <span class="k">as</span> <span class="nv">$word</span><span class="p">)</span> <span class="p">{</span>
        <span class="nb">isset</span><span class="p">(</span><span class="nv">$hash</span><span class="p">[</span><span class="nx">strtolower</span><span class="p">(</span><span class="nv">$word</span><span class="p">)]);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">echo</span> <span class="s2">&quot;hash:     &quot;</span> <span class="o">.</span> <span class="p">(</span><span class="nb">microtime</span><span class="p">(</span><span class="k">true</span><span class="p">)</span> <span class="o">-</span> <span class="nv">$s</span><span class="p">)</span> <span class="o">.</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
</code></pre></div>


<p>The results for this test are astronomically different between the in_array and hash implementation. The hash implementation is a whopping <strong>3,162% faster</strong>!</p>

<pre><code>in_array: 20.464313983917
hash:     0.0064699649810791
</code></pre>

<h2>This Isn&rsquo;t Anything New</h2>

<p>This isn&rsquo;t a new idea. It&rsquo;s a pretty common idiom in various languages. I was recently reminded of the fact that I constantly use hash lookups (no pun intended) for this sort of thing when I was reading <a href="http://www.lua.org/pil/11.5.html">&ldquo;Programming in Lua&rdquo;</a>.</p>

<p>Next time you&rsquo;re using PHP&rsquo;s <code>in_array()</code> to test a string against a known list of strings, see if it&rsquo;s at all possible to instead use a hash and <code>isset()</code>. It&rsquo;ll make your programs faster.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Guzzle 4 Release Candidate]]></title>
    <link href="http://mtdowling.com/blog/2014/03/15/guzzle-4-rc/"/>
    <updated>2014-03-15T00:00:00-07:00</updated>
    <id>http://mtdowling.com/blog/2014/03/15/guzzle-4-rc</id>
    <content type="html"><![CDATA[<p>After nearly 8 months of development, I&rsquo;m happy to announce a Guzzle 4 release candidate. Guzzle 4 is a huge step forward for the project and brings with it a number of improvements over previous versions.</p>

<h2>Swappable HTTP adapters</h2>

<p>Guzzle no longer requires cURL. New in Guzzle 4 is the ability to swap out the HTTP adapter used to send requests over the wire. You can now, for example, <a href="http://docs.guzzlephp.org/en/latest/adapters.html">create a custom HTTP adapter</a> to send requests using sockets, create an adapter to send requests with React, or create adapter proxies to choose the most appropriate adapter to use for a request based on its configuration options.</p>

<p>Guzzle actually automatically determines which adapter to use based on your environment and the request options of a request. When cURL is available on your system, Guzzle will automatically use cURL. When a request is sent with the <code>stream=true</code> <a href="http://docs.guzzlephp.org/en/latest/clients.html#request-options">request option</a>, Guzzle will automatically use the PHP stream wrapper HTTP adapter so that bytes are only read from the HTTP stream as needed.</p>

<p>Guzzle has historically only utilized cURL to send HTTP requests. cURL is an amazing HTTP client (arguably the best), and Guzzle will continue to use it by default when it is available. It is rare, but some developers don&rsquo;t have cURL installed on their systems or run into version specific issues. By allowing swappable HTTP adapters, Guzzle is now much more customizable and able to adapt to fit the needs of more developers.</p>

<p>These swappable HTTP adapters make it super easy to work with streaming API&rsquo;s like Twitter&rsquo;s:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">GuzzleHttp\Client</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">GuzzleHttp\Subscriber\Oauth\Oauth1</span><span class="p">;</span>

<span class="nv">$client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Client</span><span class="p">([</span>
    <span class="s1">&#39;base_url&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;https://stream.twitter.com/1/&#39;</span><span class="p">,</span>
    <span class="s1">&#39;defaults&#39;</span> <span class="o">=&gt;</span> <span class="p">[</span><span class="s1">&#39;auth&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;oauth&#39;</span><span class="p">]</span>
<span class="p">]);</span>

<span class="nv">$client</span><span class="o">-&gt;</span><span class="na">getEmitter</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">attach</span><span class="p">(</span><span class="k">new</span> <span class="nx">Oauth1</span><span class="p">([</span>
    <span class="s1">&#39;consumer_key&#39;</span>    <span class="o">=&gt;</span> <span class="s1">&#39;***&#39;</span><span class="p">,</span>
    <span class="s1">&#39;consumer_secret&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;***&#39;</span><span class="p">,</span>
    <span class="s1">&#39;token&#39;</span>           <span class="o">=&gt;</span> <span class="s1">&#39;***&#39;</span><span class="p">,</span>
    <span class="s1">&#39;token_secret&#39;</span>    <span class="o">=&gt;</span> <span class="s1">&#39;***&#39;</span>
<span class="p">]));</span>

<span class="nv">$response</span> <span class="o">=</span> <span class="nv">$client</span><span class="o">-&gt;</span><span class="na">post</span><span class="p">(</span><span class="s1">&#39;statuses/filter.json&#39;</span><span class="p">,</span> <span class="p">[</span>
    <span class="s1">&#39;body&#39;</span>   <span class="o">=&gt;</span> <span class="p">[</span><span class="s1">&#39;track&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;bieber&#39;</span><span class="p">],</span>
    <span class="s1">&#39;stream&#39;</span> <span class="o">=&gt;</span> <span class="k">true</span>
<span class="p">]);</span>

<span class="nv">$body</span> <span class="o">=</span> <span class="nv">$response</span><span class="o">-&gt;</span><span class="na">getBody</span><span class="p">();</span>

<span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="nv">$body</span><span class="o">-&gt;</span><span class="na">eof</span><span class="p">())</span> <span class="p">{</span>
    <span class="nv">$line</span> <span class="o">=</span> <span class="nv">$body</span><span class="o">::</span><span class="na">readLine</span><span class="p">(</span><span class="nv">$body</span><span class="p">);</span>
    <span class="nv">$data</span> <span class="o">=</span> <span class="nb">json_decode</span><span class="p">(</span><span class="nv">$line</span><span class="p">,</span> <span class="k">true</span><span class="p">);</span>
    <span class="nb">var_export</span><span class="p">(</span><span class="nv">$data</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div>


<h2>Requires PHP 5.4 or Greater</h2>

<p>Due to it&rsquo;s use of traits and array dereferencing, Guzzle 4 now requires PHP 5.4 or greater. PHP 5.4 is becoming more and more common as a requirement for PHP libraries. Guzzle now joins libraries like Laravel, Drupal 8, and React with its PHP 5.4 requirement.</p>

<h2>Improved Performance</h2>

<p>By removing superfluous features and better organizing how things work together, Guzzle 4 now offers a significant performance increase over previous version. Based on some rudimentary tests, Guzzle 4 is 40-50% faster for sending requests one after the other, and about 25% faster at sending requests in parallel.</p>

<p>When running PHP 5.5 or greater, Guzzle will now automatically send serial requests using cURL easy handles rather than cURL multi handles. This makes the typical use case of sending a few requests serially considerably faster, consumes less CPU, and works around various issues where PHP&rsquo;s cURL bindings poorly interface with cURL&rsquo;s multi API (e.g., timeouts, having to convert curl handles to file descriptors when <code>curl_multi_select()</code> is called, etc&hellip;).</p>

<h2>Simpler Interfaces</h2>

<p>The public interface of almost every class in Guzzle has been thoroughly analyzed to better define a minimal public API (following the <a href="http://my.safaribooksonline.com/book/programming/java/0201310058/methods/ch06lev1sec3">&ldquo;when in doubt, leave it out&rdquo;</a> mantra). Trimming down convenience methods, making class properties and methods private instead of protected, and trimming down extraneous method arguments helps to future proof the public interfaces. This means that you can expect 4.x to be the major version of Guzzle for the next few years. Simpler interfaces makes it easier for others to extend and implement the interfaces allowing for things like decorators and makes it easier to understand how the library works.</p>

<p>Some examples of this are:</p>

<ul>
<li>Requests no longer have a reference to a client or response. Clients send requests and transaction objects act as a mediator between a client, request, and response. The boundaries and responsibilities of these three collaborators are now more clearly defined.</li>
<li>There&rsquo;s no longer an interface separation between requests that can have a body and requests that can&rsquo;t have a body.</li>
<li>Requests no longer have state. They&rsquo;re much closer to value objects now.</li>
<li>Various methods of <code>Guzzle\Http\Client</code> have been removed in favor of a more flexible manner of <a href="http://docs.guzzlephp.org/en/latest/clients.html#creating-a-client">configuring default client request options</a>.</li>
<li>HTTP message headers are no longer header objects but rather strings and arrays.</li>
<li>There&rsquo;s now no difference between entity bodies and streams. Guzzle 4 now just uses <a href="http://docs.guzzlephp.org/en/latest/streams.html">streams</a>.</li>
</ul>


<h2>Smaller Core Library</h2>

<p>Various components have been pulled out into their own libraries to help make Guzzle a smaller library focused on sending HTTP requests. Guzzle&rsquo;s core library previously had iterators, inflectors, a batching abstraction, a service description layer, and many more components. The problem with creating such a monolithic repository is that it becomes extremely difficult to follow semver and to continue to progress the components independently of one another. A breaking change in even the most infrequently used corner of Guzzle 3 would warrant a major version bump or encourage a maintainer to not strictly follow semver.</p>

<p>Guzzle 4 has removed everything form the core Guzzle library that isn&rsquo;t required to send HTTP requests. The service description layer, most plugins, and various other components have been moved to their own repository. This means that you can expect Guzzle 4 to strictly follow semver.</p>

<ul>
<li><a href="https://github.com/guzzle/guzzle">Guzzle</a> &ndash; The main Guzzle HTTP library</li>
<li><a href="https://github.com/guzzle/streams">Streams</a> &ndash; Stream abstraction</li>
<li><a href="https://github.com/guzzle/command">Commands</a> &ndash; High level web service API commands</li>
<li><a href="https://github.com/guzzle/log-subscriber">Log Subscriber</a> &ndash; Logs requests and response messages</li>
<li><a href="https://github.com/guzzle/retry-subscriber">Retry Subscriber</a> &ndash; Retries failed HTTP requests</li>
<li><a href="https://github.com/guzzle/oauth-subscriber">OAuth Subscriber</a> &ndash; Signs requests with OAuth 1.0</li>
<li><a href="https://github.com/guzzle/message-integrity-subscriber">Message Integrity Subscriber</a> &ndash; Validates the message integrity of responses</li>
<li><a href="https://github.com/guzzle/cache-subscriber">Cache Subscriber</a> &ndash; Implements an HTTP cache (can someone help me update this for Guzzle 4 and make it cleaner?)</li>
</ul>


<h2>A More Coherent Event System</h2>

<p>The event system in Guzzle 4 is much more coherent and better defined.</p>

<ul>
<li>There are now fewer lifecycle events emitted for a request</li>
<li>There are now named event priorities that serve as a landmark for common event priorities. For example <code>GuzzleHttp\Event\RequestEvents::SIGN_REQUEST</code> can be used for all event subscribers that sign HTTP requests.</li>
<li>Errors that occur while transferring requests now consistently emit an &ldquo;error&rdquo; event. Previous versions of Guzzle had a &ldquo;request.exception&rdquo; and &ldquo;request.error&rdquo; event which basically served the same purpose, but just made them hard to work with.</li>
</ul>


<p>Guzzle now ships with its own custom event emitter based on the Symfony2 EventDispatcher. Guzzle&rsquo;s event emitter is more lightweight than the Symfony2 EventDispatcher and helps to isolate Guzzle from external versioning issues (e.g., Symfony 3).</p>

<p>You can learn more about the event system in the <a href="http://docs.guzzlephp.org/en/latest/events.html">online documentation</a>.</p>

<h2>More Straightforward Error Handling</h2>

<p>Clients now only throw exceptions that are a subclass of  <code>GuzzleHttp\Exception\RequestException</code> so the errors that can occur while sending a request are now clearly defined.</p>

<p>For example, in Guzzle 3 you had to catch <code>Guzzle\Http\Exception\RequestException</code> and <code>Guzzle\Http\CurlException</code> to catch HTTP protocol errors and networking errors (and this <a href="https://drupal.org/node/1875792">was hard to work with</a>).</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Guzzle\Http\Exception\RequestException</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Guzzle\Http\Exception\CurlException</span><span class="p">;</span>

<span class="k">try</span> <span class="p">{</span>
    <span class="nv">$client</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s1">&#39;https://github.com/_abc_123_404&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">send</span><span class="p">();</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">BadResponseException</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Do something useful.</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">CurlException</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Do something relevant.</span>
<span class="p">}</span>
</code></pre></div>


<p>Having to catch two different exceptions for a single request is an awkward API. Guzzle 4 now only throws exceptions that extend from <code>GuzzleHttp\Exception\RequestException</code>.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">GuzzleHttp\Exception\RequestException</span><span class="p">;</span>

<span class="k">try</span> <span class="p">{</span>
    <span class="nv">$client</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s1">&#39;https://github.com/_abc_123_404&#39;</span><span class="p">);</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">RequestException</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="nv">$e</span><span class="o">-&gt;</span><span class="na">getRequest</span><span class="p">();</span>
    <span class="k">if</span> <span class="p">(</span><span class="nv">$e</span><span class="o">-&gt;</span><span class="na">hasResponse</span><span class="p">())</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="nv">$e</span><span class="o">-&gt;</span><span class="na">getResponse</span><span class="p">();</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div>


<p>You can find out more about error handling in Guzzle in the <a href="http://docs.guzzlephp.org/en/latest/quickstart.html#exceptions">error handling section</a> of the documentation.</p>

<h2>Batching is Replaced by Async and Rolling Queues</h2>

<p>Guzzle 3 would previously send requests in batches. When exceptions occurred during a batch transaction, they were aggregated into an <code>ExceptionCollection</code> and thrown after all of the requests in a batch had either failed or completed. These aggregate exceptions were hard to work with and made Guzzle&rsquo;s parallel request implementation quite muddy.</p>

<p>Requests that are sent in parallel in Guzzle 4 are no longer batched with aggregate error handling. Instead, you now work with parallel requests in an asynchronous manner using events to handle both &ldquo;complete&rdquo; and &ldquo;error&rdquo; events. This approach makes it easier to work with parallel requests and easier to implement error handling.</p>

<p>Here&rsquo;s an example of sending requests in parallel and adding events to each request.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">GuzzleHttp\Client</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">GuzzleHttp\Event\BeforeEvent</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">GuzzleHttp\Event\ErrorEvent</span><span class="p">;</span>

<span class="c1">// Create a client with an optional base_url</span>
<span class="nv">$client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">GuzzleHttp\Client</span><span class="p">([</span><span class="s1">&#39;base_url&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;http://httpbin.org&#39;</span><span class="p">]);</span>

<span class="c1">// We want to send this array of requests</span>
<span class="nv">$requests</span> <span class="o">=</span> <span class="p">[</span>
    <span class="nv">$client</span><span class="o">-&gt;</span><span class="na">createRequest</span><span class="p">(</span><span class="s1">&#39;GET&#39;</span><span class="p">,</span> <span class="s1">&#39;/get&#39;</span><span class="p">),</span>
    <span class="nv">$client</span><span class="o">-&gt;</span><span class="na">createRequest</span><span class="p">(</span><span class="s1">&#39;DELETE&#39;</span><span class="p">,</span> <span class="s1">&#39;/delete&#39;</span><span class="p">),</span>
    <span class="nv">$client</span><span class="o">-&gt;</span><span class="na">createRequest</span><span class="p">(</span><span class="s1">&#39;PUT&#39;</span><span class="p">,</span> <span class="s1">&#39;/put&#39;</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;body&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;test&#39;</span><span class="p">])</span>
<span class="p">];</span>

<span class="c1">// Note: sendAll accepts an array or Iterator</span>
<span class="nv">$client</span><span class="o">-&gt;</span><span class="na">sendAll</span><span class="p">(</span><span class="nv">$requests</span><span class="p">,</span> <span class="p">[</span>
      <span class="c1">// Call this function when each request completes</span>
    <span class="s1">&#39;complete&#39;</span> <span class="o">=&gt;</span> <span class="k">function</span> <span class="p">(</span><span class="nx">CompleteEvent</span> <span class="nv">$event</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="s1">&#39;Completed request to &#39;</span> <span class="o">.</span> <span class="nv">$event</span><span class="o">-&gt;</span><span class="na">getRequest</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">getUrl</span><span class="p">()</span> <span class="o">.</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
        <span class="k">echo</span> <span class="s1">&#39;Response: &#39;</span> <span class="o">.</span> <span class="nv">$event</span><span class="o">-&gt;</span><span class="na">getResponse</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">getBody</span><span class="p">()</span> <span class="o">.</span> <span class="s2">&quot;</span><span class="se">\n\n</span><span class="s2">&quot;</span><span class="p">;</span>
    <span class="p">},</span>
    <span class="c1">// Call this function when a request encounters an error</span>
    <span class="s1">&#39;error&#39;</span> <span class="o">=&gt;</span> <span class="k">function</span> <span class="p">(</span><span class="nx">ErrorEvent</span> <span class="nv">$event</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="s1">&#39;Request failed: &#39;</span> <span class="o">.</span> <span class="nv">$event</span><span class="o">-&gt;</span><span class="na">getRequest</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">getUrl</span><span class="p">()</span> <span class="o">.</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span>
        <span class="k">echo</span> <span class="nv">$event</span><span class="o">-&gt;</span><span class="na">getException</span><span class="p">();</span>
    <span class="p">},</span>
    <span class="c1">// Maintain a maximum pool size of 25 concurrent requests.</span>
    <span class="s1">&#39;parallel&#39;</span> <span class="o">=&gt;</span> <span class="mi">25</span>
<span class="p">]);</span>
</code></pre></div>


<h2>Better POST File Support</h2>

<p>You can now send <code>multipart/form-data</code> requests with POST files that can be strings, Guzzle streams, or files on disk. Previous versions of Guzzle relied on cURL to construct <code>multipart/form-data</code> requests, and cURL has a limitation that it can only send files from disk. This caused developers to have to write temporary files to disk so that they could be send in a POST request. This is now much easier in Guzzle 4:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">GuzzleHttp\Client</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">GuzzleHttp\Stream\Stream</span><span class="p">;</span>

<span class="nv">$client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Client</span><span class="p">();</span>
<span class="nv">$client</span><span class="o">-&gt;</span><span class="na">post</span><span class="p">(</span><span class="s1">&#39;http://httpbin.org/post&#39;</span><span class="p">,</span> <span class="p">[</span>
    <span class="s1">&#39;body&#39;</span> <span class="o">=&gt;</span> <span class="p">[</span>
        <span class="s1">&#39;field&#39;</span>       <span class="o">=&gt;</span> <span class="s1">&#39;abc&#39;</span><span class="p">,</span>
        <span class="s1">&#39;other_field&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;123&#39;</span><span class="p">,</span>
        <span class="s1">&#39;file_name&#39;</span>   <span class="o">=&gt;</span> <span class="nb">fopen</span><span class="p">(</span><span class="s1">&#39;/path/to/file&#39;</span><span class="p">,</span> <span class="s1">&#39;r&#39;</span><span class="p">),</span>
        <span class="s1">&#39;other_file&#39;</span>  <span class="o">=&gt;</span> <span class="nx">Stream</span><span class="o">::</span><span class="na">factory</span><span class="p">(</span><span class="s1">&#39;file contents&#39;</span><span class="p">)</span>
    <span class="p">]</span>
<span class="p">]);</span>
</code></pre></div>


<h2>No More Exception Markers</h2>

<p>Guzzle no longer wraps every exception with pointless &ldquo;exception markers&rdquo;. Exception markers were a popular concept in the PHP community several years ago, which is why there were added to Guzzle. Exception markers that wrap standard library exceptions but provide no additional context are <a href="http://my.safaribooksonline.com/book/programming/java/9780137150021/exceptions/ch09lev1sec4">pointless and do nothing but bloat libraries</a>. I hope that this trend in the PHP community ends.</p>

<p>As an example: Guzzle previously included a <code>Guzzle\Exception\InvalidArgumentException</code> that wrapped the standard library&rsquo;s <code>\InvalidArgumentException</code>. This custom Guzzle exception marker provided absolutely no additional value to the exception. Furthermore, you almost never want to explicitly handle exception like <code>\InvalidArgumentException</code>, so the exception marker doesn&rsquo;t make much sense.</p>

<p>I didn&rsquo;t remove all custom exceptions. There are still enough so that you can catch relevant exceptions: <a href="https://github.com/guzzle/guzzle/tree/master/src/Exception">https://github.com/guzzle/guzzle/tree/master/src/Exception</a></p>

<h2>Guzzle Service Descriptions</h2>

<p>Guzzle service descriptions have been removed from the core library and broken into two components:</p>

<ul>
<li><a href="https://github.com/guzzle/command">Guzzle Commands</a></li>
<li><a href="https://github.com/guzzle/guzzle-services">Guzzle Services</a></li>
</ul>


<h3>Guzzle Commands</h3>

<p>The Commands library provides a simple interface for creating high level API clients using an event-based abstraction over Guzzle HTTP requests and responses. Events are emitted for preparing commands, processing commands, and handling errors encountered while executing a command.</p>

<ul>
<li>Commands: Key value pair objects representing an action to take on a web service. Commands have a name and a set of parameters.</li>
<li>Models: Models are key value pair objects representing the result of an API operation.</li>
</ul>


<p>By creating a simple interface for abstracting APIs, it is now easier to build request serializers and response parsers that use different service description formats (e.g., Swagger, RAML, etc&hellip;) while still being able to create service description independent event subscribers.</p>

<p>Note: Guzzle Commands is still in beta.</p>

<h3>Guzzle Services</h3>

<p><strong>Guzzle Services</strong> is an implementation of the Guzzle Commands abstraction that implements the Guzzle service description format.</p>

<p>Note: Guzzle Commands is still in beta.</p>

<h4>JSON Arrays in Service Descriptions</h4>

<p>Various APIs include arrays as the top-level value of their JSON responses. Guzzle 3 had a well-known issue with describing top-level arrays in its service description format. This issue has now been resolved in Guzzle 4&rsquo;s Guzzle Services component.</p>

<h4>Easier to Register Custom Locations</h4>

<p>Registering custom request and response locations to implement custom serialization or parsing was really difficult in Guzzle 3. It&rsquo;s now much easier in the Guzzle Services component.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">GuzzleHttp\Client</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">GuzzleHttp\Command\Guzzle\GuzzleClient</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">GuzzleHttp\Command\Guzzle\Description</span><span class="p">;</span>

<span class="nv">$client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Client</span><span class="p">();</span>

<span class="nv">$description</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Description</span><span class="p">([</span>
    <span class="s1">&#39;baseUrl&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;http://httpbin.org/&#39;</span><span class="p">,</span>
    <span class="s1">&#39;operations&#39;</span> <span class="o">=&gt;</span> <span class="p">[</span>
        <span class="s1">&#39;testing&#39;</span> <span class="o">=&gt;</span> <span class="p">[</span>
            <span class="s1">&#39;httpMethod&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;GET&#39;</span><span class="p">,</span>
            <span class="s1">&#39;uri&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;/get&#39;</span><span class="p">,</span>
            <span class="s1">&#39;responseModel&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;getResponse&#39;</span><span class="p">,</span>
            <span class="s1">&#39;parameters&#39;</span> <span class="o">=&gt;</span> <span class="p">[</span>
                <span class="s1">&#39;foo&#39;</span> <span class="o">=&gt;</span> <span class="p">[</span>
                    <span class="s1">&#39;type&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;string&#39;</span><span class="p">,</span>
                    <span class="s1">&#39;location&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;query&#39;</span>
                <span class="p">]</span>
            <span class="p">]</span>
        <span class="p">]</span>
    <span class="p">],</span>
    <span class="s1">&#39;models&#39;</span> <span class="o">=&gt;</span> <span class="p">[</span>
        <span class="s1">&#39;getResponse&#39;</span> <span class="o">=&gt;</span> <span class="p">[</span>
            <span class="s1">&#39;type&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;object&#39;</span><span class="p">,</span>
            <span class="s1">&#39;additionalProperties&#39;</span> <span class="o">=&gt;</span> <span class="p">[</span>
                <span class="s1">&#39;location&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;json&#39;</span>
            <span class="p">]</span>
        <span class="p">]</span>
    <span class="p">]</span>
<span class="p">]);</span>

<span class="nv">$guzzleClient</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">GuzzleClient</span><span class="p">(</span>
    <span class="nv">$client</span><span class="p">,</span> 
    <span class="nv">$description</span><span class="p">,</span>
    <span class="p">[</span>
        <span class="c1">// You can optionally add custom request locations</span>
        <span class="s1">&#39;request_locations&#39;</span> <span class="o">=&gt;</span> <span class="p">[</span>
            <span class="s1">&#39;custom_location&#39;</span> <span class="o">=&gt;</span> <span class="k">new</span> <span class="nx">CustomRequestLocation</span><span class="p">()</span>
        <span class="p">],</span>
        <span class="c1">// You can optionally add custom response locations</span>
        <span class="s1">&#39;response_locations&#39;</span> <span class="o">=&gt;</span> <span class="p">[</span>
            <span class="s1">&#39;custom_location&#39;</span> <span class="o">=&gt;</span> <span class="k">new</span> <span class="nx">CustomResponseLocation</span><span class="p">()</span>
        <span class="p">],</span>
    <span class="p">]</span>
<span class="p">);</span>

<span class="nv">$result</span> <span class="o">=</span> <span class="nv">$guzzleClient</span><span class="o">-&gt;</span><span class="na">testing</span><span class="p">([</span><span class="s1">&#39;foo&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;bar&#39;</span><span class="p">]);</span>
<span class="k">echo</span> <span class="nv">$result</span><span class="p">[</span><span class="s1">&#39;args&#39;</span><span class="p">][</span><span class="s1">&#39;foo&#39;</span><span class="p">];</span>
<span class="c1">// bar</span>
</code></pre></div>


<h2>Plugin Rewrites</h2>

<p>Various plugins from 3.x have been ported over to Guzzle 4. The following event subscribers are included as part of the core library:</p>

<ul>
<li>Cookie: Adds, extracts, and persists cookies between HTTP requests. Cookies are easily configured using the <a href="http://docs.guzzlephp.org/en/latest/clients.html#cookies">cookies request option</a>.</li>
<li>History: Maintains a list of requests and responses sent using a request or client.</li>
<li>HttpError: Throws exceptions when a 4xx or 5xx response is received.</li>
<li>Mock: Queues mock responses or exceptions and delivers mock responses or  exceptions in a fifo order. The mock subscriber now throws exceptions when the queue of mocked responses is empty.</li>
<li>Redirect: Implements adapter agnostic HTTP redirects. Now supports automatically adding the Referer header and specifying the maximum number of redirects. Redirects are easily configured using the <a href="http://docs.guzzlephp.org/en/latest/clients.html#allow-redirects">allow_redirects request option</a>.</li>
</ul>


<p>Other plugins were moved to their own repositories:</p>

<ul>
<li>The <a href="https://github.com/guzzle/log-subscriber">Log Subscriber</a> now uses PSR-3 loggers.</li>
<li>The <a href="https://github.com/guzzle/retry-subscriber">Retry Subscriber</a> replaces the old BackoffPlugin and allows for much easier and flexible retry policies.</li>
<li>The <a href="https://github.com/guzzle/oauth-subscriber">OAuth Subscriber</a> has been mostly rewritten to better follow OAuth 1.0 standards (in response and with the help of <a href="https://github.com/guzzle/guzzle/pull/563">this PR</a>).</li>
<li>The <a href="https://github.com/guzzle/message-integrity-subscriber">Message Integrity Subscriber</a> replaces the old MessageIntegrityPlugin and allows for much more customization, can validate
response bodies all at once, or validate streaming response bodies when the last byte of a stream is read.</li>
</ul>


<p>Some plugins were removed because they were deprecated:</p>

<ul>
<li><code>GuzzleHttp\Plugin\Async</code> has been removed. This plugin never actually worked that well and is often causes confusion. I also think the concept in general is a bad idea. Without waiting on an HTTP response, you have no idea if a request succeeded or if the remote server received all of the data correctly. Severing a socket when all of the data has been sent from a client should be implemented using a custom <a href="http://docs.guzzlephp.org/en/latest/adapters.html">HTTP adapter</a>.</li>
<li><code>GuzzleHttp\Plugin\CurlAuth</code> has been removed. You can just use the <a href="http://docs.guzzlephp.org/en/latest/clients.html#auth">&ldquo;auth&rdquo; request option</a>.</li>
<li><code>GuzzleHttp\Plugin\ErrorResponse\ErrorResponsePlugin</code> has been removed. This was implemented poorly and forced too many constraints on how error responses were constructed. This type of behavior should now be implemented using the <a href="https://github.com/guzzle/command#event-system">command event system</a>.</li>
</ul>


<h2>Migrating to Guzzle 4</h2>

<p>Have a look at the <a href="https://github.com/guzzle/guzzle/blob/master/UPGRADING.md">upgrade guide</a> for information on how to upgrade to Guzzle 4. The good news is that Guzzle 4 uses a new Packagist package name and a different namespace.</p>

<p>Guzzle 3 can still be installed with Composer using <code>guzzle/guzzle</code>. Guzzle 4 is installed using <code>guzzlehttp/guzzle</code>. Guzzle 3 will continue to use the <code>Guzzle\\</code> namespace, while Guzzle 4 now uses the <code>GuzzleHttp</code> namespace. These changes make it possible to use both Guzzle 3 and Guzzle 4 in the same project without conflicts.</p>

<p>I will not publish PEAR packages or phars for Guzzle 4, but I will continue to do so for Guzzle 3.</p>

<h3>What About Guzzle 3?</h3>

<p>Guzzle 3 is an extremely popular library. It is still going to be maintained, but development has now moved to <a href="https://github.com/guzzle/guzzle3.">https://github.com/guzzle/guzzle3.</a> Issues related to Guzzle 3 should be opened on the guzzle3 GitHub repository.</p>

<h2>Testing the Release Candidate</h2>

<p>I&rsquo;ve hopefully convinced you that Guzzle 4 is an amazing evolutionary step for the library. Now I need your help. Guzzle 4 will be in release candidate stage for the next 2 weeks (possibly 3 if significant issues are reported). I&rsquo;d really appreciate it if people could test the library and provide feedback before a stable 4.0 release is tagged. My motivation for the aggressive release is in hopes that Drupal 8 will <a href="https://twitter.com/crell/status/440911396000129025">adopt the new version</a>.</p>

<p>You can get started with Guzzle 4 with Composer and the <a href="http://guzzlephp.org">online documentation</a>.</p>

<div class="highlight"><pre><code class="javascript"><span class="p">{</span>
    <span class="s2">&quot;require&quot;</span><span class="o">:</span> <span class="p">{</span>
        <span class="s2">&quot;guzzlehttp/guzzle&quot;</span><span class="o">:</span> <span class="s2">&quot;4.*&quot;</span>
    <span class="p">},</span>
    <span class="s2">&quot;minimum-stability&quot;</span><span class="o">:</span> <span class="s2">&quot;RC&quot;</span>
<span class="p">}</span>
</code></pre></div>


<p>Enjoy!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Requiring cURL in Your PHP Library]]></title>
    <link href="http://mtdowling.com/blog/2013/05/02/requiring-curl-in-your-php-library/"/>
    <updated>2013-05-02T00:00:00-07:00</updated>
    <id>http://mtdowling.com/blog/2013/05/02/requiring-curl-in-your-php-library</id>
    <content type="html"><![CDATA[<p>I sometimes hear that people don’t want to use <a href="https://github.com/guzzle/guzzle">Guzzle</a> (a PHP HTTP client) because it requires cURL and they want their library to be “portable”. In this post, I’ll attempt to convince you that cURL is the best option for sending HTTP requests in PHP, compare cURL against more “portable” PHP alternatives, and prove that your users will probably already have cURL installed on their systems.</p>

<h2>“Portable” cURL alternatives</h2>

<p>First off, let’s define “portable”. Most of the people that throw this word around imply that if it isn’t part of PHP’s core then it isn’t portable. Ok, so what are the different ways to send HTTP requests using only things provided in PHP’s core distribution?</p>

<h3>HTTP stream wrapper</h3>

<p>The most common alternative to requiring cURL in a PHP application is to rely on PHP’s HTTP stream wrapper. If your requirements are very limited, then this might be an OK alternative for you. There are some drawbacks to using the PHP HTTP stream wrapper that you should know about before ditching cURL for it:</p>

<ul>
<li>Does not support HTTP 1.1</li>
<li>Does not support streaming uploads. Uploads for POST, PUT, etc must be from a string loaded into memory. Try uploading a 2GB file with <code>fopen()</code>.</li>
<li>Does not support <a href="http://en.wikipedia.org/wiki/HTTP_persistent_connection">persistent HTTP connections</a>. Opening and closing TCP connections over and over can be a massive performance penalty to an application that makes several requests to the same server.</li>
<li>Does not support the fine-grained timeout and speed limit <a href="http://php.net/manual/en/function.curl-setopt.php">options of cURL</a></li>
<li>Does not maintain cookies between requests. You would need to <a href="http://tools.ietf.org/html/rfc6265">implement cookie management</a> manually.</li>
<li>Does not support sending requests in parallel. Sending requests in parallel can provide significant performance gains to applications that need to send many requests at once.</li>
<li><a href="http://stackoverflow.com/questions/555523/file-get-contents-vs-curl-what-has-better-performance">It’s  slower than cURL</a></li>
</ul>


<h3>Sockets</h3>

<p>Creating a PHP HTTP client using sockets is another alternative. When I hear someone is writing a socket based HTTP client from scratch, my first thought is, “have you seen RFC 2616?!” There’s an awful lot of context, state transitions, and edge cases to consider when implementing a socket based HTTP client. Because of the complexity, developers either rarely get it right or omit swaths of HTTP/1.1 features because they are hard to implement (e.g. <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3">Expect: 100-Continue</a>, <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.39">trailing headers</a>, <a href="http://tools.ietf.org/html/rfc2388">multi-part messages</a>, etc). The one PHP HTTP/1.1 socket based client that <a href="https://github.com/zendframework/zf2/blob/master/library/Zend/Http/Client/Adapter/Socket.php">actually does a decent job</a> sadly lacks sending requests in parallel.</p>

<p>There are a great deal of edge cases to consider when implementing a socket based HTTP client:</p>

<ul>
<li>What if the remote server is not listening on the specified port?</li>
<li>What if the remote server takes too long to respond?</li>
<li>What if the HTTP response message is not a valid HTTP response?</li>
<li>What if the HTTP response states that it will send more data than it actually sends?</li>
<li>What if the connection is severed in the middle of the request?</li>
<li>What if a request with an <code>Expect: 100-Continue</code> header never receives a <code>100 Continue</code> response?</li>
<li>What if you need to implement persistent connections? Did the remote server send back a <code>Connection: close</code> header? Did the connection close unannounced?</li>
<li>What if the remote server responds with <a href="http://en.wikipedia.org/wiki/Chunked_transfer_encoding">chunked Transfer-Encoding</a>?</li>
<li>Will you implement 300 level redirects? Will you gracefully handle <code>Location</code> headers that use relative URLs?</li>
<li>What if you need to maintain a cookie session between requests?</li>
<li>What if you need to use Digest authentication?</li>
<li>How will you implement persistent connections?</li>
<li>Will you support sending requests in parallel?</li>
</ul>


<p>Need more examples that prove HTTP/1.1 is complicated? <a href="http://viswaug.files.wordpress.com/2008/11/http-headers-status1.png">Check this out</a>.</p>

<p>Trying to implement a socket based HTTP client in PHP that has a comparable feature set to cURL is a monumental undertaking. If you choose to go down this path, then Godspeed.</p>

<h2>How ubiquitous is cURL?</h2>

<p>Daniel Stenberg, the author of libcurl, recently wrote about <a href="http://daniel.haxx.se/blog/2012/05/16/300m-users/">this very topic</a>. Daniel estimates that there are probably around 550,000,000 direct or indirect libcurl users. His first number was around 300M, but he realized libcurl is installed on all iOS devices. That number is just an estimate of the number of unique cURL users, so let’s narrow this down to more PHP specific data.</p>

<h3>Shared hosts that provide cURL by default</h3>

<p>Creating a library that requires cURL expects that your users either already have cURL installed or can install <a href="http://php.net/manual/en/book.curl.php">PHP’s cURL extension</a>. The scariest part about requiring users to install cURL is that some of your users will be on a shared server without shell or root access.</p>

<p>With that in mind, I quickly compiled a list of shared hosting companies that include PHP’s cURL extension by default on all of their servers.</p>

<ul>
<li><a href="http://support.godaddy.com/help/category/435/web-hosting-languages-and-scripts-php-curl">GoDaddy</a></li>
<li><a href="http://support.hostgator.com/articles/php-modules">HostGator</a></li>
<li><a href="http://wiki.dreamhost.com/index.php/CURL">DreamHost</a></li>
<li><a href="http://secure.servergrove.com/sharedhosting#features">ServerGrove</a></li>
<li><a href="http://www.000webhost.com/free-php-hosting">WebhostingBuzz</a></li>
<li><a href="https://twitter.com/alwaysdata/status/206875904436211713">Alwaysdata.com</a></li>
<li><a href="http://vexxhost.com/shared_web_hosting/features">Vexxhost.com</a></li>
<li><a href="www.ipagereviewsblog.com/features/ipage-php/">iPage.com</a></li>
<li><em>Got bored at about this point</em></li>
</ul>


<p><em>Let me know in the comments if you can think of other shared hosting providers that provide PHP’s cURL extension by default.</em></p>

<h2>Who uses cURL?</h2>

<p>PHP’s cURL extension is utilized by countless PHP libraries. Each and every one of these library authors decided that requiring cURL for their library was an acceptable requirement.</p>

<h3>API clients that require cURL</h3>

<p>Lots of large companies offer PHP SDKs for their web services that require cURL. Any developer that utilizes any of the following libraries have installed cURL on their system:</p>

<ul>
<li><a href="https://github.com/aws/aws-sdk-php">AWS SDK for PHP</a></li>
<li><a href="https://code.google.com/p/google-api-php-client/wiki/GettingStarted">Google API PHP client</a></li>
<li><a href="https://github.com/facebook/facebook-php-sdk">Facebook PHP SDK</a></li>
<li><a href="https://github.com/tumblr/tumblr.php">Tumblr API v2 PHP Client</a></li>
<li><a href="https://github.com/twilio/twilio-php/blob/master/Services/Twilio/TinyHttp.php">Twilio PHP client</a></li>
<li><a href="https://packagist.org/packages/rackspace/php-cloudfiles">Rackspace CloudFiles</a></li>
<li><a href="https://code.google.com/p/opensocial-php-client/source/browse/trunk/src/osapi/io/osapiCurlProvider.php">Open-Social PHP client</a></li>
<li><a href="https://github.com/yahoo/yos-social-php5">Yahoo Social</a></li>
<li><a href="https://github.com/vimeo/vimeo-php-lib/blob/master/vimeo.php">Vimeo PHP lib</a></li>
<li><a href="https://github.com/dropbox/dropbox-sdk-php">Dropbox SDK for PHP</a></li>
<li><a href="https://github.com/paypal">Paypal PHP SDKs</a></li>
<li><a href="https://packagist.org/packages/stripe/stripe-php">Stripe PHP SDK</a></li>
<li><em>Tell me in the comments what other official web service clients I’m missing.</em></li>
</ul>


<h3>Who else uses cURL?</h3>

<p>Some really popular frameworks and libraries require cURL. Developers that use or will use any of the following libraries will likely have cURL installed on their system:</p>

<ul>
<li><a href="http://www.magentocommerce.com/system-requirements">Magento</a></li>
<li><a href="http://drupal.org/node/1447736">Drupal 8</a></li>
<li><a href="https://github.com/fabpot/Goutte">Goutte</a></li>
<li><a href="https://packagist.org/packages/phpunit/phpunit-selenium">PHPUnit-Selenium</a></li>
</ul>


<h2>Installing php-curl</h2>

<p>Installing cURL is usually really, really easy.</p>

<ul>
<li>Ubuntu: <code>apt-get install php5-curl</code></li>
<li>Fedora / Amazon Linux: <code>yum install php-curl</code></li>
<li><p><a href="http://www.tomjepson.co.uk/enabling-curl-in-php-php-ini-wamp-xamp-ubuntu/">WAMP</a></p>

<ol>
<li>Left-click on the WAMP server icon in the bottom right of the screen</li>
<li>PHP &ndash;&gt; PHP Extensions &ndash;&gt; php_curl</li>
</ol>
</li>
</ul>


<h2>Conclusion</h2>

<p>cURL is everywhere. Extremely popular PHP libraries already require cURL. Most shared PHP hosts support cURL by default. Requiring cURL in your PHP library will not detract a statistically significant number of users to the point of justifying resorting to the underpowered PHP HTTP stream wrapper or the frivolous wheel-reinvention that is creating a socket based HTTP client.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Guzzle 3.0: Better service descriptions and more modular]]></title>
    <link href="http://mtdowling.com/blog/2012/10/16/guzzle-3-dot-0-better-service-descriptions-and-more-modular/"/>
    <updated>2012-10-16T00:23:00-07:00</updated>
    <id>http://mtdowling.com/blog/2012/10/16/guzzle-3-dot-0-better-service-descriptions-and-more-modular</id>
    <content type="html"><![CDATA[<p><a href="https://github.com/guzzle/guzzle">Guzzle 3.0</a> was released tonight, bringing with it an enormous number of improvements to an already feature-rich PHP HTTP client and web service framework.</p>

<h2>Advanced service descriptions</h2>

<p>Hands down, the biggest changes in Guzzle are found in Guzzle&rsquo;s <a href="http://guzzlephp.org/guide/service/service_descriptions.html">service descriptions</a>. Guzzle&rsquo;s new service description format
is heavily inspired by <a href="http://swagger.wordnik.com/">Swagger</a>, and now support complex request bodies and modeled responses.</p>

<p>Guzzle 2.x only supported top-level parameters, so if a web service operation needed a complex request body, you had to create a concrete class. Concrete classes are still supported, but you
can now model nested XML and JSON input structures in service descriptions without needing to write a line of PHP. Simply create the necessary parameters of your web service using <a href="http://tools.ietf.org/id/draft-zyp-json-schema-03.html">JSON
schema</a> syntax.</p>

<p>Guzzle 3.0 now introduces the concept of response models. Any operation with a <code>responseClass</code> attribute that matches the name of a model defined in a service description will return a
<code>Guzzle\Service\Resource\Model</code> object when executed. This object looks like an array and contains the structural definition of the model. Using JSON schema definitions, you can now
define the hash-like structure of a model and provide an easier to use abstraction over SimpleXMLElements or raw arrays.</p>

<p>Let&rsquo;s work through an example. Take the following imaginary web service:</p>

<pre><code>GET/POST   /users
GET/DELETE /users/:id
</code></pre>

<p>This web service can be implemented using the following service description:</p>

<div class="highlight"><pre><code class="javascript"><span class="p">{</span>
    <span class="s2">&quot;name&quot;</span><span class="o">:</span> <span class="s2">&quot;Foo&quot;</span><span class="p">,</span>
    <span class="s2">&quot;apiVersion&quot;</span><span class="o">:</span> <span class="s2">&quot;2012-10-14&quot;</span><span class="p">,</span>
    <span class="s2">&quot;baseUrl&quot;</span><span class="o">:</span> <span class="s2">&quot;http://api.foo.com&quot;</span><span class="p">,</span>
    <span class="s2">&quot;description&quot;</span><span class="o">:</span> <span class="s2">&quot;Foo is an API that allows you to Baz Bar&quot;</span><span class="p">,</span>
    <span class="s2">&quot;operations&quot;</span><span class="o">:</span> <span class="p">{</span>
        <span class="s2">&quot;GetUsers&quot;</span><span class="o">:</span> <span class="p">{</span>
            <span class="s2">&quot;httpMethod&quot;</span><span class="o">:</span> <span class="s2">&quot;GET&quot;</span><span class="p">,</span>
            <span class="s2">&quot;uri&quot;</span><span class="o">:</span> <span class="s2">&quot;/users&quot;</span><span class="p">,</span>
            <span class="s2">&quot;summary&quot;</span><span class="o">:</span> <span class="s2">&quot;Gets a list of users&quot;</span><span class="p">,</span>
            <span class="s2">&quot;responseClass&quot;</span><span class="o">:</span> <span class="s2">&quot;GetUsersOutput&quot;</span>
        <span class="p">},</span>
        <span class="s2">&quot;CreateUser&quot;</span><span class="o">:</span> <span class="p">{</span>
            <span class="s2">&quot;httpMethod&quot;</span><span class="o">:</span> <span class="s2">&quot;POST&quot;</span><span class="p">,</span>
            <span class="s2">&quot;uri&quot;</span><span class="o">:</span> <span class="s2">&quot;/users&quot;</span><span class="p">,</span>
            <span class="s2">&quot;summary&quot;</span><span class="o">:</span> <span class="s2">&quot;Creates a new user&quot;</span><span class="p">,</span>
            <span class="s2">&quot;responseClass&quot;</span><span class="o">:</span> <span class="s2">&quot;CreateUserOutput&quot;</span><span class="p">,</span>
            <span class="s2">&quot;parameters&quot;</span><span class="o">:</span> <span class="p">{</span>
                <span class="s2">&quot;name&quot;</span><span class="o">:</span> <span class="p">{</span>
                    <span class="s2">&quot;location&quot;</span><span class="o">:</span> <span class="s2">&quot;json&quot;</span><span class="p">,</span>
                    <span class="s2">&quot;type&quot;</span><span class="o">:</span> <span class="s2">&quot;string&quot;</span>
                <span class="p">},</span>
                <span class="s2">&quot;age&quot;</span><span class="o">:</span> <span class="p">{</span>
                    <span class="s2">&quot;location&quot;</span><span class="o">:</span> <span class="s2">&quot;json&quot;</span><span class="p">,</span>
                    <span class="s2">&quot;type&quot;</span><span class="o">:</span> <span class="s2">&quot;integer&quot;</span>
                <span class="p">},</span>
                <span class="s2">&quot;tags&quot;</span><span class="o">:</span> <span class="p">{</span>
                    <span class="s2">&quot;type&quot;</span><span class="o">:</span> <span class="s2">&quot;array&quot;</span><span class="p">,</span>
                    <span class="s2">&quot;location&quot;</span><span class="o">:</span> <span class="s2">&quot;json&quot;</span><span class="p">,</span>
                    <span class="s2">&quot;items&quot;</span><span class="o">:</span> <span class="p">{</span>
                        <span class="s2">&quot;type&quot;</span><span class="o">:</span> <span class="s2">&quot;string&quot;</span>
                    <span class="p">}</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">},</span>
        <span class="s2">&quot;GetUser&quot;</span><span class="o">:</span> <span class="p">{</span>
            <span class="s2">&quot;httpMethod&quot;</span><span class="o">:</span> <span class="s2">&quot;GET&quot;</span><span class="p">,</span>
            <span class="s2">&quot;uri&quot;</span><span class="o">:</span> <span class="s2">&quot;/users/{id}&quot;</span><span class="p">,</span>
            <span class="s2">&quot;summary&quot;</span><span class="o">:</span> <span class="s2">&quot;Retrieves a single user&quot;</span><span class="p">,</span>
            <span class="s2">&quot;responseClass&quot;</span><span class="o">:</span> <span class="s2">&quot;GetUserOutput&quot;</span><span class="p">,</span>
            <span class="s2">&quot;parameters&quot;</span><span class="o">:</span> <span class="p">{</span>
                <span class="s2">&quot;id&quot;</span><span class="o">:</span> <span class="p">{</span>
                    <span class="s2">&quot;location&quot;</span><span class="o">:</span> <span class="s2">&quot;uri&quot;</span><span class="p">,</span>
                    <span class="s2">&quot;description&quot;</span><span class="o">:</span> <span class="s2">&quot;User to retrieve by ID&quot;</span><span class="p">,</span>
                    <span class="s2">&quot;required&quot;</span><span class="o">:</span> <span class="s2">&quot;true&quot;</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">},</span>
        <span class="s2">&quot;DeleteUser&quot;</span><span class="o">:</span> <span class="p">{</span>
            <span class="s2">&quot;httpMethod&quot;</span><span class="o">:</span> <span class="s2">&quot;DELETE&quot;</span><span class="p">,</span>
            <span class="s2">&quot;uri&quot;</span><span class="o">:</span> <span class="s2">&quot;/users/{id}&quot;</span><span class="p">,</span>
            <span class="s2">&quot;summary&quot;</span><span class="o">:</span> <span class="s2">&quot;Deletes a user&quot;</span><span class="p">,</span>
            <span class="s2">&quot;responseClass&quot;</span><span class="o">:</span> <span class="s2">&quot;DeleteUserOutput&quot;</span><span class="p">,</span>
            <span class="s2">&quot;parameters&quot;</span><span class="o">:</span> <span class="p">{</span>
                <span class="s2">&quot;id&quot;</span><span class="o">:</span> <span class="p">{</span>
                    <span class="s2">&quot;location&quot;</span><span class="o">:</span> <span class="s2">&quot;uri&quot;</span><span class="p">,</span>
                    <span class="s2">&quot;description&quot;</span><span class="o">:</span> <span class="s2">&quot;User to delete by ID&quot;</span><span class="p">,</span>
                    <span class="s2">&quot;required&quot;</span><span class="o">:</span> <span class="s2">&quot;true&quot;</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">},</span>
    <span class="s2">&quot;models&quot;</span><span class="o">:</span> <span class="p">{</span>
        <span class="s2">&quot;User&quot;</span><span class="o">:</span> <span class="p">{</span>
            <span class="s2">&quot;type&quot;</span><span class="o">:</span> <span class="s2">&quot;object&quot;</span><span class="p">,</span>
            <span class="s2">&quot;properties&quot;</span><span class="o">:</span> <span class="p">{</span>
                <span class="s2">&quot;name&quot;</span><span class="o">:</span> <span class="p">{</span>
                    <span class="s2">&quot;location&quot;</span><span class="o">:</span> <span class="s2">&quot;json&quot;</span><span class="p">,</span>
                    <span class="s2">&quot;type&quot;</span><span class="o">:</span> <span class="s2">&quot;string&quot;</span>
                <span class="p">},</span>
                <span class="s2">&quot;age&quot;</span><span class="o">:</span> <span class="p">{</span>
                    <span class="s2">&quot;location&quot;</span><span class="o">:</span> <span class="s2">&quot;json&quot;</span><span class="p">,</span>
                    <span class="s2">&quot;type&quot;</span><span class="o">:</span> <span class="s2">&quot;integer&quot;</span>
                <span class="p">},</span>
                <span class="s2">&quot;tags&quot;</span><span class="o">:</span> <span class="p">{</span>
                    <span class="s2">&quot;type&quot;</span><span class="o">:</span> <span class="s2">&quot;array&quot;</span><span class="p">,</span>
                    <span class="s2">&quot;location&quot;</span><span class="o">:</span> <span class="s2">&quot;json&quot;</span><span class="p">,</span>
                    <span class="s2">&quot;items&quot;</span><span class="o">:</span> <span class="p">{</span>
                        <span class="s2">&quot;type&quot;</span><span class="o">:</span> <span class="s2">&quot;string&quot;</span>
                    <span class="p">}</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">},</span>
        <span class="s2">&quot;GetUsersOutput&quot;</span><span class="o">:</span> <span class="p">{</span>
            <span class="s2">&quot;type&quot;</span><span class="o">:</span> <span class="s2">&quot;array&quot;</span><span class="p">,</span>
            <span class="s2">&quot;items&quot;</span><span class="o">:</span> <span class="p">{</span>
                <span class="s2">&quot;$ref&quot;</span><span class="o">:</span> <span class="s2">&quot;User&quot;</span>
            <span class="p">}</span>
        <span class="p">},</span>
        <span class="s2">&quot;CreateUserOutput&quot;</span><span class="o">:</span> <span class="p">{</span>
            <span class="s2">&quot;type&quot;</span><span class="o">:</span> <span class="s2">&quot;object&quot;</span><span class="p">,</span>
            <span class="s2">&quot;properties&quot;</span><span class="o">:</span> <span class="p">{</span>
                <span class="s2">&quot;id&quot;</span><span class="o">:</span> <span class="p">{</span>
                    <span class="s2">&quot;location&quot;</span><span class="o">:</span> <span class="s2">&quot;json&quot;</span><span class="p">,</span>
                    <span class="s2">&quot;type&quot;</span><span class="o">:</span> <span class="s2">&quot;string&quot;</span>
                <span class="p">},</span>
                <span class="s2">&quot;location&quot;</span><span class="o">:</span> <span class="p">{</span>
                    <span class="s2">&quot;location&quot;</span><span class="o">:</span> <span class="s2">&quot;header&quot;</span><span class="p">,</span>
                    <span class="s2">&quot;sentAs&quot;</span><span class="o">:</span> <span class="s2">&quot;Location&quot;</span><span class="p">,</span>
                    <span class="s2">&quot;type&quot;</span><span class="o">:</span> <span class="s2">&quot;string&quot;</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">},</span>
        <span class="s2">&quot;GetUserOutput&quot;</span><span class="o">:</span> <span class="p">{</span>
            <span class="s2">&quot;$ref&quot;</span><span class="o">:</span> <span class="s2">&quot;User&quot;</span>
        <span class="p">},</span>
        <span class="s2">&quot;DeleteUserOutput&quot;</span><span class="o">:</span> <span class="p">{</span>
            <span class="s2">&quot;type&quot;</span><span class="o">:</span> <span class="s2">&quot;object&quot;</span><span class="p">,</span>
            <span class="s2">&quot;properties&quot;</span><span class="o">:</span> <span class="p">{</span>
                <span class="s2">&quot;status&quot;</span><span class="o">:</span> <span class="p">{</span>
                    <span class="s2">&quot;location&quot;</span><span class="o">:</span> <span class="s2">&quot;statusCode&quot;</span><span class="p">,</span>
                    <span class="s2">&quot;type&quot;</span><span class="o">:</span> <span class="s2">&quot;integer&quot;</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div>


<p>You can attach the above service description to any <code>Guzzle\Service\Client</code> object and the client will then be completely configured to use the service:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">require</span> <span class="nx">__DIR__</span> <span class="o">.</span> <span class="s1">&#39;/vendor/autoload.php&#39;</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Guzzle\Service\Description\ServiceDescription</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Guzzle\Http\Message\Response</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Guzzle\Service\Client</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Guzzle\Plugin\Mock\MockPlugin</span><span class="p">;</span>

<span class="nv">$client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Client</span><span class="p">();</span>
<span class="nv">$client</span><span class="o">-&gt;</span><span class="na">setDescription</span><span class="p">(</span><span class="nx">ServiceDescription</span><span class="o">::</span><span class="na">factory</span><span class="p">(</span><span class="s1">&#39;/path/to/service.json&#39;</span><span class="p">));</span>

<span class="c1">// Because this web service does not exist, let&#39;s mock the response</span>
<span class="nv">$mock</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MockPlugin</span><span class="p">();</span>
<span class="nv">$mock</span><span class="o">-&gt;</span><span class="na">addResponse</span><span class="p">(</span><span class="k">new</span> <span class="nx">Response</span><span class="p">(</span><span class="mi">200</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span>
    <span class="s1">&#39;Location&#39;</span>     <span class="o">=&gt;</span> <span class="s1">&#39;http://foo.com/user/123&#39;</span><span class="p">,</span>
    <span class="s1">&#39;Content-Type&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;application/json&#39;</span>
<span class="p">),</span> <span class="s1">&#39;{&quot;id&quot;: &quot;123&quot;}&#39;</span><span class="p">));</span>
<span class="nv">$client</span><span class="o">-&gt;</span><span class="na">addSubscriber</span><span class="p">(</span><span class="nv">$mock</span><span class="p">);</span>

<span class="c1">// Create the command and supply the input</span>
<span class="nv">$command</span> <span class="o">=</span> <span class="nv">$client</span><span class="o">-&gt;</span><span class="na">getCommand</span><span class="p">(</span><span class="s1">&#39;CreateUser&#39;</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span>
    <span class="s1">&#39;name&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;Michael&#39;</span><span class="p">,</span>
    <span class="s1">&#39;age&#39;</span>  <span class="o">=&gt;</span> <span class="mi">27</span><span class="p">,</span>
    <span class="s1">&#39;tags&#39;</span> <span class="o">=&gt;</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;PHP&#39;</span><span class="p">,</span> <span class="s1">&#39;HTTP&#39;</span><span class="p">)</span>
<span class="p">));</span>

<span class="c1">// Execute the command and retrieve the model object</span>
<span class="nv">$result</span> <span class="o">=</span> <span class="nv">$command</span><span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>

<span class="k">echo</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2"># Sent the following request: </span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">.</span> <span class="nv">$command</span><span class="o">-&gt;</span><span class="na">getRequest</span><span class="p">()</span> <span class="o">.</span> <span class="s2">&quot;</span><span class="se">\n\n</span><span class="s2">&quot;</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">&quot;# Command result: </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
<span class="nb">var_export</span><span class="p">(</span><span class="nv">$result</span><span class="o">-&gt;</span><span class="na">toArray</span><span class="p">());</span>
</code></pre></div>


<p>The above script will output the following:</p>

<pre><code># Sent the following request:
POST /users HTTP/1.1
Host: api.foo.com
User-Agent: Guzzle/3.0.0 curl/7.21.4 PHP/5.3.15
Content-Length: 49

{"name":"Michael","age":27,"tags":["PHP","HTTP"]}

# Command result:
array (
  'id' =&gt; '123',
  'location' =&gt; 'http://foo.com/user/123',
)
</code></pre>

<p>There are so many features in service descriptions that it&rsquo;s a daunting task to attempt to <a href="http://guzzlephp.org/guide/service/service_descriptions.html">completely document them</a>. I definitely owe you much more documentation around these features.</p>

<h2>Broken into components</h2>

<p>In response to feedback from various developers and <a href="http://drupal.org/node/1447736">interested third-parties</a>, I&rsquo;ve reorganized Guzzle&rsquo;s namespaces into a more modular and shallow structure.
This allows consumers of Guzzle to require only the specific parts of Guzzle needed by their project. Guzzle is already fairly large for an HTTP client, and I plan on adding more features to
make it more awesome-r&hellip; It makes a lot of sense to eliminate the worry of &ldquo;does adding this feature make the library too big for project X&rdquo;? Project X can now configure its requirements to
be as granular as needed. Guzzle 3.0 now provides the following components hosted on <a href="https://packagist.org/packages/guzzle/">Packagist</a>, with PEAR subpackages soon to follow
(thanks, <a href="https://twitter.com/claylo">Clay Loveless</a>!):</p>

<ul>
<li>guzzle/guzzle: Guzzle is a PHP HTTP client library and framework for building RESTful web service clients</li>
<li>guzzle/batch: Guzzle batch component for batching requests, commands, or custom transfers</li>
<li>guzzle/cache: Guzzle cache adapter component</li>
<li>guzzle/common: Common libraries used by Guzzle</li>
<li>guzzle/<a href="http:">http:</a> HTTP libraries used by Guzzle</li>
<li>guzzle/inflection: Guzzle inflection component</li>
<li>guzzle/iterator: Provides helpful iterators and iterator decorators</li>
<li>guzzle/log: Guzzle log adapter component</li>
<li>guzzle/parser: Interchangeable parsers used by Guzzle</li>
<li>guzzle/plugin: Guzzle plugin component containing all Guzzle HTTP plugins (replaces the following, more granular plugins)

<ul>
<li>guzzle/plugin-async: Guzzle async request plugin</li>
<li>guzzle/plugin-backoff: Guzzle backoff retry plugins</li>
<li>guzzle/plugin-cache: Guzzle HTTP cache plugin</li>
<li>guzzle/plugin-cookie: Guzzle cookie plugin</li>
<li>guzzle/plugin-curlauth: Guzzle cURL authorization plugin</li>
<li>guzzle/plugin-history: Guzzle history plugin</li>
<li>guzzle/plugin-log: Guzzle log plugin for over the wire logging</li>
<li>guzzle/plugin-md5: Guzzle MD5 plugins</li>
<li>guzzle/plugin-mock: Guzzle Mock plugin</li>
<li>guzzle/plugin-oauth: Guzzle OAuth plugin</li>
</ul>
</li>
<li>guzzle/service: Guzzle service component for abstracting RESTful web services</li>
<li>guzzle/stream: Guzzle stream wrapper component</li>
</ul>


<h2>A better HTTP client</h2>

<p>A number of improvements were made in Guzzle 3 that makes Guzzle a better HTTP client:</p>

<ul>
<li>No longer sending an <code>Accept</code> or <code>Accept-Encoding</code> header by default</li>
<li>Only sending an <code>Expect: 100-Continue</code> header when the payload of a request is greater than 1 MB</li>
<li>Guzzle now ships with and uses <a href="http://curl.haxx.se/docs/caextract.html">cURL&rsquo;s CA certs</a> extracted from mozilla.org</li>
<li><code>Guzzle\Http\Client::setSslVerification()</code> now makes it easier to fine-tune the SSL behavior of a client</li>
</ul>


<h2>Better plugins</h2>

<p>Plugins are now generally more awesome because the directory structure is more modular, plugins have their own Packagist packages, and we no longer need to worry about the overall
size of the library. The plugins that ship with Guzzle itself will still be fairly selective, but the plugins themselves are now free to be as robust as needed. Three plugins
specifically got a lot of love in the 3.0 release:</p>

<ul>
<li>CachePlugin</li>
<li>BackoffPlugin</li>
<li>LogPlugin</li>
</ul>


<h3>CachePlugin</h3>

<p>The <a href="http://guzzlephp.org/guide/plugins.html#cache-plugin">CachePlugin</a> has been mostly rewritten to be much more flexible. The default implementation of the plugin is basically
the same, but allows you to diverge from a basic RFC 2616 compliant cache and now allows you to cache any request that is acceptable according to a custom
<code>Guzzle\Plugin\Cache\CanCacheInterface</code> object. After you know whether or not an object should be cached, you can create a custom cache key by implementing a custom
<code>Guzzle\Plugin\Cache\CacheKeyProviderInterface</code>. Custom cache key providers are useful when caching web service requests that might include things like signatures and
constantly changing date-based headers.</p>

<h3>BackoffPlugin</h3>

<p>The <a href="http://guzzlephp.org/guide/plugins.html#backoff-plugin">BackoffPlugin</a> now replaces the old <code>Guzzle\Http\Plugin\ExponentialBackoffPlugin</code>. The BackoffPlugin can
be used to implement any sort of retry logic while still utilizing common retry strategies provided by Guzzle. If you still want to use a basic exponential backoff
plugin, just use the static factory method, <code>getExponentialBackoff()</code>:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">Guzzle\Http\Client</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Guzzle\Plugin\Backoff\BackoffPlugin</span><span class="p">;</span>

<span class="nv">$client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Client</span><span class="p">(</span><span class="s1">&#39;http://www.test.com/&#39;</span><span class="p">);</span>
<span class="c1">// Use a static factory method to get a backoff plugin using the exponential backoff strategy</span>
<span class="nv">$backoffPlugin</span> <span class="o">=</span> <span class="nx">BackoffPlugin</span><span class="o">::</span><span class="na">getExponentialBackoff</span><span class="p">();</span>

<span class="c1">// Add the backoff plugin to the client object</span>
<span class="nv">$client</span><span class="o">-&gt;</span><span class="na">addSubscriber</span><span class="p">(</span><span class="nv">$backoffPlugin</span><span class="p">);</span>
</code></pre></div>


<p>Actually, the <code>getExponentialBackoff()</code> method is a good demonstration of how to create a custom retry strategy. Here&rsquo;s a modified version that makes for a good example:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">return</span> <span class="k">new</span> <span class="nx">BackoffPlugin</span><span class="p">(</span><span class="k">new</span> <span class="nx">HttpBackoffStrategy</span><span class="p">(</span><span class="nv">$httpCodes</span><span class="p">,</span>
    <span class="k">new</span> <span class="nx">TruncatedBackoffStrategy</span><span class="p">(</span><span class="nv">$maxRetries</span><span class="p">,</span>
        <span class="k">new</span> <span class="nx">CurlBackoffStrategy</span><span class="p">(</span><span class="nv">$curlCodes</span><span class="p">,</span>
            <span class="k">new</span> <span class="nx">ExponentialBackoffStrategy</span><span class="p">()</span>
        <span class="p">)</span>
    <span class="p">)</span>
<span class="p">));</span>
</code></pre></div>


<h3>LogPlugin</h3>

<p>The LogPlugin was simplified a bit and now relies on a <code>Guzzle\Log\MessageFormatter</code> to format log messages. The MessageFormatter object uses a variable substitution template that allows for
ver customized log messages. You can find a complete list of variables in the <a href="http://guzzlephp.org/guide/plugins.html#log-plugin">LogPlugin&rsquo;s documentation</a>.</p>

<p>Use the <code>getDebugPlugin()</code> static factory method of the LogPlugin if you want to attach a plugin to a client that sends wire logs to STDERR. This plugin uses the following template to
write the HTTP request, response, and any cURL errors to STDERR:</p>

<pre><code># Request:
{request}

# Response:
{response}

# Errors: {curl_code} {curl_error}
</code></pre>

<h2>Migrating from Guzzle 2.0</h2>

<p>With Guzzle 3.0 comes a number of breaking changes. I plan on releasing a fairly in-depth guide that will describe the process of migrating from Guzzle 2.0 to 3.0. In the meantime, the following
bash script should help get you started. Run this script on your project&rsquo;s src/ directory to rename old class paths to the new modular structure (this is probably missing some easy ones &mdash;
let me know in the comments!):</p>

<div class="highlight"><pre><code class="bash"><span class="c">#!/bin/bash</span>
find ./ -type f -exec sed -i <span class="s1">&#39;&#39;</span> <span class="s1">&#39;s/Guzzle\\Common\\Cache/Guzzle\\Cache/g&#39;</span> <span class="o">{}</span> <span class="se">\;</span>
find ./ -type f -exec sed -i <span class="s1">&#39;&#39;</span> <span class="s1">&#39;s/Guzzle.Common.Cache/Guzzle.Cache/g&#39;</span> <span class="o">{}</span> <span class="se">\;</span>
find ./ -type f -exec sed -i <span class="s1">&#39;&#39;</span> <span class="s1">&#39;s/Guzzle\\Common\\Log/Guzzle\\Log/g&#39;</span> <span class="o">{}</span> <span class="se">\;</span>
find ./ -type f -exec sed -i <span class="s1">&#39;&#39;</span> <span class="s1">&#39;s/Guzzle\\Common\\Inflection/Guzzle\\Inflection/g&#39;</span> <span class="o">{}</span> <span class="se">\;</span>
find ./ -type f -exec sed -i <span class="s1">&#39;&#39;</span> <span class="s1">&#39;s/Guzzle\\Common\\Validation/Guzzle\\Validation/g&#39;</span> <span class="o">{}</span> <span class="se">\;</span>
find ./ -type f -exec sed -i <span class="s1">&#39;&#39;</span> <span class="s1">&#39;s/Guzzle\\Common\\Batch/Guzzle\\Batch/g&#39;</span> <span class="o">{}</span> <span class="se">\;</span>
find ./ -type f -exec sed -i <span class="s1">&#39;&#39;</span> <span class="s1">&#39;s/Guzzle\\Common\\Exception\\BatchTransferException/Guzzle\\Batch\\Exception\\BatchTransferException/g&#39;</span> <span class="o">{}</span> <span class="se">\;</span>
find ./ -type f -exec sed -i <span class="s1">&#39;&#39;</span> <span class="s1">&#39;s/Guzzle\\Http\\Plugin\\AsyncPlugin/Guzzle\\Plugin\\Async\\AsyncPlugin/g&#39;</span> <span class="o">{}</span> <span class="se">\;</span>
find ./ -type f -exec sed -i <span class="s1">&#39;&#39;</span> <span class="s1">&#39;s/Guzzle\\Http\\Plugin\\CachePlugin/Guzzle\\Plugin\\Cache\\CachePlugin/g&#39;</span> <span class="o">{}</span> <span class="se">\;</span>
find ./ -type f -exec sed -i <span class="s1">&#39;&#39;</span> <span class="s1">&#39;s/Guzzle\\Http\\Plugin\\CookiePlugin/Guzzle\\Plugin\\Cookie\\CookiePlugin/g&#39;</span> <span class="o">{}</span> <span class="se">\;</span>
find ./ -type f -exec sed -i <span class="s1">&#39;&#39;</span> <span class="s1">&#39;s/Guzzle\\Http\\Plugin\\CurlAuthPlugin/Guzzle\\Plugin\\CurlAuth\\CurlAuthPlugin/g&#39;</span> <span class="o">{}</span> <span class="se">\;</span>
find ./ -type f -exec sed -i <span class="s1">&#39;&#39;</span> <span class="s1">&#39;s/Guzzle\\Http\\Plugin\\ExponentialBackoffLogger/Guzzle\\Plugin\\Backoff\\BackoffLogger/g&#39;</span> <span class="o">{}</span> <span class="se">\;</span>
find ./ -type f -exec sed -i <span class="s1">&#39;&#39;</span> <span class="s1">&#39;s/Guzzle\\Http\\Plugin\\ExponentialBackoffPlugin/Guzzle\\Plugin\\Backoff\\BackoffPlugin/g&#39;</span> <span class="o">{}</span> <span class="se">\;</span>
find ./ -type f -exec sed -i <span class="s1">&#39;&#39;</span> <span class="s1">&#39;s/Guzzle\\Http\\Plugin\\HistoryPlugin/Guzzle\\Plugin\\History\\HistoryPlugin/g&#39;</span> <span class="o">{}</span> <span class="se">\;</span>
find ./ -type f -exec sed -i <span class="s1">&#39;&#39;</span> <span class="s1">&#39;s/Guzzle\\Http\\Plugin\\LogPlugin/Guzzle\\Plugin\\Log\\LogPlugin/g&#39;</span> <span class="o">{}</span> <span class="se">\;</span>
find ./ -type f -exec sed -i <span class="s1">&#39;&#39;</span> <span class="s1">&#39;s/Guzzle\\Http\\Plugin\\Md5ValidatorPlugin/Guzzle\\Plugin\\Md5\\Md5ValidatorPlugin/g&#39;</span> <span class="o">{}</span> <span class="se">\;</span>
find ./ -type f -exec sed -i <span class="s1">&#39;&#39;</span> <span class="s1">&#39;s/Guzzle\\Http\\Plugin\\MockPlugin/Guzzle\\Plugin\\Mock\\MockPlugin/g&#39;</span> <span class="o">{}</span> <span class="se">\;</span>
find ./ -type f -exec sed -i <span class="s1">&#39;&#39;</span> <span class="s1">&#39;s/Guzzle\\Http\\Plugin\\OauthPlugin/Guzzle\\Plugin\\Oauth\\OauthPlugin/g&#39;</span> <span class="o">{}</span> <span class="se">\;</span>
</code></pre></div>


<p>Apologies for the breaking changes, but they were necessary to ensure the future of the project. You should expect the API going forward to be much more stable.</p>

<p>That about wraps it up for 3.0! Let me know what you think in the comments.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Cron Expression Parsing in PHP]]></title>
    <link href="http://mtdowling.com/blog/2012/06/03/cron-expressions-in-php/"/>
    <updated>2012-06-03T20:06:00-07:00</updated>
    <id>http://mtdowling.com/blog/2012/06/03/cron-expressions-in-php</id>
    <content type="html"><![CDATA[<p>As a PHP developer, I&rsquo;ve often been faced with the task of ensuring something happens on a recurring schedule or determining the next date in time an event will occur.
At my previous job, we needed to run scheduled <a href="http://gearman.org/">Gearman</a> jobs on a recurring basis.  We chose to use cron as the serialization format of our
schedules, and implemented a database driven system for storing these schedules.  Storing the cron schedules for these recurring jobs in the database allowed us to
have an easy to maintain and durable data store for our recurring jobs, and it allowed us to deploy a very simple crontab to our job servers.  The crontab contained
a single cron job that ran a Gearman job every minute that checked if any of the recurring cron schedules matched the current time.  When a schedule matched the
current time, the job would run. This proved to be a very easy to maintain solution and allowed us to easily enable and disable recurring jobs if we were in a
maintenance window, a job was failing, or if a job was producing erroneous results.</p>

<p>When faced with the task of creating the cron expression parsing part of this system, I searched high and low for an existing implementation in PHP that implemented
the full feature set of a modern cron expression.  Based on the context of this article, you probably guessed that I didn&rsquo;t find one.  I posted the original code I
came up with to <a href="http://stackoverflow.com/questions/321494/calculate-when-a-cron-job-will-be-executed-then-next-time/3453872#3453872">StackOverflow</a> and eventually
<a href="https://github.com/mtdowling/cron-expression">open sourced the project</a>.</p>

<h2><a href="https://github.com/mtdowling/cron-expression">Cron-Expression, a cron expression library for PHP</a></h2>

<p>The PHP cron expression parser I wrote can parse a CRON expression, determine if it is due to run, calculate the next run date of the expression, and calculate the
previous run date of the expression. You can calculate dates far into the future or past by skipping <code>n</code> number of matching dates.</p>

<p>The parser can handle increments of ranges (e.g. */12, 2-59/3), intervals (e.g. 0-9), lists (e.g. 1,2,3), W to find the nearest weekday for a given day of
the month, L to find the last day of the month, L to find the last given weekday of a month, and hash (#) to find the nth weekday of a given month.</p>

<p>You can clone the cron-expression library from the <a href="https://github.com/mtdowling/cron-expression">github page</a>, install it with <a href="http://packagist.org/packages/mtdowling/cron-expression">composer</a>, or
simply <a href="https://raw.github.com/mtdowling/cron-expression/master/build/cron.phar">download the phar</a> file and include it in your scripts.</p>

<h2>Brief introduction to cron expressions</h2>

<p><a href="http://en.wikipedia.org/wiki/Cron">Cron</a> utilizes <em>cron expressions</em> for representing recurring schedules.  Cron expressions are made up of several fields, and each field represents a measurement of time.  The fields
in a cron expression are as follows: minute, hour, day of month, month, day of week, and an optional year.  Here&rsquo;s a an example cron expression that runs every minute, and below the
expression are the positional fields.</p>

<pre><code>*    *    *    *    *    *
-    -    -    -    -    -
|    |    |    |    |    |
|    |    |    |    |    + year [optional]
|    |    |    |    +----- day of week (0 - 7) (Sunday=0 or 7)
|    |    |    +---------- month (1 - 12)
|    |    +--------------- day of month (1 - 31)
|    +-------------------- hour (0 - 23)
+------------------------- min (0 - 59)
</code></pre>

<p>There are several special characters that modify the schedule of a cron expression, and some modifiers behave differently in different fields.  You can find a list of all of the available special
characters on <a href="http://en.wikipedia.org/wiki/Cron#Special_characters">cron&rsquo;s Wikipedia page</a>.</p>

<h2>Cron expression use cases</h2>

<p>Let&rsquo;s say that you&rsquo;re building a special promotion system into your e-commerce website.  You want a special promotion to occur on a schedule.  For the sake of this example, let&rsquo;s say you want the
promotion to occur every second Friday of every other month.  This cron expression can be represented using <code>0 0 0 ? 1/2 FRI#2 *</code>.</p>

<h3>Calculate the next run date of a cron expression</h3>

<p>So now that we&rsquo;ve determined the schedule of our promotion, let&rsquo;s write a snippet of code to check and see if the promotion should be in effect for the current date.  This example assumes
that you are using a phar file to include the library.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">require</span> <span class="s1">&#39;cron.phar&#39;</span><span class="p">;</span>

<span class="nv">$cron</span> <span class="o">=</span> <span class="nx">Cron\CronExpression</span><span class="o">::</span><span class="na">factory</span><span class="p">(</span><span class="s1">&#39;0 0 0 ? 1/2 FRI#2 *&#39;</span><span class="p">);</span>

<span class="k">if</span> <span class="p">(</span><span class="nv">$cron</span><span class="o">-&gt;</span><span class="na">isDue</span><span class="p">())</span> <span class="p">{</span>
    <span class="c1">// The promotion should be enabled!</span>
<span class="p">}</span>
</code></pre></div>


<p>Awesome! Now we know when the promotion should be enabled.  But now our buyers are complaining that they have no idea when the promotion will run next.  They suggest that you build an admin
page that will show them the next 5 dates that the promotion will run.</p>

<h3>Calculate the next X run dates of a cron expression</h3>

<p>You can calculate the next run date of a cron expression using the cron-expression library using the <code>getNextRunDate()</code> method:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">require</span> <span class="s1">&#39;cron.phar&#39;</span><span class="p">;</span>

<span class="nv">$cron</span> <span class="o">=</span> <span class="nx">Cron\CronExpression</span><span class="o">::</span><span class="na">factory</span><span class="p">(</span><span class="s1">&#39;0 0 0 ? 1/2 FRI#2 *&#39;</span><span class="p">);</span>

<span class="c1">// The getNextRunDate() method returns a \DateTime object</span>
<span class="k">echo</span> <span class="nv">$cron</span><span class="o">-&gt;</span><span class="na">getNextRunDate</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">format</span><span class="p">(</span><span class="s1">&#39;Y-m-d H:i:s&#39;</span><span class="p">);</span>
</code></pre></div>


<p>This will show the buyers the next date that the promotion will be enabled.  But our buyers want to be able to plan a little in advance, so they need to know the next 5 dates that the promotion
will run.  You can get multiple next run dates using the <code>getMultipleRunDates()</code> method.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">require</span> <span class="s1">&#39;cron.phar&#39;</span><span class="p">;</span>

<span class="nv">$cron</span> <span class="o">=</span> <span class="nx">Cron\CronExpression</span><span class="o">::</span><span class="na">factory</span><span class="p">(</span><span class="s1">&#39;0 0 0 ? 1/2 FRI#2 *&#39;</span><span class="p">);</span>

<span class="k">foreach</span> <span class="p">(</span><span class="nv">$cron</span><span class="o">-&gt;</span><span class="na">getMultipleRunDates</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span> <span class="k">as</span> <span class="nv">$date</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="nv">$date</span><span class="o">-&gt;</span><span class="na">format</span><span class="p">(</span><span class="s1">&#39;Y-m-d H:i:s&#39;</span><span class="p">)</span> <span class="o">.</span> <span class="nx">PHP_EOL</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>


<p>Great! Now we know if the promotion should run on the current date and the next 5 times the promotion will run.  But now our buyers are complaining that they need to know the previous dates that
the promotion ran so that they can figure out all the fancy number projections they do when determining the sell-through of a product.</p>

<h3>Calculate the last run date of a cron expression</h3>

<p>You can get the last run date of a cron expression using the <code>getPreviousRunDate()</code> method.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">require</span> <span class="s1">&#39;cron.phar&#39;</span><span class="p">;</span>

<span class="nv">$cron</span> <span class="o">=</span> <span class="nx">Cron\CronExpression</span><span class="o">::</span><span class="na">factory</span><span class="p">(</span><span class="s1">&#39;0 0 0 ? 1/2 FRI#2 *&#39;</span><span class="p">);</span>

<span class="c1">// Remember, most methods return a DateTime object</span>
<span class="k">echo</span> <span class="nv">$cron</span><span class="o">-&gt;</span><span class="na">getPreviousRunDate</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">format</span><span class="p">(</span><span class="s1">&#39;Y-m-d H:i:s&#39;</span><span class="p">);</span>
</code></pre></div>


<p>Awesome! Our buyers still need to know the last 5 times the promotion ran.</p>

<p>If you want to know the last 5 run dates, you can use the <code>getMultipleRunDates()</code> method and set the <code>$invert</code> argument to true:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">require</span> <span class="s1">&#39;cron.phar&#39;</span><span class="p">;</span>

<span class="nv">$cron</span> <span class="o">=</span> <span class="nx">Cron\CronExpression</span><span class="o">::</span><span class="na">factory</span><span class="p">(</span><span class="s1">&#39;0 0 0 ? 1/2 FRI#2 *&#39;</span><span class="p">);</span>

<span class="k">foreach</span> <span class="p">(</span><span class="nv">$cron</span><span class="o">-&gt;</span><span class="na">getMultipleRunDates</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="s1">&#39;now&#39;</span><span class="p">,</span> <span class="k">true</span><span class="p">)</span> <span class="k">as</span> <span class="nv">$date</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="nv">$date</span><span class="o">-&gt;</span><span class="na">format</span><span class="p">(</span><span class="s1">&#39;Y-m-d H:i:s&#39;</span><span class="p">)</span> <span class="o">.</span> <span class="nx">PHP_EOL</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>


<p>That will display a list of 5 previous run dates, each going further back in time.</p>

<p>Now our buyers are asking if the promotion ran or will run on a specific day.  Instead of having to field there emails every day and tell them whether or not the promotion
ran, you decide to create an admin page so that they can enter a date and the page will tell the buyer if the promotion ran that day.</p>

<h3>Check if the cron expression matches a specific date</h3>

<p>You can see if a cron expression matches a specific date by calling <code>isDue()</code> with a specific date.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">require</span> <span class="s1">&#39;cron.phar&#39;</span><span class="p">;</span>

<span class="nv">$cron</span> <span class="o">=</span> <span class="nx">Cron\CronExpression</span><span class="o">::</span><span class="na">factory</span><span class="p">(</span><span class="s1">&#39;0 0 0 ? 1/2 FRI#2 *&#39;</span><span class="p">);</span>

<span class="k">if</span> <span class="p">(</span><span class="nv">$cron</span><span class="o">-&gt;</span><span class="na">isDue</span><span class="p">(</span><span class="s1">&#39;January 5, 2012&#39;</span><span class="p">))</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="s1">&#39;The cron expression ran on this date :)&#39;</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="s1">&#39;The cron expression did not run on this date :(&#39;</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>


<h3>Celebrate!</h3>

<p>You&rsquo;ve now successfully implemented all of the scheduling needs of your promotion! You can determine whether or not the promotion should be running, buyers can see when the
promotion last ran, determine if the promotion will run on a specific date, and they can plan out their buying strategies based on when the promotion will run next.</p>

<h2>Conclusion</h2>

<p>As you can see, cron expressions are very useful for scheduling events.  With the <a href="https://raw.github.com/mtdowling/cron-expression">PHP Cron-Expression parser library</a>, PHP developers
now have access to the advanced scheduling capabilities of cron.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Chunked Transfer-Encoding in PHP with Guzzle]]></title>
    <link href="http://mtdowling.com/blog/2012/01/27/chunked-encoding-in-php-with-guzzle/"/>
    <updated>2012-01-27T00:00:00-08:00</updated>
    <id>http://mtdowling.com/blog/2012/01/27/chunked-encoding-in-php-with-guzzle</id>
    <content type="html"><![CDATA[<h2>The problem with Content-Length</h2>

<p>HTTP/1.0 requires a client to specify a Content-Length header before sending a request to a server.  This means that requests can not be sent with a dynamically created entity body until the entire length of the entity body is known.  A lot of HTTP clients that support HTTP/1.1 still require that the data sent over the wire is sent through a string or includes a Content-Length header.  Why is this important?  Streaming.</p>

<h2>The example</h2>

<p>Let&rsquo;s imagine that you are building a website that allows users to submit an image URL to use as the background on their profile page (this is a very simple example, but it&rsquo;s the first one I came up with).  At a high level, after a URL is submitted, the application will need to download the image from the URL, upload the image to the application&rsquo;s file server (whether it be FTP, S3, whatever), and then perform any required image processing.  You&rsquo;ll often see this scenario implemented like this:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="nv">$entireImage</span> <span class="o">=</span> <span class="nb">file_get_contents</span><span class="p">(</span><span class="nv">$url</span><span class="p">);</span>
<span class="nb">file_put_contents</span><span class="p">(</span><span class="nv">$fileServer</span><span class="p">,</span> <span class="nv">$entireImage</span><span class="p">);</span>
</code></pre></div>


<p>Success!  The above code sample will download the image and then upload the image to the file server.  However, there are a couple problems with this:
&ndash; You have to store the entire image in a string which consumes a great deal of memory.
&ndash; The entire image needs to be downloaded before it can be uploaded to the file server.</p>

<h2>Chunked Transfer-Encoding to the rescue!</h2>

<p><a href="http://en.wikipedia.org/wiki/Chunked_transfer_encoding" title="Wikipedia">Chunked transfer encoding</a> allows a client or server to begin transmitting a message before the Content-Length of the entity body is known.  At a high level, when using chunked transfer encoding, a client sends the content length of a small chunk of the entity body followed by the small chunk.  A server would then continue to read from the client request&rsquo;s entity body until a 0 length chunk is received.  You can find out more about how chunked transfer encoding works by reading <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1">RFC2616 section 3.6.1</a>.</p>

<p>So now that we know about chunked encoding, let&rsquo;s send a request.  Unfortunately, PHP doesn&rsquo;t have built in support to send a PUT or POST entity body using anything other than a string (<a href="http://www.php.net/manual/en/context.http.php#context.http.content" title="php.net">see docs</a>).  PHP added <a href="http://www.php.net/manual/en/context.http.php#context.http.protocol-version" title="php.net">support for chunked encoding</a> after the 5.3 release, but that doesn&rsquo;t help much if our data has to be sent from a string that holds the entire entity body in memory.</p>

<p>You can use sockets to send your HTTP request, but you&rsquo;ll need to account for all of the nuances of <a href="HTTP:">HTTP:</a> redirects, 100-Continue responses, parsing and reading responses, etc.  It&rsquo;s kind of fun to write though; I once wrote a simple HTTP/1.1 client using sockets and a <a href="http://en.wikipedia.org/wiki/Finite-state_machine" title="Wikipedia">finite state machine</a>.  But that takes quite a bit of time and testing, and you have an application to write!</p>

<p>Lucky for us, <a href="http://php.net/manual/en/book.curl.php" title="php.net curl manual">PHP has support  for curl</a>, and curl can do anything when it comes to HTTP.</p>

<h2>cURL to the rescue!</h2>

<p>Let&rsquo;s implement the above application using a PHP stream to download the image and curl to upload the data to the file server:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="c1">// Open a stream so that we stream the image download</span>
<span class="nv">$stream</span> <span class="o">=</span> <span class="nb">fopen</span><span class="p">(</span><span class="nv">$url</span><span class="p">,</span> <span class="s1">&#39;r&#39;</span><span class="p">);</span>

<span class="c1">// Create a curl handle to upload to the file server</span>
<span class="nv">$ch</span> <span class="o">=</span> <span class="nb">curl_init</span><span class="p">(</span><span class="nv">$fileServer</span><span class="p">);</span>
<span class="c1">// Send a PUT request</span>
<span class="nb">curl_setopt</span><span class="p">(</span><span class="nv">$ch</span><span class="p">,</span> <span class="nx">CURLOPT_CUSTOMREQUEST</span><span class="p">,</span> <span class="s1">&#39;PUT&#39;</span><span class="p">);</span>
<span class="c1">// Let curl know that we are sending an entity body</span>
<span class="nb">curl_setopt</span><span class="p">(</span><span class="nv">$ch</span><span class="p">,</span> <span class="nx">CURLOPT_UPLOAD</span><span class="p">,</span> <span class="k">true</span><span class="p">);</span>
<span class="c1">// Let curl know that we are using a chunked transfer encoding</span>
<span class="nb">curl_setopt</span><span class="p">(</span><span class="nv">$ch</span><span class="p">,</span> <span class="nx">CURLOPT_HTTPHEADER</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;Transfer-Encoding: chunked&#39;</span><span class="p">));</span>
<span class="c1">// Use a callback to provide curl with data to transmit from the stream</span>
<span class="nb">curl_setopt</span><span class="p">(</span><span class="nv">$ch</span><span class="p">,</span> <span class="nx">CURLOPT_READFUNCTION</span><span class="p">,</span> <span class="k">function</span><span class="p">(</span><span class="nv">$ch</span><span class="p">,</span> <span class="nv">$fd</span><span class="p">,</span> <span class="nv">$length</span><span class="p">)</span> <span class="k">use</span> <span class="p">(</span><span class="nv">$stream</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nb">fread</span><span class="p">(</span><span class="nv">$stream</span><span class="p">,</span> <span class="nv">$length</span><span class="p">)</span> <span class="o">?</span> <span class="s1">&#39;&#39;</span><span class="p">;</span>
<span class="p">});</span>

<span class="nb">curl_exec</span><span class="p">(</span><span class="nv">$ch</span><span class="p">);</span>
</code></pre></div>


<p>The above code will upload the image to the file server by reading a small amount of the image into a string, transferring the data to the server, then repeating until the entire image has been downloaded and uploaded to the file server.  This is accomplished using a PHP stream to download the image and a curl read callback to provide curl with a custom data source for the entity body of the PUT request.</p>

<p>That code is a bit verbose.  If you need to send HTTP requests in other parts of your application, then it might be a good idea to use a layer on top of curl to make it easier to get curl to do your bidding.</p>

<h2>Guzzle to the rescue!</h2>

<p><a href="http://guzzlephp.org">Guzzle</a> is an HTTP client for PHP that makes this exercise extremely easy.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="nv">$client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Guzzle\Http\Client</span><span class="p">(</span><span class="nv">$fileServer</span><span class="p">);</span>
<span class="nv">$client</span><span class="o">-&gt;</span><span class="na">put</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="k">null</span><span class="p">,</span> <span class="nb">fopen</span><span class="p">(</span><span class="nv">$url</span><span class="p">,</span> <span class="s1">&#39;r&#39;</span><span class="p">))</span><span class="o">-&gt;</span><span class="na">send</span><span class="p">();</span>
</code></pre></div>


<p>The above code will do exactly the same thing as our curl example, except it does it in just two lines of code.</p>

<h2>Guzzle always uses streams</h2>

<p>Straight from the <a href="http://guzzlephp.org/tour/http.html#entity-bodies">Guzzle documentation</a>:</p>

<blockquote><p>Entity body is the term used for the body of an HTTP message. The entity body of requests and responses is inherently a PHP stream in Guzzle. The body of the request can be either a string or a PHP stream which are converted into a Guzzle\Http\EntityBody object using its factory method. When using a string, the entity body is stored in a temp PHP stream. The use of temp PHP streams helps to protect your application from running out of memory when sending or receiving large entity bodies in your messages. When more than 2MB of data is stored in a temp stream, it automatically stores the data on disk rather than in memory.</p></blockquote>

<p>Guzzle will automatically detect if the <code>Content-Length</code> of a stream can be easily determined based on the stream wrapper.  If the stream is a local stream (file, php://temp, etc) and seekable, then Guzzle will always send a Content-Length with the request.  If a stream is not seekable or is a remote stream (FTP, HTTP, sockets), then Guzzle will not attempt to determine the Content-Length and will transfer the request using <code>Transfer-Encoding: chunked</code>.</p>

<h2>Content-Length is sometimes required</h2>

<p>If you are interacting with a web service that requires a Content-Length header, then you will need to determine the Content-Length of the remote resource and explicitly set the Content-Length header in your request.  Alternatively, you can download the remote resource to a temp stream, have Guzzle automatically determine the Content-Length, do any sort of required validation, then upload the image to the file server:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="nv">$client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Guzzle\Http\Client</span><span class="p">();</span>

<span class="c1">// Download the image to a PHP temp stream</span>
<span class="nv">$imageResponse</span> <span class="o">=</span> <span class="nv">$client</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="nv">$url</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">send</span><span class="p">();</span>
<span class="c1">// Be sure to seek to the beginning of the entity body</span>
<span class="nv">$imageResponse</span><span class="o">-&gt;</span><span class="na">getBody</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>

<span class="c1">// Upload the image to the file server using the previously</span>
<span class="c1">// downloaded image and the Content-Length of the image</span>
<span class="nv">$uploadRequest</span> <span class="o">=</span> <span class="nv">$client</span><span class="o">-&gt;</span><span class="na">put</span><span class="p">(</span><span class="nv">$fileServer</span><span class="p">,</span> <span class="k">null</span><span class="p">,</span> <span class="nv">$imageResponse</span><span class="o">-&gt;</span><span class="na">getBody</span><span class="p">());</span>
<span class="nv">$uploadResponse</span> <span class="o">=</span> <span class="nv">$uploadRequest</span><span class="o">-&gt;</span><span class="na">send</span><span class="p">();</span>
</code></pre></div>


<p>A better way of going about this might be to send a <code>HEAD</code> request to get the Content-Length of the remote resource, and then send a <code>PUT</code> request using a PHP stream and the known Content-Length:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="nv">$client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Guzzle\Http\Client</span><span class="p">();</span>

<span class="c1">// Get information about the image without downloading the entity body</span>
<span class="nv">$imageInfo</span> <span class="o">=</span> <span class="nv">$client</span><span class="o">-&gt;</span><span class="na">head</span><span class="p">(</span><span class="nv">$url</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">send</span><span class="p">();</span>
<span class="c1">// Create an entity body using a stream and the Content-Length header from the HEAD response</span>
<span class="nv">$body</span> <span class="o">=</span> <span class="nx">Guzzle\Http\EntityBody</span><span class="o">::</span><span class="na">factory</span><span class="p">(</span><span class="nb">fopen</span><span class="p">(</span><span class="nv">$url</span><span class="p">,</span> <span class="s1">&#39;r&#39;</span><span class="p">),</span> <span class="nv">$imageInfo</span><span class="o">-&gt;</span><span class="na">getContentLength</span><span class="p">());</span>

<span class="nv">$uploadRequest</span> <span class="o">=</span> <span class="nv">$client</span><span class="o">-&gt;</span><span class="na">put</span><span class="p">(</span><span class="nv">$fileServer</span><span class="p">,</span> <span class="k">null</span><span class="p">,</span> <span class="nv">$body</span><span class="p">);</span>
<span class="nv">$uploadResponse</span> <span class="o">=</span> <span class="nv">$uploadRequest</span><span class="o">-&gt;</span><span class="na">send</span><span class="p">();</span>
</code></pre></div>


<p>After retrieving the image information using a HEAD request, this example will perform the following steps:</p>

<ol>
<li>Open a connection to the file server.</li>
<li>Send the headers of the data you will be uploading using an HTTP PUT request.</li>
<li>Open a connection to the image URL using a PHP stream.</li>
<li>Initiate a GET request.</li>
<li>Curl will read small chunks from the image stream while simulataneously writing the chunks to the file server until the entire image stream has been read.</li>
</ol>


<h2>Start using Guzzle</h2>

<p>That wraps up our look at chunked transfer encoding.  You can find out more about Guzzle at <a href="http://guzzlephp.org">http://guzzlephp.org</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[What's new in Guzzle 2.1]]></title>
    <link href="http://mtdowling.com/blog/2012/01/24/guzzle-2-released/"/>
    <updated>2012-01-24T00:00:00-08:00</updated>
    <id>http://mtdowling.com/blog/2012/01/24/guzzle-2-released</id>
    <content type="html"><![CDATA[<p><img src="http://guzzlephp.org/_static/guzzle.png" alt="Guzzle" align="right" />
There were some major improvements added to <a href="http://guzzlephp.org">Guzzle</a> in the last week.  Guzzle is now more flexible, easy to use, and more powerful than ever.  Here&rsquo;s a list of the major features introduced in the 2.x series:</p>

<ul>
<li>Guzzle now uses the <a href="http://symfony.com/doc/current/book/internals.html#the-event-dispatcher">Symfony2 EventDispatcher</a> component</li>
<li>Guzzle now uses the <a href="https://github.com/symfony/Validator">Symfony2 Validator</a> component</li>
<li>Persistent connections are now shared between single requests and requests sent in parallel</li>
<li>Added an OAuth 1.0 plugin</li>
<li>Uses <a href="http://packagist.org/about-composer">Composer</a> for dependency management</li>
<li>Added a <a href="http://guzzlephp.org/tour/http.html#batch-queue-plugin">BatchQueuePlugin</a> for sending a large number of requests in parallel</li>
<li>It&rsquo;s now easier to build HTTP requests dynamically and still implement complex response parsing (extend <code>Guzzle\Service\Command\DynamicCommand</code> and extend the <code>process()</code> method)</li>
<li>Dynamically generated HTTP requests now support parameter filters</li>
<li><code>application/json</code> responses are automatically converted into arrays for command results</li>
<li>Service descriptions can now be written in JSON and supports including other files</li>
<li>Can use Zend Framework 1.0 or 2.0 cache adapters</li>
</ul>


<h2>What is Guzzle?</h2>

<p><a href="http://guzzlephp.org/">Guzzle</a> is a PHP HTTP client and framework for building RESTful web service clients.  Guzzle allows you to truly reap the benefits of the HTTP/1.1 spec by providing managed persistent connections and the ability to easily send requests in parallel.  In addition to taking the pain out of HTTP, Guzzle provides a lightweight framework for creating web service clients. With Guzzle&rsquo;s built in error handling, OAuth support, and dynamically generated HTTP requests, building your next web service client on top of Guzzle will save you a ton of time.</p>

<h2>Symfony2 EventDispatcher</h2>

<p>The event system is the foundation of Guzzle&rsquo;s flexibility.  Using the Symfony2 EventDispatcher ensures that a well-tested and broadly adopted event framework powers the most critical aspect of Guzzle.  Implementing the Symfony2 EventDispatcher helps to make the intent of event subscribers more explicit; instead of a single callback receiving all events dispatched from a subject, callbacks are registered individually for each event they subscribe to.</p>

<h3>Listening to events</h3>

<p>All classes in Guzzle that emit events implement the <code>Guzzle\Common\HasDispatcherInterface</code>.  Any object that implements this interface has a <code>getEventDispatcher()</code> method to retrieve the EventDispatcher for that object.</p>

<p>In the following example, we are transparently retrying all 401 responses with an updated authorization token:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Guzzle\Common\Event</span><span class="p">;</span>

<span class="nv">$client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Guzzle\Http\Client</span><span class="p">(</span><span class="s1">&#39;http://www.example.com/api/v1&#39;</span><span class="p">);</span>

<span class="c1">// Add custom error handling to any request created by this client</span>
<span class="nv">$client</span><span class="o">-&gt;</span><span class="na">getEventDispatcher</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">addListener</span><span class="p">(</span><span class="s1">&#39;request.error&#39;</span><span class="p">,</span> <span class="k">function</span><span class="p">(</span><span class="nx">Event</span> <span class="nv">$event</span><span class="p">)</span> <span class="p">{</span>

    <span class="k">if</span> <span class="p">(</span><span class="nv">$event</span><span class="p">[</span><span class="s1">&#39;response&#39;</span><span class="p">]</span><span class="o">-&gt;</span><span class="na">getStatusCode</span><span class="p">()</span> <span class="o">==</span> <span class="mi">401</span><span class="p">)</span> <span class="p">{</span>

        <span class="nv">$newRequest</span> <span class="o">=</span> <span class="k">clone</span> <span class="nv">$event</span><span class="p">[</span><span class="s1">&#39;request&#39;</span><span class="p">];</span>
        <span class="nv">$newRequest</span><span class="o">-&gt;</span><span class="na">setHeader</span><span class="p">(</span><span class="s1">&#39;X-Auth-Header&#39;</span><span class="p">,</span> <span class="nx">MyApplication</span><span class="o">::</span><span class="na">getNewAuthToken</span><span class="p">());</span>
        <span class="nv">$newResponse</span> <span class="o">=</span> <span class="nv">$newRequest</span><span class="o">-&gt;</span><span class="na">send</span><span class="p">();</span>

        <span class="c1">// Set the response object of the request without firing more events</span>
        <span class="nv">$event</span><span class="p">[</span><span class="s1">&#39;response&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$newResponse</span><span class="p">;</span>

        <span class="c1">// You can also change the response and fire the normal chain of</span>
        <span class="c1">// events by calling:</span>
        <span class="c1">// $event[&#39;request&#39;]-&gt;setResponse($newResponse);</span>

        <span class="c1">// Stop other events from firing when you override 401 responses</span>
        <span class="nv">$event</span><span class="o">-&gt;</span><span class="na">stopPropagation</span><span class="p">();</span>
    <span class="p">}</span>
<span class="p">});</span>

<span class="nv">$response</span> <span class="o">=</span> <span class="nv">$client</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s1">&#39;restricted-resource.json&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">send</span><span class="p">();</span>
<span class="k">echo</span> <span class="nv">$response</span><span class="p">;</span>
</code></pre></div>


<h3>Building plugins</h3>

<p>Guzzle ships with quite a few plugins out of the box: <a href="http://guzzlephp.org/tour/http.html#over-the-wire-logging">Over the wire logging</a>, <a href="http://guzzlephp.org/tour/http.html#php-based-caching-forward-proxy">Caching forward  proxy</a>, <a href="http://guzzlephp.org/tour/http.html#truncated-exponential-backoff">Truncated exponential backoff</a>,  <a href="http://guzzlephp.org/tour/http.html#oauth-1-0-plugin">OAuth</a>, <a href="http://guzzlephp.org/tour/http.html#cookie-session-plugin">Cookies</a>, <a href="http://guzzlephp.org/tour/http.html#md5-hash-validator-plugin">MD5 hash validation</a>, <a href="http://guzzlephp.org/tour/http.html#mock-plugin">Mock response queue</a>, <a href="http://guzzlephp.org/tour/http.html#history-plugin">History</a>,  <a href="http://guzzlephp.org/tour/http.html#basic-auth-plugin">Basic authorization</a>, <a href="http://guzzlephp.org/tour/http.html#batch-queue-plugin">Batch queue</a></p>

<p>If you need to extend Guzzle to support your web service, you can create a Symfony2 event subscriber.  You&rsquo;ll need to subscribe to specific events in the request cycle to extend Guzzle&rsquo;s behavior.</p>

<p>Let&rsquo;s say you&rsquo;re building a client for a web service that requires a custom authorization header for every request.  This fictional authorization plugin could be implemented like so:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Guzzle\Foo</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Guzzle\Common\Event</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">FooAuthPlugin</span> <span class="k">implements</span> <span class="nx">Symfony\Component\EventDispatcher\EventSubscriberInterface</span>
<span class="p">{</span>
    <span class="k">private</span> <span class="nv">$secret</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">__construct</span><span class="p">(</span><span class="nv">$secret</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">secret</span> <span class="o">=</span> <span class="nv">$secret</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="nf">getSubscribedEvents</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;client.create_request&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;onRequestCreate&#39;</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">onRequestCreate</span><span class="p">(</span><span class="nx">Event</span> <span class="nv">$event</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$request</span> <span class="o">=</span> <span class="nv">$event</span><span class="p">[</span><span class="s1">&#39;request&#39;</span><span class="p">];</span>

        <span class="nv">$timestamp</span> <span class="o">=</span> <span class="nb">time</span><span class="p">();</span>
        <span class="nv">$signature</span> <span class="o">=</span> <span class="nb">hash_hmac</span><span class="p">(</span><span class="s1">&#39;sha1&#39;</span><span class="p">,</span> <span class="nv">$request</span><span class="o">-&gt;</span><span class="na">getMethod</span><span class="p">()</span> <span class="o">.</span> <span class="s1">&#39;&amp;&#39;</span>
            <span class="o">.</span> <span class="nb">rawurlencode</span><span class="p">(</span><span class="nv">$request</span><span class="o">-&gt;</span><span class="na">getResourceUri</span><span class="p">())</span> <span class="o">.</span> <span class="s1">&#39;&amp;&#39;</span> <span class="o">.</span> <span class="nv">$timestamp</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">secret</span><span class="p">);</span>

        <span class="nv">$request</span><span class="o">-&gt;</span><span class="na">setHeader</span><span class="p">(</span><span class="s1">&#39;Authorization&#39;</span><span class="p">,</span> <span class="s2">&quot;FOO signature=</span><span class="se">\&quot;</span><span class="si">{</span><span class="nv">$signature</span><span class="si">}</span><span class="se">\&quot;</span><span class="s2">, timestamp=</span><span class="se">\&quot;</span><span class="si">{</span><span class="nv">$timestamp</span><span class="si">}</span><span class="se">\&quot;</span><span class="s2">&quot;</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div>


<h2>Symfony2 Validator</h2>

<p>Validating user data is a problem that has been solved by many other developers.  Guzzle adopted the Symfony2 Validator component to leverage Symfony2&rsquo;s robust validation system.</p>

<p>Guzzle uses the Symfony2 validator component when executing web service commands.  Web service commands in Guzzle are basically collection of parameters that are turned into HTTP requests.  You can enforce that a parameter is of a certain type before sending an HTTP request by utilizing a <code>type</code> attribute.</p>

<p>After <a href="http://guzzlephp.org/tour/building_services.html#setting-up">generating a project skeleton</a> and <a href="http://guzzlephp.org/tour/building_services.html#create-a-client">creating a client</a>, you can start creating commands.  The following example shows how you might create a command to create a new user.</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Guzzle\Foo\Command</span><span class="p">;</span>

<span class="sd">/**</span>
<span class="sd"> * Create a new user for the Foo web service</span>
<span class="sd"> *</span>
<span class="sd"> * @guzzle email      type=&quot;regex:/^[a-zA-Z0-9]{3,10}$/&quot; required=&quot;true&quot; doc=&quot;User email address&quot;</span>
<span class="sd"> * @guzzle password   type=&quot;string&quot; required=&quot;true&quot; min_length=&quot;6&quot; doc=&quot;Password&quot;</span>
<span class="sd"> * @guzzle newsletter type=&quot;boolean&quot; default=&quot;true&quot; doc=&quot;Is the user subscribed to the newsletter?&quot;</span>
<span class="sd"> */</span>
<span class="k">class</span> <span class="nc">CreateUser</span> <span class="k">extends</span> <span class="nx">Guzzle\Service\Command\AbstractCommand</span>
<span class="p">{</span>
    <span class="k">protected</span> <span class="k">function</span> <span class="nf">build</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">request</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">client</span><span class="o">-&gt;</span><span class="na">post</span><span class="p">(</span><span class="s1">&#39;/users&#39;</span><span class="p">);</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">request</span><span class="o">-&gt;</span><span class="na">setHeader</span><span class="p">(</span><span class="s1">&#39;Accept&#39;</span><span class="p">,</span> <span class="s1">&#39;application/json&#39;</span><span class="p">);</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">request</span><span class="o">-&gt;</span><span class="na">setBody</span><span class="p">(</span><span class="nb">json_encode</span><span class="p">(</span><span class="k">array</span><span class="p">(</span>
            <span class="s1">&#39;username&#39;</span> <span class="o">=&gt;</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s1">&#39;username&#39;</span><span class="p">),</span>
            <span class="s1">&#39;password&#39;</span> <span class="o">=&gt;</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s1">&#39;password&#39;</span><span class="p">),</span>
            <span class="s1">&#39;newsletter&#39;</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="nx">bool</span><span class="p">)</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s1">&#39;newsletter&#39;</span><span class="p">)</span>
        <span class="p">)),</span> <span class="s1">&#39;application/json&#39;</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div>


<p>Guzzle uses <a href="http://guzzlephp.org/tour/building_services.html#docblock-annotations-for-commands">DocBlock annotations</a> to make creating commands easier.   A number of default <code>types</code> are registered with the <code>Guzzle\Service\Inspector</code> to ensure that values passed into a command validate with the associated Symfony2 validator constraints.  You can implement your own <code>Symfony\Component\Validator\Constraint</code> class to add custom validation to your web service client.</p>

<h2>Persistent connections</h2>

<p>Persistent HTTP connections are an extremely important aspect of the HTTP/1.1 protocol that is often overlooked by PHP HTTP clients. Persistent connections allows data to be transferred between a client and server without the need to reconnect each time a subsequent request is sent, providing a significant performance boost to applications that need to send many HTTP requests to the same host. Guzzle implicitly manages persistent connections for all requests.</p>

<p>All HTTP requests sent through Guzzle are sent using the same cURL multi handle. cURL will maintain a cache of persistent connections on a multi handle. As long as you do not override the default <code>Guzzle\Http\Curl\CurlMulti</code> object in your clients, you will benefit from application-wide persistent connections. More information about cURL’s internal design and persistent connection handling can be found at <a href="http://curl.haxx.se/dev/internals.html">http://curl.haxx.se/dev/internals.html</a>.</p>

<h2>OAuth plugin</h2>

<p>Guzzle now supports OAuth out of the box.  Quit worrying about <a href="http://oauth.net/core/1.0/#anchor19">signing OAuth requests</a> and start building your web service client with Guzzle!</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="nv">$client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Guzzle\Http\Client</span><span class="p">(</span><span class="s1">&#39;http://api.twitter.com/1&#39;</span><span class="p">);</span>
<span class="nv">$oauth</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Guzzle\Http\Plugin\OauthPlugin</span><span class="p">(</span><span class="k">array</span><span class="p">(</span>
    <span class="s1">&#39;consumer_key&#39;</span>    <span class="o">=&gt;</span> <span class="s1">&#39;my_key&#39;</span><span class="p">,</span>
    <span class="s1">&#39;consumer_secret&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;my_secret&#39;</span><span class="p">,</span>
    <span class="s1">&#39;token&#39;</span>           <span class="o">=&gt;</span> <span class="s1">&#39;my_token&#39;</span><span class="p">,</span>
    <span class="s1">&#39;token_secret&#39;</span>    <span class="o">=&gt;</span> <span class="s1">&#39;my_token_secret&#39;</span>
<span class="p">));</span>
<span class="nv">$client</span><span class="o">-&gt;</span><span class="na">getEventDispatcher</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">addSubscriber</span><span class="p">(</span><span class="nv">$oauth</span><span class="p">);</span>

<span class="nv">$response</span> <span class="o">=</span> <span class="nv">$client</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s1">&#39;statuses/public_timeline.json&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">send</span><span class="p">();</span>
<span class="nb">var_export</span><span class="p">(</span><span class="nb">json_decode</span><span class="p">((</span><span class="nx">string</span><span class="p">)</span> <span class="nv">$response</span><span class="o">-&gt;</span><span class="na">getBody</span><span class="p">()));</span>
</code></pre></div>


<h2>Composer for dependency management</h2>

<p>Guzzle has switched from git submodules to using <a href="http://packagist.org/about-composer">Composer</a> for dependency managment.  You can add Guzzle to your composer enabled project by adding the following to your composer.json file:</p>

<div class="highlight"><pre><code class="javascript"><span class="p">{</span>
    <span class="s2">&quot;require&quot;</span><span class="o">:</span> <span class="p">{</span>
        <span class="s2">&quot;guzzle/guzzle&quot;</span><span class="o">:</span> <span class="s2">&quot;*&quot;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div>


<p>You then just call <code>php composer.phar install</code>, and you&rsquo;re done!  You can learn more about installing Guzzle using Composer, PHAR, PEAR, or GIT by reading the <a href="http://guzzlephp.org/tour/installation.html">installation instructions</a>.</p>

<h2>Easier to dynamically generate HTTP requests</h2>

<p>You can leverage Guzzle&rsquo;s dynamically generated HTTP requests if the web service you are interacting with has a ton of very similar commands.  All you need to do is create a Guzzle <a href="http://guzzlephp.org/guide/service/creating_dynamic_commands.html">service description</a> that describes the different commands supported by the web service.</p>

<p>You can implement the previously created <code>CreateUser</code> command using a JSON service description:</p>

<div class="highlight"><pre><code class="javascript"><span class="p">{</span>
    <span class="s2">&quot;commands&quot;</span><span class="o">:</span> <span class="p">{</span>
        <span class="c1">// Define an abstract command and extend it for each command</span>
        <span class="s2">&quot;abstract&quot;</span><span class="o">:</span> <span class="p">{</span>
            <span class="c1">// You would need to create this default command that would convert</span>
            <span class="c1">// all of the JSON parameters into a JSON entity body for requests</span>
            <span class="s2">&quot;class&quot;</span><span class="o">:</span> <span class="s2">&quot;Guzzle\Foo\JsonFooCommand&quot;</span><span class="p">,</span>
            <span class="s2">&quot;params&quot;</span><span class="o">:</span> <span class="p">{</span>
                <span class="s2">&quot;headers&quot;</span><span class="o">:</span> <span class="p">{</span>
                    <span class="s2">&quot;Accept&quot;</span><span class="o">:</span> <span class="s2">&quot;application/json&quot;</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">},</span>
        <span class="s2">&quot;create_user&quot;</span><span class="o">:</span> <span class="p">{</span>
            <span class="c1">// Extend the abstract command defined above</span>
            <span class="s2">&quot;extends&quot;</span><span class="o">:</span> <span class="s2">&quot;abstract&quot;</span><span class="p">,</span>
            <span class="c1">// Use a path relative to the base URL of the client</span>
            <span class="s2">&quot;path&quot;</span><span class="o">:</span> <span class="s2">&quot;users&quot;</span><span class="p">,</span>
            <span class="s2">&quot;method&quot;</span><span class="o">:</span> <span class="s2">&quot;POST&quot;</span><span class="p">,</span>
            <span class="s2">&quot;params&quot;</span><span class="o">:</span> <span class="p">{</span>
                <span class="s2">&quot;username&quot;</span><span class="o">:</span> <span class="p">{</span>
                    <span class="s2">&quot;type&quot;</span><span class="o">:</span> <span class="s2">&quot;regex:/^[a-zA-Z0-9]{3,10}$/&quot;</span><span class="p">,</span>
                    <span class="s2">&quot;required&quot;</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
                    <span class="s2">&quot;filter&quot;</span><span class="o">:</span> <span class="s2">&quot;trim&quot;</span><span class="p">,</span>
                    <span class="s2">&quot;location&quot;</span><span class="o">:</span> <span class="s2">&quot;json&quot;</span>
                <span class="p">},</span>
                <span class="s2">&quot;password&quot;</span><span class="o">:</span> <span class="p">{</span>
                    <span class="s2">&quot;type&quot;</span><span class="o">:</span> <span class="s2">&quot;string&quot;</span><span class="p">,</span>
                    <span class="s2">&quot;required&quot;</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
                    <span class="s2">&quot;min_length&quot;</span><span class="o">:</span> <span class="mi">6</span><span class="p">,</span>
                    <span class="s2">&quot;location&quot;</span><span class="o">:</span> <span class="s2">&quot;json&quot;</span>
                <span class="p">},</span>
                <span class="s2">&quot;newsletter&quot;</span><span class="o">:</span> <span class="p">{</span>
                    <span class="s2">&quot;type&quot;</span><span class="o">:</span> <span class="s2">&quot;boolean&quot;</span><span class="p">,</span>
                    <span class="s2">&quot;default&quot;</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
                    <span class="s2">&quot;location&quot;</span><span class="o">:</span> <span class="s2">&quot;json&quot;</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div>


<p>The above JSON describes the commands that can be executed on the Foo web service.  This JSON is roughly equivalent to the concrete command class we created earlier.  I threw in a <code>filter</code> parameter that allows you to pass the input of the parameter through a series of functions that accepts a variable and returns the filtered variable.  In the above example, we are running anything entered into the <code>username</code> parameter through the <code>trim()</code> function.  You can specify multiple filters by separating them with a comma.</p>

<p>Assuming you saved the above JSON as foo.json, you can send validated HTTP requests to the web service by attaching a service description to your client:</p>

<div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Guzzle\Service\Client</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Guzzle\Service\Description\JsonDescriptionBuilder</span><span class="p">;</span>

<span class="nv">$description</span> <span class="o">=</span> <span class="nx">JsonDescriptionBuilder</span><span class="o">::</span><span class="na">build</span><span class="p">(</span><span class="s1">&#39;foo.json&#39;</span><span class="p">);</span>
<span class="nv">$client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Client</span><span class="p">(</span><span class="s1">&#39;http://foo.com/api/v1&#39;</span><span class="p">);</span>
<span class="nv">$client</span><span class="o">-&gt;</span><span class="na">setDescription</span><span class="p">(</span><span class="nv">$description</span><span class="p">);</span>

<span class="nv">$command</span> <span class="o">=</span> <span class="nv">$client</span><span class="o">-&gt;</span><span class="na">getCommand</span><span class="p">(</span><span class="s1">&#39;create_user&#39;</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span>
    <span class="s1">&#39;username&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;michael&#39;</span><span class="p">,</span>
    <span class="s1">&#39;password&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;foobar&#39;</span>
<span class="p">));</span>

<span class="nv">$jsonResult</span> <span class="o">=</span> <span class="nv">$client</span><span class="o">-&gt;</span><span class="na">execute</span><span class="p">(</span><span class="nv">$command</span><span class="p">);</span>
<span class="nv">$request</span> <span class="o">=</span> <span class="nv">$command</span><span class="o">-&gt;</span><span class="na">getRequest</span><span class="p">();</span>
<span class="nv">$response</span> <span class="o">=</span> <span class="nv">$command</span><span class="o">-&gt;</span><span class="na">getResponse</span><span class="p">();</span>
</code></pre></div>


<h2>Going forward</h2>

<p>The release of Guzzle 2.0 is a huge milestone for the project.  As the project continues to mature, we hope to make it even easier to build web service clients.  Have a suggestion on how we can make Guzzle better?  Submit an issue to <a href="https://github.com/guzzle/guzzle">Guzzle on github</a>.</p>
]]></content>
  </entry>
  
</feed>
