<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
    xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:wfw="http://wellformedweb.org/CommentAPI/"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:atom="http://www.w3.org/2005/Atom"
    xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
    xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
>

    <channel>
        <title>Joseph Silber</title>
        <atom:link href="https://josephsilber.com/posts/feed" rel="self" type="application/rss+xml" />
        <link>https://josephsilber.com</link>
        <description>A blog by Joseph Silber</description>
        <lastBuildDate>Sun, 25 Oct 2026 14:29:45 +0000</lastBuildDate>
        <language>en-US</language>
        <sy:updatePeriod>hourly</sy:updatePeriod>
        <sy:updateFrequency>1</sy:updateFrequency>

                    <item>
                <title>Releasing Bouncer: Roles and Permissions for Laravel apps</title>
                <link>https://josephsilber.com/posts/2022/05/17/releasing-bouncer-laravel-roles-and-permissions</link>
                <pubDate>Tue, 17 May 2022 00:00:00 +0000</pubDate>
                <dc:creator><![CDATA[Joseph Silber]]></dc:creator>

                                    <category><![CDATA[Programming]]></category>
                                    <category><![CDATA[Bouncer]]></category>
                                    <category><![CDATA[PHP]]></category>
                                    <category><![CDATA[Laravel]]></category>
                                    <category><![CDATA[Eloquent]]></category>
                
                <guid isPermaLink="true">https://josephsilber.com/posts/2022/05/17/releasing-bouncer-laravel-roles-and-permissions</guid>
                <description><![CDATA[<p>A personal post with some musings about my journey through the years - from inception to final release</p>]]></description>
                <content:encoded><![CDATA[<h1>Releasing Bouncer: Roles and Permissions for Laravel apps</h1>
<p><img src="/img/posts/releasing-bouncer/bouncer-banner.jpg" alt="Bouncer"></p>
<p>After many years in development, 56 releases, 1.3 million downloads, and over 2,800 unsolicited stars, <strong><a href="https://github.com/JosephSilber/bouncer">Bouncer</a> has finally reached version 1.0</strong>. It has been extremely reliable and stable for quite a while now, and is being used in production by countless apps worldwide.</p>
<p>This is a personal update, with some musings about my journey through the years - from inception to final release. For technical information on how to use Bouncer day to day, check out <a href="https://github.com/JosephSilber/bouncer/blob/master/readme.md#introduction">the extensive documentation</a> or listen to me discuss it with Matt Stauffer on <a href="https://laravelpodcast.com/episodes/bouncer-with-joseph-silber">The Laravel Podcast</a>.</p>
<hr>
<h2>What is Bouncer?</h2>
<p>Before diving into my personal journey, here's a quick overview of what Bouncer is, and how it fits into the greater Laravel ecosystem.</p>
<blockquote>
<p><strong>Bouncer is an open source package for dynamically managing roles and permissions in the database, fully integrated with Laravel's Gate</strong>.</p>
</blockquote>
<p>Without getting into detail, here's a short list of some of its key features:</p>
<ul>
<li>
<p><a href="https://github.com/JosephSilber/bouncer/blob/master/readme.md#giving-a-user-an-ability-directly">Simple abilities</a>:</p>
<pre><code class="language-php">Bouncer::allow($user)-&gt;to('access-dashboard');
</code></pre>
</li>
<li>
<p><a href="https://github.com/JosephSilber/bouncer/blob/master/readme.md#restricting-an-ability-to-a-model">Model abilities</a>:</p>
<pre><code class="language-php">Bouncer::allow($user)-&gt;to('view', Invoice::class);
Bouncer::allow($user)-&gt;to('delete', $invoice);
</code></pre>
</li>
<li>
<p><a href="https://github.com/JosephSilber/bouncer/blob/master/readme.md#assigning-roles-to-a-user">Flexible roles</a>:</p>
<pre><code class="language-php">Bouncer::allow('admin')-&gt;everything();
Bouncer::assign('admin')-&gt;to($user);
</code></pre>
</li>
<li>
<p><a href="https://github.com/JosephSilber/bouncer/blob/master/readme.md#forbidding-an-ability">Forbidding abilities</a>:</p>
<pre><code class="language-php">Bouncer::allow($user)-&gt;to('view', Invoice::class);
Bouncer::forbid($user)-&gt;to('view', $confidentialInvoice);
</code></pre>
</li>
<li>
<p><a href="https://github.com/JosephSilber/bouncer/blob/master/readme.md#allowing-a-user-or-role-to-own-a-model">Powerful ownership</a>:</p>
<pre><code class="language-php">Bouncer::allow($user)-&gt;toOwn(Post::class);
</code></pre>
</li>
<li>
<p><a href="https://github.com/JosephSilber/bouncer/blob/master/readme.md#multi-tenancy">Straighforward multi-tenancy</a>:</p>
<pre><code class="language-php">Bouncer::scope()-&gt;to($tenantId);
</code></pre>
</li>
<li>
<p><a href="https://github.com/JosephSilber/bouncer/blob/master/readme.md#enabling-cache">Built-in caching</a></p>
<pre><code class="language-php">Bouncer::cache();
</code></pre>
</li>
</ul>
<p>...and much more. For details, check out <a href="https://github.com/JosephSilber/bouncer/blob/master/readme.md">the full documentation</a>, or just glance over <a href="https://github.com/JosephSilber/bouncer/blob/master/readme.md#cheat-sheet">the cheat sheet</a>.</p>
<h2>The original idea for Bouncer</h2>
<p>Back in August of 2015, <a href="https://github.com/taylorotwell">Taylor</a> added a <a href="https://github.com/laravel/framework/commit/9a5189822bba546f33a550752b57161e9689c6cd">new Authorization system in Laravel 5.2</a>, called the <code>Gate</code>. This provided a nice API for defining permission checks in your app for various actions, through <a href="https://laravel.com/docs/9.x/authorization#writing-gates">simple <code>define</code> callbacks</a> and full on <a href="https://laravel.com/docs/9.x/authorization#creating-policies">policies</a>, as well as <a href="https://laravel.com/docs/9.x/authorization#authorizing-actions-using-policies">hooks throughout the system for checking permissions</a> against what you've defined.</p>
<p>As soon as I started playing with this, I knew it will be the future of <a href="https://en.wikipedia.org/wiki/Access-control_list">ACL</a> for all Laravel apps. It's just so good. Taylor has this amazing sense for clear and intuitive APIs, and the <code>Gate</code> abstraction really brought that to light.</p>
<p><strong>However, one thing was missing from the built-in authorization system: dynamic permissions, stored in the database</strong>. The way the gate is built, all checks are performed by hard-coded functions defined in your app, so there's no way to allow your admins to control any of it at runtime via some dashboard UI. As Taylor's <a href="https://github.com/laravel/framework/commit/9a5189822bba546f33a550752b57161e9689c6cd">original commit</a> clearly states:</p>
<blockquote>
<p>[The built-in gate] gives a structure to organizing logic that authorizes actions on entities. It does not make any determination on how "user roles" are stored</p>
</blockquote>
<p>At the time, there were many other popular <a href="https://en.wikipedia.org/wiki/Access-control_list">ACL</a> systems which did support tweaking permissions at runtime, but they had one major drawback: they were all built prior to Laravel's <code>Gate</code>. They were completely separate systems; if you decided to use them, you would forgo all of the niceties and beautiful integrations that Laravel's gate offered.</p>
<p>So I decided to build an open source package that would get you the best of both worlds: dynamic DB-driven permissions, fully integrated with Laravel's gate. <a href="https://josephsilber.com/posts/2016/08/03/authorization-improvements-in-laravel-5-3#normalizing-ability-names">We made some improvements to the gate checks in Laravel 5.3</a>, making it more streamlined and predictable, thus easier to store those abilities in the DB.</p>
<h2>The Bouncer name and logo</h2>
<p>The name <code>Bouncer</code> came to me pretty early on. A <a href="https://en.wikipedia.org/wiki/Bouncer">bouncer</a>'s duty is to provide security at the gate and to check people's permissions. So this was a very natural paring to the <code>Gate</code> in Laravel.</p>
<p>Interestingly, the logo designer I was working with at the time (who is not a native English speaker) did not get the reference. Here are <a href="https://twitter.com/joseph_silber/status/967037000812498944">some original logos</a> he designed:</p>
<p><img src="/img/posts/releasing-bouncer/early-draft-logos-1.jpg" alt="Bouncer early logo drafts"></p>
<p>The two to the right are clearly inspired by a bouncing motion. Oof! Hopefully native speakers do get it right away.</p>
<p>After quickly clarifying the meaning of the word bouncer, we started iterating on actual bouncers. We tried friendly bouncers, threatening bouncers, bearded bouncers, square-jawed bouncers, and a ton of different variations. Here are just a few:</p>
<p><img src="/img/posts/releasing-bouncer/early-draft-logos-2.jpg" alt="Bouncer early logo drafts"></p>
<p>I'm quite fond of what we ultimately ended up with:</p>
<p><img src="/img/posts/releasing-bouncer/bouncer-banner.jpg" alt="Bouncer"></p>
<p>It exudes a strong sense of security, but the roundness makes it feel friendlier and less threatening.</p>
<h2>Technical underpinnings</h2>
<p>Bouncer's raison d'etre is to seamlessly integrate with Laravel's gate. To achieve that, I set out with a single goal in mind: you should only have to interact with <code>Bouncer</code> when assigning roles and abilities to users. For the actual authorization checks, Laravel's own hooks throughout the system should work automatically, without any special Bouncer syntax.</p>
<p>The way Bouncer hooks into Laravel's gate checks is pretty simple. The <code>Gate</code> lets you define <a href="https://laravel.com/docs/9.x/authorization#intercepting-gate-checks">a global <code>before</code> callback</a>, which gets called before any other checks you've defined: if your <code>before</code> callback allows or disallows an action, no further checks will run.</p>
<p>While the <code>before</code> callback was originally intended for stuff like "allow everything for admins", I immediately realized that this would be the perfect place to hook up dynamic checks, allowing me to query the database for any permissions. This is how it originally worked (we later switched it to using <a href="https://github.com/laravel/framework/pull/24935">the <code>after</code> callback</a> - you can read more about that <a href="https://github.com/JosephSilber/bouncer/issues/264#issuecomment-406921249">in this thread</a>).</p>
<h2>Documentation</h2>
<p>From the get-go, documentation has been extremely important to me. <strong>Open source projects live or die by their documentation</strong>, so I wanted Bouncer's docs to be the best it possibly can. And especially in the Laravel ecosystem, Taylor has set an extremely high bar for meticulous documentation.</p>
<p>In a way, clear docs are sometimes even more important than the code itself. Without telling your users how to use your tool, very few of them will source dive to figure it out. They'll just move on to the next thing.</p>
<p>I attribute a lot of Bouncer's success to the clear documentation, but there's still a lot more to do on that front. Being the creator and having a clear picture of the whole puzzle, it's easy to forget what people new to the tool struggle with.</p>
<p>For example: as stated earlier, Bouncer is only meant to be used for assigning roles and permissions to users. The actual authorization checks are to be handled like you would in any standard Laravel app. So I figured I don't have to repeat all that, since <a href="https://laravel.com/docs/9.x/authorization#authorizing-actions-using-policies">it's clearly outlined in the Laravel docs</a>. Nevertheless, I still see people struggle with that a lot. They set up their their roles and permissions, then don't know where to go from there. That's an area I still want to flesh out in the docs.</p>
<h2>Working up to the release</h2>
<p>Let me just state this right now: postponing the 1.0 release till now has done my users a disservice. Bouncer has been stable for years, and actively used in production the world over. And yet, I was always hesitant to release it, since I knew there's so much more I want to add to it. I discussed this at length with Matt on <a href="https://laravelpodcast.com/episodes/bouncer-with-joseph-silber">the podcast</a>: I fell down the trap of wanting to make it perfect before releasing it, which is obviously impossible. As Voltaire <a href="https://en.wikipedia.org/wiki/Perfect_is_the_enemy_of_good">has warned</a>: "Perfect is the enemy of good".</p>
<p>So as I'm releasing version 1.0 of Bouncer, there are still 2 outstanding features that I really wanted to have included in the initial release, but didn't make the cut:</p>
<ol>
<li>
<p><strong>Per-model roles</strong>. For the longest time, people have been clamoring to have a way of assigning roles to users only for given model (or model class). Here's what that code would look like:</p>
<pre><code class="language-php">// Note: this is not implemented yet
Bouncer::allow('editor')-&gt;to(['view', 'edit'])-&gt;everything();
Bouncer::assign('editor')-&gt;to($user)-&gt;for(Invoice:class);
</code></pre>
<p>With that, the user would be able to see and edit all invoices, but nothing else. This can of course now be done directly without a role, but doing it through a role would provide another level of flexibility.</p>
<p>I've tried tackling this many times, but it turns out to be quite tricky, because caching becomes a real nightmare. I still hope to tackle it one day. We'll see.</p>
</li>
<li>
<p><strong>Ability constraints</strong>. Allowing arbitrary constraints on a given ability would add way more granular control:</p>
<pre><code class="language-php">// Note: this is not implemented yet
Bouncer::allow($user)
    -&gt;to('view', Post::class)
    -&gt;where('is_confidential', false);
</code></pre>
<p>If you go source diving in Bouncer, you'll find some <a href="https://github.com/JosephSilber/bouncer/tree/master/src/Constraints">code</a> and <a href="https://github.com/JosephSilber/bouncer/tree/master/tests/Unit/Constraints">tests</a> where I started implementing this. It's far from done, but stay tuned.</p>
</li>
</ol>
<p>Overall, Bouncer is in a really great place. Every good product has a long roadmap, and thinking I can get to the end of that road before releasing a 1.0 was both foolish and unrealistic.</p>
<p>So there, <a href="https://overcast.fm/+LF1UtwFlc/22:26">live on air during the podcast</a>, I released Bouncer. It felt great!</p>
<h2>Enjoy using it!</h2>
<p>Well that's a wrap. I hope you try <a href="https://github.com/JosephSilber/bouncer">Bouncer</a> in your app, and enjoy using it. Bouncer's API is designed to feel like prose, with every method call reading like a proper English sentence. Try it, and let me know if you get that feeling too!</p>
]]></content:encoded>
            </item>
                    <item>
                <title>Lazy Collections in Laravel</title>
                <link>https://josephsilber.com/posts/2020/07/29/lazy-collections-in-laravel</link>
                <pubDate>Wed, 29 Jul 2020 00:00:00 +0000</pubDate>
                <dc:creator><![CDATA[Joseph Silber]]></dc:creator>

                                    <category><![CDATA[Programming]]></category>
                                    <category><![CDATA[PHP]]></category>
                                    <category><![CDATA[Laravel]]></category>
                                    <category><![CDATA[Collections]]></category>
                                    <category><![CDATA[Lazy Collections]]></category>
                                    <category><![CDATA[Performance]]></category>
                
                <guid isPermaLink="true">https://josephsilber.com/posts/2020/07/29/lazy-collections-in-laravel</guid>
                <description><![CDATA[<p>A deep dive into Laravel&#039;s Lazy Collections, and how to process enormous amounts of data with very little memory.</p>]]></description>
                <content:encoded><![CDATA[<h1>Lazy Collections in Laravel</h1>
<p>Laravel's <a href="https://laravel.com/docs/7.x/collections#lazy-collections"><code>LazyCollection</code></a> class is a powerful tool that lets you process <em>enormous</em> amounts of data with very little memory. It's a recent addition to the framework (<a href="https://github.com/laravel/framework/pull/29415">introduced in Laravel 6</a>), and is not that well known yet.</p>
<p>To get people more familiar with the power of lazy collections, I gave a talk at the first <a href="https://meetup.laravel.com/">Laravel Worldwide Meetup</a>:</p>
<blockquote>
<p><strong><a href="https://www.youtube.com/watch?v=ajDwUNfKu48">Doing More With Less: Lazy Collections in Laravel</a></strong></p>
<p>A deep dive into Lazy Collections. We'll learn what they are, how they work under the hood, and how to use them to vastly decrease your app's memory footprint.</p>
</blockquote>
<p>This post is the written counterpart of that talk. There's only so much you can cram into a 30 minute talk, so this post also has a ton of additional information that didn't make the cut for the talk.</p>
<hr>
<p>We'll start by looking at regular collections and how they're not really suitable for huge amounts of data. Then we'll see how lazy collections can help us with that.</p>
<h2>Regular Collections</h2>
<p>The <a href="https://laravel.com/docs/7.x/collections"><code>Collection</code> class</a> has been a staple of Laravel since time immemorial. As <a href="https://laravel.com/docs/7.x/collections#introduction">the documentation says</a>, regular collections wrap a native PHP array, providing a fluent, convenient API to interact with the underlying array.</p>
<p>To create a regular collection, you pass it an array of values. To play around, let's start with a simple array of numbers:</p>
<pre><code class="language-php">use Illuminate\Support\Collection;

new Collection([1, 2, 3, 4, 5]);
</code></pre>
<p>In fact, Laravel collections have a handy <a href="https://laravel.com/docs/7.x/collections#method-times"><code>times</code></a> method, which is a convenient way to create a collection with a range of numbers:</p>
<pre><code class="language-php">Collection::times(100); // [1, 2, 3, ... 98, 99, 100]
</code></pre>
<p>Once we have a collection instance, we can start chaining methods onto it:</p>
<pre><code class="language-php">Collection::times(100)  // [1, 2, 3, ... 98, 99, 100]
    -&gt;map(fn ($number) =&gt; $number * 2)  // [2, 4, 6, ... 196, 198, 200]
    -&gt;filter(fn ($number) =&gt; $number % 20 == 0); // [20, 40, 60, ... 160, 180, 200]
</code></pre>
<p>While this simplified example isn't really useful in real life, it shows an important fact about regular collections: all values are held in memory, and every method call creates a new in-memory array of values (wrapped in a new <code>Collection</code> instance).</p>
<h2>Running Out of Memory</h2>
<p>Keeping all values in memory is okay when we have a relatively short list, but as the amount of data we're dealing with starts to grow, we'll quickly run out of memory.</p>
<p>To illustrate, let's try creating a collection class with <em>a billion</em> values:</p>
<pre><code class="language-php">Collection::times(1000 * 1000 * 1000);
</code></pre>
<p>If you try to run this on your computer, you'll most likely get an error that you've run out of memory:</p>
<blockquote>
<p>Allowed memory size of 3154116608 bytes exhausted (tried to allocate 34359738376 bytes)</p>
</blockquote>
<p>The reason for this is quite simple: the <code>times</code> method creates a collection that stores all its values in memory. Trying to allocate memory for <em>a billion</em> numbers will obviously exceed the amount of memory available.</p>
<p>Furthermore, even if we only want to work with a small subset of the collection (for example, to take the first 1,000 even numbers):</p>
<pre><code class="language-php">Collection::times(1000 * 1000 * 1000)
    -&gt;filter(fn ($number) =&gt; $number % 2 == 0)
    -&gt;take(1000);
</code></pre>
<p>...it'll still blow up, because each step builds an entire collection in memory. When we call the <code>times</code> method, it has no way of knowing that we're about to filter its values; that only happens in the next step.</p>
<h2>Switching to Lazy Collections</h2>
<p>If we try the above code using a lazy collection:</p>
<pre><code class="language-php">use Illuminate\Support\LazyCollection;

$collection = LazyCollection::times(1000 * 1000 * 1000)
    -&gt;filter(fn ($number) =&gt; $number % 2 == 0)
    -&gt;take(1000);
</code></pre>
<p>...we won't run out of memory, since none of those values have been generated yet (more on this shortly). In fact, this code snippet uses virtually no memory at all!</p>
<p>How's that possible? Through the power of <a href="https://www.php.net/manual/en/language.generators.overview.php"><code>Generator</code></a>s.</p>
<p>To fully understand lazy collections, we first need a solid understanding of PHP generators:</p>
<h2>Generator Functions in PHP</h2>
<p>The "generator function" is a powerful construct introduced in PHP 5.5. Trying to read the <a href="https://www.php.net/manual/en/language.generators.overview.php">PHP documentation</a> on it can be quite daunting, so let's break it down step by step, learning it in mini, bite-sized lessons.</p>
<h3>Generator functions may return multiple values</h3>
<p>Regular functions in PHP can only return a single value. After returning the first value, all subsequent <code>return</code> statements will be ignored.</p>
<pre><code class="language-php">function run() {
    return 1;
    return 2;
}

dump(run());
</code></pre>
<p>This will only dump <code>1</code>. After the first <code>return</code> statement, the function is terminated, and no futher code in the function is executed.</p>
<p>To return multiple values from a function, we can use the <code>yield</code> keyword instead of <code>return</code>.</p>
<pre><code class="language-php">function run() {
    yield 1;
    yield 2;
}

dump(run());
</code></pre>
<p>But hold on! If you actually run this code, you'll probably be surprised by its output, which will be something like this:</p>
<pre><code>Generator {
    executing: {...}
    closed: false
}
</code></pre>
<p>A <code>Generator</code> object? We never created this object, nor did we return that from our <code>run</code> function. So where is it coming from?</p>
<blockquote>
<p><strong>Lesson 1</strong>: This is what "generator functions" are. The mere presence of the <code>yield</code> keyword in a function instructs PHP that this is not an ordinary function, but a generator function. Generator functions are treated entirely different from regular functions.</p>
</blockquote>
<p>We can see this by adding a <code>dump</code> into our generator function:</p>
<pre><code class="language-php">function run() {
    dump('Did we get here?');
    yield 1;
    yield 2;
}

run();
</code></pre>
<p>This will <em>not</em> dump anything at all. Why?</p>
<blockquote>
<p><strong>Lesson 2</strong>: Calling a generator function does not even execute any of the code inside of the function body. Instead, we get a <a href="https://www.php.net/manual/en/class.generator.php"><code>Generator</code></a> object, which is a mechanism by which we can step through the function's code step by step, pausing at each <code>yield</code> statement.</p>
</blockquote>
<h3>Using <code>current</code> and <code>next</code> to get the generator function's values</h3>
<p>To start stepping through the code in the generator function, use the <code>Generator</code>'s <code>current</code> method. This will actually start executing the code until the first <code>yield</code> statement, and return the value that was <code>yield</code>ed.</p>
<pre><code class="language-php">function run() {
    yield 1;
    yield 2;
}

$generator = run();

$firstValue = $generator-&gt;current();

dump($firstValue);
</code></pre>
<p>Running the code above will give us <code>1</code>, which is the first value that is <code>yield</code>ed from within the generator function.</p>
<blockquote>
<p><strong>Lesson 3</strong>: Use the <code>Generator</code>'s <code>current</code> method to "power up" the generator function. The code in the function will execute till the first <code>yield</code> statement, and its value will be returned.</p>
</blockquote>
<p>Unlike regular functions, the generator function is not terminated after the first value is returned. The function is still alive, waiting for us to get the next value from the <code>Generator</code>.</p>
<p>This time, instead of dumping the <code>current</code> value right away, let's first move the generator to the next <code>yield</code> statement, and only log that second value:</p>
<pre><code class="language-php">function run() {
    yield 1;
    yield 2;
}

$generator = run();

$firstValue = $generator-&gt;current();
$generator-&gt;next();
$secondValue = $generator-&gt;current();

dump($secondValue);
</code></pre>
<p>This will dump <code>2</code>, which is the value returned by the second <code>yield</code> statement.</p>
<blockquote>
<p><strong>Lesson 4</strong>: Use the <code>Generator</code>'s <code>next</code> method to advance the generator function to the next <code>yield</code> statement.</p>
</blockquote>
<h3>Using <code>yield</code> in a loop</h3>
<p>Up until now, we've dealt with multiple hard-coded <code>yield</code> statements inside the generator function. But the true power of the <code>yield</code> statement can only be realized once we start using it in a loop:</p>
<pre><code class="language-php">function generate_numbers()
{
    $number = 1;

    while (true) {
        yield $number;

        $number++;
    }
}

$generator = generate_numbers();

dump($generator-&gt;current()); // Dumps: 1
$generator-&gt;next();
dump($generator-&gt;current()); // Dumps: 2
$generator-&gt;next();
dump($generator-&gt;current()); // Dumps: 3
</code></pre>
<p>Wait, what? An infinite loop???</p>
<p>Yep! Since the code in each iteration of the loop will not execute on its own, this loop is not actually infinite. It will only produce as many values as we pull out of it (by using a combination of <code>current</code> and <code>next</code>).</p>
<blockquote>
<p><strong>Lesson 5</strong>: Using <code>yield</code> from within an infinite loop does not actually <em>cause</em> an infinite loop. Since the generator function's execution pauses after every <code>yield</code>, it'll only run the loop as many iterations as the amount of values that are later requested.</p>
</blockquote>
<h3>Using <code>foreach</code> with <code>Generator</code>s</h3>
<p>Constantly calling <code>current</code> and <code>next</code> will get tiring really fast. So instead of having to do that manually, PHP supports passing a <code>Generator</code> directly to <code>foreach</code>!</p>
<p>Let's try dumping the first 20 numbers from our generator:</p>
<pre><code class="language-php">$generator = generate_numbers();

foreach ($generator as $number) {
    dump($number);

    if ($number == 20) break;
}
</code></pre>
<p>Notice the <code>break</code> there? Since we have an "infinite loop" in the generator function, we must take care to only pull a finite amount of values out of it. Otherwise this <code>foreach</code> will cause an <em>actual</em> infinite loop.</p>
<blockquote>
<p><strong>Lesson 6</strong>: Use <code>foreach</code> to easily enumerate all values in a generator. If there's an infinite loop in your generator function, take care to stop your <code>foreach</code> loop at some point.</p>
</blockquote>
<h3>Composing Generator Functions</h3>
<p>Now, instead of having to add in a <code>break</code> manually, let's create a general helper function called <code>take</code>. We'll pass it 2 arguments: a generator, and a "limit":</p>
<pre><code class="language-php">function take($generator, $limit)
{
    foreach ($generator as $index =&gt; $value) {
        if ($index == $limit) break;

        yield $value;
    }
}
</code></pre>
<blockquote>
<p><strong>Note</strong>: The above <code>take</code> helper is intentionally very naive, to keep the sample simple. For a more robust version of it, <a href="https://github.com/laravel/framework/blob/29c64cb6c1d8cc712463c63fcf60c0a46fe3455e/src/Illuminate/Support/LazyCollection.php#L1132-L1153">read the source</a> (you should be able to understand that at the end of this post).</p>
</blockquote>
<p>Now that we have this <code>take</code> helper in place, we can <em>compose</em> the two generator functions together (<em>composition</em> is just a fancy word that means: using two functions together by passing the result of one function into the other function). We'll pass the numbers generator to the <code>take</code> generator function, and use <em>that</em> in our <code>foreach</code> loop:</p>
<pre><code class="language-php">$allNumbersGenerator = generate_numbers();
$twentyNumbersGenerator = take($allNumbersGenerator, 20);

foreach ($twentyNumbersGenerator as $number) {
    dump($number);
}
</code></pre>
<p>We can also do this directly inline, without the intermediate variables (shown above for clarity):</p>
<pre><code class="language-php">foreach (take(generate_numbers(), 20) as $number) {
    dump($number);
}
</code></pre>
<blockquote>
<p><strong>Lesson 7</strong>: You can create helper generator functions. They take a generator, and return a different generator based on the values in the first one. This lets you compose a whole chain of operations together, which is the actual secret sauce that drives Laravel's lazy collections!</p>
</blockquote>
<p>Now that we have a solid understanding of generators and generator functions in native PHP, let's get back to Lazy Collections.</p>
<h2>Lazy Collections Wrap a Generator Function</h2>
<p>Unlike regular (eager) collections, which wrap a native PHP array, lazy collections wrap a native PHP generator function.</p>
<p>Let's wrap a lazy collection around our numbers generator function:</p>
<pre><code class="language-php">use Illuminate\Support\LazyCollection;

$collection = LazyCollection::make(function () {
    $number = 1;

    while (true) {
        yield $number++;
    }
});
</code></pre>
<p>We now have a collection that "holds" a sequence of all numbers. I put "holds" in quotes because, as we've seen, these numbers haven't been generated yet.</p>
<p>Being a collection means we have access to the countless methods provided to us by Laravel. In fact, the eager <code>Collection</code> class and the <code>LazyCollection</code> class both implement <a href="https://laravel.com/docs/7.x/collections#the-enumerable-contract">the same <code>Enumerable</code> interface</a>, providing the same set of APIs to both collection classes.</p>
<p>Using our lazy collection of all numbers, let's just take the first 10 of them, using the collection's <code>take</code> method:</p>
<pre><code class="language-php">$firstTenNumbers = $collection-&gt;take(10);
</code></pre>
<p>Ah... that's a much nicer API than our own function composition above!</p>
<p>Each method that we chain onto our lazy collection returns a new <code>LazyCollection</code> instance, which internally wraps a new generator function.</p>
<p>To bring this full circle, let's revisit our example from the beginning of this post (with a slight twist):</p>
<pre><code class="language-php">$collection = LazyCollection::times(INF)
    -&gt;filter(fn ($number) =&gt; $number % 2 == 0)
    -&gt;take(1000);
</code></pre>
<p>We start out with a collection that "holds" an <em>infinite</em> number of items, then filter them to only even numbers, and then take the first 1,000 values.</p>
<p>As we already know by now, <em>not a single value has been generated yet</em>. That's why this code uses almost no memory at all. These numbers will only be generated once we start enumerating them (using <code>foreach</code>, or the collection's <code>each</code> method):</p>
<pre><code class="language-php">LazyCollection::times(INF)
    -&gt;filter(fn ($number) =&gt; $number % 2 == 0)
    -&gt;take(1000)
    -&gt;each(fn ($number) =&gt; dump($number));
</code></pre>
<p>Now, and only now, will those numbers be generated!</p>
<blockquote>
<p><strong>Exercise</strong>: How many numbers will be generated in total? Don't just keep reading. Think for a second before you proceed. In the end, how many numbers will be generated by the first generator in this snippet above?</p>
<p>The answer is two thousand. The code snippet above will generate a total of two thousand values. Why? Think about how the <code>filter</code> function works: it pulls values out of the original generator, discards any values that don't pass the filter, and then yields only the values that do pass the filter. So to get to 1,000 even numbers, it had to throw away 1,000 odd numbers!</p>
</blockquote>
<hr>
<p>At this point, you hopefully understand how lazy collections work under the hood (to learn more, take a <a href="https://github.com/laravel/framework/blob/29c64cb6c1d8cc712463c63fcf60c0a46fe3455e/src/Illuminate/Support/LazyCollection.php">deep dive into the source</a>). Next up, let's get away from using simple numbers, and see how we can use lazy collections in a real-world scenario.</p>
<h2>Streaming File Downloads With Lazy Collections</h2>
<p>One of the most useful use-cases for lazy collections is streaming data exports to a download file. Streaming an export gives us many benefits:</p>
<ol>
<li>We don't have to keep all source records in memory.</li>
<li>We don't have to build up the whole export file in memory.</li>
<li>The user doesn't have to wait till the whole file is built up on the server. The download can start instantly!</li>
</ol>
<p>Let's see how we can use a lazy collection to stream a CSV file to the browser, using <a href="https://csv.thephpleague.com/">the versatile <code>league/csv</code> package</a>.</p>
<p>To start, let's create a lazy collection with a million dummy login logs:</p>
<pre><code class="language-php">$logins = LazyCollection::times(1000000, fn () =&gt; [
    'user_id' =&gt; 24,
    'name' =&gt; 'Houdini',
    'logged_in_at' =&gt; now()-&gt;toIsoString(),
]);
</code></pre>
<p>Now that we have this huge dataset (<em>which hasn't actually been generated yet</em>), let's see how we can stream it as a CSV file directly to the browser, without having to build it up as a <em>huge</em> CSV string in memory.</p>
<h3>Streamed Downloads in Laravel</h3>
<p>First off, since we're using Laravel, we need to figure out how streamed downloads work in Laravel. Laravel expects all routes to return a response (either a <code>View</code>, something that may be converted to JSON, or an actual <code>Response</code> object). Route handlers should never directly output anything to the client (by using <code>echo</code> et al).</p>
<p>For streamed downloads, use <a href="https://laravel.com/docs/7.x/responses#file-downloads">a <code>StreamedResponse</code></a>, which uses a callback to stream the response when the framework is ready for it. Within the callback, we can output stuff directly to the client:</p>
<pre><code class="language-php">Route::get('streamed-download', function () {
    return response()-&gt;streamDownload(function () {
        // From within here we can "echo"
        // or write to the PHP output stream
    }, 'the-filename.txt');
});
</code></pre>
<h3>Writing to the PHP Output Buffer</h3>
<p>Next up, let's see how to use <code>league/csv</code>'s <a href="https://csv.thephpleague.com/9.0/writer/"><code>Writer</code> class</a> to stream a CSV file to the browser. The <code>Writer</code> expects a file or a stream, to which the CSV records will be written. We'll use the native <code>php://output</code> stream which, as the name suggests, lets us write to the output buffer directly. From <a href="https://www.php.net/manual/en/wrappers.php.php">the docs</a>:</p>
<blockquote>
<p><code>php://output</code> is a write-only stream that allows you to write to the output buffer mechanism in the same way as <code>print</code> and <code>echo</code>.</p>
</blockquote>
<h3>Putting It All Together</h3>
<p>Putting it all together, we end up with this:</p>
<pre><code class="language-php">use Illuminate\Support\LazyCollection;
use League\Csv\Writer;

Route::get('streamed-download', function () {
    $logins = LazyCollection::times(1000 * 1000, fn () =&gt; [
        'user_id' =&gt; 24,
        'name' =&gt; 'Houdini',
        'logged_in_at' =&gt; now()-&gt;toIsoString(),
    ]);

    return response()-&gt;streamDownload(function () use ($logins) {
        $csvWriter = Writer::createFromFileObject(
            new SplFileObject('php://output', 'w+')
        );

        $csvWriter-&gt;insertOne(['User ID', 'Name', 'Login Time']);

        $csvWriter-&gt;insertAll($logins);
    }, 'logins.csv');
});
</code></pre>
<p>To recap:</p>
<ol>
<li>We create a lazy collection with a million dummy records of login logs.</li>
<li>The route returns a <code>StreamedResponse</code>, with a callback that the framework will call once it's ready for the stream.</li>
<li>Inside the callback, we create a CSV <code>Writer</code> using the <code>php://output</code> buffer, so that we can write CSV records directly to the streaming download file.</li>
<li><code>insertOne</code> adds a single row in the CSV file, which acts as the header row of column names.</li>
<li>The lazy collection is passed directly to <code>insertAll</code>, which <a href="https://github.com/thephpleague/csv/blob/562277db9d595cee999102fc66b9b8cd0f654569/src/Writer.php#L122-L124">internally uses <code>foreach</code></a> to spin through all records in the generator.</li>
</ol>
<p>At no point do we have all of our records in memory; not the original raw data, nor the generated CSV. Each record is generated one by one, and imediately written to the streaming file in the user's browser!</p>
<hr>
<p>We learned how to <em>write</em> data in a lazy manner. Now we'll learn how to <em>read</em> data lazily.</p>
<h2>Reading Files Lazily With a Lazy Collection</h2>
<p>Another area where lazy collections are extremely helpful is reading a file lazily. That is: reading a file line by line, processing each line as it comes in, never loading the whole file into memory.</p>
<h3>JSONL Log Files</h3>
<p>A good example for reading files as a stream involves using the <a href="https://jsonlines.org/">JSONL</a> format (also called JSON Lines). These newline-delimited JSON files are a convenient format for storing or streaming structured data that may be processed one record at a time.</p>
<p>Here's how it would look to store recent logins as JSONL:</p>
<pre><code class="language-js">{ "user_id": 2, "name": "Alice", "timestamp": "2020-07-29T22:51:30.352869Z" }
{ "user_id": 1, "name": "Jinfeng", "timestamp": "2020-07-29T22:54:05.280122Z" }
{ "user_id": 2, "name": "Alice", "timestamp": "2020-07-29T22:54:16.565840Z" }
</code></pre>
<p>Notice that this isn't an array, nor are there commas at the end of each line. Each line is a self-contained JSON object, which can be parsed and processed on its own.</p>
<h3>Writing a File to Disk Lazily</h3>
<p>To play around with this, we need an actual JSONL file. Let's take a little detour, and see how to create such a file with a bunch of fake data, using a lazy collection:</p>
<pre><code class="language-php">LazyCollection::times(10 * 1000)
    -&gt;flatMap(fn () =&gt; [
        ['user_id' =&gt; 1, 'name' =&gt; 'Jinfeng'],
        ['user_id' =&gt; 2, 'name' =&gt; 'Alice'],
    ])
    -&gt;map(fn ($user, $index) =&gt; array_merge($user, [
        'timestamp' =&gt; now()-&gt;addSeconds($index)-&gt;toIsoString(),
    ]))
    -&gt;map(fn ($entry) =&gt; json_encode($entry))
    -&gt;each(fn ($json) =&gt; Storage::append('logins.jsonl', $json));
</code></pre>
<p>This will create a file at <code>storage/app/logins.jsonl</code> and add 20,000 fake login records, all without ever holding more than a single line in memory!</p>
<h3>Reading a File Line by Line</h3>
<p>Now that we have a log file, let's play around with it and see how we can run some statistics on this file, without loading the whole thing into memory.</p>
<p>To create a lazy collection that reads a single line of a file at a time, we can use the native PHP <a href="https://www.php.net/manual/en/function.fopen.php"><code>fopen</code></a> and <a href="https://www.php.net/manual/en/function.fgets.php"><code>fgets</code></a> functions, as shown in <a href="https://github.com/laravel/framework/pull/29415#:~:text=Another%20use-case%20would%20be%20reading%20the%20lines%20of%20a%20multi-GB%20log%20file">the 4th example of the original lazy collections PR</a>:</p>
<pre><code class="language-php">$logins = LazyCollection::make(function () {
    $handle = fopen(storage_path('app/logins.jsonl'), 'r');

    while (($line = fgets($handle)) !== false) {
        yield $line;
    }
});
</code></pre>
<p>We now have a <code>$logins</code> lazy collection, where each item in the collection is a standalone JSON string.</p>
<blockquote>
<p><strong>Note</strong>: Laravel 8.0 <a href="https://github.com/laravel/framework/pull/34187">introduced</a> a new <code>File::lines($path)</code> method, which returns a <code>LazyCollection</code> with the lines of the file - just like our code above. In the next example, we'll use the <code>File::lines()</code> method directly.</p>
</blockquote>
<p>Let's see how many times Alice has logged in:</p>
<pre><code class="language-php">$loginCountForAlice = $logins
    -&gt;map(fn ($json) =&gt; json_decode($json))
    -&gt;filter() // In case we have empty lines
    -&gt;where('name', 'Alice')
    -&gt;count();
</code></pre>
<p>We now have the total count of how many times Alice has logged in (100,000 times), without ever keeping more than a single log entry in memory!</p>
<h2>Reading &amp; Streaming Files</h2>
<p>For our last practical example, we'll combine reading <em>and</em> streaming a file download, using a single lazy collection.</p>
<p>Combining everything we've learned so far, we can parse the log file and stream it to the user as a CSV file download:</p>
<pre><code class="language-php">use File;
use Illuminate\Support\LazyCollection;
use League\Csv\Writer;

Route::get('read-and-stream', function () {
    $logins = File::lines(storage_path('app/logins.jsonl'))
        -&gt;map(fn ($json) =&gt; json_decode($json, true))
        -&gt;filter();

    return response()-&gt;streamDownload(function () use ($logins) {
        $csvWriter = Writer::createFromFileObject(
            new SplFileObject('php://output', 'w+')
        );

        $csvWriter-&gt;insertOne(['User ID', 'Name', 'Login Time']);

        $csvWriter-&gt;insertAll($logins);
    }, 'logins.csv');
});
</code></pre>
<p>This will read the source file <em>one line at a time</em>, parse the JSON, convert it to a CSV record, and stream it to the user. All that, while using virtually no memory at all!</p>
<h2>Converting a Regular Collection Into a Lazy Collection</h2>
<p>Before we go, let's quickly see how we can convert a regular collection into a lazy collection, and why we would even want to do that.</p>
<p>Let's say we're dealing with a huge dataset that can't be streamed, such as the results of a single API call:</p>
<pre><code class="language-php">use Illuminate\Support\Collection;

function get_all_customers_from_quickbooks() : Collection
{
    // Run some code that gets all QuickBooks customers,
    // and return it as a regular, eager collection...
}
</code></pre>
<p>The actual implementation of that function is not important. All we care about is that it returns a huge eager collection that can't be streamed to us, so we have to keep it all in memory.</p>
<p>However, lazy collections may still come in handy. To see how, let's count the amount of customers in France who have a balance over 100 euros:</p>
<pre><code class="language-php">$count = get_all_customers_from_quickbooks()
    -&gt;where('country', 'FR')
    -&gt;where('balance', '&gt;', '100')
    -&gt;count();
</code></pre>
<p>Simple, right? But let's look at what's happening under the hood: every time we call <code>where</code>, we're actually creating a brand new <code>Collection</code>, which means we're creating another array in memory to hold all filtered values.</p>
<p>We can do better.</p>
<p>Even though the <em>original</em> values are all held in memory, the subsequent filters shouldn't have to store <em>their</em> values in memory. We can use the <code>lazy</code> method on the regular <code>Collection</code> class to convert it to a <code>LazyCollection</code>:</p>
<pre><code class="language-php">$count = get_all_customers_from_quickbooks()
    -&gt;lazy()
    -&gt;where('country', 'FR')
    -&gt;where('balance', '&gt;', 100)
    -&gt;count();
</code></pre>
<p>While the original values will still all be kept in memory, no additional memory will be allocated when we filter its results. Pretty neat.</p>
<h2>Phew! That's a Wrap</h2>
<p>That's gonna do it! This hopefully shed some light on how lazy collections work, and how you can use them to do more in your app with far less memory than you would otherwise need.</p>
<p>If you want to play around with the techniques we learned here, check out <a href="https://github.com/JosephSilber/lazy-collections-article-code">this GitHub repository</a>, which has working examples of all code in this article. All of the relevant code is in <a href="https://github.com/JosephSilber/lazy-collections-article-code/blob/master/routes/web.php">the single <code>routes/web.php</code> file</a>, each in its own route, ready for you to run in your browser and toy around with. Enjoy!</p>
<hr>
<p><strong>P.S.</strong> We didn't even get a chance to touch on <a href="https://laravel.com/docs/7.x/eloquent#chunking-results">the query builder's <code>cursor</code> method</a>.</p>
<p>We'll leave that for another day.</p>
]]></content:encoded>
            </item>
                    <item>
                <title>How to rid your database of PHP class names in Eloquent&#039;s Polymorphic tables</title>
                <link>https://josephsilber.com/posts/2018/07/02/eloquent-polymorphic-relations-morph-map</link>
                <pubDate>Mon, 02 Jul 2018 00:00:00 +0000</pubDate>
                <dc:creator><![CDATA[Joseph Silber]]></dc:creator>

                                    <category><![CDATA[Programming]]></category>
                                    <category><![CDATA[PHP]]></category>
                                    <category><![CDATA[Laravel]]></category>
                                    <category><![CDATA[Eloquent]]></category>
                
                <guid isPermaLink="true">https://josephsilber.com/posts/2018/07/02/eloquent-polymorphic-relations-morph-map</guid>
                <description><![CDATA[<p>Using Relation::morphMap() to instruct Eloquent to store more generic values for polymorphic types.</p>]]></description>
                <content:encoded><![CDATA[<h1>How to rid your database of PHP class names in Eloquent's Polymorphic tables</h1>
<p><a href="https://laravel.com/docs/5.6/eloquent-relationships#polymorphic-relations">Polymorphic relations</a> let you set up a relationship between many different model types, without the need for extra tables. This works by storing the "morphable type" (explained <a href="#the-default-morph-type">below</a>) in the database, in addition to the morphable type's ID.</p>
<p>By default, the morphable type stored in the database is the model's full class name. While this works, it tightly couples your database to your PHP application. Let's look at how we can instruct Eloquent to use more generic values for these morphable types.</p>
<h2>A short refresher on polymorphic relationships</h2>
<p>If you're already familiar with polymorphic relationships, you can <a href="#the-default-morph-type">skip right ahead</a>.</p>
<p><a href="https://laravel.com/docs/5.6/eloquent-relationships#polymorphic-relations">Polymorphic relationships</a> are one of Eloquent's most powerful features. Let's take a quick look at what they are and why we'd want to use them:</p>
<p>Imagine we have an <code>addresses</code> table that stores our customer's addresses:</p>
<pre><code>Table name:
  addresses

Columns:
  id
  customer_id
  street_number
  street_name
</code></pre>
<p>The <code>customer_id</code> column points to a given record in the <code>customers</code> table, connecting the address to the customer via the customer's ID. That's a pretty standard SQL relationship.</p>
<p>Using Eloquent, we set up the relationship in the <code>Customer</code> model using a <code>HasOne</code> relationship:</p>
<pre><code class="language-php">class Customer
{
    public function address()
    {
        return $this-&gt;hasOne(Address::class);
    }
}
</code></pre>
<p>This works great if <code>Customer</code> is the only entity type in our app that has an address. What if we have other entities in our app, such as <code>Warehouse</code>, that can also have an address? We don't want to create a separate table for warehouse addresses; we'd like to use the same <code>addresses</code> table for both customer and warehouse addresses.</p>
<p>This is what polymorphic relations are for. In addition to storing the foreign record's ID in the table, we'll now also store which <em>type</em> of entity the address belongs to:</p>
<pre><code class="language-diff">Table name:
  addresses

Columns:
  id
- customer_id
+ addressable_id
+ addressable_type
  street_number
  street_name
</code></pre>
<p>Note that we...</p>
<ol>
<li>
<p>Renamed the <code>customer_id</code> column to <code>addressable_id</code>, since an address can now belong to <em>any</em> entity type (the <code>addressable</code> prefix (called the morph name) can really be anything; pick whatever makes sense in your context).</p>
</li>
<li>
<p>Added the <code>addressable_type</code> column, which will tell us which entity <em>type</em> this address belongs to.</p>
</li>
</ol>
<p>Next, we need to update our <code>Customer</code> model to use a <code>MorphOne</code> relationship:</p>
<pre><code class="language-php">class Customer
{
    public function address()
    {
        return $this-&gt;morphOne(Address::class, 'addressable');
    }
}
</code></pre>
<p>...and do the same for our <code>Warehouse</code> model:</p>
<pre><code class="language-php">class Warehouse
{
    public function address()
    {
        return $this-&gt;morphOne(Address::class, 'addressable');
    }
}
</code></pre>
<p>Now we can store both the customer and warehouse addresses in the same table, and Eloquent will manage it all for us behind the scenes:</p>
<pre><code class="language-php">$customer-&gt;address  // Both of these now work.
$warehouse-&gt;address // Polymorphic relations FTW!
</code></pre>
<p>This was a quick crash course on polymorphic relations. Now onto the crux of this article.</p>
<h2>The default Morph Type</h2>
<p>In Eloquent parlance, the "morph type" is the value that is stored in the <code>{morph}_type</code> column (in our example, this is the <code>addressable_type</code> column).</p>
<p>By default, Eloquent will store the model's full class name as the morph type.</p>
<p>Using our example above, let's assume we have two addresses: one for a <code>Customer</code> with an ID of <code>34</code>, and another for a <code>Warehouse</code> with an ID of <code>83</code>. Looking at our <code>addresses</code> table, we should see something like this:</p>
<table>
<thead>
<tr>
<th><code>id</code></th>
<th><code>addressable_id</code></th>
<th><code>addressable_type</code></th>
<th><code>street_number</code></th>
<th><code>street_name</code></th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>34</td>
<td><strong>App\Customer</strong></td>
<td>109</td>
<td>Old Mill Rd.</td>
</tr>
<tr>
<td>2</td>
<td>83</td>
<td><strong>App\Warehouse</strong></td>
<td>2</td>
<td>Willow Rd.</td>
</tr>
</tbody>
</table>
<p>As we can see, the <code>App\Customer</code> and <code>App\Warehouse</code> values are stored directly in the database. This is how Eloquent knows which entity type a given address belongs to.</p>
<p>This works, but it tightly couples the database to our PHP application's internal structure. If we have other systems accessing this database, the value <code>App\Customer</code> has no meaning to them.</p>
<p>What we really want is a way for us to instruct Eloquent what value to use for each entity type in the <code>addressable_type</code> column.</p>
<h2>Customizing the Morph Type</h2>
<p>Using the <a href="https://github.com/laravel/framework/blob/1ce5f49586089098f0d6ee75f39e097ceaf93026/src/Illuminate/Database/Eloquent/Relations/Relation.php#L309-L326"><code>morphMap</code></a> method on Eloquent's <code>Relation</code> class, we can instruct Eloquent to use a custom name for each entity instead of the class name.</p>
<p>We're looking for a value that would make sense to another system accessing this database. Using the foreign entities' table names sounds like a good approach.</p>
<p>We'll add this piece of code in the <code>AppServiceProvider</code>'s <a href="https://github.com/laravel/laravel/blob/c6d7d83ba3c81b31d663ae2917be4c81cc905b8b/app/Providers/AppServiceProvider.php#L14-L17"><code>boot</code></a> method:</p>
<pre><code class="language-php">use Illuminate\Database\Eloquent\Relations\Relation;

public function boot()
{
    Relation::morphMap([
        'customers' =&gt; 'App\Customer',
        'warehouses' =&gt; 'App\Warehouse',
    ]);
}
</code></pre>
<p>With this in place, our scenario above would generate the following rows in the database:</p>
<table>
<thead>
<tr>
<th><code>id</code></th>
<th><code>addressable_id</code></th>
<th><code>addressable_type</code></th>
<th><code>street_number</code></th>
<th><code>street_name</code></th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>34</td>
<td><strong>customers</strong></td>
<td>109</td>
<td>Old Mill Rd.</td>
</tr>
<tr>
<td>2</td>
<td>83</td>
<td><strong>warehouses</strong></td>
<td>2</td>
<td>Willow Rd.</td>
</tr>
</tbody>
</table>
<p>Our PHP class names are now nowhere to be found. We've successfully decoupled our database from our application code!</p>
<p><strong>Bonus</strong>: Since using the foreign table names is such a common practice, you can actually omit the keys when setting the morph map, and Eloquent will automatically use the model's table name as the morph type:</p>
<pre><code class="language-php">Relation::morphMap([
    'App\Customer',
    'App\Warehouse',
]);
</code></pre>
<h2>Why doesn't Eloquent do this automatically?</h2>
<p>After realizing the benefits of decoupling the database from the application structure, the natural question arises: why doesn't Eloquent default to using the model's table name for the morph type?</p>
<p>The answer to this lies in the <em>inverse relationship</em>.</p>
<p>So far, we've only looked at the code in our <code>Customer</code> and <code>Warehouse</code> models, which allows us to get at their address with <code>$customer-&gt;address</code> or <code>$warehouse-&gt;address</code>. But what about the other way around? What if we have an <code>$address</code>, and we want to get the related model?</p>
<p>Let's add the <code>MorphTo</code> relationship to our <code>Address</code> class:</p>
<pre><code class="language-php">class Address
{
    public function addressable()
    {
        return $this-&gt;morphTo(); // Yes. No arguments :)
    }
}
</code></pre>
<p>With the relationship in place, we can now access the related model via the <code>addressable</code> attribute on any address:</p>
<pre><code class="language-php">Address::first()-&gt;addressable; // A Customer or a Warehouse
</code></pre>
<p>Pretty neat!</p>
<p>Now let's think back to our original question: why doesn't Eloquent default to using the model's table name for the morph type?</p>
<p>The answer is that it's simply impossible. If Eloquent would've always used the table name by default, the following code would indeed properly save the <code>addressable_type</code> as <code>customers</code>:</p>
<pre><code class="language-php">Customer::first()-&gt;address()-&gt;create([...]);
</code></pre>
<p>...but if we later have an <code>Address</code> instance and want to know which entity it belongs to, how would a <code>customers</code> value in the <code>addressable_type</code> column help us? There's nothing that connects the <code>App\Customer</code> class to the <code>customers</code> morph type.</p>
<p>Since PHP classes are lazy loaded on demand, there's no outstanding list of all classes in the app. There's no way for Eloquent to know on its own where all of your models are located, or what their class names are.</p>
<p>That's why we need to register our models with <code>Relation::morphMap()</code>, so that we can always know which entity a given morph type is associated with.</p>
<h2>In closing</h2>
<p>To fully decouple your database from your app's structure, always register all of your models with <code>Relation::morphMap()</code>, and live happily ever after.</p>
]]></content:encoded>
            </item>
                    <item>
                <title>Getting the current user (or other session data) in a Laravel controller constructor</title>
                <link>https://josephsilber.com/posts/2017/01/23/getting-current-user-in-laravel-controller-constructor</link>
                <pubDate>Mon, 23 Jan 2017 00:00:00 +0000</pubDate>
                <dc:creator><![CDATA[Joseph Silber]]></dc:creator>

                                    <category><![CDATA[Programming]]></category>
                                    <category><![CDATA[PHP]]></category>
                                    <category><![CDATA[Laravel]]></category>
                                    <category><![CDATA[Authorization]]></category>
                                    <category><![CDATA[Session]]></category>
                
                <guid isPermaLink="true">https://josephsilber.com/posts/2017/01/23/getting-current-user-in-laravel-controller-constructor</guid>
                <description><![CDATA[<p>Session data is not available directly in controller constructors. Let&#039;s see how we can work around that.</p>]]></description>
                <content:encoded><![CDATA[<h1>Getting the current user (or other session data) in a Laravel controller constructor</h1>
<p>Let's discuss something many people have accidentally discovered: you cannot use session data directly in a controller's constructor.</p>
<p>This change was introduced in Laravel 5.3, when <a href="/posts/2016/07/10/authentication-improvements-in-laravel-5-3#route-model-binding-and-global-scopes">the middleware pipeline was rewired to make global scopes work with session data</a>.</p>
<p>In this post we'll examine the problem in more detail, and look at various ways to solve it.</p>
<h2>The Problem</h2>
<p>There are many reasons people want session data in the controller's constructor. Let's look at 2 examples:</p>
<ol>
<li>
<p><strong>Sharing the current user to all views:</strong></p>
<p>Instead of using <code>auth()-&gt;user()</code> in your views, it's sometimes nicer to just have a global <code>$user</code> variable available across all views. A quick way to achieve that is to add a constructor to <a href="https://github.com/laravel/laravel/blob/a9fad67e1fb369779f4c5ebe454524a24e3698b7/app/Http/Controllers/Controller.php#L10-L13">the base controller</a> and share it from there:</p>
<pre><code class="language-php">public function __construct()
{
    view()-&gt;share('user', auth()-&gt;user());
}
</code></pre>
</li>
<li>
<p><strong>Setting a property on the controller that needs the session:</strong></p>
<p>If you need the same piece of information in all of your methods, you may opt to set it as a property on the controller:</p>
<pre><code class="language-php">public function __construct()
{
    $this-&gt;account = Account::find(session('account_id'));
}
</code></pre>
</li>
</ol>
<p>In both of these cases, the code in the constructor assumes that the session is primed and ready. But if we try to run the code, it'll fail. At this point, the request has not yet been routed and no session data is available.</p>
<h2>Solution #1: The <code>Authenticated</code> event</h2>
<p>For every request, Laravel will fire the <code>Authenticated</code> event when the user is authenticated. You can listen for this event in a service provider, and share the <code>$user</code> from there:</p>
<pre><code class="language-php">use Illuminate\Auth\Events\Authenticated;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        $this-&gt;app['events']-&gt;listen(Authenticated::class, function ($e) {
            view()-&gt;share('user', $e-&gt;user);
        });
    }
}
</code></pre>
<h2>Solution #2: Inline view composer</h2>
<p>If you'd rather share the user from the base controller, you can use an inline view composer:</p>
<pre><code class="language-php">public function __construct()
{
    view()-&gt;composer('*', function ($view) {
        $view-&gt;with('user', auth()-&gt;user());
    });
}
</code></pre>
<p>Since the callback will only execute when the view is composed, you'll have access to the session.</p>
<h2>Solution #3: Converting a property to a method</h2>
<p>Let's go back to the second example in <a href="#the-problem">the problem</a> section. Instead of finding the current account directly in the constructor, you can put its logic into its own method and only call it when you actually need it:</p>
<pre><code class="language-php">public function index()
{
    $account = $this-&gt;account();

    // use it as before...
}

protected function account()
{
    return Account::find(session('account_id'));
}
</code></pre>
<p>This is great for new projects, but can be a little tedious if you already have a big project that relies on the property being available across all controller methods. For such cases, you can use an inline middleware.</p>
<h2>Solution #4: Inline middleware</h2>
<p>Inline middleware are a little more involved than the other solutions, but are probably the most flexible.</p>
<p>You may have seen <code>$this-&gt;middleware('auth')</code> before, which registers an existing middleware directly from within the controller constructor. What you may not know is that you can actually use a closure to define the middleware on the fly.</p>
<p>Using an inline middleware, we can hook into the request's routing, so that we have full access to the session:</p>
<pre><code class="language-php">public function __construct()
{
    $this-&gt;middleware(function ($request, $next) {
        $this-&gt;account = Account::find(session('account_id'));

        return $next($request);
    });
}
</code></pre>
<p>We can also use an inline middleware to share the <code>$user</code> to all views:</p>
<pre><code class="language-php">public function __construct()
{
    $this-&gt;middleware(function ($request, $next) {
        view()-&gt;share('user', $request-&gt;user());

        return $next($request);
    });
}
</code></pre>
<p>As you can see, this is a little more complex than the other solutions, but it gives us the most flexibilty.</p>
<hr>
<p>These 4 solutions should cover all your session needs. If there's any controller session problem that's not solved by these, or if you have any better solutions, do let me know!</p>
]]></content:encoded>
            </item>
                    <item>
                <title>Gate and authorization improvements in Laravel 5.3</title>
                <link>https://josephsilber.com/posts/2016/08/03/authorization-improvements-in-laravel-5-3</link>
                <pubDate>Wed, 03 Aug 2016 00:00:00 +0000</pubDate>
                <dc:creator><![CDATA[Joseph Silber]]></dc:creator>

                                    <category><![CDATA[Programming]]></category>
                                    <category><![CDATA[PHP]]></category>
                                    <category><![CDATA[Laravel]]></category>
                                    <category><![CDATA[Laravel 5.3]]></category>
                                    <category><![CDATA[Authorization]]></category>
                
                <guid isPermaLink="true">https://josephsilber.com/posts/2016/08/03/authorization-improvements-in-laravel-5-3</guid>
                <description><![CDATA[<p>With Laravel 5.2 we got a nice authorization system right out of the box. In 5.3 this got a lot of improvements and refinements. Let&#039;s take a look.</p>]]></description>
                <content:encoded><![CDATA[<h1>Gate and authorization improvements in Laravel 5.3</h1>
<p>After <a href="https://josephsilber.com/posts/2016/07/10/authentication-improvements-in-laravel-5-3">looking at the improvements coming to authentication</a>, let's now take a look at what's in store for authorization in Laravel 5.3.</p>
<blockquote>
<p><strong>Note:</strong> some of the features discussed below have originaly been introduced in the middle of the 5.2 cycle. However, all of these features have been tweaked and refined for 5.3, so we'll cover them here.</p>
</blockquote>
<h2>Laravel authorization primer</h2>
<p>If you're already familiar with authorization in Laravel, you can <a href="#the-problem-with-matching-ability-names-to-method-names">skip right ahead</a>.</p>
<p>Laravel's authorization is built around 2 main concepts:</p>
<ol>
<li>
<p><strong>A <code>Gate</code> class</strong>. The gate is the official authority on who has what ability (i.e. who can do what). You use the gate to register a user's abilities, and later check the gate if the user can perform a given action.</p>
</li>
<li>
<p><strong>Policy classes</strong>. Policies are responsible for checking abilities on a single model type. For each model class in your system you want to authorize against, you'll have a matching policy class.</p>
</li>
</ol>
<p>To see how all this works together, let's generate a policy class for a theoretical <code>Task</code> model, by running <code>php artisan make:policy TaskPolicy</code>. Once created, we'll add a simple <code>update</code> method that checks if the user can update the given task:</p>
<pre><code class="language-php">namespace App\Policies;

use App\Task;
use App\User;

class TaskPolicy
{
    public function update(User $user, Task $task)
    {
        return $user-&gt;id === $task-&gt;user_id;
    }
}
</code></pre>
<p>Next we should register this policy with the gate, by adding it to the <code>AuthServiceProvider</code>'s <a href="https://github.com/laravel/laravel/blob/e316be/app/Providers/AuthServiceProvider.php#L15-L17">policy mappings</a>:</p>
<pre><code class="language-php">protected $policies = [
    \App\Task::class =&gt; \App\Policies\TaskPolicy::class,
];
</code></pre>
<p><a href="https://github.com/laravel/framework/blob/414faa8/src/Illuminate/Foundation/Support/Providers/AuthServiceProvider.php#L26">Behind the scenes</a>, this will register the policy with the <code>Gate</code>. From now on, any authorization check against a <code>Task</code> will be routed to the <code>TaskPolicy</code>.</p>
<p>To demonstare, let's create a simple route to update a given task:</p>
<pre><code class="language-php">Route::put('tasks/{task}', function (App\Task $task) {
   abort_unless(Gate::allows('update', $task), 403);

   $task-&gt;update(request()-&gt;input());
});
</code></pre>
<p>We check the gate if the user can update the given task. The gate will call the <code>update</code> method on our policy, passing it both the currently authenticated user as well as the given task (if the user is not logged in, the gate will automatically deny all ability inquiries). If the ability is not granted, we abort with a 403.</p>
<p>(By the way, don't you just love that <a href="https://github.com/laravel/framework/blob/bf987ea/src/Illuminate/Foundation/helpers.php#L68-L73"><code>abort_unless</code></a> function? I mean, just look at that! It reads like a full sentence: "abort unless the gate allows updating the task". This is Laravel at its best.)</p>
<h2>Easily authorizing requests in controllers</h2>
<p>Controllers in Laravel use <a href="https://github.com/laravel/framework/blob/9872318/src/Illuminate/Foundation/Auth/Access/AuthorizesRequests.php">the <code>AuthorizesRequests</code> trait</a> to easily authorize any given request. You can call the <code>authorize</code> method from within a controller and it'll check for the ability at the gate. If the ability is denied, the request will automatically be aborted with a 403 response.</p>
<p>To see this in action, let's move our route to a controller:</p>
<pre><code class="language-php">use App\Task;

class TaskController
{
    public function update(Task $task)
    {
        $this-&gt;authorize('update', $task);

        $task-&gt;update(request()-&gt;input());
    }
}
</code></pre>
<p>Just like before, the gate will consult our <code>TaskPolicy</code>'s <code>update</code> method and return its result.</p>
<h2>Automatic ability names</h2>
<p>Laravel actually goes a tiny step further, and allows you to omit the ability name when calling the <code>authorize</code> method. When the ability name is not provided, Laravel will automatically pick up the ability name from the controller's method.</p>
<p>In our sample controller, calling <code>$this-&gt;authorize($task)</code> would still end up consulting <code>TaskPolicy@update</code> for the check. Pretty nifty!</p>
<p>In Laravel 5.2, the automatic ability name is always the name of the controller method that calls it. Given the following controller:</p>
<pre><code class="language-php">use App\Task;

class TaskController
{
    public function show(Task $task)
    {
        $this-&gt;authorize($task);

        return view('tasks.show')-&gt;with('task', $task);
    }

    public function create()
    {
        $this-&gt;authorize(Task::class);

        return view('tasks.create');
    }
}
</code></pre>
<p>...you would have a policy with methods whose names match up with the names of the controller's methods:</p>
<pre><code class="language-php">use App\Task;
use App\User;

class TaskPolicy
{
    public function show(User $user, Task $task)
    {
        // check if the user can view the given $task
    }

    public function create(User $user)
    {
        // check if the user can create new tasks
    }
}
</code></pre>
<h2>The problem with matching ability names to method names</h2>
<blockquote>
<p><strong>Update August 8, 2016:</strong> after publishing this article, Taylor made some additional changes to authorization. The following has been updated to reflect these changes.</p>
</blockquote>
<p>On the surface this seems quite intuitive, but if you looks closely you'll find some cracks in this convention.</p>
<p>Consider these 2 samples of where this convention breaks down:</p>
<ol>
<li>
<p><strong>Checking abilities outside of a controller</strong>. The controller's method name is not always the most intuitive way to check an ability. Let's examine this template, where we loop through and check each task:</p>
<pre><code class="language-php">@foreach ($tasks as $task)
    @if ($user-&gt;can('show', $task))
        &lt;a href="{{ url('tasks', $task) }}"&gt;View task&lt;/a&gt;
    @endif
@endforeach
</code></pre>
<p>Hmmm... That doesn't look quite right. What does <code>$user-&gt;can('show', $task)</code> check for? Does it check if the user can show tasks? What does that even mean? We want to know if they can view it, not show it!?</p>
</li>
<li>
<p><strong>Duplicate policy methods</strong>. The check for whether we should show the form to create a new task is the very same check that determines whether we allow the user to subsequently store that task. Naively mapping the controller's method names leads to the policy having two identical methods:</p>
<pre><code class="language-php">use App\User;

class TaskPolicy
{
    public function create(User $user)
    {
        // check if the user can create new tasks
    }

    public function store(User $user)
    {
        // check if the user can create new tasks
    }
}
</code></pre>
<p>These two run the very same check, but we need them both for the two different methods on the controller. The same duplication applies to <code>edit</code> and <code>update</code>.</p>
</li>
</ol>
<h2>Normalizing ability names</h2>
<p>In Laravel 5.3, the automatic ability names are getting an upgrade. Instead of blindly using the method name, Laravel will pick a sensible ability name based on the action you're trying to complete. If you're trying to view an item, it'll use the <code>view</code> ability name. If you're trying to create a new record, it'll use the <code>create</code> ability name, even if you call it from the controller's <code>store</code> method.</p>
<p>Laravel does this via a simple mapping between the methods and abilities. Here's the complete map <a href="https://github.com/laravel/framework/blob/d2a41e4/src/Illuminate/Foundation/Auth/Access/AuthorizesRequests.php#L104-L114">straight from the source</a>:</p>
<pre><code class="language-php">[
    'show' =&gt; 'view',
    'create' =&gt; 'create',
    'store' =&gt; 'create',
    'edit' =&gt; 'update',
    'update' =&gt; 'update',
    'destroy' =&gt; 'delete',
]
</code></pre>
<p>This happens automatically, with no change to the code in your controller. You can now check if <code>$user-&gt;can('view', $task)</code> in your views, which is much more intuitive.</p>
<p>Now that the controller doesn't always call the gate with ability names matching the controller methods, the policies should no longer have those methods. Given this controller:</p>
<pre><code class="language-php">use App\Task;

class TaskController
{
    public function create()
    {
        $this-&gt;authorize(Task::class);

        return view('tasks.create');
    }

    public function store()
    {
        $this-&gt;authorize(Task::class);

        Task::create(request()-&gt;input());
    }
}
</code></pre>
<p>...you would have a policy with just a <code>create</code> method:</p>
<pre><code class="language-php">use App\User;

class TaskPolicy
{
    public function create(User $user)
    {
        // check if the user can create tasks
    }
}
</code></pre>
<p>This <code>create</code> method wil be called from both <code>create</code> and <code>store</code> in the controller. Much cleaner!</p>
<h2>Full policy generator</h2>
<p>To help out with these changes, the policy generator is getting a nice boost. If you pass a model name to the generator it'll fully stub out the necessary policy methods to cover all default resource controller methods:</p>
<pre><code>php artisan make:policy TaskPolicy --model=Task
</code></pre>
<p>You can see the raw stub <a href="https://github.com/laravel/framework/blob/d2a41e4/src/Illuminate/Foundation/Console/stubs/policy.stub">in Laravel's source code</a>, which should give you a better picture about the methods being generated.</p>
<h2>The <code>can</code> middleware</h2>
<p>While authorizing abilities inline works well, sometimes it makes more sense to do it at the route level - such as when the same ability applies to a whole group of routes. Laravel ships with a <code>can</code> middleware just for this purpose.</p>
<p>Let's <a href="https://laravel.com/docs/5.2/authorization#defining-abilities">define a general ability</a> named <code>access-dashboard</code>:</p>
<pre><code class="language-php">Gate::define('access-dashboard', function ($user) {
    return $user-&gt;isAdmin();
});
</code></pre>
<p>To guard a whole group of routes against unauthorized access, we can wrap them in a group with the <code>can</code> middleware:</p>
<pre><code class="language-php">Route::group(['middleware' =&gt; 'can:access-dashboard'], function () {
    // define all dashboard routes...
});
</code></pre>
<p>Now the gate will be checked for the <code>access-dashboard</code> ability before running any routes in this group.</p>
<p>You can also pass a second argument to the middleware. This can be either the model's class name, or - to check for a given model instance - the model's route parameter name:</p>
<pre><code class="language-php">Route::get('tasks/{task}', [
   'uses' =&gt; 'TaskController@show',
   'middleware' =&gt; 'can:view,task',
]);

Route::post('tasks', [
   'uses' =&gt; 'TaskController@store',
   'middleware' =&gt; 'can:create,App\Task',
]);
</code></pre>
<p>When passing a route parameter name, the middleware will pull the model instance from the route itself. Refer to Laravel's documentation for more on <a href="https://laravel.com/docs/5.2/routing#route-model-binding">route model binding</a>.</p>
<h2>Authorizing a full resource controller</h2>
<p>Another neat gem in the authorization system is the <code>authorizeResource</code> method now available in controllers. This has the potential to considerably clean up your controllers. So what does this magical <code>authorizeResource</code> do?</p>
<p>In short, it replaces all your calls to <code>authorize</code> in the various controller methods with a single call in the constructor:</p>
<pre><code class="language-php">use App\Task;

class TaskController
{
    public function __construct()
    {
        $this-&gt;authorizeResource(Task::class);
    }

    // ... all resource methods ...
}
</code></pre>
<p>That's all it takes! You can now skip all calls to <code>authorize</code> in the individual methods. Laravel will now automagically check the right abilities for any given action. It's pretty magical actually.</p>
<h2>Managing roles &amp; permissions in the database with Bouncer.</h2>
<p>Laravel's built-in gate works by hard-coding all authorization logic in your app. If you want to manage your users' roles and permissions via the database, check out <a href="https://github.com/JosephSilber/bouncer/blob/master/readme.md"><strong>Bouncer</strong></a>, which integrates effortlessly with Laravel's built-in authorization system.</p>
]]></content:encoded>
            </item>
                    <item>
                <title>The new Closure::fromCallable() in PHP 7.1</title>
                <link>https://josephsilber.com/posts/2016/07/13/closure-from-callable-in-php-7-1</link>
                <pubDate>Wed, 13 Jul 2016 00:00:00 +0000</pubDate>
                <dc:creator><![CDATA[Joseph Silber]]></dc:creator>

                                    <category><![CDATA[Programming]]></category>
                                    <category><![CDATA[PHP]]></category>
                                    <category><![CDATA[PHP 7.1]]></category>
                                    <category><![CDATA[Closures]]></category>
                
                <guid isPermaLink="true">https://josephsilber.com/posts/2016/07/13/closure-from-callable-in-php-7-1</guid>
                <description><![CDATA[<p>Let&#039;s take a look at a neat little feature coming in PHP 7.1: easily converting any callable into a proper Closure using the new Closure::fromCallable() method.</p>]]></description>
                <content:encoded><![CDATA[<h1>The new <code>Closure::fromCallable()</code> in PHP 7.1</h1>
<p>With PHP 5.5 going EOL earlier this week and the PHP 7.1 beta expected later this month, now sounds like a good time to look into a neat little feature coming in 7.1: easily converting any <code>callable</code> into a proper <code>Closure</code> using the new <code>Closure::fromCallable()</code> method.</p>
<h2>A short refresher on closures in PHP</h2>
<p>If you're already familiar with closures in PHP, you can <a href="#when-you-need-to-convert-a-callable-to-a-closure">skip right ahead</a>.</p>
<p>PHP has had closures since version 5.3. Think of it as similar to an anonymous function in Javascript; they're usually passed off to another method, which either calls it directly or stores it for later use.</p>
<p>As an example, let's look at Laravel's collection class. It has a <code>reject</code> method, which you can use to filter out values you don't want in the collection:</p>
<pre><code class="language-php">$ages = collect([3, 7.5, 12, 19.5, 23]);

$adults = $ages-&gt;reject(function ($age) {
    return $age &lt; 18;
});
</code></pre>
<p>Behind the scenes, the <code>reject</code> method will call our closure callback for every item in the collection. If the age is less than <code>18</code>, it will be rejected from our collection.</p>
<h2>When you need to convert a <code>callable</code> to a <code>Closure</code></h2>
<p>Now imagine you want to reject every value in the collection that is not a whole number. Basically, reject all <code>float</code>s. There's a built-in <a href="http://php.net/manual/en/function.is-float.php"><code>is_float</code></a> function, so why don't we pass that in directly?</p>
<pre><code class="language-php">$ages = collect([3, 7.5, 12, 19.5, 23]);

$integers = $ages-&gt;reject('is_float');
</code></pre>
<p>Unexpectedly, this will not work. Why? In addition to a closure, Laravel also allows you to pass in a single value to <code>reject</code>, which will remove that value from the collection. Since we've passed it a string, Laravel thinks we want to remove the <code>'is_float'</code> item from the collection. Whoops!</p>
<p>The way around this is to actually pass in a closure and call <code>is_float</code> from within our closure callback:</p>
<pre><code class="language-php">$ages = collect([3, 7.5, 12, 19.5, 23]);

$integers = $ages-&gt;reject(function ($age) {
    return is_float($age);
});
</code></pre>
<h2>Introducing <code>Closure::fromCallable()</code></h2>
<p>In PHP 7.1, the <code>Closure</code> class has a new static <code>fromCallable</code> method, which automatically creates a <code>Closure</code> from any <code>callbable</code> you pass it. Using this new method, we can clean up our code a bit:</p>
<pre><code class="language-php">$ages = collect([3, 7.5, 12, 19.5, 23]);

$integers = $ages-&gt;reject(Closure::fromCallable('is_float'));
</code></pre>
<p>Pretty neat!</p>
<h2>Creating a closure that wraps a private method</h2>
<p>Another scenario where you'd want a closure is if you want to pass in an array-callable of a private method. As mentioned in <a href="http://php.net/manual/en/language.types.callable.php">the PHP docs</a>, you can create a callable to a method on an object by using an array with this format: <code>[$object, 'method']</code>. This can be quite convenient when using a method on your class that has the logic for the callback:</p>
<pre><code class="language-php">$due = $orders-&gt;filter([$this, 'isDue']);
</code></pre>
<p>This works well, with the only caveat being that the <code>isDue</code> method now has to be made <code>public</code> - otherwise the collection class won't be able to access it.</p>
<p>This is where <code>Closure::fromCallable()</code> once again comes to the rescue. When used from within a class, the resulting closure will automatically be bound to that class, allowing it to access private methods:</p>
<pre><code class="language-php">$due = $orders-&gt;filter(Closure::fromCallable([$this, 'isDue']));
</code></pre>
<p>The <code>isDue</code> method can now stay <code>private</code> or <code>protected</code>, but the collection will still be able to access it through the wrapping closure!</p>
<p>None of this is really earth shattering, but it's a neat little addition that can come in handy every so often.</p>
]]></content:encoded>
            </item>
                    <item>
                <title>Improvements to authentication in Laravel 5.3</title>
                <link>https://josephsilber.com/posts/2016/07/10/authentication-improvements-in-laravel-5-3</link>
                <pubDate>Sun, 10 Jul 2016 00:00:00 +0000</pubDate>
                <dc:creator><![CDATA[Joseph Silber]]></dc:creator>

                                    <category><![CDATA[Programming]]></category>
                                    <category><![CDATA[PHP]]></category>
                                    <category><![CDATA[Laravel]]></category>
                                    <category><![CDATA[Laravel 5.3]]></category>
                                    <category><![CDATA[Authentication]]></category>
                
                <guid isPermaLink="true">https://josephsilber.com/posts/2016/07/10/authentication-improvements-in-laravel-5-3</guid>
                <description><![CDATA[<p>Authentication has gotten some nice improvements in 5.3, so let&#039;s examine it piece by piece. We&#039;ll start with the current state of affairs, then take it from there.</p>]]></description>
                <content:encoded><![CDATA[<h1>Improvements to authentication in Laravel 5.3</h1>
<p>Authentication has gotten some nice improvements in 5.3, so let's examine it piece by piece. We'll start with the current state of affairs, then take it from there.</p>
<h2>Authentication in Laravel 5.2</h2>
<p>In Laravel 5.2, you generally use one of the following methods to make sure a user is authenticated:</p>
<ol>
<li>
<p><strong><a href="https://laravel.com/docs/5.2/authentication#protecting-routes">The <code>auth</code> middleware</a></strong>. Using this middleware on a route, you can restrict access to logged-in users. It will redirect unauthenticated requests (or, for an AJAX request, respond with a 401).</p>
</li>
<li>
<p><strong>The guard's <code>check</code> method</strong>. Using <code>auth()-&gt;check()</code> in your code, you can check if the user is logged in, and branch your logic from there.</p>
</li>
</ol>
<p>This is all nice and dandy, but it can potentially lead to a lot of duplicated code.</p>
<p>If you need some custom logic for an unauthenticated user, using <code>auth()-&gt;check()</code> works perfectly. However, most of the time you simply want to redirect an unauthenticated user (or return with a 401 if it's an AJAX request). The logic for this currently lives in the <code>auth</code> middleware, so there's no way to reuse it. Utilizing <code>auth()-&gt;check()</code> in your code means you have to replicate this logic all over again:</p>
<pre><code class="language-php">public function view(Request $request)
{
    if (! auth()-&gt;check()) {
        if (($request-&gt;ajax() &amp;&amp; ! $request-&gt;pjax()) || $request-&gt;wantsJson()) {
            return response()-&gt;json(['error' =&gt; 'Unauthenticated.'], 401);
        } else {
            return redirect()-&gt;guest('login');
        }
    }

    // The user is logged in. Proceed.
}
</code></pre>
<p>Clearly this is <em>a lot</em> of extra code that we shouldn't need here. Ideally, there should be a single global location for handling unauthenticated responses. Lucky for us, Laravel 5.3 makes this a breeze!</p>
<h2>Introducing the <code>authenticate</code> method</h2>
<p>In Laravel 5.3, there's now a better way: the <code>authenticate</code> method. Calling <code>authenticate</code> will throw an exception if the user is not logged in, so that you don't even need a conditional in your code:</p>
<pre><code class="language-php">public function view()
{
    $user = auth()-&gt;authenticate();

    // The user is logged in. Proceed.
}
</code></pre>
<p>If the user isn't logged in, it'll throw an <code>AuthenticationException</code>. There's no need for you to catch it - Laravel gracefully handles this for you in a single global location.</p>
<h2>The exception handler's <code>unauthenticated</code> method</h2>
<p>The global exception handler catches all authentication exceptions and calls <a href="https://github.com/laravel/laravel/blob/b787586/app/Exceptions/Handler.php#L56-L63">its <code>unauthenticated</code> method</a>. It'll redirect the request to the login page, or, for an AJAX request, return with a 401 error status code.</p>
<p>You can customize this method to your liking, giving you full flexibility on how to handle unauthenticated requests in a single centralized location.</p>
<h2>The <code>Authenticate</code> middleware</h2>
<p>In Laravel 5.2, the <code>Authenticate</code> middleware <a href="https://github.com/laravel/laravel/blob/336d80c/app/Http/Middleware/Authenticate.php">ships in the app skeleton</a>. This middleware is responsible for creating a valid response for an unauthenticated request. To customize its functionality, you edit the <code>handle</code> method directly in the middleware class.</p>
<p>In Laravel 5.3, the auth middleware <a href="https://github.com/laravel/framework/blob/5.3/src/Illuminate/Auth/Middleware/Authenticate.php">has been pulled into the core</a>, allowing us to properly cover it in our tests. Since the middleware does not ship with the app skeleton anymore, you cannot customize it directly. Instead, the auth middleware now throws an <code>AuthenticationException</code> when the user is not logged in, allowing the global exception handler to catch it. As mentioned before, you can customize the response there.</p>
<h2>Authenticating against multiple guards</h2>
<p>Another neat addition to the auth middleware is authentication against multiple guards.</p>
<p>Imagine you're using both the <code>web</code> &amp; <code>api</code> guards throughout your app. You may have some routes that you want to be accessible if the user is logged in with <em>either one</em> of those guards. The updated middleware makes this a breeze:</p>
<pre><code class="language-php">Route::get('users', [
    'uses' =&gt; 'UsersController@index',
    'middleware' =&gt; 'auth:web,api',
]);
</code></pre>
<p>The auth middleware will check each guard. If the user is logged in to <em>any</em> of the guards, the request will be authenticated. Additionally, that guard will be set as the default, so that any calls to <code>auth()-&gt;user()</code> throughout your app will properly return the user.</p>
<h2>Route model binding and global scopes</h2>
<p>The final enhancement to authentication we'll cover here is with regards to route model binding. Route model binding is one of my favorite features in Laravel, removing boilerplate all over your controllers. For the uninitiated, here's a short primer from <a href="https://laravel.com/docs/5.2/routing#route-model-binding">the docs</a>:</p>
<blockquote>
<p>Route model binding provides a convenient way to inject model instances into your routes. For example, instead of injecting a user's ID, you can inject the entire <code>User</code> model instance that matches the given ID.</p>
</blockquote>
<p>As people started using route model binding more and more (especially since 5.2 introduced implicit model binding), they started running into the following issue: if you have a global scope on your model that tries to access the current user, well... you can't. That's because route model binding runs before authentication, so when the model resolves the current user has not yet been authenticated.</p>
<p>Here's some code to explain this issue with a little more detail:</p>
<pre><code class="language-php">// routes.php
Route::get('invoices/{invoice}', [
    'uses' =&gt; 'InvoicesController@show',
    'middleware' =&gt; 'auth',
]);

// InvoicesController.php
public function show(Invoice $invoice)
{
    // show the invoice
}

// Invoice.php
class Invoice extends Model
{
    protected static function boot()
    {
        static::addGlobalScope(function ($query) {
            $query-&gt;where('user_id', auth()-&gt;id());
        });
    }
}
</code></pre>
<p>We're restricting all queries on the invoice model to just the ones that belong to the current user (this is obviously a bit contrived to keep things simple. For a real-world example, <a href="https://github.com/mpociot/teamwork/blob/5ea38ff/src/Mpociot/Teamwork/Traits/UsedByTeams.php">check out Teamwork's excellent <code>UsedByTeams</code> trait</a>).</p>
<p>The problem, as mentioned above, is that <code>auth()-&gt;id()</code> will return <code>null</code> when the model is being resolved through the route's model binding, since it runs before the <code>auth</code> middleware.</p>
<p>In Laravel 5.2 there was really no way around this issue. The only remedy was to forgo route model binding and fetch the model yourself:</p>
<pre><code class="language-php">// InvoicesController.php
public function show($id)
{
    $invoice = Invoice::findOrFail($id);

    // show the invoice
}
</code></pre>
<p>Not the end of the world, I know, but once you've been spoiled by route model binding there's really no going back. Laravel's neat little features tend to have that effect on you...</p>
<p>If you've ever run into this issue before, you'll be happy to hear that in Laravel 5.3 this problem is no more. The middleware stack has been rewired so that authentication will now always run before route model binding and you can now safely get the authenticated user in your global scopes. Hallelujah!</p>
<blockquote>
<p><strong>Note:</strong> as part of this change, session data is no longer available directly in a controller constructor. If you ever run into that, <a href="/posts/2017/01/23/getting-current-user-in-laravel-controller-constructor">here are some workarounds</a>.</p>
</blockquote>
<h2>Bonus: the request's <code>expectsJson</code> method</h2>
<p>While not directly tied to authentication, I thought it'd be nice to include this little tidbit in here.</p>
<p>As you can see in the first code snippet in this post, determining whether the request needs JSON can be quite tedious. If it's an AJAX request it probably wants JSON, unless it's actually a PJAX request. If it's a regular HTTP request, there may be an <code>Accept</code> header specifying that the response should be JSON.</p>
<p>To make all this easier, there's a new <code>expectsJson</code> method on the request. You can use that directly to determine whether to repond with JSON or not:</p>
<pre><code class="language-php">public function view(Invoice $invoice)
{
    if (request()-&gt;expectsJson()) {
        return $invoice;
    } else {
        return view('invoices.show', compact('invoice'));
    }
}
</code></pre>
<p>Just a little tip if you ever have a need for this.</p>
]]></content:encoded>
            </item>
            </channel>

</rss>
