<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
  <channel>
    <title>Blog entries tagged programming :: mwop.net</title>
    <description>Blog entries tagged programming :: mwop.net</description>
    <pubDate>Thu, 24 Jan 2019 11:30:00 -0600</pubDate>
    <generator>Laminas_Feed_Writer 2 (https://getlaminas.org)</generator>
    <link>https://mwop.net/blog/tag/programming</link>
    <atom:link rel="self" type="application/rss+xml" href="https://mwop.net/blog/tag/programming/rss.xml"/>
    <item>
      <title>Registering Module-Specific Routes in Expressive</title>
      <pubDate>Thu, 24 Jan 2019 11:30:00 -0600</pubDate>
      <link>https://mwop.net/blog/2019-01-24-expressive-routes.html</link>
      <guid>https://mwop.net/blog/2019-01-24-expressive-routes.html</guid>
      <author>contact@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>In <a href="https://getexpressive.org">Expressive</a>, we have standardized on a file named
<code>config/routes.php</code> to contain all your route registrations. A typical file
might look something like this:</p>
<pre><code class="language-php hljs php" data-lang="php"><span class="hljs-keyword">declare</span>(strict_types=<span class="hljs-number">1</span>);

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

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

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

    $app-&gt;get(
        <span class="hljs-string">'/blog[/]'</span>,
        App\Blog\Handler\LandingPageHandler::class,
        <span class="hljs-string">'blog'</span>
    );
    $app-&gt;get(<span class="hljs-string">'/blog/{id:[^/]+\.html'</span>, [
        SessionMiddleware::class,
        CsrfMiddleware::class,
        App\Blog\Handler\BlogPostHandler::class,
    ], <span class="hljs-string">'blog.post'</span>);
    $app-&gt;post(<span class="hljs-string">'/blog/comment/{id:[^/]+\.html'</span>, [
        SessionMiddleware::class,
        CsrfMiddleware::class,
        App\Blog\Handler\ProcessBlogCommentHandler::class,
    ], <span class="hljs-string">'blog.comment'</span>);
}
</code></pre>
<p>and so on.</p>
<p>These files can get <em>really</em> long, and organizing them becomes imperative.</p>


<h2>Using Delegator Factories</h2>
<p>One way we have recommended to make these files simpler is to use <a href="https://docs.zendframework.com/zend-expressive/v3/features/container/delegator-factories/">delegator
factories</a>
registered with the <code>Zend\Expressive\Application</code> class to add routes. That
looks something like this:</p>
<pre><code class="language-php hljs php" data-lang="php"><span class="hljs-keyword">namespace</span> <span class="hljs-title">App</span>\<span class="hljs-title">Blog</span>;

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

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

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

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

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

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

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

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

<span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(
    \Zend\Expressive\Application $app,
    \Zend\Expressive\MiddlewareFactory $factory,
    \Psr\Container\ContainerInterface $container
)</span> : <span class="hljs-title">void</span> </span>{
    (<span class="hljs-keyword">new</span> \App\Blog\ConfigProvider())-&gt;registerRoutes($app);
}
</code></pre>
<p>This approach eliminates the problems of using delegator factories:</p>
<ul>
<li>There's a clear indication that a given class method registers routes.</li>
<li>I can then look directly at that method to determine what they are.</li>
</ul>
<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.</p>
<p>What strategies have you tried?</p>


<div class="h-entry">
    <img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&u=79dd2ea1d4d8855944715d09ee4c86215027fa80&s=140" alt="matthew">
    <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</a> was originally
    published <time class="dt-published" datetime="2019-01-24T11:30:00-06:00">24 January 2019</time>
    on <a href="https://mwop.net">https://mwop.net</a> by
    <a rel="author" class="p-author" href="https://mwop.net">Matthew Weier O&#039;Phinney</a>.
</div>
]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>Creating Exception types on-the-fly in modern PHP</title>
      <pubDate>Wed, 05 Dec 2018 16:26:00 -0600</pubDate>
      <link>https://mwop.net/blog/2018-12-05-on-the-fly-exceptions.html</link>
      <guid>https://mwop.net/blog/2018-12-05-on-the-fly-exceptions.html</guid>
      <author>contact@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<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:</p>
<ul>
<li>We would create a marker <code>ExceptionInterface</code> for each package.</li>
<li>We would extend <a href="http://php.net/manual/en/spl.exceptions.php">SPL exceptions</a>
and implement the package marker interface when doing so.</li>
</ul>
<p>What this gave users was the ability to catch in three ways:</p>
<ul>
<li>They could catch the most specific exception type by class name.</li>
<li>They could catch all package-level exceptions using the marker interface.</li>
<li>The could catch general exceptions using the associated SPL type.</li>
</ul>


<p>So, as an example:</p>
<pre><code class="language-php hljs php" data-lang="php"><span class="hljs-keyword">try</span> {
    $do-&gt;something();
} <span class="hljs-keyword">catch</span> (MostSpecificException $e) {
} <span class="hljs-keyword">catch</span> (PackageLevelExceptionInterface $e) {
} <span class="hljs-keyword">catch</span> (\RuntimeException $e) {
}
</code></pre>
<p>This kind of granularity is really nice to work with. So nice that some
standards produced by <a href="https://www.php-fig.org/">PHP-FIG</a> now ship them, such as
<a href="https://www.php-fig.org/psr/psr-11/">PSR-11</a>, which ships a
<code>ContainerExceptionInterface</code> and a <code>NotFoundExceptionInterface</code>.</p>
<blockquote>
<p>One thing we've started doing recently as we make packages support only PHP 7
versions is to have the marker <code>ExceptionInterface</code> extend the <code>Throwable</code>
interface; this ensures that implementations <strong>must</strong> be able to be thrown!</p>
</blockquote>
<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?</p>
<p>Why, use an anonymous class, of course!</p>
<p>As an example, I was writing up some documentation that illustrated a custom
<code>ContainerInterface</code> implementation today, and realized I needed to throw an
exception at one point, specifically a <code>Psr\Container\NotFoundExceptionInterface</code>.
I wrote up the following snippet:</p>
<pre><code class="language-php hljs php" data-lang="php">$message = sprintf(<span class="hljs-comment">/* ... */</span>);
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-class"><span class="hljs-keyword">class</span>($<span class="hljs-title">message</span>) <span class="hljs-keyword">extends</span> <span class="hljs-title">RuntimeException</span> <span class="hljs-keyword">implements</span>
    <span class="hljs-title">NotFoundExceptionInterface</span> </span>{
};
</code></pre>
<p>Done!</p>
<p>This works because <code>RuntimeException</code> takes a message as the first
constructor argument; by extending that class, I gain that behavior. Since
<code>NotFoundExceptionInterface</code> is a marker interface, I did not need to add any
additional behavior, so this inline example works out-of-the-box.</p>
<p>What else are <em>you</em> using anonymous classes for?</p>


<div class="h-entry">
    <img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&u=79dd2ea1d4d8855944715d09ee4c86215027fa80&s=140" alt="matthew">
    <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</a> was originally
    published <time class="dt-published" datetime="2018-12-05T16:26:00-06:00">5 December 2018</time>
    on <a href="https://mwop.net">https://mwop.net</a> by
    <a rel="author" class="p-author" href="https://mwop.net">Matthew Weier O&#039;Phinney</a>.
</div>
]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>The Future of Zend Framework</title>
      <pubDate>Thu, 18 Oct 2018 13:20:00 -0500</pubDate>
      <link>https://mwop.net/blog/2018-10-17-long-live-zf.html</link>
      <guid>https://mwop.net/blog/2018-10-17-long-live-zf.html</guid>
      <author>contact@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>For the past thirteen years, I've been either consuming <a href="https://framework.zend.com">Zend Framework</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
<a href="https://apigility.org">Apigility</a> to the ZF ecosystem, and helped bring
middleware paradigms to the mainstream by assisting with the creation of
Stratigility and coordination of the <a href="https://getexpressive.org">Expressive</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!</p>


<p>In the last three years, I have performed this work under the umbrella of
<a href="https://www.roguewave.com">Rogue Wave Software</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 <a href="https://www.zimuel.it">Enrico Zimuel</a> will be leaving the company
and looking for new opportunities in the not-too-distant future, along with
<a href="https://zsuraski.blogspot.com">Zeev Suraski</a> and Dmitry Stogov.</p>
<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
<a href="mailto:matthew@weierophinney.net">matthew@weierophinney.net</a> with questions or
queries.</p>


<div class="h-entry">
    <img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&u=79dd2ea1d4d8855944715d09ee4c86215027fa80&s=140" alt="matthew">
    <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</a> was originally
    published <time class="dt-published" datetime="2018-10-17T11:30:00-05:00">17 October 2018</time>
    on <a href="https://mwop.net">https://mwop.net</a> by
    <a rel="author" class="p-author" href="https://mwop.net">Matthew Weier O&#039;Phinney</a>.
</div>
]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>Async Expressive with Swoole</title>
      <pubDate>Wed, 17 Oct 2018 08:30:00 -0500</pubDate>
      <link>https://mwop.net/blog/2018-10-16-swoole.html</link>
      <guid>https://mwop.net/blog/2018-10-16-swoole.html</guid>
      <author>contact@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>Have you used <a href="https://nodejs.org/">Node.js</a>?</p>
<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.</p>
<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 <a href="https://www.swoole.co.uk">Swoole</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!</p>
<p>We've been gradually adding and refining our <a href="https://docs.zendframework.com/zend-expressive-swoole/">Swoole support</a>
in <a href="https://docs.zendframework.com/zend-expressive/">Expressive</a>, and recently
issued a stable release that will work with any <a href="https://www.php-fig.org/psr/psr-15">PSR-15</a>
request handler. In this post, I'll enumerate what I feel are the reasons for
considering Swoole when deploying your PHP middleware application.</p>


<p>I feel there are three key advantages to Swoole, and, by extension, any async
PHP runtime:</p>
<ul>
<li>Application-specific servers</li>
<li>Performance</li>
<li>Async processing</li>
</ul>
<h2>Application-specific servers</h2>
<p>There are a few general architectures for applications:</p>
<ul>
<li>A single web server sitting in front of many web applications.</li>
<li>A single web server sitting in front of a single web application.</li>
<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.)</li>
</ul>
<p><img src="https://uploads.mwop.net/nginx-php-many.png" alt="nginx serving many PHP sites" /></p>
<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.</p>
<p>When you want to isolate the environment, you'll move to a single web server,
single PHP application model:</p>
<p><img src="https://uploads.mwop.net/nginx-php-single.png" alt="nginx serving a single PHP site" /></p>
<p>And when you start scaling, this becomes a load balancer sitting in front of
many of these web server/PHP application pairs:</p>
<p><img src="https://uploads.mwop.net/load-balancer-nginx-php.png" alt="A load balancer in front of many nginx+php sites" /></p>
<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.</p>
<blockquote>
<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.</p>
</blockquote>
<p>In these scenarios, this means each &quot;server&quot; 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.</p>
<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.</p>
<p>What Swoole lets us do is remove one layer of that complexity.</p>
<p><img src="https://uploads.mwop.net/load-balancer-php.png" alt="A load balancer in front of php servers" /></p>
<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.</p>
<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 &quot;web server&quot; becomes a reverse proxy instead.</p>
<p>Application-specific servers allow us to simplify our deployment, and ship
microservices quickly.</p>
<h2>Performance</h2>
<p>Remember when PHP 7 came out, and it was like doubling the performance of your
application?</p>
<p>What if you could do that again?</p>
<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!</p>
<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!</p>
<blockquote>
<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.</p>
</blockquote>
<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.</p>
<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.</p>
<h2>Async processing</h2>
<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.</p>
<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:</p>
<pre><code class="language-php hljs php" data-lang="php"><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handle</span><span class="hljs-params">(ServerRequestInterface $request)</span> : <span class="hljs-title">ResponseInterface</span>
</span>{
    $ts = <span class="hljs-keyword">new</span> DateTimeImmutable();
    \Swoole\Event::defer(<span class="hljs-keyword">$this</span>-&gt;createCacheDeferment($ts));
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> EmptyResponse(<span class="hljs-number">202</span>);
}

<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createCacheDeferment</span><span class="hljs-params">(DateTimeImmutable $ts)</span> : <span class="hljs-title">callable</span>
</span>{
    <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> <span class="hljs-title">use</span> <span class="hljs-params">($ts)</span> </span>{
        sleep(<span class="hljs-number">5</span>);
        $now = <span class="hljs-keyword">new</span> DateTimeImmutable();
        $item = <span class="hljs-keyword">$this</span>-&gt;cache-&gt;getItem(<span class="hljs-string">'ts'</span>);
        $item-&gt;set(sprintf(
            <span class="hljs-string">"Started: %s\nEnded: %s"</span>,
            $ts-&gt;format(<span class="hljs-string">'r'</span>),
            $now-&gt;format(<span class="hljs-string">'r'</span>)
        ));
        <span class="hljs-keyword">$this</span>-&gt;cache-&gt;save($item);
    };
}
</code></pre>
<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.</p>
<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.</p>
<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.</p>
<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:</p>
<pre><code class="language-php hljs php" data-lang="php"><span class="hljs-keyword">use</span> <span class="hljs-title">Swoole</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Client</span> <span class="hljs-title">as</span> <span class="hljs-title">HttpClient</span>;

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

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

<span class="hljs-comment">// This code executes before the request completes:</span>
$counter++;
</code></pre>
<p>Code like the above has led to the term &quot;callback hell&quot; when you have many such
deferments that depend on each other.  So, what do you do if you want your
code to be &quot;non-blocking&quot;, 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.</p>
<pre><code class="language-php hljs php" data-lang="php"><span class="hljs-comment">// This spawns a coroutine:</span>
$statement = $pdo-&gt;query($sql);
</code></pre>
<p>Async functionality may not directly improve the performance of your
application, but it <strong>will</strong> let your application answer more requests, allowing
you to handle greater volumes of traffic!</p>
<h2>zend-expressive-swoole</h2>
<p>We released <a href="https://docs.zendframework.com/zend-expressive-swoole/">zendframework/zend-expressive-swoole 1.0.0</a>
two weeks ago. This library acts as a zend-httphandlerrunner
<code>RequestHandlerRunner</code> implementation, which means:</p>
<ul>
<li>It can be used with any PSR-15 application.</li>
<li>It can be used with any PSR-7 implementation.</li>
</ul>
<p>In other words, if you want to use Swoole with the upcoming Slim 4 or with
<a href="https://github.com/equip/dispatch">equip/dispatch</a> or with
<a href="https://github.com/northwoods/broker">northwoods/broker</a> or any of the myriad
PSR-15 dispatch systems out there, you can.</p>
<p>The library provides some interesting features for users:</p>
<ul>
<li>Serving of static resources, with HTTP client-side caching headers.</li>
<li>Configurable logging.</li>
<li>Abiility to restart worker processes.</li>
</ul>
<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!</p>
<h2>Fin</h2>
<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 <a href="https://twitter.com/mwop">tweeting at
me</a>, and I'll add it to the <a href="https://tinyletter.com/mwopzend">ZF newsletter</a>.</p>
<h3>Updates</h3>
<ul>
<li>2018-10-17: Fixed typo in first sentence.</li>
</ul>


<div class="h-entry">
    <img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&u=79dd2ea1d4d8855944715d09ee4c86215027fa80&s=140" alt="matthew">
    <a class="u-url u-uid p-name" href="https://mwop.net/blog/2018-10-16-swoole.html">Async Expressive with Swoole</a> was originally
    published <time class="dt-published" datetime="2018-10-16T16:00:00-05:00">16 October 2018</time>
    on <a href="https://mwop.net">https://mwop.net</a> by
    <a rel="author" class="p-author" href="https://mwop.net">Matthew Weier O&#039;Phinney</a>.
</div>
]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>Notes on GraphQL</title>
      <pubDate>Wed, 19 Sep 2018 08:10:00 -0500</pubDate>
      <link>https://mwop.net/blog/2018-07-18-graphql.html</link>
      <guid>https://mwop.net/blog/2018-07-18-graphql.html</guid>
      <author>contact@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>The last week has been my first foray into GraphQL, using the <a href="https://developer.github.com/v4/">GitHub GraphQL
API</a> endpoints. I now have Opinions<sup>TM</sup>.</p>
<p>The promise is fantastic: query for everything you need, but nothing more. Get
it all in one go.</p>
<p>But the reality is somewhat... different.</p>


<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 <code>array_column()</code>,
<code>array_map()</code>, and <code>array_reduce()</code> operations on the returned data to get a
structure I can actually use.</p>
<p>The final data I needed looked like this:</p>
<pre><code class="language-javascript hljs javascript" data-lang="javascript">[
  {
    <span class="hljs-string">"name"</span>: <span class="hljs-string">"zendframework/zend-expressive"</span>,
    <span class="hljs-string">"tags"</span>: [
      {
        <span class="hljs-string">"name"</span>: <span class="hljs-string">"3.0.2"</span>,
        <span class="hljs-string">"date"</span>: <span class="hljs-string">"2018-04-10"</span>
      }
    ]
  }
]
</code></pre>
<p>To fetch it, I needed a query like the following:</p>
<pre><code class="language-javascript hljs javascript" data-lang="javascript">query showOrganizationInfo(
  $organization:<span class="hljs-built_in">String</span>!
  $cursor:<span class="hljs-built_in">String</span>!
) {
  organization(login:$organization) {
    repositories(first: <span class="hljs-number">100</span>, <span class="hljs-attr">after</span>: $cursor) {
      pageInfo {
        startCursor
        hasNextPage
        endCursor
      }
      nodes {
        nameWithOwner
        <span class="hljs-attr">tags</span>:refs(refPrefix: <span class="hljs-string">"refs/tags/"</span>, <span class="hljs-attr">first</span>: <span class="hljs-number">100</span>, <span class="hljs-attr">orderBy</span>:{<span class="hljs-attr">field</span>:TAG_COMMIT_DATE, <span class="hljs-attr">direction</span>:DESC}) {
          edges {
            <span class="hljs-attr">tag</span>: node {
              name
              target {
                ... on Commit {
                  pushedDate
                }
                ... on Tag {
                  tagger {
                    date
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
</code></pre>
<p>Which gave me data like the following:</p>
<pre><code class="language-javascript hljs javascript" data-lang="javascript">{
  <span class="hljs-string">"data"</span>: {
    <span class="hljs-string">"organization"</span>: {
      <span class="hljs-string">"repositories: {
        "</span>pageInfo<span class="hljs-string">": {
          "</span>startCursor<span class="hljs-string">": "</span>...<span class="hljs-string">",
          "</span>hasNextPage<span class="hljs-string">": true,
          "</span>endCursor<span class="hljs-string">": "</span>...<span class="hljs-string">"
        },
        "</span>nodes<span class="hljs-string">": [
          {
            "</span>nameWithOwner<span class="hljs-string">": "</span>zendframework/zend-expressive<span class="hljs-string">",
            "</span>tags<span class="hljs-string">": {
              "</span>edges<span class="hljs-string">": [
                "</span>tag<span class="hljs-string">": {
                  "</span>name<span class="hljs-string">": "</span><span class="hljs-number">3.0</span><span class="hljs-number">.2</span><span class="hljs-string">",
                  "</span>target<span class="hljs-string">": {
                    "</span>tagger<span class="hljs-string">": {
                      "</span>date<span class="hljs-string">": "</span><span class="hljs-number">2018</span><span class="hljs-number">-04</span><span class="hljs-number">-10</span><span class="hljs-string">"
                    }
                  }
                }
              ]
            }
          }
        ]
      }
    }
  }
}
</span></code></pre>
<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 &quot;nodes&quot; and &quot;edges&quot; bits were, or why they were necessary. (I eventually
found the information, but it's still rather opaque as an end-user.)</p>
<p>Additionally, see that <code>pageInfo</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 &quot;after&quot; 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.</p>
<blockquote>
<p>I get why clients cannot unfurl pagination, as pagination data could appear
<em>anywhere</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.</p>
</blockquote>
<p>If any items further down the tree <em>also</em> require pagination, you're in for some
real headaches, as you then have to fetch paginated sets depth-first.</p>
<p>So, while GraphQL promises fewer round trips and exactly the data you need, my
experience so far is:</p>
<ul>
<li>
<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.</p>
</li>
<li>
<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.</p>
</li>
</ul>
<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.</p>
<blockquote>
<p>Before anybody suggests it, yes, I am <em>very</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 <code>author</code> or the <code>committer</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.</p>
<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
<em>consumers</em> are needing comes in handy, instead of simply mandating <em>graphql
all the things</em> to allow infinite flexibility (and the frustrations of such
flexibility, both for the API developer and consumer).</p>
</blockquote>
<h3>Updates</h3>
<ul>
<li>2018-09-19: syntax highlighting fixes.</li>
</ul>


<div class="h-entry">
    <img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&u=79dd2ea1d4d8855944715d09ee4c86215027fa80&s=140" alt="matthew">
    <a class="u-url u-uid p-name" href="https://mwop.net/blog/2018-07-18-graphql.html">Notes on GraphQL</a> was originally
    published <time class="dt-published" datetime="2018-07-18T17:05:00-05:00">18 July 2018</time>
    on <a href="https://mwop.net">https://mwop.net</a> by
    <a rel="author" class="p-author" href="https://mwop.net">Matthew Weier O&#039;Phinney</a>.
</div>
]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>PSR-15</title>
      <pubDate>Tue, 23 Jan 2018 14:05:00 -0600</pubDate>
      <link>https://mwop.net/blog/2018-01-23-psr-15.html</link>
      <guid>https://mwop.net/blog/2018-01-23-psr-15.html</guid>
      <author>contact@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>Yesterday, following a unanimous vote from its Core Committee,
<a href="http://www.php-fig.org/">PHP-FIG</a> formally accepted the proposed
<a href="https://github.com/php-fig/fig-standards/tree/master/accepted/PSR-15-request-handlers.md">PSR-15, HTTP Server Handlers</a>
standard.</p>
<p>This new standard defines interfaces for <em>request handlers</em> and <em>middleware</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!</p>


<blockquote>
<h3>Caveat</h3>
<p>I acted as sponsor on PSR-15, and as final arbiter of changes during the review
period.</p>
</blockquote>
<h2>Background</h2>
<p>PSR-15 was started by <a href="http://shadowhand.me">Woody Gilk</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:</p>
<pre><code class="language-php hljs php" data-lang="php"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(
    ServerRequestInterface $request,
    ResponseInterface $response,
    callable $next
)</span> : <span class="hljs-title">ResponseInterface</span>
</span></code></pre>
<p>where <code>$next</code> should implement the following signature:</p>
<pre><code class="language-php hljs php" data-lang="php"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(
    ServerRequestInterface $request,
    ResponseInterface $response
)</span> : <span class="hljs-title">ResponseInterface</span>
</span></code></pre>
<blockquote>
<h3>&quot;Double Pass&quot;</h3>
<p>The above pattern has been dubbed &quot;double pass&quot; middleware, for the fact that
it passes <em>two</em> instances to the collaborator to <em>pass</em> to the next layer.</p>
</blockquote>
<p>However, a number of critiques of this existing practice started to arise almost
immediately, with <a href="https://blog.ircmaxell.com/2016/05/all-about-middleware.html">one from Anthony Ferrara</a>
holding particular weight. The primary problems noted were:</p>
<ul>
<li>
<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.</p>
</li>
<li>
<p>Typehinting <code>$next</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.</p>
</li>
</ul>
<p>After debate within the working group, the next iteration proposed the
following (some details differ, but basic interactions are the same):</p>
<pre><code class="language-php hljs php" data-lang="php"><span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">DelegateInterface</span>
</span>{
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">process</span><span class="hljs-params">(ServerRequestInterface $request)</span> : <span class="hljs-title">ResponseInterface</span></span>;
}

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

<span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">MiddlewareInterface</span>
</span>{
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">process</span><span class="hljs-params">(
        ServerRequestInterface $request,
        RequestHandlerInterface $handler
    )</span> : <span class="hljs-title">ResponseInterface</span></span>;
}
</code></pre>
<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.</p>
<p>As a result, we made the change to ship the two interfaces <em>as separate
packages</em>, with the package containing the <code>MiddlewareInterface</code> depending on
the package defining the <code>RequestHandlerInterface</code>.</p>
<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.</p>
<p>While work on the specification was in progress, each iteration of the
interfaces was published within the github organization
<a href="https://github.com/http-interop">http-interop</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 <code>Interop\Http</code> as the top-level namespace. Members of
the working group, as well as other interested parties, would pin their
offerings to specific iterations.</p>
<p>The final packages are now owned by the PHP-FIG group, however, and use the
<code>Psr</code> top-level namespace.</p>
<h2>The Interfaces</h2>
<p>That brings us to the final standard:</p>
<ul>
<li><a href="https://github.com/php-fig/fig-standards/tree/master/accepted/PSR-15-request-handlers.md">PSR-15</a></li>
<li><a href="https://github.com/php-fig/fig-standards/tree/master/accepted/PSR-15-request-handlers-meta.md">PSR-15 Meta Document</a>
(which covers the <em>whys</em> behind the specification)</li>
</ul>
<p><a href="https://github.com/php-fig/http-server-handler">psr/http-server-handler</a>
provides the following interface:</p>
<pre><code class="language-php hljs php" data-lang="php"><span class="hljs-keyword">namespace</span> <span class="hljs-title">Psr</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Server</span>;

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

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

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

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

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

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

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

        <span class="hljs-keyword">return</span> $response-&gt;withHeader(<span class="hljs-string">'X-Origin'</span>, $origin);
    }
}
</code></pre>
<p>A few things to note about this middleware:</p>
<ul>
<li>
<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.</p>
</li>
<li>
<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.</p>
</li>
<li>
<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
<code>process()</code> is called.</p>
</li>
</ul>
<p>How might I consume such middleware?</p>
<p>In <a href="https://docs.zendframework.com/zend-expressive/">Expressive</a>), I might do
any one of the following:</p>
<pre><code class="language-php hljs php" data-lang="php"><span class="hljs-comment">// Pipe it as a service to pull from the DI container:</span>
$app-&gt;pipe(CheckOriginMiddleware::class);

<span class="hljs-comment">// Use it within a route-specific pipeline:</span>
$app-&gt;post(<span class="hljs-string">'/api/foo'</span>, [
    CheckOriginMiddleware::class,
    FooMiddleware::class,
]);
</code></pre>
<p>In <a href="https://github.com/northwoods/broker">northwoods/broker</a> (maintained by
Woody Gilk, the PSR-15 editor), it looks like this:</p>
<pre><code class="language-php hljs php" data-lang="php">$broker-&gt;always([CheckOriginMiddleware::class]);
</code></pre>
<p>In <a href="https://github.com/middlewares/utils">middlewares/utils Dispatcher</a>, you'd
do this:</p>
<pre><code class="language-php hljs php" data-lang="php">$dispatcher = <span class="hljs-keyword">new</span> Dispatcher([
    <span class="hljs-comment">/* ... */</span>
    <span class="hljs-keyword">new</span> CheckOriginMiddleware($acceptedOrigins, $responsePrototype),
    <span class="hljs-comment">/* ... */</span>
]);
</code></pre>
<p>With any one of these solutions, if your middleware is executed, it will act
exactly the same; <em>how</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
<code>process()</code>.</p>
<h2>What about request handlers?</h2>
<p>Most of the libraries I've looked at at this time define handlers in one of two
ways:</p>
<ul>
<li>
<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:</p>
</li>
<li>
<p>As a &quot;final&quot; handler to pass to the middleware dispatcher. In other words, if
the last middleware processed <em>also</em> calls on its handler, this &quot;fallback&quot; or
&quot;final&quot; handler will be what's invoked. This will typically return a 404
response or a 500 response, depending on the implementation.</p>
</li>
</ul>
<p>One other possibility that's been floated by several is for use with <em>routing
middleware</em>. In this case, when routing middleware matches a request, it would
then call on a request handler mapped to that request.</p>
<h2>Notes for implementors</h2>
<p>PSR-15 is accepted; let's make all the things PSR-15!</p>
<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.</p>
<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 <a href="https://github.com/slimphp/Slim/pull/2379">also has a patch submitted with PSR-15 support</a>,
which would likely not drop until an upcoming 4.0 release.</p>
<p>As such, have patience with library and framework maintainers, and help test
releases for them.</p>
<p>Additionally, consider tracking and testing the <a href="https://github.com/php-fig/fig-standards/tree/de189e864044ce726f7e75b7d17ac98ea049f45c/proposed/http-factory">proposed PSR-17
specification</a>.
This proposal will standardize PSR-7 <em>factories</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 <em>body</em>, which is
a <code>Psr\Http\Message\StreamInterface</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 <em>stream</em> prototype. What if you could compose
a single factory instead?</p>
<h2>Closing thoughts</h2>
<p>When I started work on PSR-7 originally, <em>it was because I wanted a standard
middleware interface for PHP</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:</p>
<ul>
<li>
<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:</p>
</li>
<li>
<p>Built-in HTTP message abstractions in the Node core library.</p>
</li>
</ul>
<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!).</p>
<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.</p>


<div class="h-entry">
    <img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&u=79dd2ea1d4d8855944715d09ee4c86215027fa80&s=140" alt="matthew">
    <a class="u-url u-uid p-name" href="https://mwop.net/blog/2018-01-23-psr-15.html">PSR-15</a> was originally
    published <time class="dt-published" datetime="2018-01-23T14:05:00-06:00">23 January 2018</time>
    on <a href="https://mwop.net">https://mwop.net</a> by
    <a rel="author" class="p-author" href="https://mwop.net">Matthew Weier O&#039;Phinney</a>.
</div>
]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>Using Anonymous Classes to Write Middleware</title>
      <pubDate>Thu, 30 Mar 2017 13:20:00 -0500</pubDate>
      <link>https://mwop.net/blog/2017-03-30-anonymous-class-middleware.html</link>
      <guid>https://mwop.net/blog/2017-03-30-anonymous-class-middleware.html</guid>
      <author>contact@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<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?</p>
<p>Convention-based approaches usually allow for
<a href="https://en.wikipedia.org/wiki/Duck_typing">duck-typing</a>; with middleware, it
means you can write <a href="http://php.net/language.types.callable">PHP callables</a>
— usually <a href="http://php.net/closure">closures</a> — and just expect them
to work.</p>
<p>Contract-based approaches use <em>interfaces</em>. I think you can see where this is
going.</p>


<h2>PSR-7 Middleware</h2>
<p>When <a href="http://www.php-fig.org/psr/psr-7/">PSR-7</a> was introduced, a number of
middleware microframeworks adopted a common signature for middleware:</p>
<pre><code class="language-php hljs php" data-lang="php"><span class="hljs-keyword">use</span> <span class="hljs-title">Psr</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Message</span>\<span class="hljs-title">ResponseInterface</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Psr</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Message</span>\<span class="hljs-title">ServerRequestInterface</span>;

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

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

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

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

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

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

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

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

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

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

$pipeline-&gt;pipe(<span class="hljs-keyword">new</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">MiddlewareInterface</span> </span>{
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">process</span><span class="hljs-params">(ServerRequestInterface $request, DelegateInterface $delegate)</span>
    </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> TextResponse(<span class="hljs-string">'Hello world!'</span>);
    }
});
</code></pre>
<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
<em>type-safety</em>. Our middleware runner no longer has to <em>assume</em> that any
middleware piped to it is correctly defined, but can instead <em>know</em>, as it can
enforce a typehint.</p>
<p>The approach is also useful to IDEs, which can now properly typehint arguments,
and let us know when the contract is being violated.</p>
<h2>What about closures?</h2>
<p>A <em>closure</em> in PHP allows you to <em>close over</em> or <em>bind</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:</p>
<pre><code class="language-php hljs php" data-lang="php"><span class="hljs-comment">// Where $log is a PSR-3 logger:</span>
<span class="hljs-keyword">use</span> <span class="hljs-title">Zend</span>\<span class="hljs-title">Diactoros</span>\<span class="hljs-title">Response</span>\<span class="hljs-title">EmptyResponse</span>;

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

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

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

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

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

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

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

        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> EmptyResponse(<span class="hljs-number">500</span>);
    }
});
</code></pre>
<p>This approach gives you added type-safety: if <code>$log</code> is of a different type,
you'll know when that middleware is created, as PHP will raise a fatal error.</p>
<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.</p>
<p>So, don't let the PSR-15 interfaces stop you! Start using anonymous classes for
your own middleware prototypes!</p>


<div class="h-entry">
    <img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&u=79dd2ea1d4d8855944715d09ee4c86215027fa80&s=140" alt="matthew">
    <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</a> was originally
    published <time class="dt-published" datetime="2017-03-30T13:20:00-05:00">30 March 2017</time>
    on <a href="https://mwop.net">https://mwop.net</a> by
    <a rel="author" class="p-author" href="https://mwop.net">Matthew Weier O&#039;Phinney</a>.
</div>
]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>PSR-7 Request and Method Utilities</title>
      <pubDate>Thu, 26 Jan 2017 13:50:00 -0600</pubDate>
      <link>https://mwop.net/blog/2017-01-26-http-message-util.html</link>
      <guid>https://mwop.net/blog/2017-01-26-http-message-util.html</guid>
      <author>contact@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>We all know the standard HTTP request methods and status codes, right? Or do we?</p>
<p>We definitely know whether or not they should be integers or strings, and/or how
string values should be normalized, right?</p>
<p>And our IDEs can <em>totally</em> autocomplete them, right?</p>
<p>Oh, that's not the case?</p>


<p>Some time ago, a few folks floated the idea of creating a utility repository
related to the <a href="http://www.php-fig.org/psr/psr-7/">PSR-7</a>
<a href="https://github.com/php-fig/http-message">psr/http-message</a> package, but
containing some useful bits such as constants for HTTP request methods and
status codes.</p>
<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.</p>
<p>The package is <a href="https://github.com/php-fig/http-message-util">fig/http-message-util</a>,
and is available via Composer and Packagist:</p>
<pre><code class="language-bash hljs bash" data-lang="bash">$ composer require fig/http-message-util
</code></pre>
<p>It provides two interfaces:</p>
<ul>
<li><code>Fig\Http\Message\RequestMethodInterface</code>, containing constants for HTTP
request method values.</li>
<li><code>Fig\Http\Message\StatusCodeInterface</code>, containing constants for HTTP status
code values.</li>
</ul>
<p>The constants are prefixed with <code>METHOD_</code> and <code>STATUS_</code>, respectively, and use
the standard names as presented in the various IETF specifications that
originally define them.</p>
<p>As an example, I could write middleware that looks like this:</p>
<pre><code class="language-php hljs php" data-lang="php"><span class="hljs-keyword">use</span> <span class="hljs-title">Fig</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Message</span>\<span class="hljs-title">RequestMethodInterface</span> <span class="hljs-title">as</span> <span class="hljs-title">RequestMethod</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Fig</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Message</span>\<span class="hljs-title">StatusCodeInterface</span> <span class="hljs-title">as</span> <span class="hljs-title">StatusCode</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Interop</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">ServerMiddleware</span>\<span class="hljs-title">DelegateInterface</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Interop</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">ServerMiddleware</span>\<span class="hljs-title">MiddlewareInterface</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Psr</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Message</span>\<span class="hljs-title">ServerRequestInterface</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Zend</span>\<span class="hljs-title">Diactoros</span>\<span class="hljs-title">EmptyResponse</span>;

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

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

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

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

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

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

        <span class="hljs-comment">// Not allowed!</span>
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> EmptyResponse(StatusCode::STATUS_METHOD_NOT_ALLOWED, [
            <span class="hljs-string">'Allow'</span> =&gt; implode(<span class="hljs-string">','</span>, <span class="hljs-keyword">$this</span>-&gt;map[$path]);
        ]);
    }
}
</code></pre>
<p>The things to notice in the above are:</p>
<ul>
<li>
<p><code>$alwaysAllowed</code> uses the <code>RequestMethodInterface</code> constants in order to
provide a list of always allowed HTTP methods; it doesn't use strings, which
are prone to typos.</p>
</li>
<li>
<p>When a dis-allowed method is encountered, we use a <code>StatusCodeInterface</code>
constant to provide the status. This allows us to use code completion,
but also signify the <em>intent</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 <em>mean</em>.</p>
</li>
</ul>
<p>The other thing to notice is that I alias the interfaces to shorter names.
We require interfaces to have the <code>Interface</code> suffix in FIG, but in situations
like these, I don't particularly care that the constants are defined in an
<em>interface</em>; I just want to consume them. This is one of the reasons PHP
supports aliasing.</p>
<p>If you're not already using this package, and use PSR-7 middleware, I highly
recommend checking the package out!</p>


<div class="h-entry">
    <img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&u=79dd2ea1d4d8855944715d09ee4c86215027fa80&s=140" alt="matthew">
    <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</a> was originally
    published <time class="dt-published" datetime="2017-01-26T13:50:00-06:00">26 January 2017</time>
    on <a href="https://mwop.net">https://mwop.net</a> by
    <a rel="author" class="p-author" href="https://mwop.net">Matthew Weier O&#039;Phinney</a>.
</div>
]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>Automating PHPUnit with Node</title>
      <pubDate>Mon, 24 Oct 2016 15:25:00 -0500</pubDate>
      <link>https://mwop.net/blog/2016-10-24-watch-phpunit-with-node.html</link>
      <guid>https://mwop.net/blog/2016-10-24-watch-phpunit-with-node.html</guid>
      <author>contact@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>I've been trying to automate everything this year. When working on OSS, this is
usually as simple as setting up <a href="https://www.travis-ci.org">Travis CI</a>; in
<a href="/blog/2015-12-14-secure-phar-automation.html">some cases</a>,
<a href="/blog/2016-01-29-automating-gh-pages.html">even that</a> becomes
<a href="/blog/2016-06-30-aws-codedeploy.html">a little more involved</a>, but remains
possible.</p>
<p>But that's <em>continuous integration</em>. What about <em>continuous development</em>?</p>


<h2>Continuous development?</h2>
<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.</p>
<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.</p>
<p>Manually? Ugh. Too easy to forget, and too easy to lose track and make a ton of
changes between runs, making breakage easier.</p>
<p>I'd like to <em>automate</em> running these as part of my development process. I want
<em>continuous development</em> cycles.</p>
<h2>Preparing your project</h2>
<p>The first step is preparing your project. I like to run my tests and CS checks
using <a href="https://getcomposer.org">Composer</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 <em>scripts</em> in my <code>composer.json</code>:</p>
<pre><code class="language-json hljs json" data-lang="json"><span class="hljs-string">"scripts"</span>: {
  <span class="hljs-attr">"check"</span>: [
    <span class="hljs-string">"@cs-check"</span>,
    <span class="hljs-string">"@test"</span>
  ],
  <span class="hljs-attr">"cs-check"</span>: <span class="hljs-string">"phpcs --colors"</span>,
  <span class="hljs-attr">"cs-fix"</span>: <span class="hljs-string">"phpcbf --colors"</span>,
  <span class="hljs-attr">"test"</span>: <span class="hljs-string">"phpunit --colors=always"</span>
}
</code></pre>
<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 &quot;check&quot; target, which runs all the
various QA tools.</p>
<p>You don't <em>need</em> to do this. But I definitely recommend it. If you can simplify
invocation for your users, and for your <em>tools</em>, automation is far easier.</p>
<h2>Using gulp</h2>
<p><a href="https://nodejs.org/">Node</a> has some great tools for watching the filesystem and
reacting to it. Two of these are considered &quot;build&quot; or &quot;workflow&quot; tools:
<a href="http://gruntjs.com">Grunt</a> and <a href="http://gulpjs.com">Gulp</a>.</p>
<p>I've opted for Gulp here, as the setup is far simpler; that said, it's not
difficult to do in Grunt, either.</p>
<p>First, you'll need <a href="https://www.npmjs.com/">npm</a>, which usually comes packaged
with node, or <a href="https://yarnpkg.com/">yarn</a>, a more recent addition to the node
ecosystem. Once you have these, you can continue.</p>
<p>Second, I installed a few dependencies:</p>
<ul>
<li><code>gulp</code> is the actual taskrunner. It needs to be installed both <em>globally</em>, and
<em>locally</em>. It includes the functionality for watching the filesystem.</li>
<li><code>gulp-shell</code> provides the ability to execute arbitrary command line tools.</li>
<li><code>gulp-notify</code> ties into your system's notifications abilities.</li>
</ul>
<p>Navigate to your project directory, and install these as follows:</p>
<pre><code class="language-bash hljs bash" data-lang="bash">$ npm install -g gulp <span class="hljs-comment"># this may require sudo, depending on your system</span>
$ npm install --dev gulp gulp-shell gulp-notify
</code></pre>
<p>If you are using yarn:</p>
<pre><code class="language-bash hljs bash" data-lang="bash">$ yarn global add gulp <span class="hljs-comment"># this may require sudo, depending on your system</span>
$ yarn add --dev gulp gulp-shell gulp-notify
</code></pre>
<p>Third, create the following <code>gulpfile.js</code> in your project:</p>
<pre><code class="language-javascript hljs javascript" data-lang="javascript"><span class="hljs-comment">/* jshint: node: true */</span>
<span class="hljs-keyword">var</span> gulp = <span class="hljs-built_in">require</span>(<span class="hljs-string">'gulp'</span>);
<span class="hljs-keyword">var</span> notify = <span class="hljs-built_in">require</span>(<span class="hljs-string">'gulp-notify'</span>);
<span class="hljs-keyword">var</span> shell = <span class="hljs-built_in">require</span>(<span class="hljs-string">'gulp-shell'</span>);
<span class="hljs-keyword">var</span> project = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>).posix.basename(__dirname);

gulp.task(<span class="hljs-string">'default'</span>, [<span class="hljs-string">'watch'</span>]);
gulp.task(<span class="hljs-string">'php_check'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  gulp.src(<span class="hljs-string">''</span>)
    .pipe(shell(<span class="hljs-string">'composer check'</span>))
    .on(<span class="hljs-string">'error'</span>, notify.onError({
      <span class="hljs-attr">title</span>: project + <span class="hljs-string">' failures'</span>,
      <span class="hljs-attr">message</span>: project + <span class="hljs-string">' CS checks and/or tests failed'</span>
    }));
});
gulp.task(<span class="hljs-string">'watch'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  gulp.watch(
    [<span class="hljs-string">'phpunit.xml.dist'</span>, <span class="hljs-string">'phpcs.xml'</span>, <span class="hljs-string">'src/**/*.php'</span>, <span class="hljs-string">'test/**/*.php'</span>],
    [<span class="hljs-string">'php_check'</span>]
  );
});
</code></pre>
<p>What the above does is:</p>
<ul>
<li>Watch the filesystem for changes to any of:
<ul>
<li><code>phpunit.xml.dist</code>, which would indicate a change to the test runner behavior.</li>
<li><code>phpcs.xml</code>, which would indicate a change to the coding standards.</li>
<li>PHP files found in either the <code>src/</code> or <code>test/</code> directories.</li>
</ul>
</li>
<li>On changes, run <code>composer check</code>.</li>
<li>On errors running <code>composer check</code>, create a system notification.</li>
</ul>
<h3>Using the gulp automation</h3>
<p>Once you've done the above, run the following within your project directory:</p>
<pre><code class="language-bash hljs bash" data-lang="bash">$ gulp
</code></pre>
<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 <code>composer check</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.)</p>
<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.</p>
<h2>Making it reusable with node</h2>
<p>The above is nice, but do you <em>really</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.</p>
<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,
<a href="https://www.npmjs.com/package/phly-php-qa-watch">phly-php-qa-watch</a>,
which ships with the binary <code>php-qa-watch</code>.</p>
<p>Install it as follows:</p>
<pre><code class="language-bash hljs bash" data-lang="bash">$ npm install phly-php-qa-watch -g  <span class="hljs-comment"># via npm; may require sudo</span>
$ yarn global add phly-php-qa-watch <span class="hljs-comment"># via yarn; may require sudo</span>
</code></pre>
<p>Once installed, you can run it in your project:</p>
<pre><code class="language-php hljs php" data-lang="php">$ php-qa-watch
</code></pre>
<p>If you need to specify an alternate checker, or a different list of files, flags
will provide this:</p>
<ul>
<li><code>-c|--check-command</code> allows you to specify an alternate check command to use;
it defaults to <code>composer-check</code>.</li>
<li><code>-w|--watch-files</code> allows you to specify a comma-separated list of files,
directories, and globs to watch. It defaults to
<code>phpunit.xml.dist,phpcs.xml,src/**/*.php,test/**/*.php</code>.</li>
</ul>
<p>So, as an example, I could run:</p>
<pre><code class="language-bash hljs bash" data-lang="bash">$ php-qa-watch \
&gt; -c <span class="hljs-string">"./vendor/bin/php-cs-fixer fix --dry-run &amp;&amp; ./vendor/bin/phpunit"</span> \
&gt; -w <span class="hljs-string">".php_cs,phpunit.xml.dist,phpunit.xml,lib/**/*.php,tests/**/*.php"</span>
</code></pre>
<p>The above would run the locally installed <code>php-cs-fixer</code> in dry-run mode and
phpunit. Further, it would re-run if the <code>php-cs-fixer</code> configuration changes,
the local or project PHPUnit configuration changes, or if PHP files in either
the <code>lib/</code> or <code>tests/</code> directories change.</p>
<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.</p>
<h2>Automate all the things</h2>
<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.</p>
<blockquote>
<h3>Note</h3>
<p>This post is derived from a talk I prepared recently on quality PHP packages,
and details one facet of the &quot;automation&quot; section. I plan to blog on the
topics covered, and release related tools, in the coming weeks.</p>
</blockquote>


<div class="h-entry">
    <img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&u=79dd2ea1d4d8855944715d09ee4c86215027fa80&s=140" alt="matthew">
    <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</a> was originally
    published <time class="dt-published" datetime="2016-10-24T15:25:00-05:00">24 October 2016</time>
    on <a href="https://mwop.net">https://mwop.net</a> by
    <a rel="author" class="p-author" href="https://mwop.net">Matthew Weier O&#039;Phinney</a>.
</div>
]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>Using Composer to Autoload ZF Modules</title>
      <pubDate>Wed, 17 Aug 2016 12:15:00 -0500</pubDate>
      <link>https://mwop.net/blog/2016-08-17-zf-composer-autoloading.html</link>
      <guid>https://mwop.net/blog/2016-08-17-zf-composer-autoloading.html</guid>
      <author>contact@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>One aspect of <a href="https://framework.zend.com/blog/2016-06-28-zend-framework-3.html">Zend Framework 3</a>,
we paid particular focus on was leveraging the <a href="https://getcomposer.org">Composer</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 &quot;more&quot; I particularly want to talk about.</p>


<h2>Registering modules on install</h2>
<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:</p>
<ol>
<li>Install module: <code>composer require some/module</code></li>
<li>Register module with application: edit <code>config/(application|modules).config.php</code>
and add <code>Some\Module</code> to the list of modules.</li>
</ol>
<p>This second item has been problematic:</p>
<ul>
<li>Easy to forget</li>
<li>Easy to introduce a typo</li>
</ul>
<p>For the v3 release, we wanted to solve this if we could. We were able to do so
via a Composer plugin, <a href="https://docs.zendframework.com/zend-component-installer">zend-component-installer</a>.</p>
<p>Module authors may add some metadata to their package now, like the following:</p>
<pre><code class="language-json hljs json" data-lang="json"><span class="hljs-string">"extra"</span>: {
  <span class="hljs-attr">"zf"</span>: {
    <span class="hljs-attr">"module"</span>: <span class="hljs-string">"Some\\Module"</span>
  }
}
</code></pre>
<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!)</p>
<p>We also added rules to allow specifying a package as a component; in this case,
the module is added to the <em>top</em> of the module list, to ensure that userland
modules can override its settings.</p>
<p>This ability to make a common task turn-key via Composer makes me happy.</p>
<h2>Autoloading your own modules via Composer</h2>
<p>Recently, while working on Apigility, a collaborator made a suggestion: &quot;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?&quot;</p>
<p>This turned out to be really easy to accomplish, and we ended up creating a new
package, <a href="https://apigility.org/documentation/modules/zf-composer-autoloading">zfcampus/zf-composer-autoloading</a>,
to make it re-usable.</p>
<p>Let's say you've created a new module in your ZF or Apigility application, named
<code>Blog</code>. Chances are, you put a <code>Module.php</code> file at the module's root, and it
either contains a <code>Blog\Module</code> class, or requires a classfile from your source
tree that will. Let's setup autoloading:</p>
<pre><code class="language-bash hljs bash" data-lang="bash">$ composer require --dev zfcampus/zf-composer-autoloading
$ ./vendor/bin/<span class="hljs-built_in">autoload</span>-module-via-composer Blog
</code></pre>
<p>Done.</p>
<p>The package ships with only a vendor binary, and that does the following:</p>
<ul>
<li>Adds an entry in your <code>composer.json</code> to autoload the module.</li>
<li>Regenerates the Composer autoloading rules.</li>
</ul>
<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.</p>
<p>Once you're done, if you defined a <code>getAutoloaderConfig()</code> method in your
module, you can now remove it, as it's redundant!</p>
<p>This tool will work with existing ZF2 and Apigility installs, of any version.</p>
<p>Composer all the things!</p>


<div class="h-entry">
    <img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&u=79dd2ea1d4d8855944715d09ee4c86215027fa80&s=140" alt="matthew">
    <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</a> was originally
    published <time class="dt-published" datetime="2016-08-17T12:15:00-05:00">17 August 2016</time>
    on <a href="https://mwop.net">https://mwop.net</a> by
    <a rel="author" class="p-author" href="https://mwop.net">Matthew Weier O&#039;Phinney</a>.
</div>
]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
  </channel>
</rss>
