<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="text">Blog entries tagged programming :: mwop.net</title>
  <updated>2019-01-24T11:30:00-06:00</updated>
  <generator uri="https://getlaminas.org" version="2">Laminas_Feed_Writer</generator>
  <link rel="alternate" type="text/html" href="https://mwop.net/blog/tag/programming"/>
  <link rel="self" type="application/atom+xml" href="https://mwop.net/blog/tag/programming/atom.xml"/>
  <id>https://mwop.net/blog/tag/programming</id>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Registering Module-Specific Routes in Expressive]]></title>
    <published>2019-01-24T11:30:00-06:00</published>
    <updated>2019-01-24T11:30:00-06:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2019-01-24-expressive-routes.html"/>
    <id>https://mwop.net/blog/2019-01-24-expressive-routes.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>In <xhtml:a href="https://getexpressive.org">Expressive</xhtml:a>, we have
standardized on a file named <xhtml:code>config/routes.php</xhtml:code> to
contain all your route registrations. A typical file might look
something like this:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">declare</xhtml:span>(strict_types=<xhtml:span class="hljs-number">1</xhtml:span>);

<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Expressive</xhtml:span>\<xhtml:span class="hljs-title">Csrf</xhtml:span>\<xhtml:span class="hljs-title">CsrfMiddleware</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Expressive</xhtml:span>\<xhtml:span class="hljs-title">Session</xhtml:span>\<xhtml:span class="hljs-title">SessionMiddleware</xhtml:span>;

<xhtml:span class="hljs-keyword">return</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">(
    \Zend\Expressive\Application $app,
    \Zend\Expressive\MiddlewareFactory $factory,
    \Psr\Container\ContainerInterface $container
)</xhtml:span> : <xhtml:span class="hljs-title">void</xhtml:span> </xhtml:span>{
    $app-&gt;get(<xhtml:span class="hljs-string">'/'</xhtml:span>, App\HomePageHandler::class, <xhtml:span class="hljs-string">'home'</xhtml:span>);

    $app-&gt;get(<xhtml:span class="hljs-string">'/contact'</xhtml:span>, [
        SessionMiddleware::class,
        CsrfMiddleware::class,
        App\Contact\ContactPageHandler::class
    ], <xhtml:span class="hljs-string">'contact'</xhtml:span>);
    $app-&gt;post(<xhtml:span class="hljs-string">'/contact'</xhtml:span>, [
        SessionMiddleware::class,
        CsrfMiddleware::class,
        App\Contact\ProcessContactRequestHandler::class
    ]);
    $app-&gt;get(
        <xhtml:span class="hljs-string">'/contact/thank-you'</xhtml:span>,
        App\Contact\ThankYouHandler::class,
        <xhtml:span class="hljs-string">'contact.done'</xhtml:span>
    );

    $app-&gt;get(
        <xhtml:span class="hljs-string">'/blog[/]'</xhtml:span>,
        App\Blog\Handler\LandingPageHandler::class,
        <xhtml:span class="hljs-string">'blog'</xhtml:span>
    );
    $app-&gt;get(<xhtml:span class="hljs-string">'/blog/{id:[^/]+\.html'</xhtml:span>, [
        SessionMiddleware::class,
        CsrfMiddleware::class,
        App\Blog\Handler\BlogPostHandler::class,
    ], <xhtml:span class="hljs-string">'blog.post'</xhtml:span>);
    $app-&gt;post(<xhtml:span class="hljs-string">'/blog/comment/{id:[^/]+\.html'</xhtml:span>, [
        SessionMiddleware::class,
        CsrfMiddleware::class,
        App\Blog\Handler\ProcessBlogCommentHandler::class,
    ], <xhtml:span class="hljs-string">'blog.comment'</xhtml:span>);
}
</xhtml:code></xhtml:pre>
<xhtml:p>and so on.</xhtml:p>
<xhtml:p>These files can get <xhtml:em>really</xhtml:em> long, and organizing them
becomes imperative.</xhtml:p>
<xhtml:h2>Using Delegator Factories</xhtml:h2>
<xhtml:p>One way we have recommended to make these files simpler is to
use <xhtml:a href="https://docs.zendframework.com/zend-expressive/v3/features/container/delegator-factories/">
delegator factories</xhtml:a> registered with the
<xhtml:code>Zend\Expressive\Application</xhtml:code> class to add routes. That
looks something like this:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">namespace</xhtml:span> <xhtml:span class="hljs-title">App</xhtml:span>\<xhtml:span class="hljs-title">Blog</xhtml:span>;

<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Psr</xhtml:span>\<xhtml:span class="hljs-title">Container</xhtml:span>\<xhtml:span class="hljs-title">ContainerInterface</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Expressive</xhtml:span>\<xhtml:span class="hljs-title">Application</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Expressive</xhtml:span>\<xhtml:span class="hljs-title">Csrf</xhtml:span>\<xhtml:span class="hljs-title">CsrfMiddleware</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Expressive</xhtml:span>\<xhtml:span class="hljs-title">Session</xhtml:span>\<xhtml:span class="hljs-title">SessionMiddleware</xhtml:span>;

<xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">class</xhtml:span> <xhtml:span class="hljs-title">RoutesDelegator</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">__invoke</xhtml:span><xhtml:span class="hljs-params">(
        ContainerInterface $container,
        string $serviceName,
        callable $callback
    )</xhtml:span> : <xhtml:span class="hljs-title">Application</xhtml:span> </xhtml:span>{
        <xhtml:span class="hljs-comment">/** <xhtml:span class="hljs-doctag">@var</xhtml:span> Application $app */</xhtml:span>
        $app = $callback();

        $app-&gt;get(
            <xhtml:span class="hljs-string">'/blog[/]'</xhtml:span>,
            App\Blog\Handler\LandingPageHandler::class,
            <xhtml:span class="hljs-string">'blog'</xhtml:span>
        );
        $app-&gt;get(<xhtml:span class="hljs-string">'/blog/{id:[^/]+\.html'</xhtml:span>, [
            SessionMiddleware::class,
            CsrfMiddleware::class,
            Handler\BlogPostHandler::class,
        ], <xhtml:span class="hljs-string">'blog.post'</xhtml:span>);
        $app-&gt;post(<xhtml:span class="hljs-string">'/blog/comment/{id:[^/]+\.html'</xhtml:span>, [
            SessionMiddleware::class,
            CsrfMiddleware::class,
            Handler\ProcessBlogCommentHandler::class,
        ], <xhtml:span class="hljs-string">'blog.comment'</xhtml:span>);

        <xhtml:span class="hljs-keyword">return</xhtml:span> $app;
    }
}
</xhtml:code></xhtml:pre>
<xhtml:p>You would then register this as a delegator factory somewhere in
your configuration:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">App</xhtml:span>\<xhtml:span class="hljs-title">Blog</xhtml:span>\<xhtml:span class="hljs-title">RoutesDelegator</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Expressive</xhtml:span>\<xhtml:span class="hljs-title">Application</xhtml:span>;

<xhtml:span class="hljs-keyword">return</xhtml:span> [
    <xhtml:span class="hljs-string">'dependencies'</xhtml:span> =&gt; [
        <xhtml:span class="hljs-string">'delegators'</xhtml:span> =&gt; [
            Application::class =&gt; [
                RoutesDelegator::class,
            ],
        ],
    ],
];
</xhtml:code></xhtml:pre>
<xhtml:p>Delegator factories run after the service has been created for
the first time, but before it has been returned by the container.
They allow you to interact with the service before it's returned;
you can configure it futher, add listeners, use it to configure
other services, or even use them to replace the instance with an
alternative. In this example, we're opting to <xhtml:em>configure</xhtml:em>
the <xhtml:code>Application</xhtml:code> class further by registering routes
with it.</xhtml:p>
<xhtml:p><xhtml:a href="https://docs.zendframework.com/zend-expressive/v3/cookbook/autowiring-routes-and-pipelines/">
We've even written this approach up in our documentation.</xhtml:a></xhtml:p>
<xhtml:p>So far, so good. But it means discovering where routes are
registered becomes more difficult. You now have to look in each
of:</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:code>config/routes.php</xhtml:code></xhtml:li>
<xhtml:li>Each file in <xhtml:code>config/autoload/</xhtml:code>:
<xhtml:ul>
<xhtml:li>looking for delegators attached to the <xhtml:code>Application</xhtml:code>
class,</xhtml:li>
<xhtml:li>and then checking those to see if they register routes.</xhtml:li>
</xhtml:ul>
</xhtml:li>
<xhtml:li>In <xhtml:code>config/config.php</xhtml:code> to identify
<xhtml:code>ConfigProvider</xhtml:code> classes, and then:
<xhtml:ul>
<xhtml:li>looking for delegators attached to the <xhtml:code>Application</xhtml:code>
class,</xhtml:li>
<xhtml:li>and then checking those to see if they register routes.</xhtml:li>
</xhtml:ul>
</xhtml:li>
</xhtml:ul>
<xhtml:p>The larger your application gets, the more work this becomes.
Your <xhtml:code>config/routes.php</xhtml:code> becomes way more readable, but
it becomes far harder to find all your routes.</xhtml:p>
<xhtml:h2>One-off Functions</xhtml:h2>
<xhtml:p>In examining this problem for the upteenth time this week, I
stumbled upon a solution that is initially acceptable to me,
finally.</xhtml:p>
<xhtml:p>What I've done is as follows:</xhtml:p>
<xhtml:ul>
<xhtml:li>I've created a function in my <xhtml:code>ConfigProvider</xhtml:code> that
accepts the <xhtml:code>Application</xhtml:code> instance and any other
arguments I want to pass to it, and which registers routes with the
instance.</xhtml:li>
<xhtml:li>I call that function within my
<xhtml:code>config/routes.php</xhtml:code>.</xhtml:li>
</xhtml:ul>
<xhtml:p>Building on the example above, the <xhtml:code>ConfigProvider</xhtml:code>
for the <xhtml:code>App\Blog</xhtml:code> module now has the following
method:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">namespace</xhtml:span> <xhtml:span class="hljs-title">App</xhtml:span>\<xhtml:span class="hljs-title">Blog</xhtml:span>;

<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Expressive</xhtml:span>\<xhtml:span class="hljs-title">Application</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Expressive</xhtml:span>\<xhtml:span class="hljs-title">Csrf</xhtml:span>\<xhtml:span class="hljs-title">CsrfMiddleware</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Expressive</xhtml:span>\<xhtml:span class="hljs-title">Session</xhtml:span>\<xhtml:span class="hljs-title">SessionMiddleware</xhtml:span>;

<xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">class</xhtml:span> <xhtml:span class="hljs-title">ConfigProvider</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">__invoke</xhtml:span><xhtml:span class="hljs-params">()</xhtml:span> : <xhtml:span class="hljs-title">array</xhtml:span>
    </xhtml:span>{
        <xhtml:span class="hljs-comment">/* ... */</xhtml:span>
    }

    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">registerRoutes</xhtml:span><xhtml:span class="hljs-params">(
        Application $app,
        string $basePath = <xhtml:span class="hljs-string">'/blog'</xhtml:span>
    )</xhtml:span> : <xhtml:span class="hljs-title">void</xhtml:span> </xhtml:span>{
        $app-&gt;get(
            $basePath . <xhtml:span class="hljs-string">'[/]'</xhtml:span>,
            App\Blog\Handler\LandingPageHandler::class,
            <xhtml:span class="hljs-string">'blog'</xhtml:span>
        );
        $app-&gt;get($basePath . <xhtml:span class="hljs-string">'/{id:[^/]+\.html'</xhtml:span>, [
            SessionMiddleware::class,
            CsrfMiddleware::class,
            Handler\BlogPostHandler::class,
        ], <xhtml:span class="hljs-string">'blog.post'</xhtml:span>);
        $app-&gt;post($basePath . <xhtml:span class="hljs-string">'/comment/{id:[^/]+\.html'</xhtml:span>, [
            SessionMiddleware::class,
            CsrfMiddleware::class,
            Handler\ProcessBlogCommentHandler::class,
        ], <xhtml:span class="hljs-string">'blog.comment'</xhtml:span>);
    }
}
</xhtml:code></xhtml:pre>
<xhtml:p>Within my <xhtml:code>config/routes.php</xhtml:code>, I can create a
temporary instance and call the method:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">declare</xhtml:span>(strict_types=<xhtml:span class="hljs-number">1</xhtml:span>);

<xhtml:span class="hljs-keyword">return</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">(
    \Zend\Expressive\Application $app,
    \Zend\Expressive\MiddlewareFactory $factory,
    \Psr\Container\ContainerInterface $container
)</xhtml:span> : <xhtml:span class="hljs-title">void</xhtml:span> </xhtml:span>{
    (<xhtml:span class="hljs-keyword">new</xhtml:span> \App\Blog\ConfigProvider())-&gt;registerRoutes($app);
}
</xhtml:code></xhtml:pre>
<xhtml:p>This approach eliminates the problems of using delegator
factories:</xhtml:p>
<xhtml:ul>
<xhtml:li>There's a clear indication that a given class method registers
routes.</xhtml:li>
<xhtml:li>I can then look directly at that method to determine what they
are.</xhtml:li>
</xhtml:ul>
<xhtml:p>One thing I like about this approach is that it allows me to
keep the routes close to the code that handles them (i.e., within
each module), while still giving me control over their registration
at the application level.</xhtml:p>
<xhtml:p>What strategies have you tried?</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2019-01-24-expressive-routes.html">Registering
Module-Specific Routes in Expressive</xhtml:a> was originally published
<xhtml:time class="dt-published" datetime="2019-01-24T11:30:00-06:00">24
January 2019</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by <xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew Weier
O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Creating Exception types on-the-fly in modern PHP]]></title>
    <published>2018-12-05T16:26:00-06:00</published>
    <updated>2018-12-05T16:26:00-06:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2018-12-05-on-the-fly-exceptions.html"/>
    <id>https://mwop.net/blog/2018-12-05-on-the-fly-exceptions.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>We pioneered a pattern for exception handling for Zend Framework
back as we initially began development on version 2 around seven
years ago. The pattern looks like this:</xhtml:p>
<xhtml:ul>
<xhtml:li>We would create a marker <xhtml:code>ExceptionInterface</xhtml:code> for
each package.</xhtml:li>
<xhtml:li>We would extend <xhtml:a href="http://php.net/manual/en/spl.exceptions.php">SPL exceptions</xhtml:a>
and implement the package marker interface when doing so.</xhtml:li>
</xhtml:ul>
<xhtml:p>What this gave users was the ability to catch in three ways:</xhtml:p>
<xhtml:ul>
<xhtml:li>They could catch the most specific exception type by class
name.</xhtml:li>
<xhtml:li>They could catch all package-level exceptions using the marker
interface.</xhtml:li>
<xhtml:li>The could catch general exceptions using the associated SPL
type.</xhtml:li>
</xhtml:ul>
<xhtml:p>So, as an example:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">try</xhtml:span> {
    $do-&gt;something();
} <xhtml:span class="hljs-keyword">catch</xhtml:span> (MostSpecificException $e) {
} <xhtml:span class="hljs-keyword">catch</xhtml:span> (PackageLevelExceptionInterface $e) {
} <xhtml:span class="hljs-keyword">catch</xhtml:span> (\RuntimeException $e) {
}
</xhtml:code></xhtml:pre>
<xhtml:p>This kind of granularity is really nice to work with. So nice
that some standards produced by <xhtml:a href="https://www.php-fig.org/">PHP-FIG</xhtml:a> now ship them, such as
<xhtml:a href="https://www.php-fig.org/psr/psr-11/">PSR-11</xhtml:a>, which
ships a <xhtml:code>ContainerExceptionInterface</xhtml:code> and a
<xhtml:code>NotFoundExceptionInterface</xhtml:code>.</xhtml:p>
<xhtml:blockquote>
<xhtml:p>One thing we've started doing recently as we make packages
support only PHP 7 versions is to have the marker
<xhtml:code>ExceptionInterface</xhtml:code> extend the <xhtml:code>Throwable</xhtml:code>
interface; this ensures that implementations <xhtml:strong>must</xhtml:strong>
be able to be thrown!</xhtml:p>
</xhtml:blockquote>
<xhtml:p>So, what happens when you're writing a one-off implementation of
something that is expected to throw an exception matching one of
these interfaces?</xhtml:p>
<xhtml:p>Why, use an anonymous class, of course!</xhtml:p>
<xhtml:p>As an example, I was writing up some documentation that
illustrated a custom <xhtml:code>ContainerInterface</xhtml:code> implementation
today, and realized I needed to throw an exception at one point,
specifically a
<xhtml:code>Psr\Container\NotFoundExceptionInterface</xhtml:code>. I wrote up
the following snippet:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php">$message = sprintf(<xhtml:span class="hljs-comment">/* ... */</xhtml:span>);
<xhtml:span class="hljs-keyword">throw</xhtml:span> <xhtml:span class="hljs-keyword">new</xhtml:span> <xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">class</xhtml:span>($<xhtml:span class="hljs-title">message</xhtml:span>) <xhtml:span class="hljs-keyword">extends</xhtml:span> <xhtml:span class="hljs-title">RuntimeException</xhtml:span> <xhtml:span class="hljs-keyword">implements</xhtml:span>
    <xhtml:span class="hljs-title">NotFoundExceptionInterface</xhtml:span> </xhtml:span>{
};
</xhtml:code></xhtml:pre>
<xhtml:p>Done!</xhtml:p>
<xhtml:p>This works because <xhtml:code>RuntimeException</xhtml:code> takes a message
as the first constructor argument; by extending that class, I gain
that behavior. Since <xhtml:code>NotFoundExceptionInterface</xhtml:code> is a
marker interface, I did not need to add any additional behavior, so
this inline example works out-of-the-box.</xhtml:p>
<xhtml:p>What else are <xhtml:em>you</xhtml:em> using anonymous classes for?</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2018-12-05-on-the-fly-exceptions.html">Creating
Exception types on-the-fly in modern PHP</xhtml:a> was originally
published <xhtml:time class="dt-published" datetime="2018-12-05T16:26:00-06:00">5 December 2018</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by <xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew Weier
O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[The Future of Zend Framework]]></title>
    <published>2018-10-17T11:30:00-05:00</published>
    <updated>2018-10-18T13:20:00-05:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2018-10-17-long-live-zf.html"/>
    <id>https://mwop.net/blog/2018-10-17-long-live-zf.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>For the past thirteen years, I've been either consuming <xhtml:a href="https://framework.zend.com">Zend Framework</xhtml:a> or directly
contributing to it. Since 2009, I've operated as project lead, and,
since then, shepherded the version 2 and 3 releases, added <xhtml:a href="https://apigility.org">Apigility</xhtml:a> to the ZF ecosystem, and
helped bring middleware paradigms to the mainstream by assisting
with the creation of Stratigility and coordination of the <xhtml:a href="https://getexpressive.org">Expressive</xhtml:a> project. As I write
this, the various ZF packages have been downloaded over 300 MILLION
times, with 200 million of those being in the past 18 months!</xhtml:p>
<xhtml:p>In the last three years, I have performed this work under the
umbrella of <xhtml:a href="https://www.roguewave.com">Rogue Wave
Software</xhtml:a>, who acquired Zend in 2015. However, Rogue Wave has
recently made a strategic decision to focus its efforts on the Zend
Server product of the Zend portfolio. Consequently, this means both
myself and <xhtml:a href="https://www.zimuel.it">Enrico Zimuel</xhtml:a> will
be leaving the company and looking for new opportunities in the
not-too-distant future, along with <xhtml:a href="https://zsuraski.blogspot.com">Zeev Suraski</xhtml:a> and Dmitry
Stogov.</xhtml:p>
<xhtml:p>We all care deeply about the Zend Framework ecosystem, and we
are evaluating options to ensure its continuation and longevity.
These include either finding a new corporate sponsor for the
project, or forming a foundation. This is where YOU come in: if you
work for a company that would be interested in supporting such
efforts, I would love to hear from you. Feel free to reach out to
me at <xhtml:a href="mailto:matthew@weierophinney.net">matthew@weierophinney.net</xhtml:a>
with questions or queries.</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2018-10-17-long-live-zf.html">The Future of
Zend Framework</xhtml:a> was originally published <xhtml:time class="dt-published" datetime="2018-10-17T11:30:00-05:00">17 October
2018</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by
<xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew
Weier O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Async Expressive with Swoole]]></title>
    <published>2018-10-16T16:00:00-05:00</published>
    <updated>2018-10-17T08:30:00-05:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2018-10-16-swoole.html"/>
    <id>https://mwop.net/blog/2018-10-16-swoole.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>Have you used <xhtml:a href="https://nodejs.org/">Node.js</xhtml:a>?</xhtml:p>
<xhtml:p>For those of my readers unfamiliar with Node.js, it's a
server-side JavaScript framework that provides the ability to
create, among other things, network services. To do so, it provides
an event loop, which allows for such things as asynchronous
processing.</xhtml:p>
<xhtml:p>In the PHP ecosystem, a group of Chinese developers have been
creating an extension that provides many of the same capabilities
as Node.js. This extension, called <xhtml:a href="https://www.swoole.co.uk">Swoole</xhtml:a>, allows you to create web
servers with asynchronous capabilities. In many cases, the
asynchronous capabilities are handled via coroutines, allowing you
to write normal, synchronous code that still benefits from the
asynchronous nature of the system event loop, allowing your server
to continue responding to new requests as they come in!</xhtml:p>
<xhtml:p>We've been gradually adding and refining our <xhtml:a href="https://docs.zendframework.com/zend-expressive-swoole/">Swoole
support</xhtml:a> in <xhtml:a href="https://docs.zendframework.com/zend-expressive/">Expressive</xhtml:a>,
and recently issued a stable release that will work with any
<xhtml:a href="https://www.php-fig.org/psr/psr-15">PSR-15</xhtml:a> request
handler. In this post, I'll enumerate what I feel are the reasons
for considering Swoole when deploying your PHP middleware
application.</xhtml:p>
<xhtml:p>I feel there are three key advantages to Swoole, and, by
extension, any async PHP runtime:</xhtml:p>
<xhtml:ul>
<xhtml:li>Application-specific servers</xhtml:li>
<xhtml:li>Performance</xhtml:li>
<xhtml:li>Async processing</xhtml:li>
</xhtml:ul>
<xhtml:h2>Application-specific servers</xhtml:h2>
<xhtml:p>There are a few general architectures for applications:</xhtml:p>
<xhtml:ul>
<xhtml:li>A single web server sitting in front of many web
applications.</xhtml:li>
<xhtml:li>A single web server sitting in front of a single web
application.</xhtml:li>
<xhtml:li>A load balancer sitting in front of many servers. Some servers
might serve the same application, to provide redundancy. (Often,
today, these may even be identical docker containers.)</xhtml:li>
</xhtml:ul>
<xhtml:p><xhtml:img src="https://uploads.mwop.net/nginx-php-many.png" alt="nginx serving many PHP sites"/></xhtml:p>
<xhtml:p>The first scenario is common in internal networks and
development, and in many shared hosting scenarios. It's generally
considered less secure, however, as a vulnerability in one
application can potentially escalate to affect all applications
hosted on the server. Additionally, it means that any updates to
PHP versions must be tested on all applications, which often means
updates are few and far between — which is also problematic from a
security standpoint.</xhtml:p>
<xhtml:p>When you want to isolate the environment, you'll move to a
single web server, single PHP application model:</xhtml:p>
<xhtml:p><xhtml:img src="https://uploads.mwop.net/nginx-php-single.png" alt="nginx serving a single PHP site"/></xhtml:p>
<xhtml:p>And when you start scaling, this becomes a load balancer sitting
in front of many of these web server/PHP application pairs:</xhtml:p>
<xhtml:p><xhtml:img src="https://uploads.mwop.net/load-balancer-nginx-php.png" alt="A load balancer in front of many nginx+php sites"/></xhtml:p>
<xhtml:p>In each of these last two scenarios, there's one thing I want to
point out: your application consists of at least two distinct
services: the PHP processes, and a web server.</xhtml:p>
<xhtml:blockquote>
<xhtml:p>You may have other services as well, such as an RDBMS or
document database, cache, search, etc. But generally these are on
separate servers and scaled separately. As such, they're outside of
this discussion.</xhtml:p>
</xhtml:blockquote>
<xhtml:p>In these scenarios, this means each "server" is actually a
composite. And when you are adding redundancy to your architecture,
this adds significant complexity. It's one more process on each and
every node that can fail, and additional configuration you need
when deploying.</xhtml:p>
<xhtml:p>When we start thinking about microservices, this becomes more
problematic. Microservices should be quick and easy to deploy; one
service per container is both typical and desired.</xhtml:p>
<xhtml:p>What Swoole lets us do is remove one layer of that
complexity.</xhtml:p>
<xhtml:p><xhtml:img src="https://uploads.mwop.net/load-balancer-php.png" alt="A load balancer in front of php servers"/></xhtml:p>
<xhtml:p>We can have a service per container, and that container can be
built with only PHP. We start the Swoole HTTP server, and it's
ready to go. We then tell the reverse proxy or load balancer how to
route to it, and we're done.</xhtml:p>
<xhtml:p>This is useful in each of the scenarios, including the one web
server/mulitiple applications scenario, as we can have different
PHP runtimes per application. Our "web server" becomes a reverse
proxy instead.</xhtml:p>
<xhtml:p>Application-specific servers allow us to simplify our
deployment, and ship microservices quickly.</xhtml:p>
<xhtml:h2>Performance</xhtml:h2>
<xhtml:p>Remember when PHP 7 came out, and it was like doubling the
performance of your application?</xhtml:p>
<xhtml:p>What if you could do that again?</xhtml:p>
<xhtml:p>In our initial benchmarks of Expressive applications, we found
that they performed four times better under Swoole than under a
traditional nginx+php-fpm pair. More interesting: when benchmarking
with a high number of concurrent requests, we also found that
Swoole had fewer failed requests. This means you get both better
performance and better resilience!</xhtml:p>
<xhtml:p>And the hits keep rolling in: when we enabled Swoole's coroutine
support and benchmarked endpoints that made use of functionality
backed by that coroutine support, we observed up to a ten-fold
increase!</xhtml:p>
<xhtml:blockquote>
<xhtml:p>The coroutine support covers primarily network I/O operations.
As such, operations that hit cache servers, use PDO, or make web
requests benefit from it immediately, with no changes to your
code.</xhtml:p>
</xhtml:blockquote>
<xhtml:p>Swoole makes this possible in a couple of ways. First, because
you are firing up a server exactly once, you lose the price of
bootstrapping your application that you normally incur on each and
every request; your application is bootstrapped from the moment you
start accepting requests. Bootstrapping often accounts for the
greatest single amount of resource usage in your application.</xhtml:p>
<xhtml:p>Second, Swoole runs as an event loop, just like Node.js,
allowing it to defer processing of long-running requests in order
to respond to new, incoming requests. This leads into my last
point.</xhtml:p>
<xhtml:h2>Async processing</xhtml:h2>
<xhtml:p>Swoole's event loop provides async functionality to PHP
applications. While a number of userland libraries have popped up
over the past five years or so that provide async capabilities for
PHP, Swoole's is done as a native C extension, and works regardless
of the operating system.</xhtml:p>
<xhtml:p>When you have an event loop, you can defer processing, which
allows the server to respond to additional requests. Commonly,
deferment can be explicit:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">handle</xhtml:span><xhtml:span class="hljs-params">(ServerRequestInterface $request)</xhtml:span> : <xhtml:span class="hljs-title">ResponseInterface</xhtml:span>
</xhtml:span>{
    $ts = <xhtml:span class="hljs-keyword">new</xhtml:span> DateTimeImmutable();
    \Swoole\Event::defer(<xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;createCacheDeferment($ts));
    <xhtml:span class="hljs-keyword">return</xhtml:span> <xhtml:span class="hljs-keyword">new</xhtml:span> EmptyResponse(<xhtml:span class="hljs-number">202</xhtml:span>);
}

<xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">createCacheDeferment</xhtml:span><xhtml:span class="hljs-params">(DateTimeImmutable $ts)</xhtml:span> : <xhtml:span class="hljs-title">callable</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-keyword">return</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">()</xhtml:span> <xhtml:span class="hljs-title">use</xhtml:span> <xhtml:span class="hljs-params">($ts)</xhtml:span> </xhtml:span>{
        sleep(<xhtml:span class="hljs-number">5</xhtml:span>);
        $now = <xhtml:span class="hljs-keyword">new</xhtml:span> DateTimeImmutable();
        $item = <xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;cache-&gt;getItem(<xhtml:span class="hljs-string">'ts'</xhtml:span>);
        $item-&gt;set(sprintf(
            <xhtml:span class="hljs-string">"Started: %s\nEnded: %s"</xhtml:span>,
            $ts-&gt;format(<xhtml:span class="hljs-string">'r'</xhtml:span>),
            $now-&gt;format(<xhtml:span class="hljs-string">'r'</xhtml:span>)
        ));
        <xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;cache-&gt;save($item);
    };
}
</xhtml:code></xhtml:pre>
<xhtml:p>In this example, we calculate the content to return, defer
caching, and return a response immediately. This means your user
does not need to wait for you to finish caching content.</xhtml:p>
<xhtml:p>Logging is another use case. In the Expressive Swoole bindings,
we do access logging after we mark the response complete. This
ensures that logging does not impact response times.</xhtml:p>
<xhtml:p>Another use case is webhooks. Your application can accept a
payload immediately, but finish processing of it after sending the
response back to the client.</xhtml:p>
<xhtml:p>Swoole also provides async-enabled versions of common filesystem
operations, Mysql, Redis, and an HTTP client. In each of these, you
provide a callback indicating what should be done once the
operation is complete:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Swoole</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">Client</xhtml:span> <xhtml:span class="hljs-title">as</xhtml:span> <xhtml:span class="hljs-title">HttpClient</xhtml:span>;

$client = <xhtml:span class="hljs-keyword">new</xhtml:span> HttpClient(<xhtml:span class="hljs-string">'https://example.com'</xhtml:span>);
$client-&gt;setHeaders([
    <xhtml:span class="hljs-string">'Accept'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'application/json'</xhtml:span>,
    <xhtml:span class="hljs-string">'Authorization'</xhtml:span> =&gt; sprintf(<xhtml:span class="hljs-string">'Bearer %s'</xhtml:span>, $token),
]);

<xhtml:span class="hljs-comment">// Make the request, telling it what code to execute once</xhtml:span>
<xhtml:span class="hljs-comment">// it is complete:</xhtml:span>
$client-&gt;get(<xhtml:span class="hljs-string">'/api/resource'</xhtml:span>, <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">($response)</xhtml:span> </xhtml:span>{
    <xhtml:span class="hljs-comment">// process the response </xhtml:span>
});

<xhtml:span class="hljs-comment">// This code executes before the request completes:</xhtml:span>
$counter++;
</xhtml:code></xhtml:pre>
<xhtml:p>Code like the above has led to the term "callback hell" when you
have many such deferments that depend on each other. So, what do
you do if you want your code to be "non-blocking", but don't want
to write callbacks all the time? Well, recent versions of Swoole
allow you to enable coroutine support for most I/O operations. What
this means is that you can write your code just like you would in a
synchronous environment, but whenever code that triggers a
coroutine occurs, the server will advance the event loop, allowing
it to answer additional requests before the current one completes
its work, and then resume execution once it has.</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-comment">// This spawns a coroutine:</xhtml:span>
$statement = $pdo-&gt;query($sql);
</xhtml:code></xhtml:pre>
<xhtml:p>Async functionality may not directly improve the performance of
your application, but it <xhtml:strong>will</xhtml:strong> let your application
answer more requests, allowing you to handle greater volumes of
traffic!</xhtml:p>
<xhtml:h2>zend-expressive-swoole</xhtml:h2>
<xhtml:p>We released <xhtml:a href="https://docs.zendframework.com/zend-expressive-swoole/">zendframework/zend-expressive-swoole
1.0.0</xhtml:a> two weeks ago. This library acts as a
zend-httphandlerrunner <xhtml:code>RequestHandlerRunner</xhtml:code>
implementation, which means:</xhtml:p>
<xhtml:ul>
<xhtml:li>It can be used with any PSR-15 application.</xhtml:li>
<xhtml:li>It can be used with any PSR-7 implementation.</xhtml:li>
</xhtml:ul>
<xhtml:p>In other words, if you want to use Swoole with the upcoming Slim
4 or with <xhtml:a href="https://github.com/equip/dispatch">equip/dispatch</xhtml:a> or with
<xhtml:a href="https://github.com/northwoods/broker">northwoods/broker</xhtml:a> or any
of the myriad PSR-15 dispatch systems out there, you can.</xhtml:p>
<xhtml:p>The library provides some interesting features for users:</xhtml:p>
<xhtml:ul>
<xhtml:li>Serving of static resources, with HTTP client-side caching
headers.</xhtml:li>
<xhtml:li>Configurable logging.</xhtml:li>
<xhtml:li>Abiility to restart worker processes.</xhtml:li>
</xhtml:ul>
<xhtml:p>I've been running applications on versions of it for the past
two months, and have noted that it has been stable and reliable. I
definitely think it's worth giving it a spin!</xhtml:p>
<xhtml:h2>Fin</xhtml:h2>
<xhtml:p>I'm really excited about the possibilities of Swoole and other
async systems, as I think they afford us better performance, better
reliability, and the ability to defer functionality that doesn't
need to complete before we respond to clients. I'd love to hear
YOUR experiences, though, particularly in the form of blog posts!
Send me a link to a blog post via a comment, or by <xhtml:a href="https://twitter.com/mwop">tweeting at me</xhtml:a>, and I'll add it to
the <xhtml:a href="https://tinyletter.com/mwopzend">ZF
newsletter</xhtml:a>.</xhtml:p>
<xhtml:h3>Updates</xhtml:h3>
<xhtml:ul>
<xhtml:li>2018-10-17: Fixed typo in first sentence.</xhtml:li>
</xhtml:ul>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2018-10-16-swoole.html">Async Expressive
with Swoole</xhtml:a> was originally published <xhtml:time class="dt-published" datetime="2018-10-16T16:00:00-05:00">16 October 2018</xhtml:time> on
<xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by <xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew Weier
O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Notes on GraphQL]]></title>
    <published>2018-07-18T17:05:00-05:00</published>
    <updated>2018-09-19T08:10:00-05:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2018-07-18-graphql.html"/>
    <id>https://mwop.net/blog/2018-07-18-graphql.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>The last week has been my first foray into GraphQL, using the
<xhtml:a href="https://developer.github.com/v4/">GitHub GraphQL API</xhtml:a>
endpoints. I now have Opinions<xhtml:sup>TM</xhtml:sup>.</xhtml:p>
<xhtml:p>The promise is fantastic: query for everything you need, but
nothing more. Get it all in one go.</xhtml:p>
<xhtml:p>But the reality is somewhat... different.</xhtml:p>
<xhtml:p>What I found was that you end up with a lot of garbage data
structures that you then, on the client side, need to decipher and
massage, unpacking edges, nodes, and whatnot. I ended up having to
do almost a dozen <xhtml:code>array_column()</xhtml:code>,
<xhtml:code>array_map()</xhtml:code>, and <xhtml:code>array_reduce()</xhtml:code>
operations on the returned data to get a structure I can actually
use.</xhtml:p>
<xhtml:p>The final data I needed looked like this:</xhtml:p>
<xhtml:pre><xhtml:code class="language-javascript hljs javascript" data-lang="javascript">[
  {
    <xhtml:span class="hljs-string">"name"</xhtml:span>: <xhtml:span class="hljs-string">"zendframework/zend-expressive"</xhtml:span>,
    <xhtml:span class="hljs-string">"tags"</xhtml:span>: [
      {
        <xhtml:span class="hljs-string">"name"</xhtml:span>: <xhtml:span class="hljs-string">"3.0.2"</xhtml:span>,
        <xhtml:span class="hljs-string">"date"</xhtml:span>: <xhtml:span class="hljs-string">"2018-04-10"</xhtml:span>
      }
    ]
  }
]
</xhtml:code></xhtml:pre>
<xhtml:p>To fetch it, I needed a query like the following:</xhtml:p>
<xhtml:pre><xhtml:code class="language-javascript hljs javascript" data-lang="javascript">query showOrganizationInfo(
  $organization:<xhtml:span class="hljs-built_in">String</xhtml:span>!
  $cursor:<xhtml:span class="hljs-built_in">String</xhtml:span>!
) {
  organization(login:$organization) {
    repositories(first: <xhtml:span class="hljs-number">100</xhtml:span>, <xhtml:span class="hljs-attr">after</xhtml:span>: $cursor) {
      pageInfo {
        startCursor
        hasNextPage
        endCursor
      }
      nodes {
        nameWithOwner
        <xhtml:span class="hljs-attr">tags</xhtml:span>:refs(refPrefix: <xhtml:span class="hljs-string">"refs/tags/"</xhtml:span>, <xhtml:span class="hljs-attr">first</xhtml:span>: <xhtml:span class="hljs-number">100</xhtml:span>, <xhtml:span class="hljs-attr">orderBy</xhtml:span>:{<xhtml:span class="hljs-attr">field</xhtml:span>:TAG_COMMIT_DATE, <xhtml:span class="hljs-attr">direction</xhtml:span>:DESC}) {
          edges {
            <xhtml:span class="hljs-attr">tag</xhtml:span>: node {
              name
              target {
                ... on Commit {
                  pushedDate
                }
                ... on Tag {
                  tagger {
                    date
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
</xhtml:code></xhtml:pre>
<xhtml:p>Which gave me data like the following:</xhtml:p>
<xhtml:pre><xhtml:code class="language-javascript hljs javascript" data-lang="javascript">{
  <xhtml:span class="hljs-string">"data"</xhtml:span>: {
    <xhtml:span class="hljs-string">"organization"</xhtml:span>: {
      <xhtml:span class="hljs-string">"repositories: {
        "</xhtml:span>pageInfo<xhtml:span class="hljs-string">": {
          "</xhtml:span>startCursor<xhtml:span class="hljs-string">": "</xhtml:span>...<xhtml:span class="hljs-string">",
          "</xhtml:span>hasNextPage<xhtml:span class="hljs-string">": true,
          "</xhtml:span>endCursor<xhtml:span class="hljs-string">": "</xhtml:span>...<xhtml:span class="hljs-string">"
        },
        "</xhtml:span>nodes<xhtml:span class="hljs-string">": [
          {
            "</xhtml:span>nameWithOwner<xhtml:span class="hljs-string">": "</xhtml:span>zendframework/zend-expressive<xhtml:span class="hljs-string">",
            "</xhtml:span>tags<xhtml:span class="hljs-string">": {
              "</xhtml:span>edges<xhtml:span class="hljs-string">": [
                "</xhtml:span>tag<xhtml:span class="hljs-string">": {
                  "</xhtml:span>name<xhtml:span class="hljs-string">": "</xhtml:span><xhtml:span class="hljs-number">3.0</xhtml:span><xhtml:span class="hljs-number">.2</xhtml:span><xhtml:span class="hljs-string">",
                  "</xhtml:span>target<xhtml:span class="hljs-string">": {
                    "</xhtml:span>tagger<xhtml:span class="hljs-string">": {
                      "</xhtml:span>date<xhtml:span class="hljs-string">": "</xhtml:span><xhtml:span class="hljs-number">2018</xhtml:span><xhtml:span class="hljs-number">-04</xhtml:span><xhtml:span class="hljs-number">-10</xhtml:span><xhtml:span class="hljs-string">"
                    }
                  }
                }
              ]
            }
          }
        ]
      }
    }
  }
}
</xhtml:span></xhtml:code></xhtml:pre>
<xhtml:p>How did I discover how to create the query? I'd like to say it
was by reading the docs. I really would. But these gave me almost
zero useful examples, particularly when it came to pagination,
ordering results sets, or what those various "nodes" and "edges"
bits were, or why they were necessary. (I eventually found the
information, but it's still rather opaque as an end-user.)</xhtml:p>
<xhtml:p>Additionally, see that <xhtml:code>pageInfo</xhtml:code> bit? This brings me
to my next point: pagination sucks, particularly if it's not at the
top-level. You can only fetch 100 items at a time from any given
node in the GitHub GraphQL API, which means pagination. And I have
yet to find a client that will detect pagination data in results
and auto-follow them. Additionally, the "after" property had to be
something valid... but there were no examples of what a valid value
would be. I had to resort to StackOverflow to find an example, and
I still don't understand why it works.</xhtml:p>
<xhtml:blockquote>
<xhtml:p>I get why clients cannot unfurl pagination, as pagination data
could appear <xhtml:em>anywhere</xhtml:em> in the query. However, it hit me
hard, as I thought I had a complete set of data, only to discover
around half of it was missing once I finally got the processing
correct.</xhtml:p>
</xhtml:blockquote>
<xhtml:p>If any items further down the tree <xhtml:em>also</xhtml:em> require
pagination, you're in for some real headaches, as you then have to
fetch paginated sets depth-first.</xhtml:p>
<xhtml:p>So, while GraphQL promises fewer round trips and exactly the
data you need, my experience so far is:</xhtml:p>
<xhtml:ul>
<xhtml:li>
<xhtml:p>I end up having to be very careful about structuring my queries,
paying huge attention to pagination potential, and often sending
multiple queries ANYWAYS. A well-documented REST API is often far
easier to understand and work with immediately.</xhtml:p>
</xhtml:li>
<xhtml:li>
<xhtml:p>I end up doing MORE work client-side to make the data I receive
back USEFUL. This is because the payload structure is based on the
query structure and the various permutations you need in order to
get at the data you need. Again, a REST API usually has a single,
well-documented payload, making consumption far easier.</xhtml:p>
</xhtml:li>
</xhtml:ul>
<xhtml:p>I'm sure I'm probably mis-using GraphQL, or missing a number of
features to make this stuff easier, but so far, I'm left wishing I
could just have a number of useful REST endpoints that I can hit
consistently in order to aggregate the data I need.</xhtml:p>
<xhtml:blockquote>
<xhtml:p>Before anybody suggests it, yes, I am <xhtml:em>very</xhtml:em> aware that
GitHub also offers a REST API, and the v3 API has endpoints for
most of what I needed. However, I had to rely on tags, not
releases, as not all of our tags have associated releases. However,
the data returned for tags does not include the commit date; for
that, you need to fetch the associated commit, and then the date
may be under either the <xhtml:code>author</xhtml:code> or the
<xhtml:code>committer</xhtml:code>. This approach would have meant literally
thousands of calls to get the data I need, which would have had me
hitting rate limits, and potentially taking hours to complete.</xhtml:p>
<xhtml:p>My point: perhaps instead of GraphQL, aggregating a bit more
data in REST resources (e.g., including commit data with tags), or
providing endpoints that allow merging specific resource types
could have solved the problem easily. This is where having a
developer relations team that finds out what data
<xhtml:em>consumers</xhtml:em> are needing comes in handy, instead of simply
mandating <xhtml:em>graphql all the things</xhtml:em> to allow infinite
flexibility (and the frustrations of such flexibility, both for the
API developer and consumer).</xhtml:p>
</xhtml:blockquote>
<xhtml:h3>Updates</xhtml:h3>
<xhtml:ul>
<xhtml:li>2018-09-19: syntax highlighting fixes.</xhtml:li>
</xhtml:ul>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2018-07-18-graphql.html">Notes on
GraphQL</xhtml:a> was originally published <xhtml:time class="dt-published" datetime="2018-07-18T17:05:00-05:00">18 July 2018</xhtml:time> on
<xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by <xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew Weier
O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[PSR-15]]></title>
    <published>2018-01-23T14:05:00-06:00</published>
    <updated>2018-01-23T14:05:00-06:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2018-01-23-psr-15.html"/>
    <id>https://mwop.net/blog/2018-01-23-psr-15.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>Yesterday, following a unanimous vote from its Core Committee,
<xhtml:a href="http://www.php-fig.org/">PHP-FIG</xhtml:a> formally accepted the
proposed <xhtml:a href="https://github.com/php-fig/fig-standards/tree/master/accepted/PSR-15-request-handlers.md">
PSR-15, HTTP Server Handlers</xhtml:a> standard.</xhtml:p>
<xhtml:p>This new standard defines interfaces for <xhtml:em>request
handlers</xhtml:em> and <xhtml:em>middleware</xhtml:em>. These have enormous
potential impact on the PHP ecosystem, as they provide standard
mechanisms for writing HTTP-facing, server-side applications.
Essentially, they pave the way for developers to create re-usable
web components that will work in any application that works with
PSR-15 middleware or request handlers!</xhtml:p>
<xhtml:blockquote>
<xhtml:h3>Caveat</xhtml:h3>
<xhtml:p>I acted as sponsor on PSR-15, and as final arbiter of changes
during the review period.</xhtml:p>
</xhtml:blockquote>
<xhtml:h2>Background</xhtml:h2>
<xhtml:p>PSR-15 was started by <xhtml:a href="http://shadowhand.me">Woody
Gilk</xhtml:a>, who has acted in the role of Editor for its duration. The
original intent was to ratify a middleware standard, and it was
initially thought that it would be a quick ratification of a
pattern that was already in wide use:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">(
    ServerRequestInterface $request,
    ResponseInterface $response,
    callable $next
)</xhtml:span> : <xhtml:span class="hljs-title">ResponseInterface</xhtml:span>
</xhtml:span></xhtml:code></xhtml:pre>
<xhtml:p>where <xhtml:code>$next</xhtml:code> should implement the following
signature:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">(
    ServerRequestInterface $request,
    ResponseInterface $response
)</xhtml:span> : <xhtml:span class="hljs-title">ResponseInterface</xhtml:span>
</xhtml:span></xhtml:code></xhtml:pre>
<xhtml:blockquote>
<xhtml:h3>"Double Pass"</xhtml:h3>
<xhtml:p>The above pattern has been dubbed "double pass" middleware, for
the fact that it passes <xhtml:em>two</xhtml:em> instances to the collaborator
to <xhtml:em>pass</xhtml:em> to the next layer.</xhtml:p>
</xhtml:blockquote>
<xhtml:p>However, a number of critiques of this existing practice started
to arise almost immediately, with <xhtml:a href="https://blog.ircmaxell.com/2016/05/all-about-middleware.html">one
from Anthony Ferrara</xhtml:a> holding particular weight. The primary
problems noted were:</xhtml:p>
<xhtml:ul>
<xhtml:li>
<xhtml:p>Passing the response from layer to layer can lead to issues
where an outer layer makes a change to the response it passes to an
inner layer, expecting it to propagate back out, but an inner layer
returns a different response entirely. Essentially, the pattern
promotes problematic practices. If middleware needs to operate on a
response, it should operate on the response returned by another
layer.</xhtml:p>
</xhtml:li>
<xhtml:li>
<xhtml:p>Typehinting <xhtml:code>$next</xhtml:code> as callable means there's no way
to ensure that the callable is actually capable of accepting the
arguments passed to it. In other words, it's not type safe.</xhtml:p>
</xhtml:li>
</xhtml:ul>
<xhtml:p>After debate within the working group, the next iteration
proposed the following (some details differ, but basic interactions
are the same):</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">interface</xhtml:span> <xhtml:span class="hljs-title">DelegateInterface</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">process</xhtml:span><xhtml:span class="hljs-params">(ServerRequestInterface $request)</xhtml:span> : <xhtml:span class="hljs-title">ResponseInterface</xhtml:span></xhtml:span>;
}

<xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">interface</xhtml:span> <xhtml:span class="hljs-title">MiddlewareInterface</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">process</xhtml:span><xhtml:span class="hljs-params">(
        ServerRequestInterface $request,
        DelegateInterface $delegate
    )</xhtml:span> : <xhtml:span class="hljs-title">ResponseInterface</xhtml:span></xhtml:span>;
}
</xhtml:code></xhtml:pre>
<xhtml:p>This largely solved the problems highlighted above. However, a
few more details came up as different teams developed
implementations.</xhtml:p>
<xhtml:p>First, many noted that they felt defining the same method name
prevented polymorphism. A common use case was to define a "request
handler" that could be called and which would in turn
<xhtml:em>process</xhtml:em> itself. So, we updated the interfaces as
follows:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">interface</xhtml:span> <xhtml:span class="hljs-title">RequestHandlerInterface</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">handle</xhtml:span><xhtml:span class="hljs-params">(ServerRequestInterface $request)</xhtml:span> : <xhtml:span class="hljs-title">ResponseInterface</xhtml:span></xhtml:span>;
}

<xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">interface</xhtml:span> <xhtml:span class="hljs-title">MiddlewareInterface</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">process</xhtml:span><xhtml:span class="hljs-params">(
        ServerRequestInterface $request,
        RequestHandlerInterface $handler
    )</xhtml:span> : <xhtml:span class="hljs-title">ResponseInterface</xhtml:span></xhtml:span>;
}
</xhtml:code></xhtml:pre>
<xhtml:p>Second, once that change was done, a number of others noted that
the request handler could be useful in and of itself. For example,
when creating a simple site, you could marshal a server request,
pass it to a handler, and emit the response returned; middleware
might not be necessary in this case. Another use case is for the
final, internal end points of a middleware application: instead of
implementing these as middleware, one could implement them as
request handlers instead, as they do not operate on the results of
the handler.</xhtml:p>
<xhtml:p>As a result, we made the change to ship the two interfaces
<xhtml:em>as separate packages</xhtml:em>, with the package containing the
<xhtml:code>MiddlewareInterface</xhtml:code> depending on the package defining
the <xhtml:code>RequestHandlerInterface</xhtml:code>.</xhtml:p>
<xhtml:p>Finally, over the close to two years that this specification was
being developed, PHP 7 gained in maturity, with 7.1 and 7.2
releases. We decided to pin the specification to PHP 7 or greater,
and formally adopted return type hints within it.</xhtml:p>
<xhtml:p>While work on the specification was in progress, each iteration
of the interfaces was published within the github organization
<xhtml:a href="https://github.com/http-interop">http-interop</xhtml:a>, with
packages matching whatever the current specification detailed
(http-middleware, then http-server-middleware, and, eventually,
adding http-server-handler). These packages also used
<xhtml:code>Interop\Http</xhtml:code> as the top-level namespace. Members of
the working group, as well as other interested parties, would pin
their offerings to specific iterations.</xhtml:p>
<xhtml:p>The final packages are now owned by the PHP-FIG group, however,
and use the <xhtml:code>Psr</xhtml:code> top-level namespace.</xhtml:p>
<xhtml:h2>The Interfaces</xhtml:h2>
<xhtml:p>That brings us to the final standard:</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:a href="https://github.com/php-fig/fig-standards/tree/master/accepted/PSR-15-request-handlers.md">
PSR-15</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="https://github.com/php-fig/fig-standards/tree/master/accepted/PSR-15-request-handlers-meta.md">
PSR-15 Meta Document</xhtml:a> (which covers the <xhtml:em>whys</xhtml:em> behind the
specification)</xhtml:li>
</xhtml:ul>
<xhtml:p><xhtml:a href="https://github.com/php-fig/http-server-handler">psr/http-server-handler</xhtml:a>
provides the following interface:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">namespace</xhtml:span> <xhtml:span class="hljs-title">Psr</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">Server</xhtml:span>;

<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Psr</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">Message</xhtml:span>\<xhtml:span class="hljs-title">ResponseInterface</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Psr</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">Message</xhtml:span>\<xhtml:span class="hljs-title">ServerRequestInterface</xhtml:span>;

<xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">interface</xhtml:span> <xhtml:span class="hljs-title">RequestHandlerInterface</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">handle</xhtml:span><xhtml:span class="hljs-params">(ServerRequestInterface $request)</xhtml:span> : <xhtml:span class="hljs-title">ResponseInterface</xhtml:span></xhtml:span>;
}
</xhtml:code></xhtml:pre>
<xhtml:p><xhtml:a href="https://github.com/php-fig/http-server-middleware">psr/http-server-middleware</xhtml:a>
provides the following interface:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">namespace</xhtml:span> <xhtml:span class="hljs-title">Psr</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">Server</xhtml:span>;

<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Psr</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">Message</xhtml:span>\<xhtml:span class="hljs-title">ResponseInterface</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Psr</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">Message</xhtml:span>\<xhtml:span class="hljs-title">ServerRequestInterface</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Psr</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">Server</xhtml:span>\<xhtml:span class="hljs-title">RequestHandlerInterface</xhtml:span>;

<xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">interface</xhtml:span> <xhtml:span class="hljs-title">MiddlewareInterface</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">process</xhtml:span><xhtml:span class="hljs-params">(
        ServerRequestInterface $request,
        RequestHandlerInterface $handler
    )</xhtml:span> : <xhtml:span class="hljs-title">ResponseInterface</xhtml:span></xhtml:span>;
}
</xhtml:code></xhtml:pre>
<xhtml:p>Both packages depend on <xhtml:a href="http://www.php-fig.org/psr/psr-7/">PSR-7</xhtml:a> as they typehint
against the HTTP message interfaces that package defines. The
http-server-middleware package depends on the http-server-handler
package.</xhtml:p>
<xhtml:h2>How to write re-usable middleware</xhtml:h2>
<xhtml:p>Most middleware dispatchers available currently (and there are a
LOT of them, as it turns out!) allow you to compose middleware in
such a way that none of it needs to know how or what is composing
it. This is A Good Thing™. It allows you to write middleware that
is de-coupled from the context in which it is used.</xhtml:p>
<xhtml:p>But how do you do that?</xhtml:p>
<xhtml:p>In the meta document for the specification, we <xhtml:a href="https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-15-request-handlers-meta.md#reusable-middleware-examples">
suggest the following</xhtml:a>:</xhtml:p>
<xhtml:ul>
<xhtml:li>
<xhtml:p>Test the request for required pre-conditions, if any. If it does
not satisfy any, use a composed <xhtml:em>response prototype</xhtml:em> or
<xhtml:em>response factory</xhtml:em> to generate and return a response.</xhtml:p>
</xhtml:li>
<xhtml:li>
<xhtml:p>If pre-conditions are met, delegate creation of the response to
the provided handler, optionally providing a "new" request (PSR-7
requests are immutable, so this means calling one of its
<xhtml:code>with*()</xhtml:code> methods, which return new instances).</xhtml:p>
</xhtml:li>
<xhtml:li>
<xhtml:p>Either pass the response back from the handler verbatim, or
return a new response by manipulating the one returned (again, via
one of the <xhtml:code>with*()</xhtml:code> methods).</xhtml:p>
</xhtml:li>
</xhtml:ul>
<xhtml:p>The first point is probably the most important here: do not
directly instantiate a response in your middleware, but instead use
a <xhtml:em>prototype</xhtml:em> or a <xhtml:em>factory</xhtml:em> that is provided during
instantiation. This allows you to de-couple your middleware from
the PSR-7 implementation used by the application.</xhtml:p>
<xhtml:p>In practice, that might look something like this:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">class</xhtml:span> <xhtml:span class="hljs-title">CheckOriginMiddleware</xhtml:span> <xhtml:span class="hljs-keyword">implements</xhtml:span> <xhtml:span class="hljs-title">MiddlewareInterface</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-keyword">private</xhtml:span> $acceptedOrigins;
    <xhtml:span class="hljs-keyword">private</xhtml:span> $responsePrototype;

    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">__construct</xhtml:span><xhtml:span class="hljs-params">(array $acceptedOrigins, ResponseInterface $responsePrototype)</xhtml:span>
    </xhtml:span>{
        <xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;acceptedOrigins = $acceptedOrigins;
        <xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;responsePrototype = $responsePrototype;
    }

    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">process</xhtml:span><xhtml:span class="hljs-params">(ServerRequestInterface $request, RequestHandlerInterface $handler)</xhtml:span> : <xhtml:span class="hljs-title">ResponseInterface</xhtml:span>
    </xhtml:span>{
        $origin = $request-&gt;getHeaderLine(<xhtml:span class="hljs-string">'origin'</xhtml:span>);
        <xhtml:span class="hljs-keyword">if</xhtml:span> (! in_array($origin, <xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;acceptedOrigins, <xhtml:span class="hljs-keyword">true</xhtml:span>)) {
            <xhtml:span class="hljs-keyword">return</xhtml:span> <xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;responsePrototype
                -&gt;withStatus(<xhtml:span class="hljs-number">401</xhtml:span>)
                -&gt;withHeader(<xhtml:span class="hljs-string">'X-Invalid-Origin'</xhtml:span>, $origin);
        }

        $response = $handler-&gt;handle($request);

        <xhtml:span class="hljs-keyword">return</xhtml:span> $response-&gt;withHeader(<xhtml:span class="hljs-string">'X-Origin'</xhtml:span>, $origin);
    }
}
</xhtml:code></xhtml:pre>
<xhtml:p>A few things to note about this middleware:</xhtml:p>
<xhtml:ul>
<xhtml:li>
<xhtml:p>It accepts dependencies via its constructor. This practice
allows us to easily test the middleware, and defines what it needs
in order to do its work.</xhtml:p>
</xhtml:li>
<xhtml:li>
<xhtml:p>The response prototype ensures we are de-coupled from the PSR-7
implementation. I can pass a Diactoros response, a Guzzle response,
a Slim response, or any other implementation. As a result,
consumers of this middleware will not need to potentially install
another PSR-7 implementation.</xhtml:p>
</xhtml:li>
<xhtml:li>
<xhtml:p>The middleware has no idea where it will be used, or what stack
it will be used in. It simply operates on the request and the
handler provided when <xhtml:code>process()</xhtml:code> is called.</xhtml:p>
</xhtml:li>
</xhtml:ul>
<xhtml:p>How might I consume such middleware?</xhtml:p>
<xhtml:p>In <xhtml:a href="https://docs.zendframework.com/zend-expressive/">Expressive</xhtml:a>),
I might do any one of the following:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-comment">// Pipe it as a service to pull from the DI container:</xhtml:span>
$app-&gt;pipe(CheckOriginMiddleware::class);

<xhtml:span class="hljs-comment">// Use it within a route-specific pipeline:</xhtml:span>
$app-&gt;post(<xhtml:span class="hljs-string">'/api/foo'</xhtml:span>, [
    CheckOriginMiddleware::class,
    FooMiddleware::class,
]);
</xhtml:code></xhtml:pre>
<xhtml:p>In <xhtml:a href="https://github.com/northwoods/broker">northwoods/broker</xhtml:a>
(maintained by Woody Gilk, the PSR-15 editor), it looks like
this:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php">$broker-&gt;always([CheckOriginMiddleware::class]);
</xhtml:code></xhtml:pre>
<xhtml:p>In <xhtml:a href="https://github.com/middlewares/utils">middlewares/utils
Dispatcher</xhtml:a>, you'd do this:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php">$dispatcher = <xhtml:span class="hljs-keyword">new</xhtml:span> Dispatcher([
    <xhtml:span class="hljs-comment">/* ... */</xhtml:span>
    <xhtml:span class="hljs-keyword">new</xhtml:span> CheckOriginMiddleware($acceptedOrigins, $responsePrototype),
    <xhtml:span class="hljs-comment">/* ... */</xhtml:span>
]);
</xhtml:code></xhtml:pre>
<xhtml:p>With any one of these solutions, if your middleware is executed,
it will act exactly the same; <xhtml:em>how</xhtml:em> it is composed doesn't
matter, as the way it operates is only dependent on the request and
handler passed to the middleware during <xhtml:code>process()</xhtml:code>.</xhtml:p>
<xhtml:h2>What about request handlers?</xhtml:h2>
<xhtml:p>Most of the libraries I've looked at at this time define
handlers in one of two ways:</xhtml:p>
<xhtml:ul>
<xhtml:li>
<xhtml:p>As a middleware dispatcher. In this particular case, each
middleware is processed until one returns a response. If the last
one processed calls on the handler again, then a canned response is
returned, an exception is thrown, or the next scenario comes into
play:</xhtml:p>
</xhtml:li>
<xhtml:li>
<xhtml:p>As a "final" handler to pass to the middleware dispatcher. In
other words, if the last middleware processed <xhtml:em>also</xhtml:em> calls
on its handler, this "fallback" or "final" handler will be what's
invoked. This will typically return a 404 response or a 500
response, depending on the implementation.</xhtml:p>
</xhtml:li>
</xhtml:ul>
<xhtml:p>One other possibility that's been floated by several is for use
with <xhtml:em>routing middleware</xhtml:em>. In this case, when routing
middleware matches a request, it would then call on a request
handler mapped to that request.</xhtml:p>
<xhtml:h2>Notes for implementors</xhtml:h2>
<xhtml:p>PSR-15 is accepted; let's make all the things PSR-15!</xhtml:p>
<xhtml:p>But have some patience! While a number of projects have been
working with various iterations of the http-interop packages, and
may need some time to update to the final PSR-15 specification.</xhtml:p>
<xhtml:p>For example, we've been tracking various iterations of
http-interop in both Stratigility and Expressive, but updating to
the PSR-15 specification requires backwards-incompatible changes,
necessitating a new 3.0 version — which need a few more weeks to
drop. Slim <xhtml:a href="https://github.com/slimphp/Slim/pull/2379">also
has a patch submitted with PSR-15 support</xhtml:a>, which would likely
not drop until an upcoming 4.0 release.</xhtml:p>
<xhtml:p>As such, have patience with library and framework maintainers,
and help test releases for them.</xhtml:p>
<xhtml:p>Additionally, consider tracking and testing the <xhtml:a href="https://github.com/php-fig/fig-standards/tree/de189e864044ce726f7e75b7d17ac98ea049f45c/proposed/http-factory">
proposed PSR-17 specification</xhtml:a>. This proposal will standardize
PSR-7 <xhtml:em>factories</xhtml:em>, which will provide a standard way for
middleware to generate, in particular, responses to return. Instead
of composing a response prototype, you would compose a factory. Why
is this easier? Well, in cases where you may also want to address
the response <xhtml:em>body</xhtml:em>, which is a
<xhtml:code>Psr\Http\Message\StreamInterface</xhtml:code> instance, it allows
you to create new instances of those as well. Since streams cannot
be immutable (due to language limitations), any time you write to a
stream, you could be appending existing content, which means
middleware that writes to the response prototype body generally
needs to also compose a <xhtml:em>stream</xhtml:em> prototype. What if you
could compose a single factory instead?</xhtml:p>
<xhtml:h2>Closing thoughts</xhtml:h2>
<xhtml:p>When I started work on PSR-7 originally, <xhtml:em>it was because I
wanted a standard middleware interface for PHP</xhtml:em>. I'd been
playing with Node, and, more specifically, Sencha Connect and
ExpressJS. The middleware ecosystem in Node was and continues to be
tremendous. The reason it exists is because of two factors:</xhtml:p>
<xhtml:ul>
<xhtml:li>
<xhtml:p>Accepted, standard middleware signature. Even though JS doesn't
provide interfaces, and there is no userland standards body, a
consensus signature emerged, and everyone used it. These were
possible because of:</xhtml:p>
</xhtml:li>
<xhtml:li>
<xhtml:p>Built-in HTTP message abstractions in the Node core library.</xhtml:p>
</xhtml:li>
</xhtml:ul>
<xhtml:p>If I wanted standard middleware in PHP, we first needed standard
HTTP messages, which PSR-7 accomplished. That could have been the
end of it, as many libraries started using the same middleware
signatures; however, we soon had at least two, and possibly as many
as a half-dozen different approaches. Thankfully, Woody stepped up
to the task and proposed what became PSR-15; further, he, and the
other members of the working group, had the patience and stamina to
see it to acceptance (though I know there were several times he and
others almost threw the towel in!).</xhtml:p>
<xhtml:p>With PSR-15 accepted, we are a step closer to something I have
long envisioned: a possibility for PHP developers to no longer work
within monolithic MVC frameworks, but instead compose applications
out of commodity, reusable middleware.</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2018-01-23-psr-15.html">PSR-15</xhtml:a> was
originally published <xhtml:time class="dt-published" datetime="2018-01-23T14:05:00-06:00">23 January 2018</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by <xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew Weier
O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Using Anonymous Classes to Write Middleware]]></title>
    <published>2017-03-30T13:20:00-05:00</published>
    <updated>2017-03-30T13:20:00-05:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2017-03-30-anonymous-class-middleware.html"/>
    <id>https://mwop.net/blog/2017-03-30-anonymous-class-middleware.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>I faced an interesting question recently with regards to
middleware: What happens when we go from a convention-based to a
contract-based approach when programming?</xhtml:p>
<xhtml:p>Convention-based approaches usually allow for <xhtml:a href="https://en.wikipedia.org/wiki/Duck_typing">duck-typing</xhtml:a>; with
middleware, it means you can write <xhtml:a href="http://php.net/language.types.callable">PHP callables</xhtml:a> —
usually <xhtml:a href="http://php.net/closure">closures</xhtml:a> — and just
expect them to work.</xhtml:p>
<xhtml:p>Contract-based approaches use <xhtml:em>interfaces</xhtml:em>. I think you
can see where this is going.</xhtml:p>
<xhtml:h2>PSR-7 Middleware</xhtml:h2>
<xhtml:p>When <xhtml:a href="http://www.php-fig.org/psr/psr-7/">PSR-7</xhtml:a> was
introduced, a number of middleware microframeworks adopted a common
signature for middleware:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Psr</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">Message</xhtml:span>\<xhtml:span class="hljs-title">ResponseInterface</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Psr</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">Message</xhtml:span>\<xhtml:span class="hljs-title">ServerRequestInterface</xhtml:span>;

<xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">(
    ServerRequestInterface $request,
    ResponseInterface $response,
    callable $next
)</xhtml:span> : <xhtml:span class="hljs-title">ResponseInterface</xhtml:span>
</xhtml:span></xhtml:code></xhtml:pre>
<xhtml:p>where <xhtml:code>$next</xhtml:code> had the following signature:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Psr</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">Message</xhtml:span>\<xhtml:span class="hljs-title">ResponseInterface</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Psr</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">Message</xhtml:span>\<xhtml:span class="hljs-title">ServerRequestInterface</xhtml:span>;

<xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">(
    ServerRequestInterface $request,
    ResponseInterface $response
)</xhtml:span> : <xhtml:span class="hljs-title">ResponseInterface</xhtml:span>
</xhtml:span></xhtml:code></xhtml:pre>
<xhtml:p>This approach meant that you could wire middleware using
closures, which makes for a nice, succinct, programmatic
interface:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-comment">// Examples are using zend-stratigility</xhtml:span>
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Diactoros</xhtml:span>\<xhtml:span class="hljs-title">Response</xhtml:span>\<xhtml:span class="hljs-title">TextResponse</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Stratigility</xhtml:span>\<xhtml:span class="hljs-title">MiddlewarePipe</xhtml:span>;

$pipeline = <xhtml:span class="hljs-keyword">new</xhtml:span> MiddlewarePipe();

$pipeline-&gt;pipe(<xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">($request, $response, callable $next)</xhtml:span> </xhtml:span>{
    $response = $next($request, $response);
    <xhtml:span class="hljs-keyword">return</xhtml:span> $response-&gt;withHeader(<xhtml:span class="hljs-string">'X-ClacksOverhead'</xhtml:span>, <xhtml:span class="hljs-string">'GNU Terry Pratchett'</xhtml:span>);
});

$pipeline-&gt;pipe(<xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">($request, $response, callable $next)</xhtml:span> </xhtml:span>{
    <xhtml:span class="hljs-keyword">return</xhtml:span> <xhtml:span class="hljs-keyword">new</xhtml:span> TextResponse(<xhtml:span class="hljs-string">'Hello world!'</xhtml:span>);
});
</xhtml:code></xhtml:pre>
<xhtml:p>Easy-peasey!</xhtml:p>
<xhtml:p>This convention-based approach was easy to write for, because
there was no need to create discrete classes. You <xhtml:em>could</xhtml:em>,
but it wasn't strictly necessary. Just throw any PHP callable at
it, and profit.</xhtml:p>
<xhtml:p>(I'll note that some libraries, such as <xhtml:a href="https://docs.zendframework.com/zend-stratigility">Stratigility</xhtml:a>,
codified at least the middleware via an interface as well, though
implementation of the interface was strictly optional.)</xhtml:p>
<xhtml:p>The <xhtml:strong>big</xhtml:strong> problem, however, is that it can lead
to subtle errors:</xhtml:p>
<xhtml:ul>
<xhtml:li>what happens if you expect <xhtml:em>more</xhtml:em> arguments than the
middleware dispatcher provides?</xhtml:li>
<xhtml:li>what happens if you expect <xhtml:em>different</xhtml:em> arguments and/or
argument types than the middleware dispatcher provides?</xhtml:li>
<xhtml:li>what happens if your middleware returns something
unexpected?</xhtml:li>
</xhtml:ul>
<xhtml:p>Essentially, a convention-based approach has no <xhtml:a href="https://en.wikipedia.org/wiki/Type_safety">type safety</xhtml:a>, which
can lead to a lot of subtle, unexpected, runtime errors.</xhtml:p>
<xhtml:h2>PSR-15 Middleware</xhtml:h2>
<xhtml:p>The proposed <xhtml:a href="https://github.com/php-fig/fig-standards/tree/10bb43b1802c0427f8a4a5d1e6a84da83fa7724d/proposed/http-middleware">
PSR-15 (HTTP Server Middleware)</xhtml:a> is <xhtml:em>not</xhtml:em>
convention-based, and instead proposes two <xhtml:em>interfaces</xhtml:em>:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">namespace</xhtml:span> <xhtml:span class="hljs-title">Interop</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">ServerMiddleware</xhtml:span>;

<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Psr</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">Message</xhtml:span>\<xhtml:span class="hljs-title">ResponseInterface</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Psr</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">Message</xhtml:span>\<xhtml:span class="hljs-title">ServerRequestInterface</xhtml:span>;

<xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">interface</xhtml:span> <xhtml:span class="hljs-title">MiddlewareInterface</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-comment">/**
     * Docblock annotations, because PHP 5.6 compatibility
     *
     * <xhtml:span class="hljs-doctag">@return</xhtml:span> ResponseInterface
     */</xhtml:span>
    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">process</xhtml:span><xhtml:span class="hljs-params">(ServerRequestInterface $request, DelegateInterface $delegate)</xhtml:span></xhtml:span>;
}

<xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">interface</xhtml:span> <xhtml:span class="hljs-title">DelegateInterface</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-comment">/**
     * Docblock annotations, because PHP 5.6 compatibility
     *
     * <xhtml:span class="hljs-doctag">@return</xhtml:span> ResponseInterface
     */</xhtml:span>
    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">process</xhtml:span><xhtml:span class="hljs-params">(ServerRequestInterface $request)</xhtml:span></xhtml:span>;
}
</xhtml:code></xhtml:pre>
<xhtml:p>This leads to type safety: if you typehint on these interfaces
(and, typically, for middleware dispatchers, you're only concerned
with the <xhtml:code>MiddlewareInterface</xhtml:code>), you know that PHP will
have your back with regards to invalid middleware.</xhtml:p>
<xhtml:p>However, this also means that for any given middleware, <xhtml:em>you
<xhtml:strong>must</xhtml:strong> create a class</xhtml:em>!</xhtml:p>
<xhtml:p>Well, that makes things more difficult, doesn't it!</xhtml:p>
<xhtml:p>Or does it?</xhtml:p>
<xhtml:h2>Anonymous classes</xhtml:h2>
<xhtml:p>Starting in PHP 7, we now have the ability to declare <xhtml:a href="http://php.net/language.oop5.anonymous">anonymous classes</xhtml:a>.
These are similar to closures, which can be thought of as
<xhtml:em>anonymous functions</xhtml:em> (though with quite a lot more
semantics and functionality!), applied at the class level.</xhtml:p>
<xhtml:p>Interestingly, anonymous classes in PHP allow for:</xhtml:p>
<xhtml:ul>
<xhtml:li>Extension</xhtml:li>
<xhtml:li>Interface implementation</xhtml:li>
<xhtml:li>Trait composition</xhtml:li>
</xhtml:ul>
<xhtml:p>In other words, they behave just like any standard class
declaration.</xhtml:p>
<xhtml:p>Let's adapt our previous pipeline to use PSR-15 instead. (We'll
continue using Stratigility, as, since version 2, it supports the
proposed PSR-15 specification.)</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Interop</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">ServerMiddleware</xhtml:span>\<xhtml:span class="hljs-title">DelegateInterface</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Interop</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">ServerMiddleware</xhtml:span>\<xhtml:span class="hljs-title">MiddlewareInterface</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Psr</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">Message</xhtml:span>\<xhtml:span class="hljs-title">ServerRequestInterface</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Diactoros</xhtml:span>\<xhtml:span class="hljs-title">Response</xhtml:span>\<xhtml:span class="hljs-title">TextResponse</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Stratigility</xhtml:span>\<xhtml:span class="hljs-title">MiddlewarePipe</xhtml:span>;

$pipeline = <xhtml:span class="hljs-keyword">new</xhtml:span> MiddlewarePipe();

$pipeline-&gt;pipe(<xhtml:span class="hljs-keyword">new</xhtml:span> <xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">class</xhtml:span> <xhtml:span class="hljs-keyword">implements</xhtml:span> <xhtml:span class="hljs-title">MiddlewareInterface</xhtml:span> </xhtml:span>{
    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">process</xhtml:span> <xhtml:span class="hljs-params">(ServerRequestInterface $request, DelegateInterface $delegate)</xhtml:span>
    </xhtml:span>{
        $response = $delegate-&gt;process($request);
        <xhtml:span class="hljs-keyword">return</xhtml:span> $response-&gt;withHeader(<xhtml:span class="hljs-string">'X-ClacksOverhead'</xhtml:span>, <xhtml:span class="hljs-string">'GNU Terry Pratchett'</xhtml:span>);
    }
});

$pipeline-&gt;pipe(<xhtml:span class="hljs-keyword">new</xhtml:span> <xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">class</xhtml:span> <xhtml:span class="hljs-keyword">implements</xhtml:span> <xhtml:span class="hljs-title">MiddlewareInterface</xhtml:span> </xhtml:span>{
    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">process</xhtml:span><xhtml:span class="hljs-params">(ServerRequestInterface $request, DelegateInterface $delegate)</xhtml:span>
    </xhtml:span>{
        <xhtml:span class="hljs-keyword">return</xhtml:span> <xhtml:span class="hljs-keyword">new</xhtml:span> TextResponse(<xhtml:span class="hljs-string">'Hello world!'</xhtml:span>);
    }
});
</xhtml:code></xhtml:pre>
<xhtml:p>While there's slightly more verbiage — what were essentially our
anonymous functions previously are now wrapped in a class, adding a
couple lines to each — the result is not terribly onerous, and
gives us important <xhtml:em>type-safety</xhtml:em>. Our middleware runner no
longer has to <xhtml:em>assume</xhtml:em> that any middleware piped to it is
correctly defined, but can instead <xhtml:em>know</xhtml:em>, as it can enforce
a typehint.</xhtml:p>
<xhtml:p>The approach is also useful to IDEs, which can now properly
typehint arguments, and let us know when the contract is being
violated.</xhtml:p>
<xhtml:h2>What about closures?</xhtml:h2>
<xhtml:p>A <xhtml:em>closure</xhtml:em> in PHP allows you to <xhtml:em>close over</xhtml:em> or
<xhtml:em>bind</xhtml:em> variables in the current scope to the anonymous
function. As an example, if I want to create logging middleware, I
might do the following:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-comment">// Where $log is a PSR-3 logger:</xhtml:span>
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Diactoros</xhtml:span>\<xhtml:span class="hljs-title">Response</xhtml:span>\<xhtml:span class="hljs-title">EmptyResponse</xhtml:span>;

$pipeline-&gt;pipe(<xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">($request, $response, callable $next)</xhtml:span> <xhtml:span class="hljs-title">use</xhtml:span> <xhtml:span class="hljs-params">($log)</xhtml:span> </xhtml:span>{
    <xhtml:span class="hljs-keyword">try</xhtml:span> {
        $response = $next($request, $response);
        <xhtml:span class="hljs-keyword">return</xhtml:span> $response;
    } <xhtml:span class="hljs-keyword">catch</xhtml:span> (Throwable $e) {
    }

    $log-&gt;error(sprintf(
        <xhtml:span class="hljs-string">'[%d] (%s) %s'</xhtml:span>,
        $e-&gt;getCode(),
        get_class($e),
        $e-&gt;getMessage()
    ), [<xhtml:span class="hljs-string">'exception'</xhtml:span> =&gt; $e]);

    <xhtml:span class="hljs-keyword">return</xhtml:span> <xhtml:span class="hljs-keyword">new</xhtml:span> EmptyResponse(<xhtml:span class="hljs-number">500</xhtml:span>);
});
</xhtml:code></xhtml:pre>
<xhtml:p>How would I accomplish this with an anonymous class?</xhtml:p>
<xhtml:p>Anonymous classes let you pass arguments during declaration that
are then passed to the constructor. As such, you <xhtml:em>bind</xhtml:em>
variables from the current scope into the class typically as
<xhtml:em>class properties</xhtml:em>:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-comment">// Where $log is a PSR-3 logger:</xhtml:span>
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Interop</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">ServerMiddleware</xhtml:span>\<xhtml:span class="hljs-title">DelegateInterface</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Interop</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">ServerMiddleware</xhtml:span>\<xhtml:span class="hljs-title">MiddlewareInterface</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Psr</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">Message</xhtml:span>\<xhtml:span class="hljs-title">ServerRequestInterface</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Psr</xhtml:span>\<xhtml:span class="hljs-title">Log</xhtml:span>\<xhtml:span class="hljs-title">LoggerInterface</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Diactoros</xhtml:span>\<xhtml:span class="hljs-title">Response</xhtml:span>\<xhtml:span class="hljs-title">EmptyResponse</xhtml:span>;

$pipeline-&gt;pipe(<xhtml:span class="hljs-keyword">new</xhtml:span> <xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">class</xhtml:span>($<xhtml:span class="hljs-title">log</xhtml:span>) <xhtml:span class="hljs-keyword">implements</xhtml:span> <xhtml:span class="hljs-title">MiddlewareInterface</xhtml:span> </xhtml:span>{
    <xhtml:span class="hljs-keyword">private</xhtml:span> $log;

    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">__construct</xhtml:span><xhtml:span class="hljs-params">(LoggerInterface $log)</xhtml:span>
    </xhtml:span>{
        <xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;log = $log;
    }

    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">process</xhtml:span><xhtml:span class="hljs-params">(ServerRequestInterface $request, DelegateInterface $delegate)</xhtml:span>
    </xhtml:span>{
        <xhtml:span class="hljs-keyword">try</xhtml:span> {
            $response = $delegate-&gt;process($request);
            <xhtml:span class="hljs-keyword">return</xhtml:span> $response;
        } <xhtml:span class="hljs-keyword">catch</xhtml:span> (Throwable $e) {
        }

        <xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;log-&gt;error(sprintf(
            <xhtml:span class="hljs-string">'[%d] (%s) %s'</xhtml:span>,
            $e-&gt;getCode(),
            get_class($e),
            $e-&gt;getMessage()
        ), [<xhtml:span class="hljs-string">'exception'</xhtml:span> =&gt; $e]);

        <xhtml:span class="hljs-keyword">return</xhtml:span> <xhtml:span class="hljs-keyword">new</xhtml:span> EmptyResponse(<xhtml:span class="hljs-number">500</xhtml:span>);
    }
});
</xhtml:code></xhtml:pre>
<xhtml:p>This approach gives you added type-safety: if <xhtml:code>$log</xhtml:code>
is of a different type, you'll know when that middleware is
created, as PHP will raise a fatal error.</xhtml:p>
<xhtml:p>Another thing I like about this approach is it allows me to
prototype classes before I write them formally. I can start seeing
what the re-use possibilities are, what arguments I might need, and
more. Because the syntax for anonymous classes is identical to
declared classes, I can later extract it to a named class by simply
cutting the definition and pasting it into a file of its own.</xhtml:p>
<xhtml:p>So, don't let the PSR-15 interfaces stop you! Start using
anonymous classes for your own middleware prototypes!</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2017-03-30-anonymous-class-middleware.html">Using
Anonymous Classes to Write Middleware</xhtml:a> was originally published
<xhtml:time class="dt-published" datetime="2017-03-30T13:20:00-05:00">30
March 2017</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by <xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew Weier
O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[PSR-7 Request and Method Utilities]]></title>
    <published>2017-01-26T13:50:00-06:00</published>
    <updated>2017-01-26T13:50:00-06:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2017-01-26-http-message-util.html"/>
    <id>https://mwop.net/blog/2017-01-26-http-message-util.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>We all know the standard HTTP request methods and status codes,
right? Or do we?</xhtml:p>
<xhtml:p>We definitely know whether or not they should be integers or
strings, and/or how string values should be normalized, right?</xhtml:p>
<xhtml:p>And our IDEs can <xhtml:em>totally</xhtml:em> autocomplete them, right?</xhtml:p>
<xhtml:p>Oh, that's not the case?</xhtml:p>
<xhtml:p>Some time ago, a few folks floated the idea of creating a
utility repository related to the <xhtml:a href="http://www.php-fig.org/psr/psr-7/">PSR-7</xhtml:a> <xhtml:a href="https://github.com/php-fig/http-message">psr/http-message</xhtml:a>
package, but containing some useful bits such as constants for HTTP
request methods and status codes.</xhtml:p>
<xhtml:p>Six months ago, we released it... but didn't publicize it. I
remembered that fact today while writing some unit tests that were
utilizing the package, and thought I'd finally write it up.</xhtml:p>
<xhtml:p>The package is <xhtml:a href="https://github.com/php-fig/http-message-util">fig/http-message-util</xhtml:a>,
and is available via Composer and Packagist:</xhtml:p>
<xhtml:pre><xhtml:code class="language-bash hljs bash" data-lang="bash">$ composer require fig/http-message-util
</xhtml:code></xhtml:pre>
<xhtml:p>It provides two interfaces:</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:code>Fig\Http\Message\RequestMethodInterface</xhtml:code>,
containing constants for HTTP request method values.</xhtml:li>
<xhtml:li><xhtml:code>Fig\Http\Message\StatusCodeInterface</xhtml:code>, containing
constants for HTTP status code values.</xhtml:li>
</xhtml:ul>
<xhtml:p>The constants are prefixed with <xhtml:code>METHOD_</xhtml:code> and
<xhtml:code>STATUS_</xhtml:code>, respectively, and use the standard names as
presented in the various IETF specifications that originally define
them.</xhtml:p>
<xhtml:p>As an example, I could write middleware that looks like
this:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Fig</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">Message</xhtml:span>\<xhtml:span class="hljs-title">RequestMethodInterface</xhtml:span> <xhtml:span class="hljs-title">as</xhtml:span> <xhtml:span class="hljs-title">RequestMethod</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Fig</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">Message</xhtml:span>\<xhtml:span class="hljs-title">StatusCodeInterface</xhtml:span> <xhtml:span class="hljs-title">as</xhtml:span> <xhtml:span class="hljs-title">StatusCode</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Interop</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">ServerMiddleware</xhtml:span>\<xhtml:span class="hljs-title">DelegateInterface</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Interop</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">ServerMiddleware</xhtml:span>\<xhtml:span class="hljs-title">MiddlewareInterface</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Psr</xhtml:span>\<xhtml:span class="hljs-title">Http</xhtml:span>\<xhtml:span class="hljs-title">Message</xhtml:span>\<xhtml:span class="hljs-title">ServerRequestInterface</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Diactoros</xhtml:span>\<xhtml:span class="hljs-title">EmptyResponse</xhtml:span>;

<xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">class</xhtml:span> <xhtml:span class="hljs-title">RequestMethodNegotiation</xhtml:span> <xhtml:span class="hljs-keyword">implements</xhtml:span> <xhtml:span class="hljs-title">MiddlewareInterface</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-keyword">private</xhtml:span> $alwaysAllowed = [
        RequestMethod::METHOD_HEAD,
        RequestMethod::METHOD_OPTIONS,
    ];

    <xhtml:span class="hljs-keyword">private</xhtml:span> $map;

    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">__construct</xhtml:span><xhtml:span class="hljs-params">(array $map)</xhtml:span>
    </xhtml:span>{
        <xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;map = $map;
    }

    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">process</xhtml:span><xhtml:span class="hljs-params">(ServerRequestInterface $request, DelegateInterface $delegate)</xhtml:span>
    </xhtml:span>{
        $path = $request-&gt;getUri()-&gt;getPath();
        <xhtml:span class="hljs-keyword">if</xhtml:span> (! <xhtml:span class="hljs-keyword">isset</xhtml:span>(<xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;map[$path])) {
            <xhtml:span class="hljs-keyword">return</xhtml:span> $delegate-&gt;process($request);
        }

        $method = $request-&gt;getMethod();
        <xhtml:span class="hljs-keyword">if</xhtml:span> (in_array($method, <xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;alwaysAllowed, <xhtml:span class="hljs-keyword">true</xhtml:span>)) {
            <xhtml:span class="hljs-comment">// Always allowed</xhtml:span>
            <xhtml:span class="hljs-keyword">return</xhtml:span> $delegate-&gt;process($request);
        }

        <xhtml:span class="hljs-keyword">if</xhtml:span> (in_array($method, <xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;map[$path], <xhtml:span class="hljs-keyword">true</xhtml:span>)) {
            <xhtml:span class="hljs-comment">// In map; proceed</xhtml:span>
            <xhtml:span class="hljs-keyword">return</xhtml:span> $delegate-&gt;process($request);
        }

        <xhtml:span class="hljs-comment">// Not allowed!</xhtml:span>
        <xhtml:span class="hljs-keyword">return</xhtml:span> <xhtml:span class="hljs-keyword">new</xhtml:span> EmptyResponse(StatusCode::STATUS_METHOD_NOT_ALLOWED, [
            <xhtml:span class="hljs-string">'Allow'</xhtml:span> =&gt; implode(<xhtml:span class="hljs-string">','</xhtml:span>, <xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;map[$path]);
        ]);
    }
}
</xhtml:code></xhtml:pre>
<xhtml:p>The things to notice in the above are:</xhtml:p>
<xhtml:ul>
<xhtml:li>
<xhtml:p><xhtml:code>$alwaysAllowed</xhtml:code> uses the
<xhtml:code>RequestMethodInterface</xhtml:code> constants in order to provide a
list of always allowed HTTP methods; it doesn't use strings, which
are prone to typos.</xhtml:p>
</xhtml:li>
<xhtml:li>
<xhtml:p>When a dis-allowed method is encountered, we use a
<xhtml:code>StatusCodeInterface</xhtml:code> constant to provide the status.
This allows us to use code completion, but also signify the
<xhtml:em>intent</xhtml:em> of the code. Integer values are great, but unless
you have all the status codes memorized, it's often easy to forget
what they <xhtml:em>mean</xhtml:em>.</xhtml:p>
</xhtml:li>
</xhtml:ul>
<xhtml:p>The other thing to notice is that I alias the interfaces to
shorter names. We require interfaces to have the
<xhtml:code>Interface</xhtml:code> suffix in FIG, but in situations like these,
I don't particularly care that the constants are defined in an
<xhtml:em>interface</xhtml:em>; I just want to consume them. This is one of the
reasons PHP supports aliasing.</xhtml:p>
<xhtml:p>If you're not already using this package, and use PSR-7
middleware, I highly recommend checking the package out!</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2017-01-26-http-message-util.html">PSR-7
Request and Method Utilities</xhtml:a> was originally published
<xhtml:time class="dt-published" datetime="2017-01-26T13:50:00-06:00">26
January 2017</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by <xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew Weier
O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Automating PHPUnit with Node]]></title>
    <published>2016-10-24T15:25:00-05:00</published>
    <updated>2016-10-24T15:25:00-05:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2016-10-24-watch-phpunit-with-node.html"/>
    <id>https://mwop.net/blog/2016-10-24-watch-phpunit-with-node.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>I've been trying to automate everything this year. When working
on OSS, this is usually as simple as setting up <xhtml:a href="https://www.travis-ci.org">Travis CI</xhtml:a>; in <xhtml:a href="/blog/2015-12-14-secure-phar-automation.html">some cases</xhtml:a>,
<xhtml:a href="/blog/2016-01-29-automating-gh-pages.html">even that</xhtml:a>
becomes <xhtml:a href="/blog/2016-06-30-aws-codedeploy.html">a little
more involved</xhtml:a>, but remains possible.</xhtml:p>
<xhtml:p>But that's <xhtml:em>continuous integration</xhtml:em>. What about
<xhtml:em>continuous development</xhtml:em>?</xhtml:p>
<xhtml:h2>Continuous development?</xhtml:h2>
<xhtml:p>With continous integration, every time I push to a branch
associated with a pull request or on the origin repository, a build
is triggered. Which is great, because I can verify and validate
that my code runs fine on all the target platforms. But I have to
wait for the build to trigger and then run.</xhtml:p>
<xhtml:p>Ideally, I should also be testing locally; I likely don't want
to push anything upstream that will fail! So, I look in the
contributing guidelines, and determine how to run coding standards
checks and unit tests, and do those manually.</xhtml:p>
<xhtml:p>Manually? Ugh. Too easy to forget, and too easy to lose track
and make a ton of changes between runs, making breakage easier.</xhtml:p>
<xhtml:p>I'd like to <xhtml:em>automate</xhtml:em> running these as part of my
development process. I want <xhtml:em>continuous development</xhtml:em>
cycles.</xhtml:p>
<xhtml:h2>Preparing your project</xhtml:h2>
<xhtml:p>The first step is preparing your project. I like to run my tests
and CS checks using <xhtml:a href="https://getcomposer.org">Composer</xhtml:a>,
as that allows me to change what I'm using later, but also allows
me to standardize invocation of the tools. I define the following
<xhtml:em>scripts</xhtml:em> in my <xhtml:code>composer.json</xhtml:code>:</xhtml:p>
<xhtml:pre><xhtml:code class="language-json hljs json" data-lang="json"><xhtml:span class="hljs-string">"scripts"</xhtml:span>: {
  <xhtml:span class="hljs-attr">"check"</xhtml:span>: [
    <xhtml:span class="hljs-string">"@cs-check"</xhtml:span>,
    <xhtml:span class="hljs-string">"@test"</xhtml:span>
  ],
  <xhtml:span class="hljs-attr">"cs-check"</xhtml:span>: <xhtml:span class="hljs-string">"phpcs --colors"</xhtml:span>,
  <xhtml:span class="hljs-attr">"cs-fix"</xhtml:span>: <xhtml:span class="hljs-string">"phpcbf --colors"</xhtml:span>,
  <xhtml:span class="hljs-attr">"test"</xhtml:span>: <xhtml:span class="hljs-string">"phpunit --colors=always"</xhtml:span>
}
</xhtml:code></xhtml:pre>
<xhtml:p>You may, of course, need to alter these to use the tools
specific to your own project. The main thing is that you have a
"check" target, which runs all the various QA tools.</xhtml:p>
<xhtml:p>You don't <xhtml:em>need</xhtml:em> to do this. But I definitely recommend
it. If you can simplify invocation for your users, and for your
<xhtml:em>tools</xhtml:em>, automation is far easier.</xhtml:p>
<xhtml:h2>Using gulp</xhtml:h2>
<xhtml:p><xhtml:a href="https://nodejs.org/">Node</xhtml:a> has some great tools for
watching the filesystem and reacting to it. Two of these are
considered "build" or "workflow" tools: <xhtml:a href="http://gruntjs.com">Grunt</xhtml:a> and <xhtml:a href="http://gulpjs.com">Gulp</xhtml:a>.</xhtml:p>
<xhtml:p>I've opted for Gulp here, as the setup is far simpler; that
said, it's not difficult to do in Grunt, either.</xhtml:p>
<xhtml:p>First, you'll need <xhtml:a href="https://www.npmjs.com/">npm</xhtml:a>,
which usually comes packaged with node, or <xhtml:a href="https://yarnpkg.com/">yarn</xhtml:a>, a more recent addition to the node
ecosystem. Once you have these, you can continue.</xhtml:p>
<xhtml:p>Second, I installed a few dependencies:</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:code>gulp</xhtml:code> is the actual taskrunner. It needs to be
installed both <xhtml:em>globally</xhtml:em>, and <xhtml:em>locally</xhtml:em>. It includes
the functionality for watching the filesystem.</xhtml:li>
<xhtml:li><xhtml:code>gulp-shell</xhtml:code> provides the ability to execute
arbitrary command line tools.</xhtml:li>
<xhtml:li><xhtml:code>gulp-notify</xhtml:code> ties into your system's notifications
abilities.</xhtml:li>
</xhtml:ul>
<xhtml:p>Navigate to your project directory, and install these as
follows:</xhtml:p>
<xhtml:pre><xhtml:code class="language-bash hljs bash" data-lang="bash">$ npm install -g gulp <xhtml:span class="hljs-comment"># this may require sudo, depending on your system</xhtml:span>
$ npm install --dev gulp gulp-shell gulp-notify
</xhtml:code></xhtml:pre>
<xhtml:p>If you are using yarn:</xhtml:p>
<xhtml:pre><xhtml:code class="language-bash hljs bash" data-lang="bash">$ yarn global add gulp <xhtml:span class="hljs-comment"># this may require sudo, depending on your system</xhtml:span>
$ yarn add --dev gulp gulp-shell gulp-notify
</xhtml:code></xhtml:pre>
<xhtml:p>Third, create the following <xhtml:code>gulpfile.js</xhtml:code> in your
project:</xhtml:p>
<xhtml:pre><xhtml:code class="language-javascript hljs javascript" data-lang="javascript"><xhtml:span class="hljs-comment">/* jshint: node: true */</xhtml:span>
<xhtml:span class="hljs-keyword">var</xhtml:span> gulp = <xhtml:span class="hljs-built_in">require</xhtml:span>(<xhtml:span class="hljs-string">'gulp'</xhtml:span>);
<xhtml:span class="hljs-keyword">var</xhtml:span> notify = <xhtml:span class="hljs-built_in">require</xhtml:span>(<xhtml:span class="hljs-string">'gulp-notify'</xhtml:span>);
<xhtml:span class="hljs-keyword">var</xhtml:span> shell = <xhtml:span class="hljs-built_in">require</xhtml:span>(<xhtml:span class="hljs-string">'gulp-shell'</xhtml:span>);
<xhtml:span class="hljs-keyword">var</xhtml:span> project = <xhtml:span class="hljs-built_in">require</xhtml:span>(<xhtml:span class="hljs-string">'path'</xhtml:span>).posix.basename(__dirname);

gulp.task(<xhtml:span class="hljs-string">'default'</xhtml:span>, [<xhtml:span class="hljs-string">'watch'</xhtml:span>]);
gulp.task(<xhtml:span class="hljs-string">'php_check'</xhtml:span>, <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> () </xhtml:span>{
  gulp.src(<xhtml:span class="hljs-string">''</xhtml:span>)
    .pipe(shell(<xhtml:span class="hljs-string">'composer check'</xhtml:span>))
    .on(<xhtml:span class="hljs-string">'error'</xhtml:span>, notify.onError({
      <xhtml:span class="hljs-attr">title</xhtml:span>: project + <xhtml:span class="hljs-string">' failures'</xhtml:span>,
      <xhtml:span class="hljs-attr">message</xhtml:span>: project + <xhtml:span class="hljs-string">' CS checks and/or tests failed'</xhtml:span>
    }));
});
gulp.task(<xhtml:span class="hljs-string">'watch'</xhtml:span>, <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> () </xhtml:span>{
  gulp.watch(
    [<xhtml:span class="hljs-string">'phpunit.xml.dist'</xhtml:span>, <xhtml:span class="hljs-string">'phpcs.xml'</xhtml:span>, <xhtml:span class="hljs-string">'src/**/*.php'</xhtml:span>, <xhtml:span class="hljs-string">'test/**/*.php'</xhtml:span>],
    [<xhtml:span class="hljs-string">'php_check'</xhtml:span>]
  );
});
</xhtml:code></xhtml:pre>
<xhtml:p>What the above does is:</xhtml:p>
<xhtml:ul>
<xhtml:li>Watch the filesystem for changes to any of:
<xhtml:ul>
<xhtml:li><xhtml:code>phpunit.xml.dist</xhtml:code>, which would indicate a change to
the test runner behavior.</xhtml:li>
<xhtml:li><xhtml:code>phpcs.xml</xhtml:code>, which would indicate a change to the
coding standards.</xhtml:li>
<xhtml:li>PHP files found in either the <xhtml:code>src/</xhtml:code> or
<xhtml:code>test/</xhtml:code> directories.</xhtml:li>
</xhtml:ul>
</xhtml:li>
<xhtml:li>On changes, run <xhtml:code>composer check</xhtml:code>.</xhtml:li>
<xhtml:li>On errors running <xhtml:code>composer check</xhtml:code>, create a system
notification.</xhtml:li>
</xhtml:ul>
<xhtml:h3>Using the gulp automation</xhtml:h3>
<xhtml:p>Once you've done the above, run the following within your
project directory:</xhtml:p>
<xhtml:pre><xhtml:code class="language-bash hljs bash" data-lang="bash">$ gulp
</xhtml:code></xhtml:pre>
<xhtml:p>This will spawn a process that watches the filesystem; any time
you save a change to any of the files listed, it will run
<xhtml:code>composer check</xhtml:code>, which in turn runs your CS checks and
unit tests. If either of these processes fails, it spawns a system
notification, which will draw your attention to the fact that
you've just done something wrong. (If no errors occur, no
notification is created.)</xhtml:p>
<xhtml:p>What this means is that I can spawn the process in a terminal
that I hide, and then start editing in my favorite editor or IDE,
and get notifications immediately when I break something.</xhtml:p>
<xhtml:h2>Making it reusable with node</xhtml:h2>
<xhtml:p>The above is nice, but do you <xhtml:em>really</xhtml:em> want to add this
to every project? While it's a useful utility, different projects
run things differently, and some may or may not be amenable to
adding tooling just to support specific development workflows.</xhtml:p>
<xhtml:p>So, I decided to take this a step further, and see if I could
automate for the more generic use case. The result is an npm
package, <xhtml:a href="https://www.npmjs.com/package/phly-php-qa-watch">phly-php-qa-watch</xhtml:a>,
which ships with the binary <xhtml:code>php-qa-watch</xhtml:code>.</xhtml:p>
<xhtml:p>Install it as follows:</xhtml:p>
<xhtml:pre><xhtml:code class="language-bash hljs bash" data-lang="bash">$ npm install phly-php-qa-watch -g  <xhtml:span class="hljs-comment"># via npm; may require sudo</xhtml:span>
$ yarn global add phly-php-qa-watch <xhtml:span class="hljs-comment"># via yarn; may require sudo</xhtml:span>
</xhtml:code></xhtml:pre>
<xhtml:p>Once installed, you can run it in your project:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php">$ php-qa-watch
</xhtml:code></xhtml:pre>
<xhtml:p>If you need to specify an alternate checker, or a different list
of files, flags will provide this:</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:code>-c|--check-command</xhtml:code> allows you to specify an
alternate check command to use; it defaults to
<xhtml:code>composer-check</xhtml:code>.</xhtml:li>
<xhtml:li><xhtml:code>-w|--watch-files</xhtml:code> allows you to specify a
comma-separated list of files, directories, and globs to watch. It
defaults to
<xhtml:code>phpunit.xml.dist,phpcs.xml,src/**/*.php,test/**/*.php</xhtml:code>.</xhtml:li>
</xhtml:ul>
<xhtml:p>So, as an example, I could run:</xhtml:p>
<xhtml:pre><xhtml:code class="language-bash hljs bash" data-lang="bash">$ php-qa-watch \
&gt; -c <xhtml:span class="hljs-string">"./vendor/bin/php-cs-fixer fix --dry-run &amp;&amp; ./vendor/bin/phpunit"</xhtml:span> \
&gt; -w <xhtml:span class="hljs-string">".php_cs,phpunit.xml.dist,phpunit.xml,lib/**/*.php,tests/**/*.php"</xhtml:span>
</xhtml:code></xhtml:pre>
<xhtml:p>The above would run the locally installed
<xhtml:code>php-cs-fixer</xhtml:code> in dry-run mode and phpunit. Further, it
would re-run if the <xhtml:code>php-cs-fixer</xhtml:code> configuration
changes, the local or project PHPUnit configuration changes, or if
PHP files in either the <xhtml:code>lib/</xhtml:code> or <xhtml:code>tests/</xhtml:code>
directories change.</xhtml:p>
<xhtml:p>This finally hits the sweet-spot for me with automation: it's
literally the least effort I can muster in any given repository in
order to automate my testing tools.</xhtml:p>
<xhtml:h2>Automate all the things</xhtml:h2>
<xhtml:p>It's terribly easy to get complacent and lazy when developing,
particularly on open source where you may be investing your off
hours, and want to economize your activity. This can lead to having
patches rejected, or frustration at only discovering a completely
avoidable build error days later, as you left your console
immediately after issuing a pull request. For these reasons, I try
and automate whenever possible, not just for continuous
integration, but for my own development workflow.</xhtml:p>
<xhtml:blockquote>
<xhtml:h3>Note</xhtml:h3>
<xhtml:p>This post is derived from a talk I prepared recently on quality
PHP packages, and details one facet of the "automation" section. I
plan to blog on the topics covered, and release related tools, in
the coming weeks.</xhtml:p>
</xhtml:blockquote>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2016-10-24-watch-phpunit-with-node.html">Automating
PHPUnit with Node</xhtml:a> was originally published <xhtml:time class="dt-published" datetime="2016-10-24T15:25:00-05:00">24 October
2016</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by
<xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew
Weier O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Using Composer to Autoload ZF Modules]]></title>
    <published>2016-08-17T12:15:00-05:00</published>
    <updated>2016-08-17T12:15:00-05:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2016-08-17-zf-composer-autoloading.html"/>
    <id>https://mwop.net/blog/2016-08-17-zf-composer-autoloading.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>One aspect of <xhtml:a href="https://framework.zend.com/blog/2016-06-28-zend-framework-3.html">Zend
Framework 3</xhtml:a>, we paid particular focus on was leveraging the
<xhtml:a href="https://getcomposer.org">Composer</xhtml:a> ecosystem. We now
provide a number of Composer plugins for handling things such as
initial project installation, registering installed modules with
the application, and more. It's the "more" I particularly want to
talk about.</xhtml:p>
<xhtml:h2>Registering modules on install</xhtml:h2>
<xhtml:p>With ZF2, we were able to realize the ability to install
third-party modules into existing applications, enabling a module
ecosystem. The standard mantra for install has been:</xhtml:p>
<xhtml:ol>
<xhtml:li>Install module: <xhtml:code>composer require some/module</xhtml:code></xhtml:li>
<xhtml:li>Register module with application: edit
<xhtml:code>config/(application|modules).config.php</xhtml:code> and add
<xhtml:code>Some\Module</xhtml:code> to the list of modules.</xhtml:li>
</xhtml:ol>
<xhtml:p>This second item has been problematic:</xhtml:p>
<xhtml:ul>
<xhtml:li>Easy to forget</xhtml:li>
<xhtml:li>Easy to introduce a typo</xhtml:li>
</xhtml:ul>
<xhtml:p>For the v3 release, we wanted to solve this if we could. We were
able to do so via a Composer plugin, <xhtml:a href="https://docs.zendframework.com/zend-component-installer">zend-component-installer</xhtml:a>.</xhtml:p>
<xhtml:p>Module authors may add some metadata to their package now, like
the following:</xhtml:p>
<xhtml:pre><xhtml:code class="language-json hljs json" data-lang="json"><xhtml:span class="hljs-string">"extra"</xhtml:span>: {
  <xhtml:span class="hljs-attr">"zf"</xhtml:span>: {
    <xhtml:span class="hljs-attr">"module"</xhtml:span>: <xhtml:span class="hljs-string">"Some\\Module"</xhtml:span>
  }
}
</xhtml:code></xhtml:pre>
<xhtml:p>and, if the plugin is present in the user's application, on
installation, it will register the package as a module with the
application! (Moreover, if you later remove the package, it will
remove it!)</xhtml:p>
<xhtml:p>We also added rules to allow specifying a package as a
component; in this case, the module is added to the <xhtml:em>top</xhtml:em> of
the module list, to ensure that userland modules can override its
settings.</xhtml:p>
<xhtml:p>This ability to make a common task turn-key via Composer makes
me happy.</xhtml:p>
<xhtml:h2>Autoloading your own modules via Composer</xhtml:h2>
<xhtml:p>Recently, while working on Apigility, a collaborator made a
suggestion: "We recommend using Composer for autoloading, and yet
Apigility creates modules that use the default module autoloading
capabilities; couldn't we create a utility for enabling Composer
autoloading of a generated module?"</xhtml:p>
<xhtml:p>This turned out to be really easy to accomplish, and we ended up
creating a new package, <xhtml:a href="https://apigility.org/documentation/modules/zf-composer-autoloading">
zfcampus/zf-composer-autoloading</xhtml:a>, to make it re-usable.</xhtml:p>
<xhtml:p>Let's say you've created a new module in your ZF or Apigility
application, named <xhtml:code>Blog</xhtml:code>. Chances are, you put a
<xhtml:code>Module.php</xhtml:code> file at the module's root, and it either
contains a <xhtml:code>Blog\Module</xhtml:code> class, or requires a classfile
from your source tree that will. Let's setup autoloading:</xhtml:p>
<xhtml:pre><xhtml:code class="language-bash hljs bash" data-lang="bash">$ composer require --dev zfcampus/zf-composer-autoloading
$ ./vendor/bin/<xhtml:span class="hljs-built_in">autoload</xhtml:span>-module-via-composer Blog
</xhtml:code></xhtml:pre>
<xhtml:p>Done.</xhtml:p>
<xhtml:p>The package ships with only a vendor binary, and that does the
following:</xhtml:p>
<xhtml:ul>
<xhtml:li>Adds an entry in your <xhtml:code>composer.json</xhtml:code> to autoload
the module.</xhtml:li>
<xhtml:li>Regenerates the Composer autoloading rules.</xhtml:li>
</xhtml:ul>
<xhtml:p>It will autodetect the module type (PSR-0 or PSR-4) based on the
detected directory structure, but also allows you to specify the
type via a CLI flag. You can also tell it where your Composer
binary is, if it's not on your path.</xhtml:p>
<xhtml:p>Once you're done, if you defined a
<xhtml:code>getAutoloaderConfig()</xhtml:code> method in your module, you can
now remove it, as it's redundant!</xhtml:p>
<xhtml:p>This tool will work with existing ZF2 and Apigility installs, of
any version.</xhtml:p>
<xhtml:p>Composer all the things!</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2016-08-17-zf-composer-autoloading.html">Using
Composer to Autoload ZF Modules</xhtml:a> was originally published
<xhtml:time class="dt-published" datetime="2016-08-17T12:15:00-05:00">17
August 2016</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by <xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew Weier
O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
</feed>
