<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://kevinsmith.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://kevinsmith.io/" rel="alternate" type="text/html" /><updated>2026-04-04T17:53:34+00:00</updated><id>https://kevinsmith.io/feed.xml</id><title type="html">Kevin Smith</title><subtitle>Engineering leader on a mission to help product teams love their job and consistently deliver real customer value.</subtitle><author><name>Kevin Smith</name></author><entry><title type="html">Our Goal Was Never To Write Code</title><link href="https://kevinsmith.io/our-goal-was-never-to-write-code/" rel="alternate" type="text/html" title="Our Goal Was Never To Write Code" /><published>2026-04-04T17:48:25+00:00</published><updated>2026-04-04T17:48:25+00:00</updated><id>https://kevinsmith.io/our-goal-was-never-to-write-code</id><content type="html" xml:base="https://kevinsmith.io/our-goal-was-never-to-write-code/"><![CDATA[<p><em>A memo I sent to the AxisCare product development team <a target="_blank" rel="noopener" href="https://engineering.axiscare.com/blog/our-goal-was-never-to-write-code">earlier this week</a>:</em></p>

<p>It’s now abundantly clear that we’re living through a step change in software development thanks to AI. We’ve been embracing and experimenting with the latest tech for the past several years to varying degrees of success, and you know I’ve been deliberate in my approach. Something massive changed with these models in the last few months, and it warrants a frank discussion.</p>

<p>As the staff engineers showed us a few weeks ago, it’s now finally possible to drive the AI agent and see your intent reliably carried out — even when <a target="_blank" rel="noopener" href="https://www.youtube.com/watch?v=lkKGQVHrXzE">fine-tuning a UI</a> — where even a few months back the agents would clobber your work.</p>

<p>It’s not perfect, but it doesn’t need to be. Remember that <strong>high-quality software is both valuable to the business now and easy to change later</strong>. With the latest models, we can confidently change the software incredibly quickly. And that makes all the difference in the world.</p>

<p>For as long as I can remember, writing code was by far the most critical constraint in making software. It was slow, expensive, and error-prone, and every role in product development worked to minimize that time and expense. Exhaustive requirements gathering, detailed plans covering every edge case, high-fidelity mockups, story points, backlog refinement, the list goes on. The goal was to resolve as much ambiguity as possible upstream, so that when someone finally sat down to code, they were transcribing a decision that had already been made. Everything was structured around the scarcity of coding time.</p>

<p>But our goal was never to write code. That was always a means to an end.</p>

<p>So what happens when writing code takes an order of magnitude less time? Which parts of our process no longer make sense? Which pipe dreams are now cheap to try? How quickly could we get to working software, even an unshippable prototype, and iterate from there? What do we need to have in place to make all that possible?</p>

<p>We’re not building the entire car by hand anymore, as much as we loved doing that. We’re building the factory that makes great cars, with the human in the loop where it requires the human touch. It’s time to reimagine your role in building that factory. (And I’m not just talking to the devs here.)</p>

<p>This isn’t a prediction about what’s coming soon. This is here. AI is already fundamentally changing how we make software, even if the models never improve from where they are today.</p>

<p>If all this is unsettling — if you’ve long taken pride in meticulous PRDs, beautifully designed UI mockups, hand-crafted code — I get it. As Kent Beck said in a <a target="_blank" rel="noopener" href="https://youtu.be/5htJ2ML7BKU?t=649">podcast published a few days ago</a>, we didn’t choose this. We developed skills that were in high demand. Now changes from the outside are disrupting all that, and it’s understandable to feel some grief over it. But even though we had no say in the changing environment, we <em>can</em> choose how we respond.</p>

<p>We can’t see around corners, so we don’t know what the future will hold. The best way to respond to this moment is by stepping up to create that future rather than waiting for it to arrive.</p>

<p>Let’s use the full toolkit. Let’s push the AI far enough to see where it breaks down, and then try that same thing again in 3 months. Let’s throw out the old playbook and reimagine what it takes to ship things that matter, start to finish. Let’s build the factory.</p>

<p>In software product development, we’ve historically specialized in ways that may not make sense going forward. <strong>But there will always be a need for people who deeply understand our customers’ most important problems, solve those problems with high-quality software, and run that software reliably in production.</strong> This is the work that endures.</p>

<p>I’m challenging each and every one of you to step into this moment, regularly question your assumptions about how software is made, and share your wins.</p>

<p>This is a rare opportunity. Let’s embrace it and create the future together.</p>]]></content><author><name>Kevin Smith</name></author><summary type="html"><![CDATA[In software product development, we've historically specialized in ways that may not make sense going forward. But there will always be a need for people who deeply understand our customers' most important problems, solve those problems with high-quality software, and run that software reliably in production. This is the work that endures.]]></summary></entry><entry><title type="html">Thinking Outside the Black Box</title><link href="https://kevinsmith.io/thinking-outside-the-black-box/" rel="alternate" type="text/html" title="Thinking Outside the Black Box" /><published>2026-02-11T02:17:39+00:00</published><updated>2026-02-11T02:17:39+00:00</updated><id>https://kevinsmith.io/thinking-outside-the-black-box</id><content type="html" xml:base="https://kevinsmith.io/thinking-outside-the-black-box/"><![CDATA[<p>A worthwhile thought experiment:</p>

<p>If AI can one day quickly and reliably write new code and edit existing code to produce the intended new behavior of the software system, such that the system itself effectively becomes a black box… there’s a whole slew of things that don’t matter anymore.</p>

<p>Human readability, for instance. And if we’re no longer optimizing code for the human who needs to read, understand, and change it later, what else goes with it? Code review. Design patterns. Modularity. Frameworks. Fights over syntax, or even languages. Who cares what the inside of that black box looks like?</p>

<p>There’s a lot we always assumed was essential complexity of software engineering that was really just the goings on inside that box. And sure, it was the really <em>expensive</em> part of building and running a software product, but that doesn’t mean it was the most valuable. The most valuable parts have always been what happens outside the black box. <a href="/theres-no-reason-to-worry-about-ai/">Time to double down on those skills.</a></p>

<p>Regardless what the future holds, this will always be true: high-quality software is both valuable to the business now and easy to change later.</p>]]></content><author><name>Kevin Smith</name></author><summary type="html"><![CDATA[If AI can one day quickly and reliably write new code and edit existing code to produce the intended new behavior of the software system, such that the system itself effectively becomes a black box… there's a whole slew of things that don't matter anymore.]]></summary></entry><entry><title type="html">There’s No Reason to Worry About AI</title><link href="https://kevinsmith.io/theres-no-reason-to-worry-about-ai/" rel="alternate" type="text/html" title="There’s No Reason to Worry About AI" /><published>2023-10-19T03:11:39+00:00</published><updated>2023-10-19T03:11:39+00:00</updated><id>https://kevinsmith.io/theres-no-reason-to-worry-about-ai</id><content type="html" xml:base="https://kevinsmith.io/theres-no-reason-to-worry-about-ai/"><![CDATA[<p>…if you bring value to a business by thinking critically, uncovering key customer struggles, and creating things to give it major leverage in the marketplace. There will <em>always</em> be a need for innovators, regardless the tools they use to do their work.</p>

<p>If, on the other hand, you’re merely putting puzzle pieces together at the direction of someone else who’s doing the thinking, you’ve got a lot to worry about. AI’s getting pretty good at clicking those pieces together.</p>]]></content><author><name>Kevin Smith</name></author><summary type="html"><![CDATA[Unless...]]></summary></entry><entry><title type="html">How to Produce a Rich Domain Model with Active Record</title><link href="https://kevinsmith.io/how-to-produce-a-rich-domain-model-with-active-record/" rel="alternate" type="text/html" title="How to Produce a Rich Domain Model with Active Record" /><published>2023-10-03T12:25:39+00:00</published><updated>2023-10-03T12:25:39+00:00</updated><id>https://kevinsmith.io/how-to-produce-a-rich-domain-model-with-active-record</id><content type="html" xml:base="https://kevinsmith.io/how-to-produce-a-rich-domain-model-with-active-record/"><![CDATA[<p>You can’t. It’s not possible.</p>

<p>I know that sounds like an outrageous claim given the popularity of the Active Record pattern, but it’s true.</p>

<p>Active Record provides complete access to a database row’s fields through an object’s public properties (or “attributes” of an “Active Record model”, as they’re called in both Ruby on Rails’ and Laravel’s ORMs). Any part of the codebase can access those attributes to read or change any of the data in the database row, making it easy to start working with a real database in your code.</p>

<p>The trouble starts when the complexity of the business inevitably reveals itself and you need to restrict the inherent permissiveness of Active Record to ensure that information is only retrieved or modified according to the rules of the business. In other words, you need a <strong>rich domain model</strong>: a layer of the codebase where the expressiveness of the business is encoded into a community of collaborating objects, each <a target="_blank" rel="noopener" href="https://kevinsmith.io/high-cohesion-loose-coupling/">properly bounded</a> and equipped with the information and behavior they need to <a target="_blank" rel="noopener" href="https://kevinsmith.io/whats-so-great-about-oop/#object-oriented-programming">model the relevant interactions and responsibilities of the business</a>.</p>

<p>Need to make a property private so that only the object has access to it, a fundamental principle of software design called <a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Information_hiding">information hiding</a>? <em>It’s not possible.</em></p>

<p>Need to require multiple pieces of information for an update and validate them before accepting the changes, like making sure you have both longitude and latitude before updating geo-coordinates? <em>Sorry, you can’t enforce that.</em></p>

<p>The best you can do is apply business rules in domain services that wrap the Active Record model, but you can’t actually <em>enforce</em> the rules anywhere.<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup> <strong>This is the critical, inescapable problem with using Active Record in the domain.</strong> Nothing is stopping the rest of the codebase (or worse, third-party packages) from bypassing your constraints to manipulate the data directly. And make no mistake, that will happen. The inevitable outcome is data corruption, inscrutable bugs, and feature development slowing to a crawl as you try to regain stability in your system.</p>

<p>By its very nature, Active Record’s impact on a domain cannot be contained and thus will largely determine the resulting system architecture, despite whatever plans its developers may have at the outset. Given enough time under real-world dynamics, it will lead to a <a target="_blank" rel="noopener" href="https://kevinsmith.io/separation-of-concerns-is-fundamental-to-building-high-quality-software/">big ball of mud that becomes increasingly expensive to maintain</a>.</p>

<p>Now you could try to contain Active Record to the edge of your application, only using it as a conduit between your database and domain objects that properly enforce the necessary constraints. This would keep it out of your domain and go a long way toward avoiding architectural distortion.</p>

<p>But in practice, this tends to be a fool’s errand. The most popular Active Record implementations are clearly not meant to be confined to such a petty task. The documentation for <a target="_blank" rel="noopener" href="https://guides.rubyonrails.org/active_record_basics.html">Rails</a> and <a target="_blank" rel="noopener" href="https://laravel.com/docs/10.x/eloquent">Laravel</a> both assume you’ll be using it in the heart of your system and passing these Active Record models around to use everywhere. All the third-party packages assume the same. So do the creators of these frameworks, as do their developer communities. You’d be swimming against a mighty current, and nothing would prevent the “batteries included” features of these ecosystems from bypassing your domain entirely.</p>

<p>To put it plainly: Active Record fundamentally cannot allow the enforcement of constraints on its objects, leaving you with no option but to apply all your business rules in services and therefore “completely miss the point of what object-oriented design is all about” and “incur all of the costs of a [rich] domain model, without yielding any of the benefits”.</p>

<p>Behold, the <a target="_blank" rel="noopener" href="https://www.martinfowler.com/bliki/AnemicDomainModel.html">anemic domain model</a>.</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p>This includes <a target="_blank" rel="noopener" href="https://laravel.com/docs/10.x/eloquent-mutators#value-object-casting">clever tooling in some Active Record implementations</a> that will allow you to accept value objects to update multiple attributes. Nothing enforces that as the <em>only</em> way to update those attributes. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Kevin Smith</name></author><summary type="html"><![CDATA[You can't. It's not possible. I know that sounds like an outrageous claim given the popularity of the Active Record pattern, but it's true.]]></summary></entry><entry><title type="html">“What’s the deal with Bitcoin?”</title><link href="https://kevinsmith.io/whats-the-deal-with-bitcoin/" rel="alternate" type="text/html" title="“What’s the deal with Bitcoin?”" /><published>2022-11-27T05:07:21+00:00</published><updated>2022-11-27T05:07:21+00:00</updated><id>https://kevinsmith.io/whats-the-deal-with-bitcoin</id><content type="html" xml:base="https://kevinsmith.io/whats-the-deal-with-bitcoin/"><![CDATA[<p>You’re probably here because you’ve asked a Bitcoiner that very question. What follows attempts to answer for the average reader <em>what</em> it is, <em>why</em> it matters, and <em>how</em> you can start using it securely, without getting mixed up in scams or losing your bitcoin by mistake. I’ll keep this guide free of any deep, technical detail, but I’ll provide links to go down the rabbit hole if you want.</p>

<p>First, let me just say this: we’re still in the early days of this new technology. Anyone who was just learning about movable type a decade after Gutenberg invented the printing press hadn’t missed out on the printing revolution. In fact, it took a while to catch on. But it supercharged the Renaissance, enabled the Protestant Reformation, and ushered in the Scientific Revolution and the Enlightenment. Every aspect of our world is changed because of the printing press.</p>

<p>You haven’t missed out on Bitcoin. It’s still early.</p>

<h2 id="what-is-it">What is it?</h2>

<p>Imagine you could use the cash in your pocket to instantly pay for things on the Internet and didn’t need a bank to keep your money safe. That’s Bitcoin.</p>

<p><strong>Bitcoin is peer-to-peer electronic cash.</strong> <em>Peer-to-peer</em> meaning it’s transmitted from person to person without the need for a trusted intermediary like banks or Venmo to process the transaction. <em>Electronic</em> meaning it naturally exists in digital form, so it’s global and can easily be used for online payments. <em>Cash</em> meaning it’s an asset that’s readily available to pay for goods and services without needing anyone else to follow through on their responsibilities—like your bank’s promise to process your debit card transactions.</p>

<p>When someone talks about Bitcoin, they’re referring to one of two things:</p>

<ul>
  <li>Bitcoin (with an uppercase <em>B</em>) is a global network for transferring value between participants that isn’t owned or controlled by anyone, and everyone can be a part of it by running the open source Bitcoin client software.</li>
  <li>bitcoin (with a lowercase <em>b</em>) is a digital asset often represented as BTC, and it’s the way to represent value on that network. This is a concept called the <em>unit of account</em> in economics. The total number of bitcoin available now and in the future is known by everyone and unchangeable by anyone. At most, there will only ever be 21 million bitcoin.</li>
</ul>

<p>Most of the news gets caught up in the price of BTC, but it’s the network that’s revolutionary. BTC is just a necessary part of it, and it wouldn’t be valuable at all without the incredibly well-designed dynamics of the network.</p>

<h2 id="why-does-it-matter-what-problem-does-it-solve">Why does it matter? What problem does it solve?</h2>

<p>It’s critical to human flourishing that money remain free from the influence of those who would manipulate it or control populations with it, even for what they consider noble reasons. History is rife with wretched examples, often to the benefit of the elite and powerful and the ruin of everyone else. This sounds overly pessimistic to those of us in the West, but zoom out a bit and you’ll see that we’re enjoying a rare period of stability.</p>

<ul>
  <li>Ancient Rome debased their currency to fund their insatiable spending, leading to runaway inflation, soaring taxes, and ultimately <a target="_blank" rel="noopener" href="https://money.visualcapitalist.com/currency-and-the-collapse-of-the-roman-empire/">the collapse of the Roman Empire</a>.</li>
  <li>European settlers discovered that <a target="_blank" rel="noopener" href="https://news.yale.edu/2022/09/15/beads-show-european-trade-african-interior-used-indigenous-routes">Africans used glass beads as money</a>, something the Europeans could easily manufacture in mass quantities. They were “able to <a target="_blank" rel="noopener" href="https://www.swanbitcoin.com/what-is-bitcoin/">strip the African conti­nent of its wealth</a> by trading easy-to-produce glass beads for hard-to-produce human slaves” and precious natural resources.</li>
  <li>In 1994, <a target="_blank" rel="noopener" href="https://www.youtube.com/watch?v=zYs-j6Wx-hs">France and the IMF colluded to slash the value of the CFA franc</a>, the French-controlled currency used by more than a dozen African countries. This outrageous devaluation cut Africans’ savings in <strong>half</strong> literally overnight, roiled their economies, and further entrenched French exploitation of their former colonies. (Unbelievable, right? Alex Gladstein has <a target="_blank" rel="noopener" href="https://twitter.com/gladstein/status/1407733271371259906">a great Twitter thread explaining how this happened</a> along with <a target="_blank" rel="noopener" href="https://bitcoinmagazine.com/culture/bitcoin-a-currency-of-decolonization">a thorough essay on the subject</a>.)</li>
  <li>Governments engulfed in a financial crisis—like those in Venezuela, Brazil, Indonesia, Greece, Turkey, China, Taiwan, Argentina, and Russia—often enforce <a target="_blank" rel="noopener" href="https://www.nytimes.com/2019/02/23/opinion/sunday/venezuela-bitcoin-inflation-cryptocurrencies.html">capital controls</a> or <a target="_blank" rel="noopener" href="https://www.washingtonpost.com/world/europe/greece-reportedly-decides-to-close-banks-monday/2015/06/28/071f4ef4-1dab-11e5-a135-935065bc30d0_story.html">block bank withdrawals</a> in a desperate attempt to regain control, forcing destitution on anyone who would leave.</li>
  <li>In many parts of the world, protests often result in bank account suspensions (as we’ve seen in Russia, Nigeria, and Hong Kong) and bans from payment channels (as they’ve done in China). Belarus and Canada both recently seized funds from people who merely <em>donated</em> to support protestors. But <a target="_blank" rel="noopener" href="https://www.youtube.com/watch?v=xLYYh4aPXAM">“no government can turn off Bitcoin if it’s threatened by your ideas.”</a></li>
  <li>Even <a target="_blank" rel="noopener" href="https://reason.com/volokh/2022/10/09/paypal-still-threatens-2500-fines-for-promoting-discriminatory-intolerance-even-if-not-misinformation/">PayPal says it can take your money</a> if it doesn’t like what you have to say.</li>
</ul>

<p>The US dollar is the world’s reserve currency, yet it’s created out of thin air and largely maintains its value thanks to a more than 50-year <a target="_blank" rel="noopener" href="https://bitcoinmagazine.com/culture/the-hidden-costs-of-the-petrodollar">agreement with Saudi Arabia</a> that compels the world to price oil in dollars. (You may have wondered why the US government <a target="_blank" rel="noopener" href="https://www.washingtonpost.com/national-security/2022/11/18/saudi-crown-prince-immunity-khashoggi-murder/?utm_source=twitter&amp;utm_medium=social&amp;utm_campaign=wp_main">always seems to turn a blind eye to outrageous human rights abuse by the Saudis</a>…) Other nations aren’t exactly thrilled with this arrangement, so the dollar’s stability is a costly endeavor. <a target="_blank" rel="noopener" href="https://bitcoinmagazine.com/culture/the-hidden-costs-of-the-petrodollar">How many lives, families, industries, and countries are wasted propping up the petrodollar?</a> (That’s a long essay, so if listening is more your speed, <a target="_blank" rel="noopener" href="https://www.youtube.com/watch?v=_KaeR_2JxNc">here’s a great podcast episode</a> that includes the essay’s author and covers many of the same topics.)</p>

<p>Aside from military might backing up the dollar, the current financial system is <a target="_blank" rel="noopener" href="https://www.coindesk.com/markets/2021/02/08/what-bloomberg-gets-wrong-about-bitcoins-climate-footprint/">a patchwork of inefficient, costly, and politically-vulnerable systems</a> that move money around and settle financial obligations for individuals, corporations, and nation-states. Think Visa transactions, Western Union, ACH, Fedwire, CHIPS, etc. Bitcoin and its <a target="_blank" rel="noopener" href="https://river.com/learn/what-is-the-lightning-network/">Lightning Network</a> layer replace all of this with a faster, more reliable system for a fraction of the cost. One company is now using the Lightning Network to offer <a target="_blank" rel="noopener" href="https://www.coindesk.com/business/2022/04/07/jack-mallers-strike-announces-shopify-integration-for-bitcoin-lightning-payments/">instant payments at Shopify shops and retail stores using NCR point-of-sale systems</a> <em>in the shop’s local currency</em> for pennies compared to Visa’s transaction fees. This is the future.</p>

<p>Bitcoin is open 24/7, censorship-resistant, unstoppable, efficient, borderless, pseudonymous, and egalitarian. No one controls it, and no one gets special treatment.</p>

<p><strong>Bitcoin is revolutionary.</strong> It may not happen immediately, but eventually you won’t be able to ignore it. There will be a gravity to it, an incentive to be a part of it. Those who don’t use it will put themselves at a disadvantage. Over time, the world’s financial systems will all reorient themselves to the new reality ushered in by Bitcoin.</p>

<p>I know that sounds incredible, but that’s what happened with <a target="_blank" rel="noopener" href="https://www.smithsonianmag.com/science-nature/why-fire-makes-us-human-72989884/">fire</a>, <a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Roman_architectural_revolution">concrete</a>, <a target="_blank" rel="noopener" href="https://www.history.com/news/printing-press-renaissance">the printing press</a>, <a target="_blank" rel="noopener" href="https://www.livescience.com/7476-gunpowder-changed-world.html">gunpowder</a>, <a target="_blank" rel="noopener" href="https://www.youtube.com/watch?v=yn9qhQSMCRk">aluminum</a>, <a target="_blank" rel="noopener" href="https://www.popularmechanics.com/technology/a22838/transistor-changed-the-world/">the transistor</a>, and more. At some point, it actually takes <em>more</em> work to ignore the innovation.</p>

<h2 id="how-does-it-work-without-anyone-in-charge">How does it work without anyone in charge?</h2>

<p>In short: rules without a ruler.</p>

<p>Each computer running the Bitcoin client software (called a “node”) in the network checks every new group of transactions (called a “block”) to make sure all participants are following the rules. Each node has the same rules baked into its software. Rules like <em>you can’t spend the same bitcoin multiple times</em> and <em>the person trying to spend this bitcoin has the authority to do so</em>.</p>

<p>No one can change the rules in their favor because none of the other nodes will go along with it. Trying to spend the same bitcoin twice? Everyone else will call shenanigans. All of this happens automatically in software without requiring human involvement.</p>

<p>Note that <em>nodes</em> aren’t the same as <em>miners</em>. You’ve probably heard a lot about miners and never really understood what they were doing. Simply put, miners are specialized, expensive computers that are <a target="_blank" rel="noopener" href="https://river.com/learn/terms/b/block-reward/">paid bitcoin</a> to process transactions. Want to go deep on mining? <a target="_blank" rel="noopener" href="https://www.youtube.com/watch?v=bBC-nXj3Ng4">Here’s a fantastic video on how it actually works</a>, complete with illustrations to make it easy to understand. I highly recommend it.</p>

<p>Nodes, on the other hand, make transaction requests, ensure miners are following the rules, and keep a copy of the entire history of Bitcoin transactions. Anyone can run a node from their home with very inexpensive hardware, like an old computer. Because they’re the ones enforcing the rules, nodes keep the network secure. <a target="_blank" rel="noopener" href="https://river.com/learn/what-is-a-bitcoin-node/">River does a great job explaining nodes</a> if you want to learn more.</p>

<h2 id="but-bitcoins-been-so-volatile-lately">But bitcoin’s been so volatile lately!</h2>

<p>Most Bitcoiners will tell you that we expect bitcoin to go up in value over time, but no one can predict the price in the short term. A few points to keep in mind:</p>

<p>At 13 years old, bitcoin is a relatively new asset on the world stage and one that most people still don’t understand, so it’s helpful to consider bitcoin’s current value in the context of the global economy. At the time of writing, <a target="_blank" rel="noopener" href="https://coinmarketcap.com/currencies/bitcoin/">bitcoin’s market cap</a> (the current price x total number of available bitcoin) is about $317 billion. Relatively speaking, that’s still small. <a target="_blank" rel="noopener" href="https://companiesmarketcap.com/gold/marketcap/">Gold’s market cap</a> is over 36x larger at approximately $11.5 trillion. Even the market cap of a single company, <a target="_blank" rel="noopener" href="https://finance.yahoo.com/quote/AAPL/">Apple</a>, is more than 7x larger than bitcoin at nearly $2.25 trillion. When you jump into a pool, you stir up that body of water far more than when you jump into the ocean. It’s the same thing with buying and selling assets. The more an asset grows in total value, the less any one person’s purchase or sale will move the price. Every asset stabilizes as it grows in value. Bitcoin is no exception, and there’s still a <em>lot</em> of room to grow.</p>

<p>Bitcoin experiences many of the same forces that cause stock market fluctuations because for most people right now, bitcoin is just one of their many investments. They invest heavily during bull markets, and pull back with negative economic news and rising Fed rates. So when you see bitcoin’s price move, take note of <a target="_blank" rel="noopener" href="https://bitcoinmagazine.com/markets/bitcoin-price-correlated-with-financial-markets">what else is happening in the economy</a>.</p>

<p>Bitcoin also suffers a one-two punch from negative public sentiment whenever yet another crypto scam blows up. But people are catching on. <a target="_blank" rel="noopener" href="https://www.nbcnews.com/think/opinion/bitcoin-vs-ftx-crypto-king-sam-bankman-fried-problem-rcna57964">Bitcoin is the innovation</a>; other crypto coins are trading on Bitcoin’s success, and most of them are pump-and-dump scams <a target="_blank" rel="noopener" href="https://youtu.be/PCtEDSeRoTs?t=523">with a coordinated hype machine designed to let the founders and VC investors sell at the top</a> and leave their marks holding the bag. Some are outright Ponzis. The recently disgraced Sam Bankman-Fried <a target="_blank" rel="noopener" href="https://www.youtube.com/watch?v=C6nAxiym9oc">accidentally admitted as much</a> more than 6 months before FTX blew up.</p>

<p>Don’t mess around with those things. Bitcoin is the genuine article.</p>

<h2 id="how-do-i-get-started-how-can-i-keep-my-bitcoin-safe">How do I get started? How can I keep my bitcoin safe?</h2>

<p>You’ve no doubt heard horror stories of people losing their bitcoin through hacks and forgotten passwords.</p>

<p>In the first few years, the most secure way to save bitcoin was using an offline <a target="_blank" rel="noopener" href="https://river.com/learn/bitcoin-wallets/">wallet</a> that was never connected to the Internet and was therefore extremely difficult to hack. Unfortunately, if you lost your keys or forgot your password, there was no way to recover it.</p>

<p>For that reason, many people have felt more comfortable leaving their bitcoin on the crypto exchange where they bought it. Unfortunately, that leaves you vulnerable to <a target="_blank" rel="noopener" href="https://www.investopedia.com/terms/m/mt-gox.asp">hacks</a>, <a target="_blank" rel="noopener" href="https://www.coindesk.com/business/2022/02/04/binance-ceo-cz-warns-of-massive-sms-phishing-scam/">phishing</a>, and the <a target="_blank" rel="noopener" href="https://www.nbcnews.com/think/opinion/bitcoin-vs-ftx-crypto-king-sam-bankman-fried-problem-rcna57964">poor business practices</a> of the people running the service. As I’m sure you’re well aware, there’s been <a target="_blank" rel="noopener" href="https://cointelegraph.com/news/south-korean-prosecutors-accuse-do-kwon-of-manipulating-terra-s-price">lots</a> and <a target="_blank" rel="noopener" href="https://www.cnbc.com/2022/07/19/former-employees-say-issues-plagued-crypto-company-celsius-years-before-bankruptcy.html">lots</a> of news recently about companies that haven’t been trustworthy.</p>

<p><strong>The solution to both problems is self-custody in a <a target="_blank" rel="noopener" href="https://river.com/learn/terms/m/multisig/">multisig wallet</a></strong>, a technology that maximizes security and minimizes failure by requiring multiple keys to unlock the wallet. A typical 2-of-3 multisig wallet requires any 2 of its 3 keys to spend the bitcoin. <a target="_blank" rel="noopener" href="https://www.youtube.com/watch?v=00MekMYvOBE">Like launching missiles from a submarine</a>, there’s no longer a single, precious key that unlocks the wallet. These wallets are much harder to hack <em>and</em> much easier for the rightful owner to recover if they were to accidentally lose one of their keys. You can keep bitcoin in your custody instead of trusting an online service to hold it for you and still be confident that you’re not going to lose it.</p>

<p>How do you set up a self-custody multisig wallet? Thankfully there are services like <a target="_blank" rel="noopener" href="https://unchained.com/vaults/">Unchained Capital</a> and <a target="_blank" rel="noopener" href="https://keys.casa/how-it-works">Casa</a> that can help you set up your own multisig wallet, put an inheritance plan in place, and recover funds if something goes wrong. And importantly, they never have access to your bitcoin. Take a look at both services, and see which one works best for you. Unchained Capital has <a target="_blank" rel="noopener" href="https://unchained.com/concierge/">concierge onboarding</a> to personally walk you through the process, and Casa has a <a target="_blank" rel="noopener" href="https://support.keys.casa/hc/en-us/articles/360044795911-Getting-Started-With-Casa-Gold">handy guide</a> to help you get set up.</p>

<p>To buy bitcoin, use a reputable service like <a target="_blank" rel="noopener" href="https://www.swanbitcoin.com">Swan Bitcoin</a>, <a target="_blank" rel="noopener" href="https://river.com/buy-bitcoin">River</a>, <a target="_blank" rel="noopener" href="https://strike.me">Strike</a>, <a target="_blank" rel="noopener" href="https://unchained.com/trading-desk/">Unchained Capital’s trading desk</a>, or <a target="_blank" rel="noopener" href="https://support.keys.casa/hc/en-us/articles/360046679652-Buying-bitcoin-with-Casa">Casa</a> and move it to your multisig wallet as soon as possible. I do not recommend using a crypto exchange that deals with altcoins, yield farming, or the like, since all too often it means the exchange is at risk of liquidity issues and could <a target="_blank" rel="noopener" href="https://www.reddit.com/r/CryptoCurrency/comments/zap62n/10_crypto_exchanges_have_halted_withdrawals_in/">halt withdrawals at any time</a>.</p>

<p>I also recommend setting up recurring buys to take advantage of <a target="_blank" rel="noopener" href="https://river.com/learn/what-is-dollar-cost-averaging/">dollar cost averaging</a>. I’ve got my automated weekly purchase set up at River since they offer <a target="_blank" rel="noopener" href="https://blog.river.com/announcing-zero-fee-recurring-orders-2/">free recurring orders</a>, and I transfer to my multisig wallet once a month.</p>

<p>These recommendations will get you started, and as you learn and get more familiar with the world of Bitcoin, you’ll find many other ways to get involved.</p>

<h2 id="go-deeper">Go Deeper</h2>

<p><a target="_blank" rel="noopener" href="https://vijayboyapati.medium.com/the-bullish-case-for-bitcoin-6ecc8bdecc1">The Bullish Case for Bitcoin</a> is a deep-dive essay on the origins of money and why bitcoin is so revolutionary.</p>

<p><a target="_blank" rel="noopener" href="https://www.inventingbitcoin.com/">Inventing Bitcoin</a> is an easy, non-technical book that explains Bitcoin’s fundamentals by walking through the problems it solves and explaining how Bitcoin solves them.</p>

<p>River’s <a target="_blank" rel="noopener" href="https://river.com/learn/">Bitcoin Learning Center</a> is a fantastic set of clear definitions and accessible guides to learn about all aspects of Bitcoin and its surrounding ecosystem.</p>

<p><a target="_blank" rel="noopener" href="https://medium.com/@nic__carter/a-most-peaceful-revolution-8b63b64c203e">A most peaceful revolution</a> is a widely lauded essay discussing Bitcoin’s implications for the unquenchable, inexorable state.</p>

<p><a target="_blank" rel="noopener" href="https://bitcoinmagazine.com/culture/bitcoin-adam-back-and-digital-cash">The Quest for Digital Cash</a> is a history of cryptography, prototypes of digital cash, and how Satoshi Nakamoto pulled together all the best ideas so far to ultimately solve the problems preventing full decentralization.</p>

<p>The white paper that announced Bitcoin to the world: <a target="_blank" rel="noopener" href="https://bitcoin.org/bitcoin.pdf">Bitcoin: A Peer-to-Peer Electronic Cash System</a></p>

<p><a target="_blank" rel="noopener" href="https://www.youtube.com/watch?v=HrehEWYj16s">Robert Breedlove on the Lex Fridman Podcast</a> is a discussion of Bitcoin through a philosophical and economic lens, coming at it from first principles. The ultimate “why” without focusing on the engineering. A great listen.</p>

<p><a target="_blank" rel="noopener" href="https://www.youtube.com/watch?v=kSbMU5CbFM0">Alex Gladstein on the Lex Fridman Podcast</a> is a discussion of how Bitcoin subverts authoritarian control and why it’s critical for human rights.</p>

<p>If you’ve heard that Bitcoin mining threatens us with a climate catastrophe, this is required reading: <a target="_blank" rel="noopener" href="https://www.coindesk.com/markets/2021/02/08/what-bloomberg-gets-wrong-about-bitcoins-climate-footprint/">What Bloomberg Gets Wrong About Bitcoin’s Climate Footprint</a></p>

<h2 id="dont-trust-verify">Don’t Trust, Verify</h2>

<p>Above all, remain skeptical, even of everything I’ve told you here. Check it out for yourself. Be especially wary of claims of untold riches. If an opportunity sounds like easy money without work, it’s probably too good to be true.</p>

<hr style="width:40%; text-align:center; margin-top: 42px; margin-bottom: 42px; border: 0; height: 1px; background: #333; background-image: linear-gradient(to right, #ccc, #333, #ccc);" />

<p><strong><em>Updated on Dec 2, 2022:</em></strong> Rewrote the section on multisig wallet services and where to buy bitcoin to provide multiple reputable options for each.</p>]]></content><author><name>Kevin Smith</name></author><category term="Bitcoin" /><summary type="html"><![CDATA[Bitcoin is revolutionary. It may not happen immediately, but eventually you won't be able to ignore it. There will be a gravity to it, an incentive to be a part of it. Those who don’t use it will put themselves at a disadvantage... At some point, it actually takes more work to ignore the innovation.]]></summary></entry><entry><title type="html">High Cohesion, Loose Coupling</title><link href="https://kevinsmith.io/high-cohesion-loose-coupling/" rel="alternate" type="text/html" title="High Cohesion, Loose Coupling" /><published>2021-09-22T03:03:45+00:00</published><updated>2021-09-22T03:03:45+00:00</updated><id>https://kevinsmith.io/high-cohesion-loose-coupling</id><content type="html" xml:base="https://kevinsmith.io/high-cohesion-loose-coupling/"><![CDATA[<p>High-quality software is both valuable to the business now and easy to change later. While it’s simple to be dogmatic at either end of this spectrum, both goals are important to the business in the long run. Aiming for highly cohesive and loosely coupled code is key to finding the balance, but this concept can be tough to understand at first glance. So what does it actually mean?</p>

<p><em>High Cohesion, Loose Coupling</em> characterizes software designed with a keen focus on <em><a href="/separation-of-concerns-is-fundamental-to-building-high-quality-software/">Separation of Concerns</a></em>, the foundation of effective, resilient, malleable, performant, secure, maintainable software.</p>

<p><strong>High Cohesion</strong> describes the internals of a well-bounded module that consists of coupled elements working together to accomplish something, which improves the comprehensibility of the codebase at large. Such a module contains all the decision-making power necessary to do its job.</p>

<p><strong>Loose Coupling</strong> means that with respect to a given change, one module can be changed without requiring a change in other modules.</p>

<p>Coupling inside a module leads to cohesion, while coupling outside a module leads to multiple modules that must be kept in sync to execute a given change, increasing the cost of such changes. It’s <strong>all</strong> about where you draw the boundaries.</p>

<p>It’s worth noting that a <em>module</em> is merely a distinct part of the system that performs some kind of important job and hides its inner workings from the rest of the system, according to David L. Parnas in his
<a target="_blank" rel="noopener" href="https://prl.ccs.neu.edu/img/p-tr-1971.pdf">seminal paper on software modularization</a>.</p>

<p>There are small-scale jobs and large-scale jobs, so this characterization of high-quality code applies equally to the system at every scale, from the smallest function to the entire application and beyond.</p>

<hr style="width:40%; text-align:center; margin-top: 42px; margin-bottom: 42px; border: 0; height: 1px; background: #333; background-image: linear-gradient(to right, #ccc, #333, #ccc);" />

<p><strong><em>Updated on Oct 25, 2023:</em></strong> Inspired by Kent Beck’s <a target="_blank" rel="noopener" href="https://www.youtube.com/watch?v=yBEcq23OgB4">excellent conference talk on software design</a>, I adjusted some of the language for clarity and added a paragraph to highlight the importance of <em>where</em> the boundaries are drawn.</p>]]></content><author><name>Kevin Smith</name></author><summary type="html"><![CDATA[High-quality software is both valuable to the business now and easy to change later. While it’s simple to be dogmatic at either end of this spectrum, both goals are important to the business in the long run. Aiming for highly cohesive and loosely coupled code is key to finding the balance, but this concept can be tough to understand at first glance. So what does it actually mean?]]></summary></entry><entry><title type="html">Separation of Concerns is Fundamental to Building High-Quality Software</title><link href="https://kevinsmith.io/separation-of-concerns-is-fundamental-to-building-high-quality-software/" rel="alternate" type="text/html" title="Separation of Concerns is Fundamental to Building High-Quality Software" /><published>2020-08-18T16:31:00+00:00</published><updated>2020-08-18T16:31:00+00:00</updated><id>https://kevinsmith.io/separation-of-concerns-is-fundamental-to-building-high-quality-software</id><content type="html" xml:base="https://kevinsmith.io/separation-of-concerns-is-fundamental-to-building-high-quality-software/"><![CDATA[<p>There’s something that’s been on my mind a lot lately: the significance of meaningful boundaries. It’s a theme that keeps coming up wherever I look. Not just in software engineering either. The absence of meaningful boundaries means trouble in just about every area of life.</p>

<p>Relationships without healthy boundaries encourage nosy friends and meddling family members, often bringing an endless supply of anxiety along with them.</p>

<p>Poor boundaries with news sources can easily give you a skewed sense of the world.</p>

<p>A business without meaningful boundaries is likely an aimless yet frantic organization where no one knows exactly what’s going on or who’s responsible for it. Everybody is responsible and nobody is responsible, all at the same time. Need to know what’s going on with a particular initiative at the company? You’ll have to ask somebody in every corner of the organization and piece it together yourself.</p>

<p>It’s no different in software engineering. When a piece of software looks like that, we call it a <em>Big Ball of Mud.</em></p>

<blockquote>
  <p>A Big Ball of Mud is a haphazardly structured, sprawling, sloppy, duct-tape-and-baling-wire, spaghetti-code jungle. These systems show unmistakable signs of unregulated growth, and repeated, expedient repair. Information is shared promiscuously among distant elements of the system, often to the point where nearly all the important information becomes global or duplicated.</p>

  <p>– <cite><a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Big_ball_of_mud">Brian Foote and Joseph Yoder</a></cite></p>

  <p>If you’ve been building software for long, you’ve likely had a tour of duty in one of these monstrosities. Every change is another opportunity for failure to ripple throughout the system. You start to seriously question why you ever got into this field.</p>
</blockquote>

<p>A piece of software with boundaries in the <em>wrong</em> place is a whole other kind of pain. The wave of interest in Microservices in the 2010’s brought about a whole generation of what we’ve come to call the Distributed Monolith, a system with “distinct” services that are actually deeply tangled up with each other. You often can’t even make a simple change to the system without updating multiple services and coordinating a simultaneous code release. Every inch of progress is exhausting.</p>

<hr style="width:40%; text-align:center; margin-top: 42px; margin-bottom: 42px; border: 0; height: 1px; background: #333; background-image: linear-gradient(to right, #ccc, #333, #ccc);" />

<p><em>Separation of Concerns</em> isn’t merely some overwrought principle peddled by purists too busy fussing over theoretical rightness to ever actually ship something. (Though without a doubt the purists do enjoy fussing over it.) It is <em>fundamental</em> to building effective, resilient, malleable, performant, secure, maintainable software. In other words, <em>high-quality</em> software.</p>

<p>In software engineering, there’s a pair of factors we must confront to prevent the system’s natural trend toward disorder.</p>

<p><em>Interdependency</em> is the degree to which a part of the system relies on or is relied upon by other parts of the system or other systems, especially in non-obvious ways.</p>

<p><em>Comprehensibility</em> is the degree to which a part of the system can be easily understood for the sake of making accurate changes with predictable results.</p>

<p>These two key factors have an inverse relationship. As interdependency increases, the size of the system that must be accounted for grows and comprehensibility decreases dramatically. And as a result, risk of failure rises exponentially.</p>

<p>Striking the right balance is all about meaningful boundaries. How do you reduce interdependency? Separate the system into distinct parts and make their interactions explicit. That’s the core idea behind <em>Separation of Concerns</em>.</p>

<p>(We’ll dig into <em>how</em> to identify and organize those distinct parts of the system in an upcoming post.)</p>

<p>You can often make tremendous progress in a greenfield project by throwing caution to the wind, but the cost of mixing everything together will inevitably catch up with you. We spend most of our time working within existing code, and once a software system becomes difficult to reason about, every aspect of quality takes a major hit when someone makes a change. To ignore <em>Separation of Concerns</em> is to invite the sclerotic disasters discussed earlier.</p>

<hr style="width:40%; text-align:center; margin-top: 42px; margin-bottom: 42px; border: 0; height: 1px; background: #333; background-image: linear-gradient(to right, #ccc, #333, #ccc);" />

<p>At the end of the day, what does <em>Separation of Concerns</em> mean for the business and the people involved?</p>

<ul>
  <li>Faster feature development because changes don’t require a complete, expansive understanding of the entire system.</li>
  <li>A far better chance of hitting estimate windows because you won’t discover halfway through that your changes are tangled up with and complicated by other parts of the system.</li>
  <li>A much tidier codebase when things need to be removed or refactored, which contributes to future comprehensibility.</li>
  <li>Protection against costly failures since problems in one spot are far less likely to ripple throughout the system. Meaningful boundaries help contain the blast radius when something goes wrong.</li>
  <li>A quicker recovery when things do go wrong because the issues are likely already isolated, and bug fix testing doesn’t need to be comprehensive.</li>
  <li>Less turnover thanks to happier developers who spend their mental fuel on the fun work of shipping new features instead of constantly getting pulled away to troubleshoot and untangle the knots in the system.</li>
  <li>Quicker onboarding, which means new developers are meaningfully contributing in days not months.</li>
</ul>

<p>Sure sounds to me like it’s worth the cost of a being a little more diligent about system design.</p>

<hr style="width:40%; text-align:center; margin-top: 42px; margin-bottom: 42px; border: 0; height: 1px; background: #333; background-image: linear-gradient(to right, #ccc, #333, #ccc);" />

<p>Many thanks to Ryan Singer for the enlightening <em>Synthetic A Priori</em> podcast episode  <a target="_blank" rel="noopener" href="https://pca.st/erp7vhdg">Design as a Multi-Scale Network, Risk as Network Structure</a>  which was instrumental in clarifying my thinking here. If you’re interested in getting into the weeds on the theory behind all of this, I’d highly recommend giving it a listen.</p>]]></content><author><name>Kevin Smith</name></author><summary type="html"><![CDATA[There's something that's been on my mind a lot lately: the significance of meaningful boundaries. It's a theme that keeps coming up wherever I look.]]></summary></entry><entry><title type="html">What the Ã�©Ð”ã° is going on!?</title><link href="https://kevinsmith.io/what-the-is-going-on/" rel="alternate" type="text/html" title="What the Ã�©Ð”ã° is going on!?" /><published>2019-08-17T15:41:20+00:00</published><updated>2019-08-17T15:41:20+00:00</updated><id>https://kevinsmith.io/what-the-is-going-on</id><content type="html" xml:base="https://kevinsmith.io/what-the-is-going-on/"><![CDATA[<style>.embed-container { position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%; } .embed-container iframe, .embed-container object, .embed-container embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }</style>
<div class="embed-container"><iframe src="https://www.youtube-nocookie.com/embed/cIu0_iZMoWI?si=xiVUuZQpnRR9s3Ac" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen=""></iframe></div>
<p><br /></p>

<p><em>Video of my talk at <a target="_blank" rel="noopener" href="http://2018.eeconf.com/">EEConf 2018</a> in Nashville.</em></p>

<p>Say goodbye to cargo cult solutions. Finally get a grasp on character set encoding, learn how it works for PHP apps and MySQL, and become confident in fixing encoding issues once and for all.</p>]]></content><author><name>Kevin Smith</name></author><category term="Conference Talk" /><summary type="html"><![CDATA[Say goodbye to cargo cult solutions. Finally get a grasp on character set encoding, learn how it works for PHP apps and MySQL, and become confident in fixing encoding issues once and for all.]]></summary></entry><entry><title type="html">A Better Way to Handle Validation Errors</title><link href="https://kevinsmith.io/a-better-way-to-handle-validation-errors/" rel="alternate" type="text/html" title="A Better Way to Handle Validation Errors" /><published>2019-08-13T21:28:00+00:00</published><updated>2019-08-13T21:28:00+00:00</updated><id>https://kevinsmith.io/a-better-way-to-handle-validation-errors</id><content type="html" xml:base="https://kevinsmith.io/a-better-way-to-handle-validation-errors/"><![CDATA[<p>While working on a project recently, I finally got so frustrated with the awkward way validation errors are typically handled that I was determined to figure out a solution. The usual methods tend to be:</p>
<ul>
  <li>Throwing exceptions</li>
  <li>Returning a bundle of error messages</li>
</ul>

<p>Both these methods fall <em>really</em> short.</p>

<p><a name="exceptions-dont-feel-right" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#exceptions-dont-feel-right" class="c-linked-heading__link">#</a>
Exceptions Don't Feel Right
</h2>

<p>True to their name, exceptions should be reserved almost exclusively for exceptional circumstances that result in program failure. <em>This really isn’t supposed to happen, and now this part of the program can’t continue running.</em> This doesn’t work well for validation errors for a couple of reasons.</p>

<p>First, exceptions give the application a fail-on-first-problem behavior, which means that even though there’s a possibility of multiple validation errors in a method, we can only report back one validation error at a time. That can be pretty frustrating for the user.</p>

<p>Second, it requires the caller to know about the internals of the called class, and that’s not the caller’s responsibility. It’s reasonable to catch a whole category of exceptions (or even all exceptions) when we want to gracefully handle actual program failure, but validation errors each tend to require specific handling which means the caller needs to know exactly which exception to be on the lookout for.</p>

<p>That amounts to a hidden API. Pretty tough to work with, if you ask me.</p>

<p><a name="returning-a-payload-of-errors" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#returning-a-payload-of-errors" class="c-linked-heading__link">#</a>
Returning a Payload of Errors?
</h2>

<p>Another common technique is to bundle up all the validation errors and return them in some sort of payload—an array, a custom <code class="language-plaintext highlighter-rouge">Errors</code> object, a  <a target="_blank" rel="noopener" href="https://github.com/auraphp/Aura.Payload">Domain Payload</a>  object, or the  <a target="_blank" rel="noopener" href="https://martinfowler.com/articles/replaceThrowWithNotification.html">Notification pattern</a>.</p>

<p>This improves on the technique of throwing exceptions by allowing a method to report <em>all</em> the validation errors that it might encounter, but it’s clumsy for a couple of other reasons.</p>

<p>It requires the caller to inspect the response and understand what to do with it. That’s not the caller’s responsibility.</p>

<p>The best case scenario, from the caller’s perspective, is that the response is some kind of known collection of error message strings so that the caller doesn’t have to inspect anything. It can just allow the error messages to bubble back up to the surface of the application. But that brings us to the next problem.</p>

<p>To provide fully-formed error messages, the called object has to take on presentational responsibilities. Now rather than merely noting that a particular validation error has occurred, this technique enlists the called object to provide a user-friendly error message as well.</p>

<p>To be clear, the problem here is that the called object isn’t just reporting <em>what</em> happened, it’s deciding <em>how</em> the caller should handle it. <em>Here, just show this message to the user,</em> it says. But what if the caller wants to handle a particular validation error in some other way? It would have to inspect the bundle of errors and perform string matching to find the one it’s looking for. <em>Gross.</em></p>

<p><a name="tell-dont-ask" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#tell-dont-ask" class="c-linked-heading__link">#</a>
Tell, Don't Ask
</h2>

<blockquote>
  <p>Procedural code gets information then makes decisions. Object-oriented code tells objects to do things.</p>

  <p>– <cite><a target="_blank" rel="noopener" href="https://pragprog.com/articles/tell-dont-ask">Alec Sharp, “Smalltalk By Example” McGraw-Hill, 1997</a></cite></p>
</blockquote>

<p>Object-oriented design is fundamentally about keeping responsibilities in their proper place. <em>Tell, Don’t Ask</em> is a well-known guideline for designing objects that stick to their responsibilities.</p>

<p>The opposite approach—the procedural approach—is to ask for data and then make decisions based on the result. As we saw above, that approach leaves us with a brittle system with objects that are inextricably bound together. Change even the phrasing of an error message in the called object, and now you’ve broken the behavior of the caller(s).</p>

<p>So how can we leverage <em>Tell, Don’t Ask</em> for validation errors?</p>

<p>The basic idea is this: when a method could have many possible outcomes, it should tell some other object about those significant events.</p>

<p>Create an interface (<code class="language-plaintext highlighter-rouge">CreateUserHandler</code>) with a method for each event and require it in the method signature. Think of it as a very localized event handler.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">function</span> <span class="n">createUser</span><span class="p">(</span>
    <span class="kt">CreateUserHandler</span> <span class="nv">$handler</span><span class="p">,</span>
    <span class="kt">string</span> <span class="nv">$emailAddress</span><span class="p">,</span>
    <span class="kt">string</span> <span class="nv">$firstName</span><span class="p">,</span>
    <span class="kt">string</span> <span class="nv">$lastName</span>
<span class="p">)</span> <span class="p">:</span> <span class="kt">void</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">isNameValid</span><span class="p">(</span><span class="nv">$firstName</span><span class="p">)</span> <span class="o">||</span> <span class="o">!</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">isNameValid</span><span class="p">(</span><span class="nv">$lastName</span><span class="p">))</span> <span class="p">{</span>
        <span class="nv">$handler</span><span class="o">-&gt;</span><span class="nf">nameWasInvalid</span><span class="p">();</span>
    <span class="p">}</span>
    
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">isEmailAddressValid</span><span class="p">(</span><span class="nv">$emailAddress</span><span class="p">))</span> <span class="p">{</span>
        <span class="nv">$handler</span><span class="o">-&gt;</span><span class="nf">emailAddressWasInvalid</span><span class="p">();</span>
    <span class="p">}</span>
    
    <span class="c1">// If we don't have what we need to create the User, return</span>
    
    <span class="c1">// Otherwise, create User and transform to data transfer object $userDto</span>

    <span class="nv">$handler</span><span class="o">-&gt;</span><span class="nf">userWasCreated</span><span class="p">(</span><span class="nv">$userDto</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>When calling the method, pass in any object that implements the interface, leaving it up to that object to handle the called method’s events in a way that makes sense for that part of the system.</p>

<p>For example, if you’re using the  <a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Action%E2%80%93domain%E2%80%93responder">Action-Domain-Responder</a> architectural pattern, the responder itself might be the most appropriate event handler.</p>

<p>The action passes in the responder when calling <code class="language-plaintext highlighter-rouge">createUser</code>.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">CreateUserAction</span>
<span class="p">{</span>
    <span class="cd">/** @var UserService */</span>
    <span class="k">private</span> <span class="nv">$service</span><span class="p">;</span>
    <span class="cd">/** @var CreateUserResponder */</span>
    <span class="k">private</span> <span class="nv">$responder</span><span class="p">;</span>
    
    <span class="c1">// ...</span>
    
    <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">Request</span> <span class="nv">$request</span><span class="p">)</span> <span class="p">:</span> <span class="kt">Response</span>
    <span class="p">{</span>
        <span class="c1">// Get request input data as $attributes</span>

        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">service</span><span class="o">-&gt;</span><span class="nf">createUser</span><span class="p">(</span>
            <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">responder</span><span class="p">,</span>
            <span class="nv">$attributes</span><span class="p">[</span><span class="s1">'email'</span><span class="p">],</span>
            <span class="nv">$attributes</span><span class="p">[</span><span class="s1">'firstName'</span><span class="p">],</span>
            <span class="nv">$attributes</span><span class="p">[</span><span class="s1">'lastName'</span><span class="p">]</span>
        <span class="p">);</span>

        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">responder</span><span class="o">-&gt;</span><span class="nf">response</span><span class="p">();</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The responder uses the events signaled by <code class="language-plaintext highlighter-rouge">createUser</code> to generate a response.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">CreateUserResponder</span> <span class="kd">implements</span> <span class="nc">CreateUserHandler</span>
<span class="p">{</span>
    <span class="k">private</span> <span class="nv">$response</span><span class="p">;</span>
    
    <span class="k">public</span> <span class="k">function</span> <span class="n">emailAddressWasInvalid</span><span class="p">()</span> <span class="p">:</span> <span class="kt">void</span>
    <span class="p">{</span>
        <span class="c1">// Add validation error message to $this-&gt;response</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">nameWasInvalid</span><span class="p">()</span> <span class="p">:</span> <span class="kt">void</span>
    <span class="p">{</span>
        <span class="c1">// Add validation error message to $this-&gt;response</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">userWasCreated</span><span class="p">(</span><span class="kt">UserDto</span> <span class="nv">$user</span><span class="p">)</span> <span class="p">:</span> <span class="kt">void</span>
    <span class="p">{</span>
        <span class="c1">// Create API payload with $user and add it to $this-&gt;response</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">response</span><span class="p">()</span> <span class="p">:</span> <span class="kt">Response</span>
    <span class="p">{</span>
        <span class="c1">// Returns HTTP response with application/json content-type</span>
        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">response</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><em>All the validation errors? Only the first one? Could other method events have an impact on the response?</em></p>

<p>Sure, maybe. That’s entirely up to the responder to determine how to handle it. That is the responder’s <strong>responsibility</strong> after all.</p>

<p>This example is for an HTTP request. Hopefully you can imagine how to set up a CLI command for creating a user as well. The CLI command handler class would just pass in its own responder object that implements <code class="language-plaintext highlighter-rouge">CreateUserHandler</code> to generate the command-line response, and the <code class="language-plaintext highlighter-rouge">createUser</code> method wouldn’t have to change at all.</p>

<hr style="width:40%; text-align:center; margin-top: 42px; margin-bottom: 42px; border: 0; height: 1px; background: #333; background-image: linear-gradient(to right, #ccc, #333, #ccc);" />

<p>For what it’s worth,  <a target="_blank" rel="noopener" href="https://buzzingpixel.com/">TJ Draper</a>  and I developed this technique together as an improvement upon the aforementioned techniques, but I’ll admit that I find it impossible to believe we actually <em>invented</em> this pattern. Seems to be a variant of the  <a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Delegation_pattern">delegation pattern</a>, but it doesn’t include that pattern’s requirement of shared context.</p>

<p>If you know the name of the pattern, please let me know.</p>]]></content><author><name>Kevin Smith</name></author><category term="PHP" /><summary type="html"><![CDATA[While working on a project recently, I finally got so frustrated with the awkward way validation errors are typically handled that I was determined to figure out a solution.]]></summary></entry><entry><title type="html">Sanitize Your Inputs?</title><link href="https://kevinsmith.io/sanitize-your-inputs/" rel="alternate" type="text/html" title="Sanitize Your Inputs?" /><published>2019-01-03T13:58:00+00:00</published><updated>2019-01-03T13:58:00+00:00</updated><id>https://kevinsmith.io/sanitize-your-inputs</id><content type="html" xml:base="https://kevinsmith.io/sanitize-your-inputs/"><![CDATA[<p>I’m often accused of being particularly fussy with regards to language and word choice, especially in technical discussions. It’s true, but I’ll wear that badge with pride. In software engineering, there are many instances where clear communication is so critical that the success or downfall of an entire organization may rest upon it.</p>

<p>There’s one particularly slippery term that wreaks havoc in the pursuit of application security.</p>

<p><em>Sanitize.</em></p>

<p>I say it’s slippery because there is simply no industry-wide agreement on its meaning, and therefore when used, the speaker and his or her audience cannot be entirely sure they understand each other. Its appearance in any discussion should immediately prompt the question, “What do you mean by that?”</p>

<p>Does it mean removing undesirable data while letting the good stuff through? Or converting potentially harmful data into a harmless form? Or flat-out rejecting a request when any invalid data is detected? Or perhaps it even means  <a target="_blank" rel="noopener" href="https://kevinsmith.io/protect-your-php-application-from-sql-injection">using prepared statements</a>  to protect the database from malicious input. I’ve seen “sanitize” used to mean any (and even <em>all</em>) of these things.</p>

<p>That’s worrisome because these techniques are <em>not</em> interchangeable, especially when it comes to preventing SQL injection. In that case, <strong>using prepared statements is the only way to reliably protect your database from SQL injection attacks without the risk of mangling incoming data</strong>.</p>

<p>Perhaps the author of the famous  <a target="_blank" rel="noopener" href="https://xkcd.com/327/">Bobby Tables</a>  comic actually intended the mom’s snarky response to mean “use prepared statements” instead of filtering the input, but that would be entirely lost on the beginner developer who reads the comic and Googles “sanitize database inputs” to find scores of highly-ranked guides that confidently recommend modifying the input string. (Thank goodness  <a target="_blank" rel="noopener" href="http://bobby-tables.com/about">the one guide that tends to top the search results</a>  makes it clear that “sanitizing” your inputs is prone to error and promotes prepared statements instead.)</p>

<p>Sanitize your inputs? I think not.</p>

<p>Not just because it’s wrong. Because it’s meaningless.</p>

<p>Let’s look at a few fundamental principles for web application security, and through them find the best language for clear communication.</p>

<p><a name="validate-on-input" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#validate-on-input" class="c-linked-heading__link">#</a>
Validate on Input
</h2>

<p>At every stage of input, ensure that the incoming data is valid according to the requirements of that part of the application. There are many layers in any application, and they all have a job to do. Each one expects to be given certain information that it needs to do its work, and it pays dividends to be as  <a target="_blank" rel="noopener" href="http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration.strict">explicit as possible</a>.</p>

<p>Does this PHP class method need a date and time to do its job? Type hint that you’re expecting  <a target="_blank" rel="noopener" href="http://php.net/manual/en/class.datetimeimmutable.php">DateTimeImmutable</a>  in the method signature, and if the code calling that method doesn’t provide the right information, PHP will throw a <code class="language-plaintext highlighter-rouge">TypeError</code>. This is validation using the built-in capabilities of the language right at the point where the method is being invoked.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="k">declare</span><span class="p">(</span><span class="n">strict_types</span><span class="o">=</span><span class="mi">1</span><span class="p">);</span>

<span class="kd">class</span> <span class="nc">Foo</span>
<span class="p">{</span>
  <span class="k">public</span> <span class="k">function</span> <span class="n">bar</span><span class="p">(</span><span class="kt">DateTimeImmutable</span> <span class="nv">$dateTime</span><span class="p">)</span>
  <span class="p">{</span>
    <span class="c1">// Do something with $dateTime</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Need a positive integer? Declare the parameter type to be <code class="language-plaintext highlighter-rouge">int</code> (with  <a target="_blank" rel="noopener" href="http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration.strict">strict typing</a>  enabled), and consider using an assertion library like  <a target="_blank" rel="noopener" href="https://github.com/webmozart/assert">Webmozart Assert</a>  to require the incoming data to be greater than <code class="language-plaintext highlighter-rouge">0</code> before any other work is done in the method. This combines built-in validation features and a broadly-used, well-tested third-party solution to ensure you’re working with meaningful data.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="k">declare</span><span class="p">(</span><span class="n">strict_types</span><span class="o">=</span><span class="mi">1</span><span class="p">);</span>

<span class="kn">use</span> <span class="nc">Webmozart\Assert\Assert</span><span class="p">;</span>

<span class="kd">class</span> <span class="nc">Foo</span>
<span class="p">{</span>
  <span class="k">public</span> <span class="k">function</span> <span class="n">bar</span><span class="p">(</span><span class="kt">int</span> <span class="nv">$eventId</span><span class="p">)</span>
  <span class="p">{</span>
    <span class="nc">Assert</span><span class="o">::</span><span class="nf">greaterThan</span><span class="p">(</span><span class="nv">$eventId</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="s1">'The event ID must be a positive integer. Got: %s'</span><span class="p">);</span>
    
    <span class="c1">// Do something with $eventId</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Expecting an argument to be a string with the value of either “month” or “year”? If the value of the incoming data doesn’t match one of the two (and your business dictates that it’s not possible to set a reasonable default), throw an  <a target="_blank" rel="noopener" href="http://php.net/manual/en/class.invalidargumentexception.php">InvalidArgumentException</a>  (or use Webmozart Assert’s <code class="language-plaintext highlighter-rouge">oneOf</code> assertion). This is a technique called <em>whitelisting</em>.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="k">declare</span><span class="p">(</span><span class="n">strict_types</span><span class="o">=</span><span class="mi">1</span><span class="p">);</span>

<span class="kd">class</span> <span class="nc">Foo</span>
<span class="p">{</span>
  <span class="k">public</span> <span class="k">function</span> <span class="n">bar</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$timeFrame</span><span class="p">)</span>
  <span class="p">{</span>
    <span class="nv">$timeFrame</span> <span class="o">=</span> <span class="nb">mb_strtolower</span><span class="p">(</span><span class="nv">$timeFrame</span><span class="p">);</span>
    
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span> <span class="nb">in_array</span><span class="p">(</span><span class="nv">$timeFrame</span><span class="p">,</span> <span class="p">[</span><span class="s1">'month'</span><span class="p">,</span> <span class="s1">'year'</span><span class="p">]))</span> <span class="p">{</span>
      <span class="k">throw</span> <span class="k">new</span> <span class="nc">\InvalidArgumentException</span><span class="p">(</span>
        <span class="s2">"TimeFrame must be either 'month' or 'year'. Got: </span><span class="si">{</span><span class="nv">$timeFrame</span><span class="si">}</span><span class="s2">"</span>
      <span class="p">);</span>
    <span class="p">}</span>
    
    <span class="c1">// Do something with $timeFrame</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Even better, consider using  <a target="_blank" rel="noopener" href="https://github.com/myclabs/php-enum">enums</a>  when the value should always be one of a declared (i.e. enumerated) list of values.</p>

<p>Input validation is stricter than what most developers imagine when they think of sanitizing inputs. Rather than merely “cleaning” the incoming data, we’re ensuring it adheres to a very specifically-defined format or rejecting it entirely.</p>

<p>By declaring and enforcing these expectations, the application is a lot less likely to exhibit unexpected or undesirable behavior, the playground of nearly all security vulnerabilities. This approach is not sufficient to protect against any threat—no single technique is—but ensuring the integrity of the data moving around the application goes a long way in reducing an application’s attack surface.</p>

<p>Beyond the improvement in security, your engineering team will enjoy working in a far more intelligible codebase, and the business will benefit from more reliable features delivered more quickly.</p>

<p><em>Read more on input validation in the excellent article <a target="_blank" rel="noopener" href="https://martinfowler.com/articles/web-security-basics.html#InputValidation">The Basics of Web Application Security</a> on Martin Fowler’s website.</em></p>

<p><a name="send-query-and-parameters-separately-to-the-database" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#send-query-and-parameters-separately-to-the-database" class="c-linked-heading__link">#</a>
Send Query and Parameters Separately to the Database
</h2>

<p>SQL injection happens when an attacker sneaks additional database instructions into your existing query. As noted above, the most famous example is smuggling a “drop table” statement in with an existing query, designed to maliciously destroy an entire database table.</p>

<p>The technique to prevent this type of attack is fairly straightforward. Isolate data from the instructions designed to operate on it, then (and this is important) literally send them as separate messages to the database server.</p>

<p>This allows your application to query the database server like so: “Give me all the columns from the <code class="language-plaintext highlighter-rouge">Students</code> table for rows where the <code class="language-plaintext highlighter-rouge">first_name</code> is ___; I’ll send a separate message with something to fill in the blank.” Then a very short time later, your application sends another message, “Fill in that blank with <code class="language-plaintext highlighter-rouge">Robert</code>.”</p>

<p>Under the hood, this is actually what  <a target="_blank" rel="noopener" href="https://kevinsmith.io/protect-your-php-application-from-sql-injection">prepared statements</a>  are doing.</p>

<p>If the database server receives <code class="language-plaintext highlighter-rouge">Robert'); DROP TABLE Students;--</code> instead, it won’t execute the <code class="language-plaintext highlighter-rouge">DROP TABLE</code> statement. The database server knows that’s a value, so it won’t let it alter the original instructions it received. It will treat that value literally, search for a student named <em>Robert’); DROP TABLE Students;–</em>, and return nothing.</p>

<p>It’s straightforward, fool-proof, and unlike “sanitizing” an input string, carries no risk of accidentally mangling the incoming data.</p>

<p><em>For more, read my post on <a target="_blank" rel="noopener" href="https://kevinsmith.io/protect-your-php-application-from-sql-injection">using prepared statements to prevent SQL injection attacks</a>.</em></p>

<p><a name="escape-on-output" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#escape-on-output" class="c-linked-heading__link">#</a>
Escape on Output
</h2>

<p>Escaping has the specific goal of preventing injection attacks — typically HTML injection, of which the most famous form is XSS. If our application is passing along user-supplied data, it’s our application’s responsibility to ensure that data is never regarded as code that should be executed or interpreted.</p>

<p>The eagle-eyed reader will notice a parallel with SQL injection prevention: we’re giving the data special treatment to prevent its execution as code. But unlike with prepared statements, there’s no way to send application output code and data separately to ensure such a clear distinction. We must use some other method to ensure the data cannot be executed. That’s where escaping comes in handy.</p>

<p>Escaping is the conversion of user-supplied data to a form that the receiving system will not mistake for code. As a <em>very</em> simple example (that absolutely is not advice to be followed blindly), running a blog comment through  <a target="_blank" rel="noopener" href="https://secure.php.net/manual/en/function.htmlspecialchars.php">PHP’s htmlspecialchars()</a>  will ensure any HTML included in the comment doesn’t actually get rendered by the browser.</p>

<p><em>Unfortunately, the terms “escaping” and “encoding” have</em> <a target="_blank" rel="noopener" href="https://cwe.mitre.org/data/definitions/116.html#Notes">a long history</a> <em>of being used interchangeably for this purpose. Either term should be understood to refer to the same concept outlined here. I have opted for “escaping” to align with the language most commonly used in the PHP community and to avoid confusion with the unrelated concept of setting the character encoding of output content. But as you’ll note later on, even some of the quotes and sources I reference use “encoding”. As much as I would love there to be One True Word to use here, there isn’t. Try not to get too hung up on it.</em></p>

<p>The appropriate method for escaping content will depend a lot on the context in which the data will be used. Is it going to be placed <a target="_blank" rel="noopener" href="https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#RULE_.231_-_HTML_Escape_Before_Inserting_Untrusted_Data_into_HTML_Element_Content">within an HTML element</a>? Or as <a target="_blank" rel="noopener" href="https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#RULE_.232_-_Attribute_Escape_Before_Inserting_Untrusted_Data_into_HTML_Common_Attributes">the value for an HTML attribute</a>? Or perhaps set as <a target="_blank" rel="noopener" href="https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#RULE_.233_-_JavaScript_Escape_Before_Inserting_Untrusted_Data_into_JavaScript_Data_Values">the value for a JavaScript variable</a>? Or maybe even as <a target="_blank" rel="noopener" href="https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#RULE_.235_-_URL_Escape_Before_Inserting_Untrusted_Data_into_HTML_URL_Parameter_Values">part of the query string in a link’s URL</a>? Each of these contexts requires content to be escaped in a different way.</p>

<p>I wholeheartedly suggest using a well-tested library to handle escaping. There are simply too many gotchas that are easy to miss if you try to do it on your own.  <a target="_blank" rel="noopener" href="https://docs.zendframework.com/zend-escaper/intro/">Zend Escaper</a>  is a fine choice, or if you’re already using a template engine like Twig, look for  <a target="_blank" rel="noopener" href="https://twig.symfony.com/doc/2.x/filters/escape.html">escaping utilities</a>  built right in. Both of these tools offer options for escaping in the appropriate context.</p>

<p>Escape user-supplied data as late as possible. This ensures that nothing is erroneously assumed to have already been escaped, allowing it to slip through the cracks, <em>and</em> that the appropriate escape method is performed for the given context. For a web application serving up a web page, this would probably be in the HTML template itself since the context is obvious by that point.</p>

<p><a name="filter-on-output" class="u-anchor"></a></p>
<h3 class="c-linked-heading"><a href="#filter-on-output" class="c-linked-heading__link">#</a>
Filter on Output
</h3>

<p>So how do you handle user-generated content that actually <em>should</em> be rendered on the front-end? Consider a blog post editor where the author writes in a WYSIWYG field. That rich text content is going to include a lot of HTML. How can you get the browser to safely render it?</p>

<p>Filtering is a security technique that involves examining user-supplied data and removing anything that shouldn’t be there. This is the high-wire act of web application security, so it’s a tactic that should be reserved for a very narrow set of circumstances where escaping content doesn’t make sense. That’s almost exclusively when content originates from a rich text editor.</p>

<p>There’s a lot that could go wrong here — it’s easy to be too aggressive in stripping HTML elements or not aggressive enough and fail to remove malicious input — so save yourself the trouble and use a well-tested library like  <a target="_blank" rel="noopener" href="http://htmlpurifier.org/">HTML Purifier</a>. And as with escaping, you should apply this as late as possible.</p>

<p>It’s not uncommon to see applications attempt to filter and escape data coming <em>into</em> the application — this is what’s often called “sanitizing” — but that should <em>really</em> be avoided.</p>

<p>There are security concerns at stake:</p>

<blockquote>
  <p>If you store sanitized data in a database, and then a SQL injection vulnerability is found elsewhere, the attacker can totally bypass your XSS protection by polluting the trusted-to-be-sanitized record with malware.</p>

  <p>– <cite><a target="_blank" rel="noopener" href="https://paragonie.com/blog/2017/12/2018-guide-building-secure-php-software#secure-php-xss">Paragon Initiative Enterprises, The 2018 Guide to Building Secure PHP Software</a></cite></p>
</blockquote>

<p>And escaping and filtering on input raises maintainability issues as well:</p>

<blockquote>
  <p>Be warned: you might be tempted to take the raw user input, and do the encoding before storing it. This pattern will generally bite you later on. If you were to encode the text as HTML prior to storage, you can run into problems if you need to render the data in another format: it can force you to unencode the HTML, and re-encode into the new output format. This adds a great deal of complexity and encourages developers to write code in their application code to unescape the content, making all the tricky upstream output encoding effectively useless. You are much better off storing the data in its most raw form, then handling encoding at rendering time.</p>
</blockquote>

<blockquote>
  <p>– <cite><a target="_blank" rel="noopener" href="https://martinfowler.com/articles/web-security-basics.html#CautionsAndCaveats">Cade Cairns and Daniel Somerfield, The Basics of Web Application Security</a></cite></p>
</blockquote>

<p>So escape and filter where it makes the most sense: on output.</p>

<p>Don’t rely on these techniques to protect your database or ensure the validity of data flowing around your application. They might sometimes provide those security benefits accidentally, but that’s not what they were designed to do and they often come with a hidden cost.</p>

<p><em>The sources of the preceding quotes offer a wealth of information on the how and why of escaping, and I highly recommend them both for further reading: the <a target="_blank" rel="noopener" href="https://martinfowler.com/articles/web-security-basics.html#EncodeHtmlOutput">Encode HTML Output</a> section of <a target="_blank" rel="noopener" href="https://martinfowler.com/articles/web-security-basics.html">The Basics of Web Application Security</a>; and the <a target="_blank" rel="noopener" href="https://paragonie.com/blog/2017/12/2018-guide-building-secure-php-software#secure-php-xss">Cross-Site Scripting (XSS)</a> section of <a target="_blank" rel="noopener" href="https://paragonie.com/blog/2017/12/2018-guide-building-secure-php-software">The 2018 Guide to Building Secure PHP Software</a>. See also <a target="_blank" rel="noopener" href="https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#You_Need_a_Security_Encoding_Library">OWASP’s XSS Prevention Cheat Sheet</a>.</em></p>

<p><a name="language-matters" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#language-matters" class="c-linked-heading__link">#</a>
Language Matters
</h2>

<p>So the next time you’re tempted to use “sanitize” to mean…</p>

<blockquote>
  <p>removing undesirable data while letting the good stuff through?</p>
</blockquote>

<p>May I recommend “filtering” instead?</p>

<blockquote>
  <p>Or converting potentially harmful data into a harmless form?</p>
</blockquote>

<p>“Escaping” user-supplied data — and making sure it only happens on output — is the way to go.</p>

<blockquote>
  <p>Or flat-out rejecting a request when any invalid data is detected?</p>
</blockquote>

<p>Opt for “validation” instead.</p>

<blockquote>
  <p>Or to protect the database from malicious input?</p>
</blockquote>

<p>Remember that the only reliable solution is  <a target="_blank" rel="noopener" href="https://kevinsmith.io/protect-your-php-application-from-sql-injection">using prepared statements</a>.</p>

<p>We don’t build this stuff alone. Software engineering is a human endeavor, and building great software means working well with other people. I hope this overview helps encourage much clearer communication amongst your team.</p>

<hr style="width:40%; text-align:center; margin-top: 42px; margin-bottom: 42px; border: 0; height: 1px; background: #333; background-image: linear-gradient(to right, #ccc, #333, #ccc);" />

<p><strong><em>Update:</em></strong> A few people suggested that many of the concepts discussed here are covered by the maxim “Filter Input, Escape Output”. I have no desire to reinvent the wheel, so if there’s an industry standard, I certainly want to stick to it.</p>

<p>Chris Shiflett  <a target="_blank" rel="noopener" href="http://shiflett.org/blog/2005/filter-input-escape-output">coined this phrase almost 14 years ago</a>, and I was fortunate to have a good conversation with him shortly after publishing this post. That conversation led me to dive into quite a bit of additional research, resulting in a significant rewrite of the section dealing with output.</p>

<p>On the surface, there remains a small disagreement over whether to filter on input or output, but that fades quickly with a look at how Chris defines  <a target="_blank" rel="noopener" href="http://shiflett.org/articles/input-filtering">input filtering</a>, which lines up with exactly what I’ve recommended here for  <a target="_blank" rel="noopener" href="https://kevinsmith.io/sanitize-your-inputs#validate-on-input">input validation</a>. He even uses the word validation in his definition. And importantly, in the intervening years since the maxim was coined, the web application security community seems to have  <a target="_blank" rel="noopener" href="https://www.owasp.org/index.php/Input_Validation_Cheat_Sheet">settled on “input validation”</a>  to more clearly describe this technique.</p>

<p>Further, “filtering” is commonly understood to mean blocking or containing the bad parts of a stream while letting the rest through. An air filter doesn’t test the air and completely block it if any parts are considered bad; dirty air goes into the filter, clean air comes out.</p>

<p>With that in mind, I maintain that filtering is context-sensitive modification of the data and thus most appropriate  <a target="_blank" rel="noopener" href="https://kevinsmith.io/sanitize-your-inputs#filter-on-output">during output</a>.</p>]]></content><author><name>Kevin Smith</name></author><category term="PHP" /><summary type="html"><![CDATA[There's one particularly slippery term that wreaks havoc in the pursuit of application security: _Sanitize_.]]></summary></entry><entry><title type="html">Why Your Team is Burnt Out and Getting Nothing Done</title><link href="https://kevinsmith.io/why-your-team-is-burnt-out-and-getting-nothing-done/" rel="alternate" type="text/html" title="Why Your Team is Burnt Out and Getting Nothing Done" /><published>2018-09-28T02:50:20+00:00</published><updated>2018-09-28T02:50:20+00:00</updated><id>https://kevinsmith.io/why-your-team-is-burnt-out-and-getting-nothing-done</id><content type="html" xml:base="https://kevinsmith.io/why-your-team-is-burnt-out-and-getting-nothing-done/"><![CDATA[<style>.embed-container { position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%; } .embed-container iframe, .embed-container object, .embed-container embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }</style>
<div class="embed-container"><iframe src="https://player.vimeo.com/video/242862885" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe></div>
<p><br /></p>

<p><em>Video of my talk at <a target="_blank" rel="noopener" href="http://2017.eeconf.com/">EEConf 2017</a> in Denver.</em></p>

<p><del><a target="_blank" rel="noopener" href="http://www.eeconf.com/">Tickets are still available for EEConf 2018 next month!</a> I’ll be speaking on the nasty issues we face with character encoding. Hope to see you there!</del> <a href="/what-the-is-going-on/">You can now watch that conference talk here.</a></p>]]></content><author><name>Kevin Smith</name></author><category term="Conference Talk" /><summary type="html"><![CDATA[Video of my talk at [EEConf 2017](http://2017.eeconf.com/) in Denver.]]></summary></entry><entry><title type="html">Where the Real Work is Done</title><link href="https://kevinsmith.io/where-the-real-work-is-done/" rel="alternate" type="text/html" title="Where the Real Work is Done" /><published>2018-08-15T19:38:11+00:00</published><updated>2018-08-15T19:38:11+00:00</updated><id>https://kevinsmith.io/where-the-real-work-is-done</id><content type="html" xml:base="https://kevinsmith.io/where-the-real-work-is-done/"><![CDATA[<p>If you want to make a difference in software, get better at modernizing legacy applications. The tech world is desperately in need of such skills, and it’s only gonna get more dire from here.</p>]]></content><author><name>Kevin Smith</name></author><summary type="html"><![CDATA[If you want to make a difference in software, get better at modernizing legacy applications. The tech world is desperately in need of such skills, and it’s only gonna get more dire from here.]]></summary></entry><entry><title type="html">“If you think of coding as the manipulation of data, you’re going to have a hard time writing object-oriented code.”</title><link href="https://kevinsmith.io/if-you-think-of-coding-as-the-manipulation-of-data-youre-going-to-have-a-hard-time-writing-object-oriented-code/" rel="alternate" type="text/html" title="“If you think of coding as the manipulation of data, you’re going to have a hard time writing object-oriented code.”" /><published>2018-07-11T20:32:00+00:00</published><updated>2018-07-11T20:32:00+00:00</updated><id>https://kevinsmith.io/if-you-think-of-coding-as-the-manipulation-of-data-youre-going-to-have-a-hard-time-writing-object-oriented-code</id><content type="html" xml:base="https://kevinsmith.io/if-you-think-of-coding-as-the-manipulation-of-data-youre-going-to-have-a-hard-time-writing-object-oriented-code/"><![CDATA[<p>That’s an off-the-cuff comment I made during a presentation at the <a target="_blank" rel="noopener" href="http://nashvillephp.org/">Nashville PHP</a> meetup last night, and one of the attendees messaged me later asking if I could expand on that thought.</p>

<p>First, I think a definition is important. <em>Data</em> is facts, statistics, quantities, values, characters, etc. In the context of programming, it’s anything that can be assigned to a variable.</p>

<p>Procedural code sends data through a series of instructional steps to accomplish the goals of the business. Functions may be used to make it more modular, but if the emphasis is on manipulating data as it flows through a series of steps, it’s procedural code.</p>

<p>Object-oriented programming is all about accomplishing the goals of the business through <a target="_blank" rel="noopener" href="https://kevinsmith.io/whats-so-great-about-oop">a community of collaborating objects</a>, the design for which must start with a deep understanding of the business itself. Data isn’t <em>irrelevant</em> in OOP, but an object isn’t just a dumb bag of data either. It’s an agent of purpose for the business. Data is important only insofar as the object needs to know certain things to accomplish its role. (Notably, in many cases the specific data an object holds in order to accomplish its purpose could change without the purpose itself changing.)</p>

<p>Data is in service to the purpose. It isn’t the purpose itself. Ultimately, all data in software is surrounded by a boundary that defines purpose and gives meaning to the data contained within. With procedural code, it’s often the user interface layer doing that work for the entire system. In OOP, it’s each individual object.</p>

<p>So it’s a big difference in mindset. In my opinion, if you start by thinking about the data and how it’ll be stored, structured, and manipulated, you’re already concerned with tactics before you even have a strategy. You’re starting from the wrong end of things, and it will dramatically affect how you design the entire system.</p>]]></content><author><name>Kevin Smith</name></author><category term="PHP" /><summary type="html"><![CDATA[Data is in service to the purpose. It isn’t the purpose itself.]]></summary></entry><entry><title type="html">What’s So Great About OOP?</title><link href="https://kevinsmith.io/whats-so-great-about-oop/" rel="alternate" type="text/html" title="What’s So Great About OOP?" /><published>2018-07-09T16:52:00+00:00</published><updated>2018-07-09T16:52:00+00:00</updated><id>https://kevinsmith.io/whats-so-great-about-oop</id><content type="html" xml:base="https://kevinsmith.io/whats-so-great-about-oop/"><![CDATA[<p>One of my core responsibilities as a senior software engineer is mentoring the junior engineers and interns at work. It’s one I don’t take lightly, and as a follow-up to discussions where new concepts are introduced, I usually try to find a good written reference for them to bookmark for later.</p>

<p>Recently a question came up with our new interns while talking through the design of a feature:</p>

<blockquote>
  <p>What <em>is</em> object-oriented programming? How is it different from what we’re doing now, and why should we write code that way?</p>
</blockquote>

<p>I wanted to find a fundamental explanation to send them for later, but nearly everything I came across immediately jumped into  <a target="_blank" rel="noopener" href="http://hackernoon.com/solid-principles-made-easy-67b1246bcdf">SOLID</a> or <a target="_blank" rel="noopener" href="http://www.jakowicz.com/design-patterns/">design patterns</a> or advanced concepts of some kind.</p>

<p>So let’s start where most PHP programmers began.</p>

<p><a name="procedural-programming" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#procedural-programming" class="c-linked-heading__link">#</a>
Procedural Programming
</h2>

<p>The code the interns and I were looking at during this discussion was written in a procedural style. Procedural code accomplishes the goals of the system through a series of instructional steps, often breaking those steps up into procedures—called functions, routines, subroutines, etc.—as a way of making the code more modular and easier to understand.</p>

<p>It’s the way most of us learned to code. Once you start thinking of programming as the manipulation of data, this style comes pretty naturally. <em>Do this, then do this. Assign this value to that variable. If this condition is true, do this. Then pass these variables into this function, etc.</em></p>

<p>Here’s a real world example based on a project I actually worked on, and it should help illustrate a fairly common pattern in procedural code.</p>

<p>Imagine a front-end form that allows users to create a new “schedule” (recurring set of events). Once a form is submitted, the form data is passed to a function that figures out if anything is missing and does a few transformations to get the data into the right format. Then it passes it to another function that saves it to the database.</p>

<p>You’ve been asked to build an importer to load data from an uploaded CSV, so you’ll need to reference this existing code a lot and figure out where your importer will need to intersect with it, if at all.</p>

<p>Here’s a simplified version of what that looks like.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$_POST</span> <span class="o">=</span> <span class="p">[</span>
  <span class="s1">'customer_id'</span> <span class="o">=&gt;</span> <span class="s1">'11'</span><span class="p">,</span>
  <span class="s1">'name'</span> <span class="o">=&gt;</span> <span class="s1">'Doe, John'</span><span class="p">,</span>
  <span class="s1">'frequency'</span> <span class="o">=&gt;</span> <span class="s1">'1'</span><span class="p">,</span>
  <span class="s1">'days'</span> <span class="o">=&gt;</span>
    <span class="p">[</span>
      <span class="mi">0</span> <span class="o">=&gt;</span> <span class="s1">'M'</span><span class="p">,</span>
      <span class="mi">1</span> <span class="o">=&gt;</span> <span class="s1">'W'</span><span class="p">,</span>
      <span class="mi">2</span> <span class="o">=&gt;</span> <span class="s1">'R'</span><span class="p">,</span>
      <span class="mi">3</span> <span class="o">=&gt;</span> <span class="s1">'F'</span><span class="p">,</span>
      <span class="mi">4</span> <span class="o">=&gt;</span> <span class="s1">'S'</span><span class="p">,</span>
    <span class="p">],</span>
  <span class="s1">'start_date'</span> <span class="o">=&gt;</span> <span class="s1">'06/24/2018'</span><span class="p">,</span>
  <span class="s1">'type'</span> <span class="o">=&gt;</span> <span class="s1">'Hourly'</span><span class="p">,</span>
  <span class="s1">'no_end_date'</span> <span class="o">=&gt;</span> <span class="s1">'1'</span><span class="p">,</span>
  <span class="s1">'service_hourly'</span> <span class="o">=&gt;</span> <span class="s1">'7'</span><span class="p">,</span>
  <span class="s1">'time_start'</span> <span class="o">=&gt;</span> <span class="s1">'08:30'</span><span class="p">,</span>
  <span class="s1">'pref_worker_id'</span> <span class="o">=&gt;</span> <span class="s1">'27'</span><span class="p">,</span>
  <span class="s1">'time_end'</span> <span class="o">=&gt;</span> <span class="s1">'17:00'</span><span class="p">,</span>
  <span class="s1">'mileage'</span> <span class="o">=&gt;</span> <span class="s1">''</span><span class="p">,</span>
  <span class="s1">'client_id'</span> <span class="o">=&gt;</span> <span class="s1">'11'</span><span class="p">,</span>
  <span class="s1">'plan_id'</span> <span class="o">=&gt;</span> <span class="mi">42</span><span class="p">,</span>
<span class="p">];</span>

<span class="nf">createSchedule</span><span class="p">(</span><span class="nv">$_POST</span><span class="p">);</span>
</code></pre></div></div>

<p>And the relevant functions:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span> <span class="n">createSchedule</span><span class="p">(</span><span class="nv">$schedule_data</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="nf">createScheduleErrors</span><span class="p">(</span><span class="nv">$schedule_data</span><span class="p">))</span> <span class="p">{</span>
    <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
  <span class="p">}</span>
  
  <span class="c1">// Apply default values if optional fields are empty...</span>
  
  <span class="c1">// Create new array $fields from part of $schedule_data, ignoring irrelevant data</span>

  <span class="c1">// Manipulate $fields in a variety of ways to make it acceptable to saveSchedule()</span>
  
  <span class="k">return</span> <span class="nf">saveSchedule</span><span class="p">(</span><span class="nv">$fields</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">function</span> <span class="n">createScheduleErrors</span><span class="p">(</span><span class="nv">$schedule_data</span><span class="p">)</span> <span class="p">{</span>
  <span class="c1">// Check for required keys in array</span>
<span class="p">}</span>

<span class="k">function</span> <span class="n">saveSchedule</span><span class="p">(</span><span class="nv">$fields</span><span class="p">)</span> <span class="p">{</span>
  <span class="c1">// Save to the database</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Hopefully you can see how… imprecise that can be. It’s not at all obvious what the data means or which parts are required to actually create a new schedule. That makes reusability hard.</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">name</code> is obviously the customer’s name, right? <em>Nope, it’s the schedule name.</em></li>
  <li><code class="language-plaintext highlighter-rouge">customer_id</code> and <code class="language-plaintext highlighter-rouge">client_id</code> have the same value. Is that a coincidence? Or are they <em>required</em> to be the same? <em>One of them is actually unnecessary, left over from old code before a refactoring.</em></li>
  <li><code class="language-plaintext highlighter-rouge">frequency</code> of what? Does this schedule end after 1 iteration? <em>It does not.</em></li>
  <li>Ah, so <code class="language-plaintext highlighter-rouge">no_end_date</code> must be required for this schedule to repeat forever. <em>Nope, just leave <code class="language-plaintext highlighter-rouge">end_date</code>, which we don’t even see here, blank. <code class="language-plaintext highlighter-rouge">no_end_date</code> is an artifact from a checkbox on the form that clears and disables the End Date field.</em></li>
  <li>What’s a valid value for <code class="language-plaintext highlighter-rouge">mileage</code>, if we need to provide it?</li>
  <li>Where does <code class="language-plaintext highlighter-rouge">plan_id</code> come from? Is that generated in the form? A pre-existing ID? <em>It’s generated after the submission and added to <code class="language-plaintext highlighter-rouge">$_POST</code>.</em></li>
  <li>Are there more optional fields we <em>could</em> provide that just weren’t part of this form?</li>
</ul>

<p>You actually have to read through quite a lot of code to try to get answers to these questions. And that’s just code that’s obviously related. What about some other part of the codebase you don’t even realize you should be concerned about? You know, the part that alters a global that affects how this code works?</p>

<p>At the time this code was written, the author certainly understood the requirements and constraints that were central to the concept of a schedule. Unfortunately, those business rules were only partially included in the logic of the program and not in an easily reusable way, so they’re a bit of a mystery for the next developer to work in this part of the codebase.</p>

<p><a name="object-oriented-programming" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#object-oriented-programming" class="c-linked-heading__link">#</a>
Object-Oriented Programming
</h2>

<p>Object-oriented programming is a way of building software that encapsulates the responsibilities of the system in a community of collaborating <strong>objects</strong>. An object consists of information (<strong>properties</strong> of the object) and behavior (<strong>methods</strong> of the object that operate on the object’s information) that work together to fulfill the object’s role in the system.</p>

<p>OOP is more than just different syntax. It’s a paradigm shift away from thinking of programming as the manipulation of data. This is an entirely different way of modeling solutions to real problems.</p>

<p>You may have heard that OOP is all about modeling the real world. This is true in a general sense, though this axiom is often misunderstood to mean that objects themselves should literally model real world objects. That goes too far with the analogy.</p>

<p>Instead, think of it from a higher-level view. A community of objects should model the <em>interactions</em> and <em>responsibilities</em> we see in agents of purpose in the real world. Put another way, objects should be designed to solve problems like we solve them in every day life.</p>

<p>When you go to a restaurant, they show you a menu of choices. You tell the waiter what you’d like, and they bring it to you. You don’t run back to the kitchen to check the inventory, get out the necessary ingredients, and tell the chef how to prepare your dinner. You leave that responsibility to the restaurant. They advertise a delicious dinner, and you trust that they can handle it.</p>

<p>Returning to our “schedule” example, let’s see what a class that defines schedule objects might look like.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">Schedule</span>
<span class="p">{</span>
  <span class="k">private</span> <span class="nv">$client</span><span class="p">;</span>
  <span class="k">private</span> <span class="nv">$events</span> <span class="o">=</span> <span class="p">[];</span>
  <span class="k">private</span> <span class="nv">$id</span><span class="p">;</span>
  <span class="k">private</span> <span class="nv">$name</span><span class="p">;</span>
  <span class="k">private</span> <span class="nv">$serviceRate</span><span class="p">;</span>
  <span class="k">private</span> <span class="nv">$startDate</span><span class="p">;</span>
  <span class="k">private</span> <span class="nv">$worker</span><span class="p">;</span>

  <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span>
    <span class="kt">int</span> <span class="nv">$id</span><span class="p">,</span>
    <span class="kt">string</span> <span class="nv">$name</span><span class="p">,</span>
    <span class="kt">Client</span> <span class="nv">$client</span><span class="p">,</span>
    <span class="kt">Worker</span> <span class="nv">$worker</span><span class="p">,</span>
    <span class="kt">ServiceRate</span> <span class="nv">$serviceRate</span><span class="p">,</span>
    <span class="kt">Event</span> <span class="nv">$event</span><span class="p">,</span>
    <span class="kt">DateTimeImmutable</span> <span class="nv">$startDate</span> <span class="o">=</span> <span class="kc">null</span>
  <span class="p">)</span>
  <span class="p">{</span>
    <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">id</span>           <span class="o">=</span> <span class="nv">$id</span><span class="p">;</span>
    <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">name</span>         <span class="o">=</span> <span class="nv">$name</span><span class="p">;</span>
    <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">client</span>       <span class="o">=</span> <span class="nv">$client</span><span class="p">;</span>
    <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">worker</span>       <span class="o">=</span> <span class="nv">$worker</span><span class="p">;</span>
    <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">serviceRate</span>  <span class="o">=</span> <span class="nv">$serviceRate</span><span class="p">;</span>
    <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">startDate</span>    <span class="o">=</span> <span class="nv">$startDate</span> <span class="o">??</span> <span class="k">new</span> <span class="nc">DateTimeImmutable</span><span class="p">(</span><span class="s1">'now'</span><span class="p">,</span> <span class="k">new</span> <span class="nc">DateTimeZone</span><span class="p">(</span><span class="s1">'UTC'</span><span class="p">));</span>

    <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">addEvent</span><span class="p">(</span><span class="nv">$event</span><span class="p">);</span>
  <span class="p">}</span>

  <span class="k">public</span> <span class="k">function</span> <span class="n">addEvent</span><span class="p">(</span><span class="kt">Event</span> <span class="nv">$event</span><span class="p">):</span> <span class="kt">void</span>
  <span class="p">{</span>
    <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">checkEventConflicts</span><span class="p">(</span><span class="nv">$event</span><span class="p">);</span>

    <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">events</span><span class="p">[]</span> <span class="o">=</span> <span class="nv">$event</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="k">private</span> <span class="k">function</span> <span class="n">checkEventConflicts</span><span class="p">(</span><span class="kt">Event</span> <span class="nv">$event</span><span class="p">):</span> <span class="kt">void</span>
  <span class="p">{</span>
    <span class="c1">// Throw exception if this event conflicts with any already in $this-&gt;events array.</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Note that the constructor requires everything that constitutes a valid schedule according to the business:</p>

<ul>
  <li>Name</li>
  <li>Client, for whom this schedule exists</li>
  <li>Worker who will attend to the client</li>
  <li>Service rate, so we can determine billing and payment</li>
  <li>At least one event</li>
</ul>

<p>This is already a major improvement over the procedural example. What’s the bare-minimum required for a schedule to be valid? Now we know.</p>

<p>We can also declare an optional start date upon instantiation or allow it to default to <em>now</em>. According to the business, schedule start dates can’t be changed, so this is only available in the constructor. A method for changing the start date on an existing <code class="language-plaintext highlighter-rouge">Schedule</code> would violate our business rules.</p>

<p>Let’s set up a new object with the data from the procedural example.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$schedule</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Schedule</span><span class="p">(</span>
  <span class="mi">42</span><span class="p">,</span>
  <span class="s1">'Doe, John'</span><span class="p">,</span>
  <span class="nv">$client</span><span class="p">,</span> <span class="c1">// Object representing client with ID 11</span>
  <span class="nv">$worker</span><span class="p">,</span> <span class="c1">// Object representing worker with ID 27</span>
  <span class="nv">$serviceRate</span><span class="p">,</span> <span class="c1">// Object representing hourly service rate with ID 7</span>
  <span class="nv">$monday</span><span class="p">,</span> <span class="c1">// An event object representing Monday from 8:30am to 5:00pm</span>
  <span class="k">new</span> <span class="nc">DateTimeImmutable</span><span class="p">(</span><span class="s1">'06/24/2018'</span><span class="p">,</span> <span class="k">new</span> <span class="nc">DateTimeZone</span><span class="p">(</span><span class="s1">'UTC'</span><span class="p">))</span>
<span class="p">);</span>

<span class="nv">$schedule</span><span class="o">-&gt;</span><span class="nf">addEvent</span><span class="p">(</span><span class="nv">$wednesday</span><span class="p">);</span> <span class="c1">// An event object representing Wednesday from 8:30am to 5:00pm</span>
<span class="nv">$schedule</span><span class="o">-&gt;</span><span class="nf">addEvent</span><span class="p">(</span><span class="nv">$thursday</span><span class="p">);</span> <span class="c1">// An event object representing Thursday from 8:30am to 5:00pm</span>
<span class="c1">// etc...</span>
</code></pre></div></div>

<p>For the sake of clear examples, I’m omitting some things, like the definition and creation of the objects we’re passing in here. But that’s kind of the point, isn’t it? A <code class="language-plaintext highlighter-rouge">Schedule</code> object needs to know specific information about the client, worker, service rate, and events, so it type hints against <code class="language-plaintext highlighter-rouge">Client</code>, <code class="language-plaintext highlighter-rouge">Worker</code>, <code class="language-plaintext highlighter-rouge">ServiceRate</code>, and <code class="language-plaintext highlighter-rouge">Event</code> objects to ensure it has exactly what it needs. Other parts of the system are responsible for the creation and validation of those objects, so by the time they get passed in during the construction of <code class="language-plaintext highlighter-rouge">Schedule</code>, we know we’ve got valid information to work with.</p>

<p>Remember, OOP is about more than just a single object here or there. The benefits of OOP emerge in a community of objects, when objects begin collaborating with each other.</p>

<p>Again, this is a major improvement over the procedural code, where the requirements of the <code class="language-plaintext highlighter-rouge">createSchedule</code> function were entirely hidden.</p>

<p>As we’ve already seen, we can’t change the start date on an existing schedule. But what can we do? Some additional methods are called for here, and whatever is allowed should be clearly advertised by the method names.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">Schedule</span>
<span class="p">{</span>
  <span class="c1">// ...</span>

  <span class="k">private</span> <span class="nv">$endDate</span><span class="p">;</span>
  <span class="k">private</span> <span class="nv">$repeatEveryNumberOfWeeks</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
  <span class="k">private</span> <span class="nv">$roundTripMileage</span><span class="p">;</span>

  <span class="c1">// ...</span>

  <span class="k">public</span> <span class="k">function</span> <span class="n">changeRoundTripMileage</span><span class="p">(</span><span class="kt">float</span> <span class="nv">$mileage</span><span class="p">):</span> <span class="kt">void</span>
  <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="nv">$mileage</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">)</span>
    <span class="p">{</span>
      <span class="k">throw</span> <span class="k">new</span> <span class="nc">InvalidArgumentException</span><span class="p">(</span><span class="s1">'Mileage must be a positive number.'</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">roundTripMileage</span> <span class="o">=</span> <span class="nv">$mileage</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="k">public</span> <span class="k">function</span> <span class="n">endOn</span><span class="p">(</span><span class="kt">DateTimeImmutable</span> <span class="nv">$endDate</span><span class="p">):</span> <span class="kt">void</span>
  <span class="p">{</span>
    <span class="nv">$now</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">DateTimeImmutable</span><span class="p">(</span><span class="s1">'now'</span><span class="p">,</span> <span class="k">new</span> <span class="nc">DateTimeZone</span><span class="p">(</span><span class="s1">'UTC'</span><span class="p">));</span>

    <span class="k">if</span> <span class="p">(</span><span class="nv">$endDate</span> <span class="o">&lt;</span> <span class="nv">$now</span><span class="p">)</span>
    <span class="p">{</span>
      <span class="k">throw</span> <span class="k">new</span> <span class="nc">InvalidArgumentException</span><span class="p">(</span><span class="s1">'Cannot make a schedule end in the past.'</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">endDate</span> <span class="o">=</span> <span class="nv">$endDate</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="k">public</span> <span class="k">function</span> <span class="n">reassignTo</span><span class="p">(</span><span class="kt">Worker</span> <span class="nv">$worker</span><span class="p">):</span> <span class="kt">void</span>
  <span class="p">{</span>
    <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">worker</span> <span class="o">=</span> <span class="nv">$worker</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="k">public</span> <span class="k">function</span> <span class="n">repeatEveryNumberOfWeeks</span><span class="p">(</span><span class="kt">int</span> <span class="nv">$frequency</span><span class="p">):</span> <span class="kt">void</span>
  <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="nv">$frequency</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">)</span>
    <span class="p">{</span>
      <span class="k">throw</span> <span class="k">new</span> <span class="nc">InvalidArgumentException</span><span class="p">(</span><span class="s1">'Frequency for repeating every x number of weeks must be a positive integer.'</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">repeatEveryNumberOfWeeks</span> <span class="o">=</span> <span class="nv">$frequency</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Note that each method is responsible for ensuring the information being added or updated is valid according to the business rules.</p>

<p>This just barely scratches the surface. There’s a lot more that <code class="language-plaintext highlighter-rouge">Schedule</code> might be responsible for as part of its role in the system. The point here is just to introduce you to the object-oriented way of thinking.</p>

<p><strong><em>That objects are responsible for the important work of the system</em></strong> is not only <em>the</em> distinguishing characteristic of OOP, it’s fundamental to the very practice of writing object-oriented software.</p>

<p>This is a point worth repeating. As programmers learn OOP, it’s easy to get lost in theory, principles, and design patterns and lose sight of the objects themselves. If you’re new to OOP, first commit yourself to thinking in terms of objects, <em>each with its own role</em>. It’s crucial. Everything else in OOP is built on it.</p>

<p>At some point you’ll start running into mental obstacles, unsure of how to proceed. And instead of seeing those principles and design patterns as oppressive, dogmatic rules to follow, you’ll find them to be a helpful toolkit for writing better code.</p>

<p><a name="not-just-about-using-classes" class="u-anchor"></a></p>
<h3 class="c-linked-heading"><a href="#not-just-about-using-classes" class="c-linked-heading__link">#</a>
Not Just About Using Classes
</h3>

<p>I’ve alluded to it already, but let’s be clear about something. There’s a common misconception that using classes means the code is object-oriented. That’s not even a little bit true.</p>

<p>Think of a class as a blueprint; a code organization tool, if you will. That blueprint can be for a set of related functions and scoped variables. That’s still procedural code. Or it can be the blueprint for objects that are created when that class is instantiated, each of which with knowledge and behavior that helps it accomplish its role. That’s object-oriented.</p>

<p><a name="seems-like-a-lot-more-code-to-do-the-same-thing-whats-the-real-benefit" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#seems-like-a-lot-more-code-to-do-the-same-thing-whats-the-real-benefit" class="c-linked-heading__link">#</a>
Seems like a lot more code to do the same thing. What's the real benefit?
</h2>

<p>In a word: sanity.</p>

<p>Object-oriented programming is orders of magnitude better at handling complexity than procedural programming. Divvying up responsibilities frees you up to focus on the problem at hand, which means a dramatically lower cognitive load. It makes it <em>so</em> much easier to reason about the code you’re working in. While there are quite a few big benefits to object-oriented programming, that’s the one that wins the day for me.</p>

<p>With procedural code, business rules are scattered all throughout the system and locked up in the head of the most experienced programmer on the team. To effectively write new code, a coder must build up an understanding of how the entire system works and what state it might be in by the time it reaches the code they’re working on.</p>

<aside class="c-blocks__pull-quote c-blocks__pull-quote--right">That objects are responsible for the important work of the system is not only the distinguishing characteristic of OOP, it's fundamental to the very practice of writing object-oriented software.</aside>

<p>Is “service code” a required data point for invoices in this system? What is a valid service code? Only digits? Letters and numbers? Are any special characters allowed? Once an invoice has been sent, can it be deleted? Or changed in any way?</p>

<p>In a procedural codebase, the answer to these fairly important questions could be anywhere from an input form, to a code comment that may or may not be out of date, to the many places where they’re saved to the database.</p>

<p>With OOP, those business rules are written into the responsible objects, hiding the complexity of their implementation. Code is read by humans many times more often than it’s written, and OOP helps optimize for the humans who read it.</p>

<p>Stop running into the restaurant’s kitchen with your arms full of groceries and a list of instructions for the chef. Future developers will thank you. Even if it’s just you in six months.</p>

<p><a name="further-reading" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#further-reading" class="c-linked-heading__link">#</a>
Further Reading
</h2>

<ul>
  <li><a target="_blank" rel="noopener" href="https://www.amazon.com/Introduction-Object-Oriented-Programming-3rd/dp/0201760312/ref=sr_1_1?ie=UTF8&amp;qid=1531142728&amp;sr=8-1&amp;keywords=an+introduction+to+object-oriented+programming">An Introduction to Object-Oriented Programming</a>  by Timothy Budd, the first seven chapters of which are  <a target="_blank" rel="noopener" href="http://web.engr.oregonstate.edu/~budd/Books/oopintro3e/info/ReadMe.html">available for free at his website</a></li>
  <li><a target="_blank" rel="noopener" href="https://www.amazon.com/gp/product/0201379430/ref=oh_aui_detailpage_o02_s00?ie=UTF8&amp;psc=1">Object Design: Roles, Responsibilities, and Collaborations</a>  by Rebecca Wirfs-Brock and Alan McKean</li>
</ul>]]></content><author><name>Kevin Smith</name></author><category term="PHP" /><summary type="html"><![CDATA[In a word: sanity.]]></summary></entry><entry><title type="html">Protect Your PHP Application from SQL Injection</title><link href="https://kevinsmith.io/protect-your-php-application-from-sql-injection/" rel="alternate" type="text/html" title="Protect Your PHP Application from SQL Injection" /><published>2018-04-10T02:54:00+00:00</published><updated>2018-04-10T02:54:00+00:00</updated><id>https://kevinsmith.io/protect-your-php-application-from-sql-injection</id><content type="html" xml:base="https://kevinsmith.io/protect-your-php-application-from-sql-injection/"><![CDATA[<p><a name="the-problem" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#the-problem" class="c-linked-heading__link">#</a>
The Problem
</h2>

<p>One of the most common security threats in web applications is SQL injection. It continues to top the  <a target="_blank" rel="noopener" href="https://www.owasp.org/index.php/Top_10-2017_Top_10">OWASP application security risk list</a>. Yet somehow  <a target="_blank" rel="noopener" href="https://twitter.com/jimplush/status/614443957347463169">many developers don’t even know what it is</a>.</p>

<p>SQL injection is when a malicious SQL query is injected into a legitimate query run by the application, usually by a nefarious user through an input field in the user interface. It happens when the application isn’t protecting the database from raw user input—common in <em>so many</em> PHP applications—and a cleverly formed input tricks the database into running the malicious query.</p>

<p><a name="a-simple-example" class="u-anchor"></a></p>
<h3 class="c-linked-heading"><a href="#a-simple-example" class="c-linked-heading__link">#</a>
A Simple Example
</h3>

<p>Imagine this query in an application with user profiles, where <code class="language-plaintext highlighter-rouge">$_GET['userId']</code> comes from the query string to identify the user for the profile currently being viewed.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$query</span> <span class="o">=</span> <span class="s1">'SELECT * FROM Users WHERE id='</span> <span class="o">+</span> <span class="nv">$_GET</span><span class="p">[</span><span class="s1">'userId'</span><span class="p">];</span>
</code></pre></div></div>

<p>This query would return the user data we’re looking for.</p>

<p>But what if the viewer changes the query string to <code class="language-plaintext highlighter-rouge">profile.php?userId=1%20OR%201=1</code>?</p>

<p>Given the code above, the query would look like this going into the database.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="no">SELECT</span> <span class="o">*</span> <span class="no">FROM</span> <span class="nc">Users</span> <span class="no">WHERE</span> <span class="n">id</span><span class="o">=</span><span class="mi">1</span> <span class="k">OR</span> <span class="mi">1</span><span class="o">=</span><span class="mi">1</span>
</code></pre></div></div>

<p>That’s a valid query, and if your application just runs it as-is, doing nothing to protect the database from the user input, that query will evaluate true for <em>every</em> record in the Users table. <strong>It will return all the data for every record in the table.</strong> You’ll likely leak details about <em>all</em> your users.</p>

<p>Now yes, <em>of course</em> you should be  <a target="_blank" rel="noopener" href="https://kevinsmith.io/sanitize-your-inputs#validate-on-input">validating all user input</a>  coming into your application, but that is an entirely different responsibility. That’s more about rejecting bad data than protecting the database.</p>

<p>And contrary to scores of outdated tutorials on the subject,  <a target="_blank" rel="noopener" href="https://kevinsmith.io/sanitize-your-inputs">sanitizing user input doesn’t cut it</a>. As  <a target="_blank" rel="noopener" href="https://paragonie.com/blog/2015/05/preventing-sql-injection-in-php-applications-easy-and-definitive-guide">the SQL injection guide</a>  at Paragon Initiative puts it:</p>

<blockquote>
  <p>While it’s <em>possible</em> to prevent attacks by rewriting the incoming data stream before you send it to your database driver, it’s <a target="_blank" rel="noopener" href="https://kraft.im/2015/05/how-emoji-saved-your-sites-hide">rife with dangerous nuance</a> and <a target="_blank" rel="noopener" href="http://stackoverflow.com/a/12118602/2224584">obscure edge-cases</a>. (Both links in the previous sentence are highly recommended.)</p>

  <p>Unless you want to take the time to research and attain complete mastery over every Unicode format your application uses or accepts, you’re better off not even trying to sanitize your inputs. Prepared statements are more effective at preventing SQL injection than escaping strings.</p>

  <p>Furthermore, altering your incoming data stream can cause data corruption, especially if you are dealing with raw binary blobs (e.g. images or encrypted messages).</p>

  <p><strong>Prepared statements are easier and can guarantee SQL Injection prevention.</strong></p>
</blockquote>

<p>(You may see this same technique referred to as “parameterized queries” or “parameter binding” elsewhere. Practically speaking, the terminology is interchangeable.)</p>

<p><a name="the-solution" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#the-solution" class="c-linked-heading__link">#</a>
The Solution
</h2>

<p>It’s actually not that hard to prevent SQL injections in a PHP application with a MySQL database.</p>

<p><strong>Native prepared statements are guaranteed to prevent SQL injection attacks.</strong></p>

<p>Think of prepared statements like this: you “prepare” the database for a query you’re going to run by sending a template with placeholders for variable data in the query. Then separately, you send data for those placeholders and tell the database to execute the query.</p>

<p>The code above rewritten as a prepared statement looks like this.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$statement</span> <span class="o">=</span> <span class="nv">$pdo</span><span class="o">-&gt;</span><span class="nf">prepare</span><span class="p">(</span><span class="s1">'SELECT * FROM Users WHERE id=?'</span><span class="p">);</span>

<span class="nv">$statement</span><span class="o">-&gt;</span><span class="nf">execute</span><span class="p">([</span><span class="nv">$_GET</span><span class="p">[</span><span class="s1">'userId'</span><span class="p">]]);</span>
<span class="nv">$user</span> <span class="o">=</span> <span class="nv">$statement</span><span class="o">-&gt;</span><span class="nf">fetch</span><span class="p">(</span><span class="no">PDO</span><span class="o">::</span><span class="no">FETCH_ASSOC</span><span class="p">);</span>
</code></pre></div></div>

<p>With native prepared statements, that interaction does indeed take place in 2 separate requests. Because the statement and the data are sent separately—literally sent as separate packets of data to the database server—there’s no way for cleverly formed data to alter the structure of the SQL query.</p>

<p>The prepared statement and data are <em>not</em> sent separately if emulation is enabled, so you should disable it. Emulated prepare statements are constructed differently (by PHP rather than by the database server), and don’t fully protect you from SQL injection.</p>

<p><strong>Important:</strong> <em>never</em> allow user input directly in the statement template, such as letting user input dictate which table or column is being queried. Doing so would still leave you open to attack.  <a target="_blank" rel="noopener" href="https://paragonie.com/blog/2015/05/preventing-sql-injection-in-php-applications-easy-and-definitive-guide">Consider using a whitelist</a>  in this case.</p>

<p>Use PDO to connect to your database, explicitly set your connection charset, and disable emulated prepare statements. For clarity on errors, I strongly recommend  <a target="_blank" rel="noopener" href="https://phpdelusions.net/pdo#errors">enabling exceptions for error handling</a>  as well.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$pdo</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PDO</span><span class="p">(</span>
    <span class="s1">'mysql:host=localhost;dbname=db_name;charset=utf8mb4'</span><span class="p">,</span>
    <span class="s1">'db_user'</span><span class="p">,</span>
    <span class="s1">'db_pass'</span>
<span class="p">);</span>
<span class="nv">$pdo</span><span class="o">-&gt;</span><span class="nf">setAttribute</span><span class="p">(</span><span class="no">PDO</span><span class="o">::</span><span class="no">ATTR_EMULATE_PREPARES</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span>
<span class="nv">$pdo</span><span class="o">-&gt;</span><span class="nf">setAttribute</span><span class="p">(</span><span class="no">PDO</span><span class="o">::</span><span class="no">ATTR_ERRMODE</span><span class="p">,</span> <span class="no">PDO</span><span class="o">::</span><span class="no">ERRMODE_EXCEPTION</span><span class="p">);</span>
</code></pre></div></div>

<p>Note that your connection charset must be set in  <a target="_blank" rel="noopener" href="http://www.php.net/manual/en/ref.pdo-mysql.connection.php">PDO’s DSN parameter</a>  (rather than with a <code class="language-plaintext highlighter-rouge">SET NAMES</code> statement) to prevent  <a target="_blank" rel="noopener" href="https://stackoverflow.com/a/12202218/1217620">this potential vulnerability</a>.</p>

<p><em>For a deep dive on the details behind all this, read the articles already referenced many times in this post: the Paragon Initiative’s <a target="_blank" rel="noopener" href="https://paragonie.com/blog/2015/05/preventing-sql-injection-in-php-applications-easy-and-definitive-guide">definitive guide on preventing SQL injection</a> and <a target="_blank" rel="noopener" href="https://phpdelusions.net/pdo">this exhaustive PDO explainer</a>.</em></p>

<p><a name="you-might-already-be-protected" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#you-might-already-be-protected" class="c-linked-heading__link">#</a>
You Might Already Be Protected
</h2>

<p>If you’re using a good query builder or ORM that <em>always</em> uses native prepared statements and sets the connection charset in PDO’s DSN parameter under the hood, you’re already protected. But don’t breathe that sigh of relief until you do some research to ensure your favorite database abstraction makes use of native prepared statements.</p>

<p>Still, it’s important to be very familiar with these techniques. At some point, you’ll run into a situation where you need to directly query the database. Or you’ll find yourself working on a legacy application that doesn’t have a query builder or ORM that you can rely on for protection.</p>

<p>It is ultimately your responsibility to ensure your application is protected from one of the most continually pervasive web application threats out there.</p>]]></content><author><name>Kevin Smith</name></author><category term="PHP" /><summary type="html"><![CDATA[It's one of the most continually pervasive security threats. It continues to top the OWASP security risk list. Yet somehow many developers still don't even know what it is.]]></summary></entry><entry><title type="html">“Didn’t you just build your own framework?”</title><link href="https://kevinsmith.io/didnt-you-just-build-your-own-framework/" rel="alternate" type="text/html" title="“Didn’t you just build your own framework?”" /><published>2018-04-04T16:17:00+00:00</published><updated>2018-04-04T16:17:00+00:00</updated><id>https://kevinsmith.io/didnt-you-just-build-your-own-framework</id><content type="html" xml:base="https://kevinsmith.io/didnt-you-just-build-your-own-framework/"><![CDATA[<p>Wow, <a target="_blank" rel="noopener" href="https://kevinsmith.io/modern-php-without-a-framework">my last post</a>  got way more attention than I expected, even making it all the way to the front page of  <a target="_blank" rel="noopener" href="https://news.ycombinator.com/item?id=16725492">Hacker News</a>  this past Saturday! To my surprise most of the response was positive. Even  <a target="_blank" rel="noopener" href="https://www.reddit.com/r/PHP/comments/85wjmu/modern_php_without_a_framework/">Reddit</a>  and Hacker News weren’t too brutal. There was the expected amount of snark, to be sure, but there was also some genuine misunderstanding and confusion about a few things, so let’s clear them up.</p>

<p><a name="so-this-is-a-framework-you-just-built-a-framework" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#so-this-is-a-framework-you-just-built-a-framework" class="c-linked-heading__link">#</a>
So... this is a framework. You just built a framework.
</h2>

<p>Well, no.</p>

<p>You could blindly use  <a target="_blank" rel="noopener" href="https://github.com/kevinsmith/no-framework">the resulting code</a>  as your new micro-framework, but I wouldn’t recommend it. It’s not intended to be used in production, and the only documentation for it is  <a target="_blank" rel="noopener" href="https://kevinsmith.io/modern-php-without-a-framework">the blog post</a>  that shows how it was wired up.</p>

<p><strong>Indeed, the point of that post was to **<em>show how</em></strong> it was done.**</p>

<p>At some point in the future, you <em>will</em> find yourself starting down a legacy application. Perhaps you didn’t make any of the decisions to get the application to this point, but here you are. It doesn’t have a  <a target="_blank" rel="noopener" href="https://kevinsmith.io/modern-php-without-a-framework#what-is-dependency-injection">DI container</a>, but it needs one.</p>

<p>Faced with such a need, I’ve seen countless developers assume this means they need to rebuild the application in a framework, or worse, try to slap a framework onto the existing codebase. In all but the simplest of applications, both courses of action are a fool’s errand.</p>

<p>Aside from a rewrite nearly <em>always</em> taking longer than estimated and blocking new business value while in progress, it’s impossible to know all the business knowledge contained in that existing application. You’ll almost certainly lose some of it in the rewrite.</p>

<p>Oh, and you’ll introduce new bugs. The rewrite won’t be perfect either.</p>

<p>To avoid a rewrite though, you need to know how those frameworks do what they do under the hood. If the only experience you’ve ever had building PHP applications was with a framework, you might not even know  <a target="_blank" rel="noopener" href="https://kevinsmith.io/modern-php-without-a-framework#autoloading-and-third-party-packages">how to add Composer</a>  or  <a target="_blank" rel="noopener" href="https://kevinsmith.io/modern-php-without-a-framework#properly-sending-responses">how to send a response back</a>  to the client that requested it. And that’s okay. It’s actually pretty hard to find an easy-to-follow guide that connects all the dots, especially for those things that a framework usually handles for you. The blog post attempts to fill in some of those gaps.</p>

<p><a name="this-looks-like-java-you-should-just-use-java" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#this-looks-like-java-you-should-just-use-java" class="c-linked-heading__link">#</a>
This looks like Java. You should just use Java.
</h2>

<p>I saw some variation of this comment several times, and I’ll bundle with it another one I saw: <em>If you want to grow as a developer, you should learn Go, Node.js, Python, etc.</em></p>

<p>Missing the point, of course. Yes, you can learn a lot by trying your hand in another language, but  <a target="_blank" rel="noopener" href="https://kevinsmith.io/modern-php-without-a-framework">the blog post</a>  is specifically speaking to PHP developers about a circumstance that they <em>will</em> one day face if they haven’t already: an existing <strong>PHP</strong> application in much need of some modernization.</p>

<p>I can’t think of more terrible advice than to tell that developer they should rewrite the whole thing in another language.</p>

<p><a name="interoperability-is-over-rated-nobody-actually-swaps-out-components-in-real-applications" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#interoperability-is-over-rated-nobody-actually-swaps-out-components-in-real-applications" class="c-linked-heading__link">#</a>
Interoperability is over-rated. Nobody actually swaps out components in real applications.
</h2>

<p>I remember years ago hearing that a great benefit to using a database-agnostic query builder was that you could swap out your database system later on. That was ridiculous, of course. Nobody actually did that with real applications.</p>

<p>So I get where this argument is coming from. But the benefit to interoperability and the PSR standards <em>isn’t</em> that you can swap out implementations later on. The benefit is that packages can be designed and built by different vendors without being tightly coupled to a particular implementation of a more foundational component like  <a target="_blank" rel="noopener" href="https://www.php-fig.org/psr/psr-7/">HTTP messages</a>, a  <a target="_blank" rel="noopener" href="https://www.php-fig.org/psr/psr-11/">DI container</a>, a  <a target="_blank" rel="noopener" href="https://www.php-fig.org/psr/psr-3/">logger</a>, or a  <a target="_blank" rel="noopener" href="https://www.php-fig.org/psr/psr-15/">middleware handler</a>.</p>

<p>Before PSR-11, any PHP library that needed to resolve dependencies would simply require a particular DI container. If you didn’t use that DI container, you couldn’t use that library. A common interface for dependency injection containers means that such a library can easily be written for compatibility with a wide variety of DI containers.</p>

<p>Even more commonly, third-party packages that dealt with any aspect of HTTP messages tended to be tightly coupled to a particular framework. Since one of the previously unique benefits PHP frameworks provided was an abstraction of HTTP messages, that was the only way these package developers could be sure their library would work in a given codebase.</p>

<p>Ultimately, interoperability standards lay the groundwork for a richer component ecosystem with packages that are available for much wider usage than before.</p>

<p>As an application developer, interoperability means you can build with the confidence that you won’t be pigeonholed into a particular dependency graph just because your application makes use of a particular package now. If you stick to the standards, there’s a wide variety of packages available to plug in whenever you need them.</p>

<p><a name="but-a-framework-lets-me-get-started-building-a-real-application-right-away" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#but-a-framework-lets-me-get-started-building-a-real-application-right-away" class="c-linked-heading__link">#</a>
But a framework lets me get started building a real application right away.
</h2>

<p>Sure, but  <a target="_blank" rel="noopener" href="https://kevinsmith.io/modern-php-without-a-framework">the blog post</a>  wasn’t talking about greenfield projects. It was encouraging developers to learn how it works under the hood so they can apply modern coding techniques to existing PHP applications.</p>

<p><a name="this-is-wildly-over-engineered-just-to-display-hello-world" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#this-is-wildly-over-engineered-just-to-display-hello-world" class="c-linked-heading__link">#</a>
This is wildly over-engineered just to display Hello World.
</h2>

<p>I mean, come on.</p>]]></content><author><name>Kevin Smith</name></author><category term="PHP" /><summary type="html"><![CDATA[Wow, my last post got way more attention than I expected! There was the expected amount of snark, to be sure, but there was also some genuine misunderstanding and confusion about a few things, so let's clear them up.]]></summary></entry><entry><title type="html">Modern PHP Without a Framework</title><link href="https://kevinsmith.io/modern-php-without-a-framework/" rel="alternate" type="text/html" title="Modern PHP Without a Framework" /><published>2018-03-20T13:29:00+00:00</published><updated>2018-03-20T13:29:00+00:00</updated><id>https://kevinsmith.io/modern-php-without-a-framework</id><content type="html" xml:base="https://kevinsmith.io/modern-php-without-a-framework/"><![CDATA[<p>I’ve got a challenge for you. The next time you start a new project, try <strong><em>not</em></strong> using a PHP framework.</p>

<p>Now, this isn’t an anti-framework screed. Neither is it a promotion of <a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Not_invented_here">not-invented-here</a> thinking. After all, we’re going to be using some packages written by several framework developers in this tutorial. I’ve got nothing but great respect for the innovation going on in that space.</p>

<p>This isn’t about them. This is about you. It’s about giving yourself the opportunity to grow as a developer.</p>

<p>Perhaps the biggest benefit you’ll find working without a framework is the wealth of knowledge about what’s going on under the hood. You get to see exactly what’s happening without relying on the framework’s magic to take care of things for you in a way that you can’t debug and don’t really understand.</p>

<p>It’s quite possible your next job will not grant the luxury of starting a greenfield project with your framework of choice. The reality is that most high-value, business-critical PHP jobs involve existing applications. And whether that application is built in a framework currently enjoying popular support like Laravel or Symfony, a framework from days gone by like CodeIgniter or FuelPHP, or even the depressingly widespread <a target="_blank" rel="noopener" href="https://leanpub.com/mlaphp">legacy PHP application employing an “include-oriented architecture”</a>, building <em>without</em> a framework now will better prepare you to take on <em>any</em> PHP project in the future.</p>

<p>In the past, it was an uphill battle to build without a framework because <em>some kind of system</em> had to interpret and route HTTP requests, send HTTP responses, and manage dependencies. The lack of industry standards necessarily meant that, at the very least, <em>those</em> components of a framework were tightly coupled. If you didn’t start with a framework, you’d end up building one yourself.</p>

<p>But today, thanks to all the autoloading and interoperability work done by <a target="_blank" rel="noopener" href="https://www.php-fig.org/">PHP-FIG</a>, building without a framework doesn’t mean building it all by yourself. There are so many excellent, interoperable packages from a wide range of vendors. Pulling it all together is easier than you think!</p>

<p><a name="php-how-does-it-work" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#php-how-does-it-work" class="c-linked-heading__link">#</a>
PHP, How Does it Work?
</h2>

<p>Before we get into anything else, it’s important to understand how PHP applications interact with the outside world.</p>

<p>PHP runs server-side applications in a request/response cycle. Every interaction with your app—whether it’s from the browser, the command line, or a REST API—comes into the app as a request. When that request is received, the app is booted up, it processes the request to generate a response, the response is emitted back to the client that made the request, and the app shuts down. That happens with <em>every</em> interaction.</p>

<p><a name="the-front-controller" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#the-front-controller" class="c-linked-heading__link">#</a>
The Front Controller
</h2>

<p>Armed with that knowledge, we’ll kick things off with the front controller. The front controller is the PHP file that handles every request for your app. It’s the first PHP file a request hits on its way into your app, and (essentially) the last PHP file a response runs through on its way out of your app.</p>

<p>Let’s use the classic <em>Hello, world!</em> example served up by <a target="_blank" rel="noopener" href="http://php.net/manual/en/features.commandline.webserver.php">PHP’s built-in web server</a> just to make sure we’ve got everything wired up correctly. If you haven’t already done so, be sure you have PHP 7.2 or newer installed in your environment.</p>

<p>Create a project directory with a <code class="language-plaintext highlighter-rouge">public</code> directory in it, and then inside it create <code class="language-plaintext highlighter-rouge">index.php</code> with the following code.</p>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
</pre></td><td class="code"><pre><span class="cp">&lt;?php</span>
<span class="k">declare</span><span class="p">(</span><span class="n">strict_types</span><span class="o">=</span><span class="mi">1</span><span class="p">);</span>

<span class="k">echo</span> <span class="s1">'Hello, world!'</span><span class="p">;</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p>Note that we’re declaring strict typing here—which is something you should do <a target="_blank" rel="noopener" href="http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration.strict">at the top of every PHP file</a> in your app—because type hints are <a target="_blank" rel="noopener" href="http://paul-m-jones.com/archives/6774">important for debugging and clearly communicating intent</a> to developers that come behind you.</p>

<p>Navigate to your project directory using a command-line tool (like Terminal on macOS) and start PHP’s built-in web server.</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>php <span class="nt">-S</span> localhost:8080 <span class="nt">-t</span> public/
</code></pre></div></div>

<p>Now load <a target="_blank" rel="noopener" href="http://localhost:8080/">http://localhost:8080/</a> in your browser. See “Hello, world!” without any errors?</p>

<p>Awesome. Now let’s move on to the meat and potatoes!</p>

<p><a name="autoloading-and-third-party-packages" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#autoloading-and-third-party-packages" class="c-linked-heading__link">#</a>
Autoloading and Third-Party Packages
</h2>

<p>When you first started with PHP, you may have used <code class="language-plaintext highlighter-rouge">includes</code> or <code class="language-plaintext highlighter-rouge">requires</code> statements throughout your app to bring in functionality or configuration from other PHP files. In general, we want to avoid that because it makes it much harder for a human to follow the code path and understand where dependencies lie. That makes debugging a <em>real</em> nightmare.</p>

<p>The solution is autoloading. Autoloading just means that when your application needs to use a class, PHP knows where to look for it and automatically loads it when it’s called for. It’s been available since PHP 5, but its usage really started picking up steam with the introduction of <a target="_blank" rel="noopener" href="https://www.php-fig.org/psr/psr-0/">PSR-0</a>  (the autoloading standard that has since been superseded by  <a target="_blank" rel="noopener" href="https://www.php-fig.org/psr/psr-4/">PSR-4</a>).</p>

<p>We could go through the rigamarole of writing our own autoloader, but since we’re going to use  <a target="_blank" rel="noopener" href="https://getcomposer.org/">Composer</a>  to manage third-party dependencies and it already includes a perfectly serviceable autoloader, let’s just use that one.</p>

<p>Make sure you’ve got Composer  <a target="_blank" rel="noopener" href="https://getcomposer.org/doc/00-intro.md">installed</a>  on your system. Then setup Composer for this project.</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>composer init
</code></pre></div></div>

<p>This will take you through an interactive guide to generate your <code class="language-plaintext highlighter-rouge">composer.json</code> configuration file. Once that’s done, open it in an editor and add the <code class="language-plaintext highlighter-rouge">autoload</code> field so it looks something like this. (This makes sure the autoloader knows where to look to find our app’s classes.)</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
    </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"kevinsmith/no-framework"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"An example of a modern PHP application bootstrapped without a framework."</span><span class="p">,</span><span class="w">
    </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"project"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"require"</span><span class="p">:</span><span class="w"> </span><span class="p">{},</span><span class="w">
    </span><span class="nl">"autoload"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"psr-4"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
            </span><span class="nl">"ExampleApp\\"</span><span class="p">:</span><span class="w"> </span><span class="s2">"src/"</span><span class="w">
        </span><span class="p">}</span><span class="w">
    </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>Now install composer for this project, which brings in any dependencies (if we had any yet) and sets up the autoloader for us.</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>composer <span class="nb">install</span>
</code></pre></div></div>

<p>Update <code class="language-plaintext highlighter-rouge">public/index.php</code> to bring in the autoloader. Ideally this is one of the few “include” statements you’ll use in your app.</p>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
</pre></td><td class="code"><pre><span class="cp">&lt;?php</span>
<span class="k">declare</span><span class="p">(</span><span class="n">strict_types</span><span class="o">=</span><span class="mi">1</span><span class="p">);</span>

<span class="hll"><span class="k">require_once</span> <span class="nb">dirname</span><span class="p">(</span><span class="k">__DIR__</span><span class="p">)</span> <span class="mf">.</span> <span class="s1">'/vendor/autoload.php'</span><span class="p">;</span>
</span>
<span class="k">echo</span> <span class="s1">'Hello, world!'</span><span class="p">;</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p>If you reload your app in the browser, you won’t see anything different. The autoloader is there, it’s just not doing any heavy lifting for us. Let’s move the <em>Hello, world!</em> example to an autoloaded class to see how that works.</p>

<p>Create a new directory from the project root called <code class="language-plaintext highlighter-rouge">src</code>, and inside it add <code class="language-plaintext highlighter-rouge">HelloWorld.php</code> with the following code.</p>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre><span class="cp">&lt;?php</span>
<span class="k">declare</span><span class="p">(</span><span class="n">strict_types</span><span class="o">=</span><span class="mi">1</span><span class="p">);</span>

<span class="kn">namespace</span> <span class="nn">ExampleApp</span><span class="p">;</span>

<span class="kd">class</span> <span class="nc">HelloWorld</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">announce</span><span class="p">():</span> <span class="kt">void</span>
    <span class="p">{</span>
        <span class="k">echo</span> <span class="s1">'Hello, autoloaded world!'</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p>Now in <code class="language-plaintext highlighter-rouge">public/index.php</code>, replace the echo statement with a call to the <code class="language-plaintext highlighter-rouge">announce</code> method on the <code class="language-plaintext highlighter-rouge">HelloWorld</code> class.</p>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
</pre></td><td class="code"><pre><span class="c1">// ...</span>

<span class="k">require_once</span> <span class="nb">dirname</span><span class="p">(</span><span class="k">__DIR__</span><span class="p">)</span> <span class="mf">.</span> <span class="s1">'/vendor/autoload.php'</span><span class="p">;</span>

<span class="hll"><span class="nv">$helloWorld</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">\ExampleApp\HelloWorld</span><span class="p">();</span>
</span><span class="hll"><span class="nv">$helloWorld</span><span class="o">-&gt;</span><span class="nf">announce</span><span class="p">();</span>
</span></pre></td></tr></tbody></table></code></pre></figure>

<p>Reload your app in the browser to see the new message!</p>

<p><a name="what-is-dependency-injection" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#what-is-dependency-injection" class="c-linked-heading__link">#</a>
What is Dependency Injection?
</h2>

<p>Dependency Injection is a programming technique where each dependency is provided to a class that requires it rather than that class reaching outside itself to get the information or functionality it needs.</p>

<p>For example, let’s say a class method in your application needs to read from the database. For that, you’ll need a database connection. A common technique is to create a new connection with credentials retrieved from the global space.</p>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code"><pre><span class="kd">class</span> <span class="nc">AwesomeClass</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">doSomethingAwesome</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$dbConnection</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">\PDO</span><span class="p">(</span>
            <span class="s2">"</span><span class="si">{</span><span class="nv">$_ENV</span><span class="p">[</span><span class="s1">'type'</span><span class="p">]</span><span class="si">}</span><span class="s2">:host=</span><span class="si">{</span><span class="nv">$_ENV</span><span class="p">[</span><span class="s1">'host'</span><span class="p">]</span><span class="si">}</span><span class="s2">;dbname=</span><span class="si">{</span><span class="nv">$_ENV</span><span class="p">[</span><span class="s1">'name'</span><span class="p">]</span><span class="si">}</span><span class="s2">"</span><span class="p">,</span>
            <span class="nv">$_ENV</span><span class="p">[</span><span class="s1">'user'</span><span class="p">],</span>
            <span class="nv">$_ENV</span><span class="p">[</span><span class="s1">'pass'</span><span class="p">]</span>
        <span class="p">);</span>
        
        <span class="c1">// Make magic happen with $dbConnection</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p>But that’s messy, it puts responsibilities in this method that don’t really belong here—creating a new DB connection object, retrieving credentials, <em>and</em> handling any issues that might come up if the connection fails—and it leads to <em>a lot</em> of code duplication across the app. If you ever try to unit test this class, you’ll find that you can’t. This class is tightly coupled to both the app environment and the database.</p>

<p>Instead, why not be as clear as possible about what your class needs to begin with? Let’s just require that the <code class="language-plaintext highlighter-rouge">PDO</code> object be injected into the class in the first place.</p>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre><span class="kd">class</span> <span class="nc">AwesomeClass</span>
<span class="p">{</span>
<span class="hll">    <span class="k">private</span> <span class="nv">$dbConnection</span><span class="p">;</span>
</span><span class="hll"> 
</span><span class="hll">    <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="no">\PDO</span> <span class="nv">$dbConnection</span><span class="p">)</span>
</span><span class="hll">    <span class="p">{</span>
</span><span class="hll">        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">dbConnection</span> <span class="o">=</span> <span class="nv">$dbConnection</span><span class="p">;</span>
</span><span class="hll">    <span class="p">}</span>
</span><span class="hll"> 
</span>    <span class="k">public</span> <span class="k">function</span> <span class="n">doSomethingAwesome</span><span class="p">()</span>
    <span class="p">{</span>        
<span class="hll">        <span class="c1">// Make magic happen with $this-&gt;dbConnection</span>
</span>    <span class="p">}</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p>That’s a lot cleaner, easier to understand, and less prone to bugs. Through type hinting and dependency injection, the method declares exactly what it needs to do its job and gets it without calling up an external dependency from inside itself. When it comes to unit testing, we’re in great shape to mock up a database connection and pass it in.</p>

<p>Now a dependency injection <em>container</em> is a tool that you wrap around your entire application to handle the job of creating and injecting those dependencies. The container is not required to be able to use the technique of dependency injection, but it helps considerably as your application grows and becomes more complex.</p>

<p>We’ll use one of the most popular DI containers for PHP: the aptly named  <a target="_blank" rel="noopener" href="http://php-di.org/">PHP-DI</a>. <em>(Worth noting that its docs have <a target="_blank" rel="noopener" href="http://php-di.org/doc/understanding-di.html">a different way of explaining dependency injection</a> that may be helpful to some readers.)</em></p>

<p><a name="the-dependency-injection-container" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#the-dependency-injection-container" class="c-linked-heading__link">#</a>
The Dependency Injection Container
</h2>

<p>Now that we’ve got Composer set up, it’s pretty painless to install PHP-DI. Head back over to your command line to install it.</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>composer require php-di/php-di
</code></pre></div></div>

<p>Update <code class="language-plaintext highlighter-rouge">public/index.php</code> to configure and build the container.</p>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code"><pre><span class="c1">// ...</span>

<span class="k">require_once</span> <span class="nb">dirname</span><span class="p">(</span><span class="k">__DIR__</span><span class="p">)</span> <span class="mf">.</span> <span class="s1">'/vendor/autoload.php'</span><span class="p">;</span>

<span class="hll"><span class="nv">$containerBuilder</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">\DI\ContainerBuilder</span><span class="p">();</span>
</span><span class="hll"><span class="nv">$containerBuilder</span><span class="o">-&gt;</span><span class="nf">useAutowiring</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
</span><span class="hll"><span class="nv">$containerBuilder</span><span class="o">-&gt;</span><span class="nf">useAttributes</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
</span><span class="hll"><span class="nv">$containerBuilder</span><span class="o">-&gt;</span><span class="nf">addDefinitions</span><span class="p">([</span>
</span><span class="hll">    <span class="nc">\ExampleApp\HelloWorld</span><span class="o">::</span><span class="n">class</span> <span class="o">=&gt;</span> <span class="nf">\DI\create</span><span class="p">(</span><span class="nc">\ExampleApp\HelloWorld</span><span class="o">::</span><span class="n">class</span><span class="p">)</span>
</span><span class="hll"><span class="p">]);</span>
</span><span class="hll"> 
</span><span class="hll"><span class="nv">$container</span> <span class="o">=</span> <span class="nv">$containerBuilder</span><span class="o">-&gt;</span><span class="nf">build</span><span class="p">();</span>
</span><span class="hll"> 
</span><span class="hll"><span class="nv">$helloWorld</span> <span class="o">=</span> <span class="nv">$container</span><span class="o">-&gt;</span><span class="nf">get</span><span class="p">(</span><span class="nc">\ExampleApp\HelloWorld</span><span class="o">::</span><span class="n">class</span><span class="p">);</span>
</span><span class="nv">$helloWorld</span><span class="o">-&gt;</span><span class="nf">announce</span><span class="p">();</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p>Nothing earth-shattering going on yet. It’s still a simple example with everything in one file so that it’s easy to see what’s going on.</p>

<p>So far, we’re just <a target="_blank" rel="noopener" href="http://php-di.org/doc/container-configuration.html#lightweight-container">configuring the container</a> so that we must  <a target="_blank" rel="noopener" href="http://php-di.org/doc/php-definitions.html">explicitly declare dependencies</a> (rather than using  <a target="_blank" rel="noopener" href="http://php-di.org/doc/autowiring.html">autowiring</a> or <a target="_blank" rel="noopener" href="https://php-di.org/doc/attributes.html">attributes</a>), and retrieving the <code class="language-plaintext highlighter-rouge">HelloWorld</code> object from the container.</p>

<p><em>A brief aside: Autowiring is a great feature offered by many DI containers to help minimize mindless configuration, but we’re disabling it in this tutorial to maximize learning. Explicitly configuring all dependencies here will give you a much better understanding for what an autowiring DI container is doing under the hood.</em></p>

<p>Let’s make things even easier to read by  <a target="_blank" rel="noopener" href="http://php.net/manual/en/language.namespaces.importing.php">importing namespaces</a>  where we can.</p>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre><span class="cp">&lt;?php</span>
<span class="k">declare</span><span class="p">(</span><span class="n">strict_types</span><span class="o">=</span><span class="mi">1</span><span class="p">);</span>

<span class="hll"><span class="kn">use</span> <span class="nc">DI\ContainerBuilder</span><span class="p">;</span>
</span><span class="hll"><span class="kn">use</span> <span class="nc">ExampleApp\HelloWorld</span><span class="p">;</span>
</span><span class="hll"><span class="kn">use</span> <span class="k">function</span> <span class="n">DI\create</span><span class="p">;</span>
</span>
<span class="k">require_once</span> <span class="nb">dirname</span><span class="p">(</span><span class="k">__DIR__</span><span class="p">)</span> <span class="mf">.</span> <span class="s1">'/vendor/autoload.php'</span><span class="p">;</span>

<span class="hll"><span class="nv">$containerBuilder</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ContainerBuilder</span><span class="p">();</span>
</span><span class="nv">$containerBuilder</span><span class="o">-&gt;</span><span class="nf">useAutowiring</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
<span class="nv">$containerBuilder</span><span class="o">-&gt;</span><span class="nf">useAttributes</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
<span class="nv">$containerBuilder</span><span class="o">-&gt;</span><span class="nf">addDefinitions</span><span class="p">([</span>
<span class="hll">    <span class="nc">HelloWorld</span><span class="o">::</span><span class="n">class</span> <span class="o">=&gt;</span> <span class="nf">create</span><span class="p">(</span><span class="nc">HelloWorld</span><span class="o">::</span><span class="n">class</span><span class="p">)</span>
</span><span class="p">]);</span>

<span class="nv">$container</span> <span class="o">=</span> <span class="nv">$containerBuilder</span><span class="o">-&gt;</span><span class="nf">build</span><span class="p">();</span>

<span class="hll"><span class="nv">$helloWorld</span> <span class="o">=</span> <span class="nv">$container</span><span class="o">-&gt;</span><span class="nf">get</span><span class="p">(</span><span class="nc">HelloWorld</span><span class="o">::</span><span class="n">class</span><span class="p">);</span>
</span><span class="nv">$helloWorld</span><span class="o">-&gt;</span><span class="nf">announce</span><span class="p">();</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p>As it stands right now, this just looks like a lot of extra fuss to do what we were already doing before.</p>

<p>Not to worry, the container comes in handy when we add a few other tools to help direct the request through our application. They’ll use the container to load the right classes when and where we need them.</p>

<p><a name="middleware" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#middleware" class="c-linked-heading__link">#</a>
Middleware
</h2>

<p>If you imagine your application like an onion with requests coming in from the outside, going to the center of the onion, and going back out as responses, then middleware is each layer of the onion receiving the request, potentially doing something with that request, and either passing it on to the layer below it or creating a response and sending it back up to the layer above it. (That can happen if the middleware is checking for a certain condition that the request does not satisfy, like requesting a non-existent route.)</p>

<p>If the request makes it all the way through, the app will process it and turn it into a response, and each middleware in reverse order will receive the response, potentially modify it, and pass it on to the next middleware.</p>

<p>A sampling of use cases where middleware can shine:</p>

<ul>
  <li>Debugging issues in development</li>
  <li>Gracefully handling exceptions in production</li>
  <li>Rate-limiting incoming requests</li>
  <li>Responding to incoming requests for unsupported media types</li>
  <li>Handling CORS</li>
  <li>Routing requests to the appropriate handler class</li>
</ul>

<p>Is middleware the only way to implement tools for handling these sorts of things? Not at all. But middleware implementations make the request/response cycle that much clearer for you, which means debugging is that much easier and development is that much quicker.</p>

<p>We’ll take advantage of middleware for the last use case listed above: routing.</p>

<p><a name="routing" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#routing" class="c-linked-heading__link">#</a>
Routing
</h2>

<p>A router uses information from an incoming request to figure out which class should handle it. (e.g. The URI <code class="language-plaintext highlighter-rouge">/products/purple-dress/medium</code> should be handled by <code class="language-plaintext highlighter-rouge">ProductDetails::class</code> with <code class="language-plaintext highlighter-rouge">purple-dress</code> and <code class="language-plaintext highlighter-rouge">medium</code> passed in as arguments.)</p>

<p>For our example app, we’ll use the popular  <a target="_blank" rel="noopener" href="https://github.com/nikic/FastRoute">FastRoute</a>  router through a  <a target="_blank" rel="noopener" href="https://github.com/middlewares/fast-route">PSR-15 compatible middleware implementation</a>.</p>

<p><a name="the-middleware-dispatcher" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#the-middleware-dispatcher" class="c-linked-heading__link">#</a>
The Middleware Dispatcher
</h2>

<p>To get our app to work with the FastRoute middleware—and any other middleware we install—we’ll need a middleware dispatcher.</p>

<p><a target="_blank" rel="noopener" href="https://www.php-fig.org/psr/psr-15/">PSR-15</a>  is a middleware standard that defines interfaces for both middleware and dispatchers (called “request handlers” in the spec), allowing interoperability amongst a wide variety of middleware and dispatchers. We just need to choose a PSR-15 compatible dispatcher, and we can be sure it’ll work with any PSR-15 compatible middleware.</p>

<p>Let’s install  <a target="_blank" rel="noopener" href="https://github.com/relayphp/Relay.Relay">Relay</a>  as the dispatcher.</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>composer require relay/relay
</code></pre></div></div>

<p>And since the PSR-15 middleware spec requires implementations to pass along  <a target="_blank" rel="noopener" href="http://www.php-fig.org/psr/psr-7/">PSR-7 compatible HTTP messages</a>, we’ll use <a target="_blank" rel="noopener" href="https://github.com/laminas/laminas-diactoros">Laminas Diactoros</a>  as our PSR-7 implementation.</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>composer require laminas/laminas-diactoros
</code></pre></div></div>

<p>Let’s get Relay ready to accept middleware.</p>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre><span class="c1">// ...</span>

<span class="kn">use</span> <span class="nc">DI\ContainerBuilder</span><span class="p">;</span>
<span class="kn">use</span> <span class="nc">ExampleApp\HelloWorld</span><span class="p">;</span>
<span class="hll"><span class="kn">use</span> <span class="nc">Relay\Relay</span><span class="p">;</span>
</span><span class="hll"><span class="kn">use</span> <span class="nc">Laminas\Diactoros\ServerRequestFactory</span><span class="p">;</span>
</span><span class="kn">use</span> <span class="k">function</span> <span class="n">DI\create</span><span class="p">;</span>

<span class="c1">// ...</span>

<span class="nv">$container</span> <span class="o">=</span> <span class="nv">$containerBuilder</span><span class="o">-&gt;</span><span class="nf">build</span><span class="p">();</span>

<span class="hll"><span class="nv">$middlewareQueue</span> <span class="o">=</span> <span class="p">[];</span>
</span><span class="hll"> 
</span><span class="hll"><span class="nv">$requestHandler</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Relay</span><span class="p">(</span><span class="nv">$middlewareQueue</span><span class="p">);</span>
</span><span class="hll"><span class="nv">$requestHandler</span><span class="o">-&gt;</span><span class="nf">handle</span><span class="p">(</span><span class="nc">ServerRequestFactory</span><span class="o">::</span><span class="nf">fromGlobals</span><span class="p">());</span>
</span></pre></td></tr></tbody></table></code></pre></figure>

<p>We’re using <code class="language-plaintext highlighter-rouge">ServerRequestFactory::fromGlobals()</code> on line 16 to  <a target="_blank" rel="noopener" href="https://docs.laminas.dev/laminas-diactoros/v2/usage/#marshaling-an-incoming-request">pull together all the information necessary to create a new Request</a>  and hand it off to Relay. This is where <code class="language-plaintext highlighter-rouge">Request</code> enters our middleware stack.</p>

<p>Now let’s add the FastRoute and request handler middleware. (FastRoute determines if a request is valid and can actually be handled by the application, and the request handler sends <code class="language-plaintext highlighter-rouge">Request</code> to the handler configured for that route in the routes definition.)</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>composer require middlewares/fast-route middlewares/request-handler
</code></pre></div></div>

<p>And define the route to our <em>Hello, world!</em> handler class. We’ll use a <code class="language-plaintext highlighter-rouge">/hello</code> route here to show that a route other than the base URI works.</p>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
</pre></td><td class="code"><pre><span class="c1">// ...</span>

<span class="kn">use</span> <span class="nc">DI\ContainerBuilder</span><span class="p">;</span>
<span class="kn">use</span> <span class="nc">ExampleApp\HelloWorld</span><span class="p">;</span>
<span class="hll"><span class="kn">use</span> <span class="nc">FastRoute\RouteCollector</span><span class="p">;</span>
</span><span class="hll"><span class="kn">use</span> <span class="nc">Middlewares\FastRoute</span><span class="p">;</span>
</span><span class="hll"><span class="kn">use</span> <span class="nc">Middlewares\RequestHandler</span><span class="p">;</span>
</span><span class="kn">use</span> <span class="nc">Relay\Relay</span><span class="p">;</span>
<span class="kn">use</span> <span class="nc">Laminas\Diactoros\ServerRequestFactory</span><span class="p">;</span>
<span class="kn">use</span> <span class="k">function</span> <span class="n">DI\create</span><span class="p">;</span>
<span class="hll"><span class="kn">use</span> <span class="k">function</span> <span class="n">FastRoute\simpleDispatcher</span><span class="p">;</span>
</span>
<span class="c1">// ...</span>

<span class="nv">$container</span> <span class="o">=</span> <span class="nv">$containerBuilder</span><span class="o">-&gt;</span><span class="nf">build</span><span class="p">();</span>

<span class="hll"><span class="nv">$routes</span> <span class="o">=</span> <span class="nf">simpleDispatcher</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="kt">RouteCollector</span> <span class="nv">$r</span><span class="p">)</span> <span class="p">{</span>
</span><span class="hll">    <span class="nv">$r</span><span class="o">-&gt;</span><span class="nf">get</span><span class="p">(</span><span class="s1">'/hello'</span><span class="p">,</span> <span class="nc">HelloWorld</span><span class="o">::</span><span class="n">class</span><span class="p">);</span>
</span><span class="hll"><span class="p">});</span>
</span><span class="hll"> 
</span><span class="hll"><span class="nv">$middlewareQueue</span><span class="p">[]</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">FastRoute</span><span class="p">(</span><span class="nv">$routes</span><span class="p">);</span>
</span><span class="hll"><span class="nv">$middlewareQueue</span><span class="p">[]</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">RequestHandler</span><span class="p">();</span>
</span>
<span class="nv">$requestHandler</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Relay</span><span class="p">(</span><span class="nv">$middlewareQueue</span><span class="p">);</span>
<span class="nv">$requestHandler</span><span class="o">-&gt;</span><span class="nf">handle</span><span class="p">(</span><span class="nc">ServerRequestFactory</span><span class="o">::</span><span class="nf">fromGlobals</span><span class="p">());</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p>For this to work, you’ll also need to update <code class="language-plaintext highlighter-rouge">HelloWorld</code> to make it an invokable class, meaning that  <a target="_blank" rel="noopener" href="https://lornajane.net/posts/2012/phps-magic-__invoke-method-and-the-callable-typehint">the class can be called as if it were a function</a>.</p>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre><span class="c1">// ...</span>

<span class="kd">class</span> <span class="nc">HelloWorld</span>
<span class="p">{</span>
<span class="hll">    <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">():</span> <span class="kt">void</span>
</span>    <span class="p">{</span>
        <span class="k">echo</span> <span class="s1">'Hello, autoloaded world!'</span><span class="p">;</span>
<span class="hll">        <span class="k">exit</span><span class="p">;</span>
</span>    <span class="p">}</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p>(Note the added <code class="language-plaintext highlighter-rouge">exit;</code> in the <code class="language-plaintext highlighter-rouge">__invoke()</code> magic method. We’ll get to that in a second—just didn’t want you to miss it.)</p>

<p>Now load  <a target="_blank" rel="noopener" href="http://localhost:8080/hello">http://localhost:8080/hello</a>  and bask in your success!</p>

<p><a name="the-glue-that-holds-it-all-together" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#the-glue-that-holds-it-all-together" class="c-linked-heading__link">#</a>
The Glue that Holds it All Together
</h2>

<p>The astute reader will quickly notice that although we’re still going to the trouble of configuring and building the DI container, it’s not actually doing anything for us. The dispatcher and middleware can do their job without it.</p>

<p>So when does it come into play?</p>

<p>Well, what if—as would nearly always be the case in a real application—the <code class="language-plaintext highlighter-rouge">HelloWorld</code> class has a dependency?</p>

<p>Let’s introduce a trivial dependency and see what happens.</p>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre><span class="c1">// ...</span>

<span class="kd">class</span> <span class="nc">HelloWorld</span>
<span class="p">{</span>
<span class="hll">    <span class="k">private</span> <span class="nv">$foo</span><span class="p">;</span>
</span>
<span class="hll">    <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$foo</span><span class="p">)</span>
</span><span class="hll">    <span class="p">{</span>
</span><span class="hll">        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">foo</span> <span class="o">=</span> <span class="nv">$foo</span><span class="p">;</span>
</span><span class="hll">    <span class="p">}</span>
</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">():</span> <span class="kt">void</span>
    <span class="p">{</span>
<span class="hll">        <span class="k">echo</span> <span class="s2">"Hello, </span><span class="si">{</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">foo</span><span class="si">}</span><span class="s2"> world!"</span><span class="p">;</span>
</span>        <span class="k">exit</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p>Reload the browser, and…</p>

<p><em>Yikes.</em></p>

<p>Look at that <code class="language-plaintext highlighter-rouge">ArgumentCountError</code>.</p>

<p>That’s happening because now <code class="language-plaintext highlighter-rouge">HelloWorld</code> requires a string to be injected at construction time in order to do its job, and it’s been left hanging. <em>This</em> is where the container helps out.</p>

<p>Let’s define that dependency in the container and pass the container to <code class="language-plaintext highlighter-rouge">RequestHandler</code> to  <a target="_blank" rel="noopener" href="https://github.com/middlewares/request-handler#options">resolve it</a>.</p>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</pre></td><td class="code"><pre><span class="c1">// ...</span>

<span class="kn">use</span> <span class="nc">Laminas\Diactoros\ServerRequestFactory</span><span class="p">;</span>
<span class="kn">use</span> <span class="k">function</span> <span class="n">DI\create</span><span class="p">;</span>
<span class="hll"><span class="kn">use</span> <span class="k">function</span> <span class="n">DI\get</span><span class="p">;</span>
</span><span class="kn">use</span> <span class="k">function</span> <span class="n">FastRoute\simpleDispatcher</span><span class="p">;</span>

<span class="c1">// ...</span>

<span class="nv">$containerBuilder</span><span class="o">-&gt;</span><span class="nf">addDefinitions</span><span class="p">([</span>
<span class="hll">    <span class="nc">HelloWorld</span><span class="o">::</span><span class="n">class</span> <span class="o">=&gt;</span> <span class="nf">create</span><span class="p">(</span><span class="nc">HelloWorld</span><span class="o">::</span><span class="n">class</span><span class="p">)</span>
</span><span class="hll">        <span class="o">-&gt;</span><span class="nf">constructor</span><span class="p">(</span><span class="nf">get</span><span class="p">(</span><span class="s1">'Foo'</span><span class="p">)),</span>
</span><span class="hll">    <span class="s1">'Foo'</span> <span class="o">=&gt;</span> <span class="s1">'bar'</span>
</span><span class="p">]);</span>

<span class="nv">$container</span> <span class="o">=</span> <span class="nv">$containerBuilder</span><span class="o">-&gt;</span><span class="nf">build</span><span class="p">();</span>

<span class="c1">// ...</span>

<span class="nv">$middlewareQueue</span><span class="p">[]</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">FastRoute</span><span class="p">(</span><span class="nv">$routes</span><span class="p">);</span>
<span class="hll"><span class="nv">$middlewareQueue</span><span class="p">[]</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">RequestHandler</span><span class="p">(</span><span class="nv">$container</span><span class="p">);</span>
</span>
<span class="nv">$requestHandler</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Relay</span><span class="p">(</span><span class="nv">$middlewareQueue</span><span class="p">);</span>
<span class="nv">$requestHandler</span><span class="o">-&gt;</span><span class="nf">handle</span><span class="p">(</span><span class="nc">ServerRequestFactory</span><span class="o">::</span><span class="nf">fromGlobals</span><span class="p">());</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p>Voilà! You should see “Hello, bar world!” when you reload the browser.</p>

<p><a name="properly-sending-responses" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#properly-sending-responses" class="c-linked-heading__link">#</a>
Properly Sending Responses
</h2>

<p>Remember earlier when I made a point of mentioning the <code class="language-plaintext highlighter-rouge">exit</code> statement sitting in <code class="language-plaintext highlighter-rouge">HelloWorld</code>?</p>

<p>Well that’s a quick and dirty way to make sure we get a simple response while we’re building things out, but it’s not the best way to send output to the browser. Such a crude technique gives <code class="language-plaintext highlighter-rouge">HelloWorld</code> the additional job of responding—which should really be the responsibility of another class—it overcomplicates sending proper headers and  <a target="_blank" rel="noopener" href="https://httpstatuses.com/">status codes</a>, and it shuts down the app without giving the middleware that comes <em>after</em> <code class="language-plaintext highlighter-rouge">HelloWorld</code> a chance to run.</p>

<p>Remember, each middleware has the opportunity to modify <code class="language-plaintext highlighter-rouge">Request</code> on its way into our app and (in reverse order) modify the response on its way out of the app. In addition to the common interface for <code class="language-plaintext highlighter-rouge">Request</code>, PSR-7 also defines the structure for another HTTP message that will help us out on the back half of that cycle: <code class="language-plaintext highlighter-rouge">Response</code>. (If you want to really get into the nuts and bolts, read all about  <a target="_blank" rel="noopener" href="https://mwop.net/blog/2015-01-26-psr-7-by-example.html">HTTP messages and what makes PSR-7 Request and Response standards so great</a>.)</p>

<p>Update <code class="language-plaintext highlighter-rouge">HelloWorld</code> to return a <code class="language-plaintext highlighter-rouge">Response</code>.</p>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code"><pre><span class="c1">// ...</span>

<span class="kn">namespace</span> <span class="nn">ExampleApp</span><span class="p">;</span>

<span class="hll"><span class="kn">use</span> <span class="nc">Psr\Http\Message\ResponseInterface</span><span class="p">;</span>
</span>
<span class="kd">class</span> <span class="nc">HelloWorld</span>
<span class="p">{</span>
    <span class="k">private</span> <span class="nv">$foo</span><span class="p">;</span>

<span class="hll">    <span class="k">private</span> <span class="nv">$response</span><span class="p">;</span>
</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span>
        <span class="kt">string</span> <span class="nv">$foo</span><span class="p">,</span>
<span class="hll">        <span class="kt">ResponseInterface</span> <span class="nv">$response</span>
</span>    <span class="p">)</span> <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">foo</span> <span class="o">=</span> <span class="nv">$foo</span><span class="p">;</span>
<span class="hll">        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">response</span> <span class="o">=</span> <span class="nv">$response</span><span class="p">;</span>
</span>    <span class="p">}</span>

<span class="hll">    <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">():</span> <span class="kt">ResponseInterface</span>
</span><span class="hll">    <span class="p">{</span>
</span><span class="hll">        <span class="nv">$response</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">response</span><span class="o">-&gt;</span><span class="nf">withHeader</span><span class="p">(</span><span class="s1">'Content-Type'</span><span class="p">,</span> <span class="s1">'text/html'</span><span class="p">);</span>
</span><span class="hll">        <span class="nv">$response</span><span class="o">-&gt;</span><span class="nf">getBody</span><span class="p">()</span>
</span><span class="hll">            <span class="o">-&gt;</span><span class="nf">write</span><span class="p">(</span><span class="s2">"&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;Hello, </span><span class="si">{</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">foo</span><span class="si">}</span><span class="s2"> world!&lt;/body&gt;&lt;/html&gt;"</span><span class="p">);</span>
</span><span class="hll"> 
</span><span class="hll">        <span class="k">return</span> <span class="nv">$response</span><span class="p">;</span>
</span><span class="hll">    <span class="p">}</span>
</span><span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p>And update the container definition to provide <code class="language-plaintext highlighter-rouge">HelloWorld</code> with a fresh <code class="language-plaintext highlighter-rouge">Response</code> object.</p>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code"><pre><span class="c1">// ...</span>

<span class="kn">use</span> <span class="nc">Middlewares\RequestHandler</span><span class="p">;</span>
<span class="kn">use</span> <span class="nc">Relay\Relay</span><span class="p">;</span>
<span class="hll"><span class="kn">use</span> <span class="nc">Laminas\Diactoros\Response</span><span class="p">;</span>
</span><span class="kn">use</span> <span class="nc">Laminas\Diactoros\ServerRequestFactory</span><span class="p">;</span>
<span class="kn">use</span> <span class="k">function</span> <span class="n">DI\create</span><span class="p">;</span>

<span class="c1">// ...</span>

<span class="nv">$containerBuilder</span><span class="o">-&gt;</span><span class="nf">addDefinitions</span><span class="p">([</span>
    <span class="nc">HelloWorld</span><span class="o">::</span><span class="n">class</span> <span class="o">=&gt;</span> <span class="nf">create</span><span class="p">(</span><span class="nc">HelloWorld</span><span class="o">::</span><span class="n">class</span><span class="p">)</span>
<span class="hll">        <span class="o">-&gt;</span><span class="nf">constructor</span><span class="p">(</span><span class="nf">get</span><span class="p">(</span><span class="s1">'Foo'</span><span class="p">),</span> <span class="nf">get</span><span class="p">(</span><span class="s1">'Response'</span><span class="p">)),</span>
</span><span class="hll">    <span class="s1">'Foo'</span> <span class="o">=&gt;</span> <span class="s1">'bar'</span><span class="p">,</span>
</span><span class="hll">    <span class="s1">'Response'</span> <span class="o">=&gt;</span> <span class="k">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class="hll">        <span class="k">return</span> <span class="k">new</span> <span class="nc">Response</span><span class="p">();</span>
</span><span class="hll">    <span class="p">},</span>
</span><span class="p">]);</span>

<span class="nv">$container</span> <span class="o">=</span> <span class="nv">$containerBuilder</span><span class="o">-&gt;</span><span class="nf">build</span><span class="p">();</span>

<span class="c1">// ...</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p>If you reload the page now though, you’ll get a blank screen. Our app is returning a proper <code class="language-plaintext highlighter-rouge">Response</code> object from the middleware dispatcher, but then… what?</p>

<p>Doing nothing with it, that’s what.</p>

<p>We need one more tool to wrap things up: an emitter. An emitter sits between your app and the web server (Apache, nginx, etc.) that will send your response to the client that initiated the request. It essentially takes the <code class="language-plaintext highlighter-rouge">Response</code> object and translates it into instructions that a  <a target="_blank" rel="noopener" href="https://stackoverflow.com/a/9948058/1217620">server API</a>  can understand.</p>

<p>Let’s pull in  <a target="_blank" rel="noopener" href="https://github.com/narrowspark/http-emitter">Narrowspark’s HTTP Emitter</a>.</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>composer require narrowspark/http-emitter
</code></pre></div></div>

<p>Update <code class="language-plaintext highlighter-rouge">public/index.php</code> to receive <code class="language-plaintext highlighter-rouge">Response</code> from the dispatcher and pass it off to the emitter.</p>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code"><pre><span class="c1">// ...</span>

<span class="kn">use</span> <span class="nc">Middlewares\FastRoute</span><span class="p">;</span>
<span class="kn">use</span> <span class="nc">Middlewares\RequestHandler</span><span class="p">;</span>
<span class="hll"><span class="kn">use</span> <span class="nc">Narrowspark\HttpEmitter\SapiEmitter</span><span class="p">;</span>
</span><span class="kn">use</span> <span class="nc">Relay\Relay</span><span class="p">;</span>
<span class="kn">use</span> <span class="nc">Laminas\Diactoros\Response</span><span class="p">;</span>

<span class="c1">// ...</span>

<span class="nv">$requestHandler</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Relay</span><span class="p">(</span><span class="nv">$middlewareQueue</span><span class="p">);</span>
<span class="hll"><span class="nv">$response</span> <span class="o">=</span> <span class="nv">$requestHandler</span><span class="o">-&gt;</span><span class="nf">handle</span><span class="p">(</span><span class="nc">ServerRequestFactory</span><span class="o">::</span><span class="nf">fromGlobals</span><span class="p">());</span>
</span><span class="hll"> 
</span><span class="hll"><span class="nv">$emitter</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">SapiEmitter</span><span class="p">();</span>
</span><span class="hll"><span class="k">return</span> <span class="nv">$emitter</span><span class="o">-&gt;</span><span class="nf">emit</span><span class="p">(</span><span class="nv">$response</span><span class="p">);</span>
</span></pre></td></tr></tbody></table></code></pre></figure>

<p>Reload your browser, and we’re back in business! And this time with a far more robust way of handling responses.</p>

<p>Line 15 in the code example above is where the request/response cycle ends in our app and the web server takes over.</p>

<p>Note that for the sake of the example, the emitter configuration we’re using here is very straightforward. Though it can be a bit more complex, a real app should be configured to automatically use a streaming emitter for large downloads. The documentation for Laminas’s HTTP Request Handler Runner, a combo PSR-15 dispatcher and PSR-7 emitter, discusses  <a target="_blank" rel="noopener" href="https://docs.laminas.dev/laminas-httphandlerrunner/emitters/#emitterstack">one interesting way to accomplish this</a>.</p>

<p><a name="wrapping-up" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#wrapping-up" class="c-linked-heading__link">#</a>
Wrapping Up
</h2>

<p>So there you have it. With just 44 lines and the help of several widely-used, thoroughly-tested, reliably interoperable components, we have the bootstrap for a modern PHP application. It’s compliant with  <a target="_blank" rel="noopener" href="https://www.php-fig.org/psr/psr-4">PSR-4</a>,  <a target="_blank" rel="noopener" href="https://www.php-fig.org/psr/psr-7">PSR-7</a>,  <a target="_blank" rel="noopener" href="https://www.php-fig.org/psr/psr-11">PSR-11</a>, and  <a target="_blank" rel="noopener" href="https://www.php-fig.org/psr/psr-15">PSR-15</a>, which means you can use your pick of any of a broad range of vendors’ implementations of those standards for your HTTP messages, DI container, middleware, and middleware dispatcher.</p>

<p>We dove deep into some of the technology and reasoning behind our decisions, but I hope you can see just how simple it is to bootstrap a new application without the cruft of a framework. Perhaps more importantly, I hope you’re better prepared to work these techniques into an existing application when the need arises.</p>

<p>Have a look at  <a target="_blank" rel="noopener" href="https://github.com/kevinsmith/no-framework">the GitHub repo for this example app</a>, and feel free to fork it or download it.</p>

<p>If you’re looking for more great sources for high-quality, decoupled packages, I wholeheartedly recommend checking out  <a target="_blank" rel="noopener" href="http://auraphp.com/">Aura</a>,  <a target="_blank" rel="noopener" href="https://thephpleague.com/">The League of Extraordinary Packages</a>,  <a target="_blank" rel="noopener" href="https://symfony.com/components">Symfony components</a>,  <a target="_blank" rel="noopener" href="https://docs.laminas.dev/components/">Laminas components</a>,  <a target="_blank" rel="noopener" href="https://paragonie.com/software">Paragon Initiative’s security-focused libraries</a>, and  <a target="_blank" rel="noopener" href="https://github.com/middlewares/awesome-psr15-middlewares">this list of PSR-15 middleware</a>.</p>

<p>If you were to use this example code in production, you’d probably want to break the routes and  <a target="_blank" rel="noopener" href="http://php-di.org/doc/php-definitions.html">container definitions</a>  out into their own files so that they’re easier to maintain as the complexity grows. I’d also recommend <a target="_blank" rel="noopener" href="https://framework.zend.com/blog/2017-09-14-diactoros-emitters.html">implementing EmitterStack</a>  for smart handling of file downloads and other large responses.</p>

<p><strong>Be sure to read the follow-up: <a target="_blank" rel="noopener" href="https://kevinsmith.io/didnt-you-just-build-your-own-framework">“Didn’t you just build your own framework?”</a></strong></p>

<p>Any questions, confusion, or suggestions for improvement?  <a target="_blank" rel="noopener" href="https://twitter.com/_KevinSmith">Gimme a shout.</a></p>

<hr style="width:40%; text-align:center; margin-top: 42px; margin-bottom: 42px; border: 0; height: 1px; background: #333; background-image: linear-gradient(to right, #ccc, #333, #ccc);" />

<p><strong><em>Updated on Jan 12, 2019:</em></strong> Updated all libraries, and bumped the PHP requirement to 7.2, the  <a target="_blank" rel="noopener" href="https://secure.php.net/supported-versions.php">minimum actively supported version of PHP</a>. The latest version of Zend Diactoros  <a target="_blank" rel="noopener" href="https://github.com/kevinsmith/no-framework/pull/2">no longer includes an emitter</a>, so the  <a target="_blank" rel="noopener" href="https://kevinsmith.io/modern-php-without-a-framework#properly-sending-responses">Properly Sending Responses</a>  section was updated to use Narrowspark’s emitter instead. It was an absolutely  <a target="_blank" rel="noopener" href="https://github.com/kevinsmith/no-framework/commit/a8729169eefd2bd4f8af1857e84db9949989c097">seamless replacement</a>, too. Really highlights how wonderful those PSRs can be!</p>

<p><strong><em>Updated on March 24, 2019:</em></strong> Since originally publishing this post, I’ve been persuaded to rethink my stance on autowiring. The benefits are undeniable:</p>

<ul>
  <li>Development is generally faster, and with a much lower “cost” to adding new dependencies to a class, there’s one less argument against breaking up responsibilities into separate classes.</li>
  <li>Autowiring generally only works with type-hinted parameters, which naturally discourages  <a target="_blank" rel="noopener" href="http://wiki.c2.com/?PrimitiveObsession">primitive obsession</a>.</li>
  <li>Comprehensibility is improved because container configuration cruft is gone, leaving you with only meaningful configuration.</li>
</ul>

<p>As with any “magic”, autowiring should be carefully considered before enabling, but modern DI containers handle it quite sensibly. For example,  <a target="_blank" rel="noopener" href="http://php-di.org/doc/autowiring.html">PHP-DI</a>  only autowires concrete classes, so there’s no possibility of ambiguity, and  <a target="_blank" rel="noopener" href="https://symfony.com/doc/current/service_container/autowiring.html">Symfony’s service container</a>  will throw an unavoidable exception in dev environments if there’s <em>any</em> ambiguity about which dependency should be provided.</p>

<p><strong><em>Updated on Dec 31, 2022:</em></strong> <a target="_blank" rel="noopener" href="https://framework.zend.com/blog/2020-01-24-laminas-launch.html">Zend was renamed Laminas</a> some time back, so the tutorial now uses the equivalent Laminas packages instead.</p>

<p><strong><em>Updated on Apr 9, 2024:</em></strong> PHP-DI’s Annotations were <a target="_blank" rel="noopener" href="https://php-di.org/doc/attributes.html">replaced by PHP’s native Attributes</a> in version 7. <a target="_blank" rel="noopener" href="https://github.com/kevinsmith/no-framework/pull/16">Thanks to surreal30 for the PR</a> to keep the example repo updated.</p>]]></content><author><name>Kevin Smith</name></author><category term="PHP" /><summary type="html"><![CDATA[I've got a challenge for you. The next time you start a new project, try *not* using a PHP framework.]]></summary></entry><entry><title type="html">Vision and Hard Work</title><link href="https://kevinsmith.io/vision-and-hard-work/" rel="alternate" type="text/html" title="Vision and Hard Work" /><published>2017-09-26T03:49:00+00:00</published><updated>2017-09-26T03:49:00+00:00</updated><id>https://kevinsmith.io/vision-and-hard-work</id><content type="html" xml:base="https://kevinsmith.io/vision-and-hard-work/"><![CDATA[<p>I love this contrasting pair of quotes, perfectly capturing the mindset of great leaders.</p>

<blockquote>
  <p>Vision without execution is just hallucination.</p>

  <p>– <cite>often attributed to Thomas Edison, Henry Ford, and Albert Einstein</cite></p>
</blockquote>

<p>and</p>

<blockquote>
  <p>Hard work without meaning is foolish grind.</p>

  <p>– <cite><a target="_blank" rel="noopener" href="https://acuff.me/2013/11/hustle-doesnt-matter/">John Acuff</a></cite></p>
</blockquote>]]></content><author><name>Kevin Smith</name></author><summary type="html"><![CDATA[A contrast that perfectly captures the mindset of great leaders.]]></summary></entry><entry><title type="html">Multitasking Isn’t Really a Thing</title><link href="https://kevinsmith.io/multitasking-isnt-really-a-thing/" rel="alternate" type="text/html" title="Multitasking Isn’t Really a Thing" /><published>2017-09-13T13:37:00+00:00</published><updated>2017-09-13T13:37:00+00:00</updated><id>https://kevinsmith.io/multitasking-isnt-really-a-thing</id><content type="html" xml:base="https://kevinsmith.io/multitasking-isnt-really-a-thing/"><![CDATA[<p><a target="_blank" rel="noopener" href="https://www.ted.com/talks/mihaly_csikszentmihalyi_on_flow#t-490020">According to psychologist Mihaly Csikszentmihalyi</a>, the human nervous system can only process about 110 bits of information per second. Understanding someone speaking to you requires about 60 bits per second. That’s why we can’t listen to more than one person at a time.</p>

<p>Multitasking isn’t actually doing multiple things at once.  <a target="_blank" rel="noopener" href="https://www.psychologytoday.com/blog/creativity-without-borders/201405/the-myth-multitasking">It’s rapidly switching between multiple things with incredible frequency.</a> It fatigues the brain and results in much lower quality decision-making all around.</p>

<p>If you’re feeling overwhelmed and like you’re not moving the needle on anything, it’s probably because you’re trying to do too much at once.</p>

<p>Start focusing on one thing at a time, get it done and put away, and then move on to the next thing.</p>]]></content><author><name>Kevin Smith</name></author><summary type="html"><![CDATA[The human nervous system can only process about 110 bits of information per second.]]></summary></entry><entry><title type="html">A Generation That Never Asks “Why?”</title><link href="https://kevinsmith.io/a-generation-that-never-asks-why/" rel="alternate" type="text/html" title="A Generation That Never Asks “Why?”" /><published>2017-08-25T16:43:00+00:00</published><updated>2017-08-25T16:43:00+00:00</updated><id>https://kevinsmith.io/a-generation-that-never-asks-why</id><content type="html" xml:base="https://kevinsmith.io/a-generation-that-never-asks-why/"><![CDATA[<p>From <a target="_blank" rel="noopener" href="https://theamericanscholar.org/solitude-and-leadership/">Solitude and Leadership</a>:</p>

<blockquote>
  <p>We have a crisis of leadership in America because our overwhelming power and wealth, earned under earlier generations of leaders, made us complacent, and for too long we have been training leaders who only know how to keep the routine going. Who can answer questions, but don’t know how to ask them. Who can fulfill goals, but don’t know how to set them. Who think about <em>how</em> to get things done, but not whether they’re worth doing in the first place… What we <em>don’t</em> have are leaders.</p>

  <p><cite>– William Deresiewicz</cite></p>
</blockquote>]]></content><author><name>Kevin Smith</name></author><summary type="html"><![CDATA[We've been taught to think about how to get things done, but not whether they’re even worth doing in the first place.]]></summary></entry><entry><title type="html">Deadlines are Meaningless</title><link href="https://kevinsmith.io/deadlines-are-meaningless/" rel="alternate" type="text/html" title="Deadlines are Meaningless" /><published>2017-08-17T11:38:00+00:00</published><updated>2017-08-17T11:38:00+00:00</updated><id>https://kevinsmith.io/deadlines-are-meaningless</id><content type="html" xml:base="https://kevinsmith.io/deadlines-are-meaningless/"><![CDATA[<p>If your company is like the typical digital agency or software shop, you’ve got deadlines slapped on every bit of work in the entire organization as a way to get your people to deliver work quickly.</p>

<p>If you’re honest with yourself, you know that your people will miss their deadlines on plenty—if not most—of the work they do. And while you might crack the whip and fuss about it, you know deep down that it’s expected. You’re upset about it, but that’s just how things are. How else could they be?</p>

<p>The trouble is this: <strong>your people know it’s expected too</strong>. The deadlines don’t really work as an incentive, and the side-effect is constant, corrosive stress. You never intended to run a burn-out shop, but here we are.</p>

<p>But hey, that’s all just part of doing creative work. How else could it be?</p>

<p>So when something really <em>does</em> have a deadline, like a t-shirt design for a trade show giveaway, don’t be shocked when your people don’t take those deadlines very seriously. You’ve been training your people not to take them seriously all along.</p>

<p>How do you make deadlines meaningful again? Use them sparingly. When the outcome of your work has <strong>zero value</strong> if it’s delivered after a given date, <em>that’s</em> work that needs a deadline.</p>

<p>For everything else, there is no deadline. There never was.</p>]]></content><author><name>Kevin Smith</name></author><summary type="html"><![CDATA[You never intended to run a burn-out shop, but here we are.]]></summary></entry><entry><title type="html">Is Your Team Feeling Scattered and Unfocused?</title><link href="https://kevinsmith.io/is-your-team-feeling-scattered-and-unfocused/" rel="alternate" type="text/html" title="Is Your Team Feeling Scattered and Unfocused?" /><published>2017-08-10T22:08:00+00:00</published><updated>2017-08-10T22:08:00+00:00</updated><id>https://kevinsmith.io/is-your-team-feeling-scattered-and-unfocused</id><content type="html" xml:base="https://kevinsmith.io/is-your-team-feeling-scattered-and-unfocused/"><![CDATA[<p>In the world of design and development, your team’s getting a <em>lot</em> thrown at it. It’s true if you’re running a software shop responsible for churning out a single product, and it’s <em>especially</em> problematic for digital agencies with multiple clients. But when everything’s an emergency, nothing is. We need a better way of keeping on top of all those demands and knowing which ones we should focus on <em>right now</em>.</p>

<p>I’ve been through the ringer with project management systems: notes on loose-leaf paper, to-do apps, purpose-built tools like Basecamp, complicated Scrum tools, JIRA. The old adage I keep coming back to is this: <strong>Keep it Simple</strong>. The harder your system is to work with, the less likely it is to actually be helpful.</p>

<p>The method I’ve found that works time and again—for individuals and teams alike—is called kanban. At its core, it’s about simply visualizing each bit of work as a card up on a board. (Think of a Post-it® Note on a whiteboard.) If you’ve ever toyed around with a digital tool like  <a target="_blank" rel="noopener" href="https://trello.com/">Trello</a>, you’re already familiar with the idea though you may not understand just how powerful it is.</p>

<p>Language doesn’t come naturally to us humans. It must be taught and learned, and it requires higher-level brain power to comprehend. Understanding visual elements, on the other hand, is wired into the deepest parts of who we are as a species. Had our ancestors not been able to scan a landscape and immediately identify a threat (i.e. what <em>must</em> be focused on vs. what can be ignored), they would never have survived.</p>

<p>Some research suggests our brains process visual information as much as 60,000 times faster than text. That makes sense, when you think about it. We can process visual information all at once, but text-based information must be consumed and processed in a linear fashion.</p>

<p>Getting started is simple:</p>

<ol>
  <li>Get a whiteboard (or a digital equivalent like  <a target="_blank" rel="noopener" href="https://trello.com/">Trello</a>  or  <a target="_blank" rel="noopener" href="https://leankit.com/">LeanKit</a>).</li>
  <li>Create 3 columns: To Do, Doing, and Done.</li>
  <li>Make a card for each current and planned item of work, and put the card in the appropriate column.<br />
<em>(Don’t get bogged down in defining what constitutes an item of work. You can improve on that later. Just get started for now.)</em></li>
  <li>Prioritize the work by moving the cards and putting the most pressing at the top.</li>
  <li>As you’re doing the work represented on those cards, move them across the board through the appropriate columns.</li>
</ol>

<p>What’s so special about this? And how is this better than just a checklist?</p>

<p>A checklist is great for the grocery store, but it falls flat for ongoing work because your brain has to read all the items and actually think, “Is this something I’m working on right now or not?” You can’t see what’s currently on your plate, only what “not done”. It’s an unending list of everything you haven’t accomplished yet.</p>

<p>Whew, talk about stressful!</p>

<p>The steps above aren’t magic. They’re <em>simple</em>, but they include most of the elements a human needs to get a quick sense of what’s going on and feel great about what they’ve accomplished. (There’s something else you can add to the mix as you improve. I’ll cover that in an upcoming post.)</p>

<p><strong>The key takeaway is this:</strong> don’t worry about anything that’s not in the <em>Doing</em> column. That column is your team’s job. Everything in the <em>To Do</em> column is for the future, but the <em>Doing</em> column? That’s right now. Focus all your efforts on moving those cards into the <em>Done</em> column. Then kick back and enjoy the sweet satisfaction of getting something done.</p>

<p>We’re not robots, after all. Rewards matter <em>a lot</em> for job satisfaction and ongoing motivation.</p>

<p>This isn’t a way of working that requires you to perfectly understand it before you can implement it. It’s not about some sophisticated process. Just get started with where you are right now. Put your current and planned work on the board. Don’t worry about trying to redesign <strong><em>how</em></strong> your team works just yet. That’ll all come later.</p>

<p>Just put the work on the board, and encourage your team to focus on getting <em>Doing</em> cards to <em>Done</em>.</p>]]></content><author><name>Kevin Smith</name></author><summary type="html"><![CDATA[In the world of design and development, your team’s getting a *lot* thrown at it. It’s true if you’re running a software shop responsible for churning out a single product, and it’s *especially* problematic for digital agencies with multiple clients. But when everything’s an emergency, nothing is.]]></summary></entry><entry><title type="html">Rescuing a Slow, Buggy, and Frustrating “Store Locator”</title><link href="https://kevinsmith.io/rescuing-a-slow-buggy-and-frustrating-store-locator/" rel="alternate" type="text/html" title="Rescuing a Slow, Buggy, and Frustrating “Store Locator”" /><published>2016-05-18T19:13:00+00:00</published><updated>2016-05-18T19:13:00+00:00</updated><id>https://kevinsmith.io/rescuing-a-slow-buggy-and-frustrating-store-locator</id><content type="html" xml:base="https://kevinsmith.io/rescuing-a-slow-buggy-and-frustrating-store-locator/"><![CDATA[<p>For any brick-and-mortar business, it’s a major problem if your customers can’t find you.</p>

<p>That’s true for medical professionals and their patients, too. I’m delighted that I got the opportunity to help Connect Hearing, a major network of hearing clinics in Canada and the United States. They recently asked me to fix some big issues plaguing their hearing clinic locator, namely:</p>

<ul>
  <li>The locator itself took <strong>upwards of 10 seconds to load</strong> and <strong>routinely got the visitor’s location wrong</strong> during geolocation auto-detection</li>
  <li>Individual clinic pages would <strong>often show the wrong location on the map</strong> or were <strong>zoomed in so comically close</strong> that the map lost all context</li>
  <li>Map pins were <strong>a crowded mess</strong> in the areas where several clinics were clustered close to each other</li>
  <li>Custom location pins were <strong>fuzzy on Retina devices</strong> and <strong>didn’t point to the right spot on the map</strong></li>
  <li>Visitors navigating the page with a <strong>scroll wheel would get caught in the map’s zoom feature</strong></li>
</ul>

<p>The user experience was pretty bad. In short, there was too much getting in the way of what every visitor wanted to know: where are the nearest clinics, when are they open, and how can I get there?</p>

<p>Here’s a tour of just a few of the visual issues they were dealing with:</p>

<div class="c-blocks__figure-wrapper"><figure class="c-blocks__figure c-blocks__figure--center"><img src="/uploads/general/_922xAUTO_fit_center-center/crowded-pins@2x.jpg" srcset="/uploads/general/crowded-pins@2x.jpg 2x" alt="Crowded pins on a store locator map" class="c-blocks__image" /><figcaption class="c-blocks__figcaption">
                A potential patient searches for clinics near Chicago and is shown this crowded bunch of pins. This is not helpful.
              </figcaption></figure></div>

<div class="c-blocks__figure-wrapper"><figure class="c-blocks__figure c-blocks__figure--center"><img src="/uploads/general/_589xAUTO_fit_center-center/comically-zoomed@2x.jpg" srcset="/uploads/general/comically-zoomed@2x.jpg 2x" alt="Map zoomed so far in that it has lost all context" class="c-blocks__image" /><figcaption class="c-blocks__figcaption">
                This is from a single clinic page. With it zoomed so far in, why even have a map?
              </figcaption></figure></div>

<div class="c-blocks__figure-wrapper"><figure class="c-blocks__figure c-blocks__figure--center"><img src="/uploads/general/_569xAUTO_fit_center-center/bad-location@2x.jpg" srcset="/uploads/general/bad-location@2x.jpg 2x" alt="Map viewport focused on the wrong location." class="c-blocks__image" /><figcaption class="c-blocks__figcaption">
                Doesn't look like Wichita Falls to me.
              </figcaption></figure></div>

<p><a name="the-goals" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#the-goals" class="c-linked-heading__link">#</a>
The Goals
</h2>

<p>“Make it better” was an obvious desire, sure. But for any project to be counted a success, it must have <strong>specific and measurable outcomes</strong> marked down from the beginning. It must have <strong><em>goals</em></strong>.</p>

<p>I worked with Connect Hearing to combine user frustrations with the client’s business needs to come up with several project goals.</p>

<ul>
  <li>The main clinic locator page <strong>needs to load <em>fast</em></strong> – 2 seconds at the most</li>
  <li>It should <strong>unobtrusively auto-detect a visitor’s current location</strong></li>
  <li>It should <strong>automatically display the 5 to 6 clinics closest to the user</strong> on the map and as info tiles</li>
  <li>Clinic locations should be <strong>accurately displayed in any context</strong></li>
  <li>Map styles and custom pins should be <strong>sharp on Retina screens</strong> and <strong>match the company brand</strong></li>
  <li>Maps should not <strong>hijack the scroll wheel</strong></li>
  <li>Individual clinic pages should expose data like contact info, hours, location, and business type to Google and other search engines <strong>so third-party business listings are always accurate</strong></li>
  <li>Clinic info should be <strong>added and updated through the site’s CMS</strong>, ExpressionEngine – no turnkey, third-party store locator services</li>
</ul>

<p><a name="the-fix" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#the-fix" class="c-linked-heading__link">#</a>
The Fix
</h2>

<p>The best course of action was to rebuild the entire locator experience from scratch, and I took special care to make sure the new maps would not only look great but that the logic behind it all would support a seamless user experience, something that was even more important to Connect Hearing since their target market tends toward an aging population.</p>

<p><a name="the-results" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#the-results" class="c-linked-heading__link">#</a>
The Results
</h2>

<p>Thanks to smart caching and data modeling, the clinic locator and individual clinic pages are now <strong>blazing fast</strong>. The locator quickly determines the user’s general location and does so while the rest of the map continues to load, <strong>keeping things feeling snappy for the user</strong>.</p>

<p>All location data is now represented accurately on the maps with attractive, on-brand, high-resolution graphics, and the locator <strong>automatically clusters locations</strong> that would otherwise be crowded together on the map. And clinic info is encoded into each clinic page to make it easy for Google to import.</p>

<p>The visual highlights:</p>

<div class="c-blocks__figure-wrapper"><figure class="c-blocks__figure c-blocks__figure--center"><img src="/uploads/general/_938xAUTO_fit_center-center/nearest-results-with-clustering@2x.jpg" srcset="/uploads/general/nearest-results-with-clustering@2x.jpg 2x" alt="Nearest clinics results with an good example of marker clustering" class="c-blocks__image" /><figcaption class="c-blocks__figcaption">
                Much-improved visitor location auto-detection, sensible marker clustering, and nearest-first listing of the closest clinics.
              </figcaption></figure></div>

<div class="c-blocks__figure-wrapper"><figure class="c-blocks__figure c-blocks__figure--center"><img src="/uploads/general/_859xAUTO_fit_center-center/winnipeg@2x.jpg" srcset="/uploads/general/winnipeg@2x.jpg 2x" alt="Winnipeg's clinics, showing custom markers and map styles" class="c-blocks__image" /><figcaption class="c-blocks__figcaption">
                On-brand custom markers and map styles with friendly info boxes showing the clinics in Winnipeg.
              </figcaption></figure></div>

<div class="c-blocks__figure-wrapper"><figure class="c-blocks__figure c-blocks__figure--center"><img src="/uploads/general/_926xAUTO_fit_center-center/improved-chicago-search@2x.jpg" srcset="/uploads/general/improved-chicago-search@2x.jpg 2x" alt="Improvements to results from Chicago clinics search" class="c-blocks__image" /><figcaption class="c-blocks__figcaption">
                Major improvement on searching for clinics in Chicago.
              </figcaption></figure></div>]]></content><author><name>Kevin Smith</name></author><category term="Portfolio" /><summary type="html"><![CDATA[For any brick-and-mortar business, it's a major problem if your customers can't find you.]]></summary></entry><entry><title type="html">“Putting your nose to the grindstone is a really easy way to cover up for an unhealthy business.”</title><link href="https://kevinsmith.io/putting-your-nose-to-the-grindstone-is-a-really-easy-way-to-cover-up-for-an-unhealthy-business/" rel="alternate" type="text/html" title="“Putting your nose to the grindstone is a really easy way to cover up for an unhealthy business.”" /><published>2016-04-29T19:28:00+00:00</published><updated>2016-04-29T19:28:00+00:00</updated><id>https://kevinsmith.io/putting-your-nose-to-the-grindstone-is-a-really-easy-way-to-cover-up-for-an-unhealthy-business</id><content type="html" xml:base="https://kevinsmith.io/putting-your-nose-to-the-grindstone-is-a-really-easy-way-to-cover-up-for-an-unhealthy-business/"><![CDATA[<p>My first foray into entrepreneurship was surprisingly successful. At least it started that way.</p>

<p>My business partner and I hung our shingle as <em>Hearsay</em> in 2008 (now <a target="_blank" rel="noopener" href="http://hearsayinteractive.com/">Hearsay Interactive</a>), and we quickly began scheduling one project after another, making enough to live on almost immediately. And it felt really good for a while. The problem came when a huge flat-rate project dragged on four months longer than expected and we had no margins—in terms of time or money—to absorb the blow. When the dust settled, we looked up to see nothing on the books and a few hundred dollars left in our account. By this time it was 2010, and businesses were still reeling from the Great Recession. No one wanted a new site. Everyone was just barely holding on. We were stuck, so we swallowed our pride and started applying for anything that offered a paycheck.</p>

<p>In hindsight, of course, we had gotten lucky early on. The initial success blinded us to our ignorance about the business side of things. Turns out my business degree had been preparing me for a management position in the corporate world, but it hadn’t done much to get me ready to start and run a business of my own. My partner wasn’t in any better position, and eventually he sold me his shares of the business for a pittance and moved on.</p>

<p>I kept the company and took on side projects when they came along while I worked retail jobs and whatnot for a few years. As soon as my finances and connections looked promising, I jumped back into the solo development world again.</p>

<p>I’ve been at it almost a year and a half now, and this time around I’m determined not to make the same short-sighted mistakes. I’ve taken my licks and learned my lessons. I’m now seeking out advice from others who have seen success in similar areas, reading business books that come highly recommended, and staying flexible enough to change when a strategy isn’t working.</p>

<p><a name="profit-first" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#profit-first" class="c-linked-heading__link">#</a>
Profit First
</h2>

<p>So I was delighted to see several fellow small business owners recently discussing a book called  <a target="_blank" rel="noopener" href="http://profitfirstbook.com/">Profit First</a>  by Mike Michalowicz. The author’s way of handling business finances promised to address one of the biggest issues I faced 6 years ago: the seemingly never-ending feast or famine revenue cycle. He also talked about measuring the health of the business by profitability rather than busyness, which was very appealing. I bought a copy from the iBooks store that night and began digging in.</p>

<p>I started implementing the strategy as soon as possible, and I must say I’m very happy with the results. Finally, my business has a solid plan for paying me, saving for taxes, and for the first time, paying profit distributions. I’m no longer flying by the seat of my pants!</p>

<p><a name="this-couldve-been-a-pamphlet" class="u-anchor"></a></p>
<h3 class="c-linked-heading"><a href="#this-couldve-been-a-pamphlet" class="c-linked-heading__link">#</a>
This Could've Been a Pamphlet
</h3>

<p>I’ve got a couple problems with the book, chiefly this: there’s simply not enough substance here to fill a book. What follows is part book review/part system summary. I think the system itself, distilled down to its fundamentals, could be helpful for some of my fellow entrepreneurs. I hope to do some of distillation here.</p>

<p>There are a few core concepts that form a very helpful strategy for structuring business finances, but it could’ve been covered in a single blog post. One could argue that some storytelling and positioning are necessary to really sell the system, but even then, a blog series or a small ebook would’ve been more than enough.</p>

<p>But a 191 page hardback? No sir. Less is more, especially in this case.</p>

<p>The book is rife with meandering off-topic stories, strained analogies, and awkward, inappropriate jokes that make it impossible to recommend to a fellow professional. Like this one:</p>

<blockquote>
  <p>If you don’t know your exact numbers, your mind goes wild and says crazy things (like. . . “Ahh. . . I am going broke. . . ahh. . . the only thing worse is Mike dressed up like Scarlett O’Hara. Ahh. . . what the hell am I thinking? Ahh!”). You can’t change what you don’t acknowledge, so you need to know exactly what you’re dealing with.</p>

  <p><cite>– Profit First by Mike Michalowicz, Chapter 6</cite></p>
</blockquote>

<p>And that example was tame. A good editor helps a business book like this stay focused. I got the impression several times while reading that this book was self-edited and self-published.</p>

<p>At its core, the system is a good one. My problem is the long and unfocused book. Even still, he has some gems in there; like the quote from his introduction that I used as the title for this blog post. It perfectly captures the predicament of a lot of failing small businesses.</p>

<p><a name="all-you-need-to-know" class="u-anchor"></a></p>
<h3 class="c-linked-heading"><a href="#all-you-need-to-know" class="c-linked-heading__link">#</a>
All You Need to Know
</h3>

<p>If you want to follow the system yourself, here are the important bits.</p>

<p><a name="inverting-the-equation" class="u-anchor"></a></p>
<h4 class="c-linked-heading"><a href="#inverting-the-equation" class="c-linked-heading__link">#</a>
Inverting the Equation
</h4>

<p>The thesis of the book is this: the typical business model of <strong><em>Sales - Expenses = Profit</em></strong> is wrong, and it leads you to make all those bad financial decisions you’ve been making. The supporting argument is that as sales increase, expenses inevitably increase because the money’s there and hey, why not. If you don’t intentionally set money aside for profit, you’ll never have it.</p>

<p>No arguments there.</p>

<p>Michalowicz recommends flipping that equation on its head: <strong><em>Sales - Profit = Expenses</em></strong>.</p>

<p>It makes sense, though it seems like his equation is overly simplified. That’s because as you plod through the book, you’ll discover there are some expenses that are more important than other expenses. The equation should really look more like this:</p>

<p><strong><em>Sales - Profit - Taxes - Owner’s Pay = Operating Expenses</em></strong></p>

<p>As sales come in, take a certain percentage out for profit, then taxes, and then owner’s pay. Whatever’s left is all you have available for operating expenses, so you’d better make sure you’ve cut the fat. Pretty straightforward.</p>

<p>For some reason, Michalowicz spends an whole chapter laboriously stepping through what I can only imagine is the unabridged thought process that lead him to the realization that a business should use percentages to divvy up incoming money. It’s helpful to have the structure he eventually arrives at, but the complicated spreadsheets and mind-bending explanations in the book just aren’t necessary. It essentially comes down to these guidelines:</p>

<ul>
  <li>Set aside a small percentage for <strong>Profit</strong>, starting at only 1% or 2%. Cautiously and modestly increase the percentage over time.</li>
  <li>Find the percentage of last year’s taxes paid compared to overall revenue. Set aside that percentage for <strong>Taxes</strong>. This should include the owners’ personal taxes if the business is set up as an entity with pass-through taxation.</li>
  <li>Use the percentage of overall revenue that went to owners last year as a basis to determine the percentage to set aside for <strong>Owner’s Pay</strong>.</li>
  <li>The remainder is for <strong>Operating Expenses</strong>.</li>
  <li>If your business cannot stay afloat on what remains for Operating Expenses, you’ll have to drastically cut costs.</li>
</ul>

<p><a name="the-four-accounts" class="u-anchor"></a></p>
<h4 class="c-linked-heading"><a href="#the-four-accounts" class="c-linked-heading__link">#</a>
The Four Accounts
</h4>

<p>You could use complicated spreadsheets or accounting programs to try to keep track of all those guidelines, but it’s a lot easier to just set up separate bank accounts for them. Here again Michalowicz gets overly complicated, but I sorted through it all and got the essentials:</p>

<ul>
  <li>Keep your existing checking account as your <strong>Operating Expenses</strong> account.</li>
  <li>Open up a new checking account <em>at the same bank</em> for <strong>Owner’s Pay</strong>. You’ll need check writing privileges and/or bill pay to pay yourself and any other owners, but don’t get a debit card with it. You’ll be too tempted to use it if you’re ever in a crunch.</li>
  <li>Open up 2 savings accounts <em>at a different bank</em> for <strong>Profit</strong> and <strong>Taxes</strong>. You want to make it difficult to get this money, so don’t allow yourself a checkbook, debit card, etc. If it’s too easy, you’ll inevitably use it when you’re short in Operating Expenses, and you need to <em>know</em> from the outset that you won’t be able to do this. I set it up so that I can deposit checks through their mobile app but I’ll have to physically go to the bank to make a withdrawal in the form of a cashier’s check.</li>
  <li>If your bank’s online interface allows giving your accounts nicknames, you might want to give them nicknames like “Taxes [20%]” as a helpful reminder of the percentage you’ll be putting in that account.</li>
</ul>

<p><a name="find-a-rhythm" class="u-anchor"></a></p>
<h4 class="c-linked-heading"><a href="#find-a-rhythm" class="c-linked-heading__link">#</a>
Find a Rhythm
</h4>

<p>All your revenue should be deposited to the Operating Expenses account. Obviously moving money from that account to all the others every time you get a deposit would maddening and completely unsustainable, so Michalowicz recommends doing it every few weeks: on the 10th and 25th of every month. Just total up all deposits since the last time, split it up by the designated percentages, and move it to the appropriate accounts.</p>

<p>For some reason, the author felt the above explanation was worthy of the lion’s share of a chapter.</p>

<p><a name="every-quarter" class="u-anchor"></a></p>
<h4 class="c-linked-heading"><a href="#every-quarter" class="c-linked-heading__link">#</a>
Every Quarter
</h4>

<p>When the 10th of the month in a new quarter arrives, the very first thing you should do is take your profit distribution, pay your taxes, and re-evaluate.</p>

<ul>
  <li>Withdraw 50% of the balance in the Profit account, and split it up amongst the owners. Do something unique with it: enjoy the fruits of owning a successful business. Whatever you do, don’t put it back into the company. If you find yourself forced to do that with your <em>personal</em> distributions, it’s a signal there’s something rotten elsewhere in your business model.</li>
  <li>Leave the remaining 50% in the Profit account as a rainy day fund for the company.</li>
  <li>Withdraw from the Taxes account however much is necessary to pay the owners’ quarterly taxes.</li>
  <li>Examine your current percentages and make sure they’re still working for the company. Adjust if necessary.</li>
</ul>

<p><a name="the-rest-of-the-story" class="u-anchor"></a></p>
<h2 class="c-linked-heading"><a href="#the-rest-of-the-story" class="c-linked-heading__link">#</a>
The Rest of the Story
</h2>

<p>The above is exactly what I implemented for my company, and it’s working really well for me. Above all, I learned why it never felt like I was making financial progress with my business even though I was making enough to live on.</p>

<p>I wrote this post in part because I believe the system could be very helpful to a lot of folks in my position, but for a variety of professional and stylistic reasons, I just can’t recommend the book itself.</p>

<p>While it seemed to take forever for the author to get to his main idea, the system was fully explained by the time I reached the middle of the book. What remained were more convoluted tips and tricks and oddly placed motivational stories. To my mind, there’s really no reason to read past chapter 5.</p>

<p>Do yourself a favor and take a hard look at how your company is dealing with its finances. Use the above guidelines if they’re helpful. Make sure you’re billing more than just enough to get by. There’s nothing quite so empowering as having enough money to turn down work, so sock it away.</p>]]></content><author><name>Kevin Smith</name></author><summary type="html"><![CDATA[My first foray into entrepreneurship was surprisingly successful. At least it started that way.]]></summary></entry></feed>