<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <atom:link href="https://nabilhassen.com/feed" rel="self" type="application/rss+xml" />
        <title><![CDATA[Nabil Hassen's Blog]]></title>
        <link><![CDATA[https://nabilhassen.com/feed]]></link>
        <description><![CDATA[News, tutorials, tips, and best practices for PHP and Laravel enthusiasts]]></description>
        <language>en-US</language>
        <pubDate>Wed, 24 Dec 2025 21:00:44 +0300</pubDate>

                    <item>
                <title><![CDATA[PHP 8.6 release date, upcoming features, and RFC status]]></title>
                <link>https://nabilhassen.com/php-86</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#php-86-expected-release-window-and-the-rfcs-being-proposed-right-now">PHP 8.6: expected release window and the RFCs being proposed right now</a></li>
<li><a href="#expected-php-86-release-window">Expected PHP 8.6 release window</a></li>
<li><a href="#approved-or-already-being-implemented-for-the-next-release">Approved or already being implemented for the next release</a>
<ul>
<li><a href="#partial-function-application-v2">Partial Function Application (v2)</a></li>
<li><a href="#clamp">clamp()</a></li>
</ul>
</li>
<li><a href="#rfcs-not-yet-accepted-for-php-86">RFCs not yet accepted for PHP 8.6</a>
<ul>
<li><a href="#funcgetargsbyname">func_get_args_by_name()</a></li>
<li><a href="#nullable-and-non-nullable-cast-operators">Nullable and non-nullable cast operators</a></li>
<li><a href="#deprecate-fuzzy-scalar-casts">Deprecate fuzzy scalar casts</a></li>
<li><a href="#deprecations-for-php-86">Deprecations for PHP 8.6</a></li>
<li><a href="#add-values-to-backedenum">Add values() to BackedEnum</a></li>
<li><a href="#stringable-enums">Stringable enums</a></li>
<li><a href="#stream-error-handling-improvements">Stream error handling improvements</a></li>
<li><a href="#data-encoding-api">Data encoding API</a></li>
<li><a href="#namespace-scoped-visibility">Namespace-scoped visibility</a></li>
<li><a href="#pdo-disconnect-and-isconnected">PDO disconnect() and isConnected()</a></li>
<li><a href="#object-oriented-curl-api-v2">Object-oriented curl API v2</a></li>
<li><a href="#numavailableprocessors">num_available_processors()</a></li>
<li><a href="#drop-32-bit-builds">Drop 32-bit builds</a></li>
<li><a href="#json-schema-validation-support">JSON Schema validation support</a></li>
<li><a href="#packunpack-endianness-modifiers-for-signed-integers">pack()/unpack() endianness modifiers for signed integers</a></li>
<li><a href="#context-managers">Context managers</a></li>
<li><a href="#true-async">True Async</a></li>
<li><a href="#true-async-engine-api">True Async engine API</a></li>
<li><a href="#true-async-scope-and-structured-concurrency">True Async scope and structured concurrency</a></li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="php-86-expected-release-window-and-the-rfcs-being-proposed-right-now" href="#php-86-expected-release-window-and-the-rfcs-being-proposed-right-now" class="" aria-hidden="true" title=""></a>PHP 8.6: expected release window and the RFCs being proposed right now</h2>
<p>You’ll get a current, practical view of what PHP 8.6 is likely to include. We’ll pin down the most likely release window based on the last few major releases. Then we’ll walk through the RFCs that are explicitly targeting PHP 8.6 or are being built for the next PHP 8.x. Everything here is focused on day to day PHP code you’ll actually write in CLI scripts and web apps.</p>
<h2><a id="expected-php-86-release-window" href="#expected-php-86-release-window" class="" aria-hidden="true" title=""></a>Expected PHP 8.6 release window</h2>
<p>PHP has been shipping major versions around late November for years. PHP 8.5 shipped on November 20, 2025, and PHP 8.4.0 shipped in late November 2024. If the project keeps the same cadence, PHP 8.6 is most likely to ship in the third week of November 2026. A reasonable expectation is a Thursday release (like recent majors), so think around November 19, 2026 or November 26, 2026, with the exact date depending on how many RCs are needed.</p>
<h2><a id="approved-or-already-being-implemented-for-the-next-release" href="#approved-or-already-being-implemented-for-the-next-release" class="" aria-hidden="true" title=""></a>Approved or already being implemented for the next release</h2>
<h3><a id="partial-function-application-v2" href="#partial-function-application-v2" class="" aria-hidden="true" title=""></a>Partial Function Application (v2)</h3>
<p><strong>Status: Accepted</strong></p>
<p>This adds a placeholder based syntax to partially apply arguments to any callable. If you call a function and leave one or more arguments as placeholders, PHP returns a <code>Closure</code> that remembers what you already provided. You can then call that closure later with the missing values.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">add</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">int</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$a</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">int</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$b</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">int</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$c</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">int</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$a</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">+</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$b</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">+</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$c</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$add10AndX</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">add</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">10</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">?</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">5</span><span style="color: #61AFEF;">)</span><span style="color: #ABB2BF;">;</span><span style="color: #61AFEF;">  </span><span style="color: #7F848E;">// returns Closure: fn(int $b): int</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$add10AndX</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">3</span><span style="color: #ABB2BF;">);</span><span style="color: #61AFEF;">         </span><span style="color: #7F848E;">// 18</span></div></code></pre>
<p>This creates a closure because <code>?</code> marks a missing argument. <code>$add10AndX</code> is the important variable, it holds the callable you can reuse. If the callable has strict parameter types, the closure keeps them, so you still get proper type errors.</p>
<p>You’ll also see this shine with callback heavy code.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$strings</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [</span><span style="color: #98C379;">&#39;hello world&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;hello php&#39;</span><span style="color: #ABB2BF;">];</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$replaceHello</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">str_replace</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;hello&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;hi&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">?</span><span style="color: #61AFEF;">)</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$result</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">array_map</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$replaceHello</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$strings</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">var_dump</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$result</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p><code>str_replace('hello', 'hi', ?)</code> returns a closure that expects the third argument. That closure can be passed directly into <code>array_map()</code>. Edge case: if you partially apply a callable that takes arguments by reference, the exact behavior depends on the RFC’s final rules, so verify against the RFC when using references.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/partial_function_application_v2">https://wiki.php.net/rfc/partial_function_application_v2</a></p>
<h3><a id="clamp" href="#clamp" class="" aria-hidden="true" title=""></a>clamp()</h3>
<p><strong>Status: Accepted</strong></p>
<p>This proposes a native <code>clamp()</code> function that keeps a value inside a min/max range. If the value is below <code>min</code>, you get <code>min</code>. If it is above <code>max</code>, you get <code>max</code>.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$percent</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">140</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">clamp</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$percent</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">0</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">100</span><span style="color: #ABB2BF;">); </span><span style="color: #7F848E;">// 100</span></div></code></pre>
<p><code>$percent</code> is your input. <code>0</code> and <code>100</code> are inclusive bounds. If you accidentally pass <code>min &gt; max</code>, <code>clamp()</code> is expected to throw a <code>ValueError</code>, so don’t rely on silent fixes.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/clamp_v2">https://wiki.php.net/rfc/clamp_v2</a></p>
<h2><a id="rfcs-not-yet-accepted-for-php-86" href="#rfcs-not-yet-accepted-for-php-86" class="" aria-hidden="true" title=""></a>RFCs not yet accepted for PHP 8.6</h2>
<p>Everything in this section is still draft or under discussion, so details can change or the proposal can be rejected. I’m describing what each RFC is trying to add, and where it would show up in your code if it lands.</p>
<h3><a id="funcgetargsbyname" href="#funcgetargsbyname" class="" aria-hidden="true" title=""></a>func_get_args_by_name()</h3>
<p><strong>Status: Under Discussion</strong></p>
<p>This proposes a new function that returns the current function’s arguments, but keeps parameter names as array keys for named arguments. Unlike <code>func_get_args()</code>, you don’t lose the names.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">greet</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">string</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$name</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">int</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$age</span><span style="color: #ABB2BF;">, ...</span><span style="color: #E06C75;">$extra</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">array</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">func_get_args_by_name</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">var_dump</span><span style="color: #ABB2BF;">(</span><span style="color: #61AFEF;">greet</span><span style="color: #ABB2BF;">(name:</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;Alice&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">age:</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">30</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;x&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;y&#39;</span><span style="color: #ABB2BF;">));</span></div></code></pre>
<p>The returned array should contain keys like <code>name</code> and <code>age</code> for the named arguments. Extra positional arguments remain numeric keys. Edge case: if you pass a parameter positionally, it will likely appear as a numeric key, so don’t assume everything is named.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/func_get_args_by_name">https://wiki.php.net/rfc/func_get_args_by_name</a></p>
<h3><a id="nullable-and-non-nullable-cast-operators" href="#nullable-and-non-nullable-cast-operators" class="" aria-hidden="true" title=""></a>Nullable and non-nullable cast operators</h3>
<p><strong>Status: Under Discussion</strong></p>
<p>This proposes two new cast forms:</p>
<ul>
<li><code>(?type)</code> which lets <code>null</code> pass through as <code>null</code>, but still validates and coerces non null values using weak mode parameter coercion rules.</li>
<li><code>(!type)</code> which rejects <code>null</code> and also rejects values that cannot be coerced cleanly.</li>
</ul>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">var_dump</span><span style="color: #ABB2BF;">((</span><span style="color: #C678DD;">?</span><span style="color: #E5C07B;">int</span><span style="color: #61AFEF;">) </span><span style="color: #E06C75;">$value</span><span style="color: #61AFEF;">)</span><span style="color: #ABB2BF;">;</span><span style="color: #61AFEF;"> </span><span style="color: #7F848E;">// null</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">try</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #56B6C2;">var_dump</span><span style="color: #ABB2BF;">((</span><span style="color: #56B6C2;">!</span><span style="color: #E5C07B;">int</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">}</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">catch</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">TypeError</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$e</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #56B6C2;">echo</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$e</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">getMessage</span><span style="color: #ABB2BF;">(),</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&quot;</span></div><div class='line'><span style="color: #98C379;">&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p><code>(?int)</code> is meant for pipelines where <code>null</code> is a meaningful absence. <code>(!int)</code> is meant for places where you want an explicit failure instead of silent conversion. Edge case: the exact coercion rules are the key part, and they’re based on weak mode parameter rules rather than today’s very permissive casts.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/nullable-not-nullable-cast-operator">https://wiki.php.net/rfc/nullable-not-nullable-cast-operator</a></p>
<h3><a id="deprecate-fuzzy-scalar-casts" href="#deprecate-fuzzy-scalar-casts" class="" aria-hidden="true" title=""></a>Deprecate fuzzy scalar casts</h3>
<p><strong>Status: Under Discussion</strong></p>
<p>This aims to deprecate “fuzzy” casts where PHP currently does lossy conversions without telling you. The classic example is a partially numeric string where PHP keeps the numeric prefix and discards the rest.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$raw</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;123abc&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Today this becomes 123.</span></div><div class='line'><span style="color: #7F848E;">// Under this RFC, this kind of cast is expected to raise a deprecation in PHP 8.6.</span></div><div class='line'><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">int</span><span style="color: #ABB2BF;">) </span><span style="color: #E06C75;">$raw</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">var_dump</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>If this RFC passes, the practical fix is simple: validate first, then cast.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$raw</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;123abc&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">!ctype_digit</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$raw</span><span style="color: #ABB2BF;">)) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">throw</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">InvalidArgumentException</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;Expected digits only&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">int</span><span style="color: #ABB2BF;">) </span><span style="color: #E06C75;">$raw</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #56B6C2;">var_dump</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p><code>ctype_digit()</code> is strict: it only accepts strings made of digits. That means it rejects negative numbers and whitespace, so pick a validator that matches your input rules.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/deprecate-fuzzy-and-null-casts">https://wiki.php.net/rfc/deprecate-fuzzy-and-null-casts</a></p>
<h3><a id="deprecations-for-php-86" href="#deprecations-for-php-86" class="" aria-hidden="true" title=""></a>Deprecations for PHP 8.6</h3>
<p><strong>Status: Draft</strong></p>
<p>This is an umbrella RFC that collects deprecations proposed for PHP 8.6. It’s structured so individual deprecations can be voted separately. Examples currently listed include deprecating passing objects to certain array and zlib functions, and deprecating <code>strcoll()</code> and <code>SORT_LOCALE_STRING</code>.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/deprecations_php_8_6">https://wiki.php.net/rfc/deprecations_php_8_6</a></p>
<h3><a id="add-values-to-backedenum" href="#add-values-to-backedenum" class="" aria-hidden="true" title=""></a>Add values() to BackedEnum</h3>
<p><strong>Status: Under Discussion</strong></p>
<p>This proposes a <code>values()</code> method on <code>BackedEnum</code> to return all backing values as an indexed array. If you’ve written enums and then immediately needed an <code>array_map(fn($c) =&gt; $c-&gt;value, Status::cases())</code>, this removes the boilerplate.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">enum Status: </span><span style="color: #E5C07B;">string</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">case</span><span style="color: #ABB2BF;"> Active </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;active&#39;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">case</span><span style="color: #ABB2BF;"> Inactive </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;inactive&#39;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">var_dump</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Status</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">values</span><span style="color: #ABB2BF;">());</span></div></code></pre>
<p>If the enum already defines its own <code>values()</code> method, that should keep working. If you rely on a specific sort order, confirm what the RFC guarantees (it’s usually declaration order).</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/add_values_method_to_backed_enum">https://wiki.php.net/rfc/add_values_method_to_backed_enum</a></p>
<h3><a id="stringable-enums" href="#stringable-enums" class="" aria-hidden="true" title=""></a>Stringable enums</h3>
<p><strong>Status: Under Discussion</strong></p>
<p>This proposes allowing <code>__toString()</code> on enums. That would make it legal to directly <code>echo</code> an enum case with custom formatting.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">enum Role: </span><span style="color: #E5C07B;">string</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">case</span><span style="color: #ABB2BF;"> Admin </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;admin&#39;</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">__toString</span><span style="color: #ABB2BF;">(): </span><span style="color: #E5C07B;">string</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">value</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Role</span><span style="color: #ABB2BF;">::</span><span style="color: #D19A66;">Admin</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<p>This is intentionally narrow: it’s about letting enums define <code>__toString()</code>, not about adding state to enums.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/stringable-enums">https://wiki.php.net/rfc/stringable-enums</a></p>
<h3><a id="stream-error-handling-improvements" href="#stream-error-handling-improvements" class="" aria-hidden="true" title=""></a>Stream error handling improvements</h3>
<p><strong>Status: Under Discussion</strong></p>
<p>This proposes making stream errors more consistent and more programmatically usable. The RFC describes adding structured error storage, optional exception based behavior, and consistent error codes across wrappers. If you’ve ever had to juggle warnings, error handlers, and inconsistent messages from different stream wrappers, this is aiming at that pain.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/stream_errors">https://wiki.php.net/rfc/stream_errors</a></p>
<h3><a id="data-encoding-api" href="#data-encoding-api" class="" aria-hidden="true" title=""></a>Data encoding API</h3>
<p><strong>Status: Under Discussion</strong></p>
<p>This proposes a standard encoding and decoding API for common base encodings. The motivation is to cover more variants than today’s <code>base64_encode()</code> and <code>base64_decode()</code>, including RFC 4648 family details and additional popular encodings.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/data_encoding_api">https://wiki.php.net/rfc/data_encoding_api</a></p>
<h3><a id="namespace-scoped-visibility" href="#namespace-scoped-visibility" class="" aria-hidden="true" title=""></a>Namespace-scoped visibility</h3>
<p><strong>Status: Under Discussion</strong></p>
<p>This proposes a new visibility level, written like <code>private(namespace)</code>, that allows access from within the same namespace. The goal is to share internal APIs between closely related classes without exposing them as <code>public</code> to the whole application.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/namespace_visibility">https://wiki.php.net/rfc/namespace_visibility</a></p>
<h3><a id="pdo-disconnect-and-isconnected" href="#pdo-disconnect-and-isconnected" class="" aria-hidden="true" title=""></a>PDO disconnect() and isConnected()</h3>
<p><strong>Status: Under Discussion</strong></p>
<p>This proposes two methods on <code>PDO</code>:</p>
<ul>
<li><code>PDO::disconnect()</code> to explicitly close the underlying connection.</li>
<li><code>PDO::isConnected()</code> to query whether the connection is currently established.</li>
</ul>
<p>If this lands, it gives you a supported way to drop a connection without relying on <code>unset($pdo)</code> and garbage collection timing.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/pdo_disconnect">https://wiki.php.net/rfc/pdo_disconnect</a></p>
<h3><a id="object-oriented-curl-api-v2" href="#object-oriented-curl-api-v2" class="" aria-hidden="true" title=""></a>Object-oriented curl API v2</h3>
<p><strong>Status: Under Discussion</strong></p>
<p>PHP has curl handles as objects today, but they are still used mostly through procedural functions. This RFC proposes a real object oriented API on top of curl objects, with a cleaner structure and better type safety.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/curl_oop_v2">https://wiki.php.net/rfc/curl_oop_v2</a></p>
<h3><a id="numavailableprocessors" href="#numavailableprocessors" class="" aria-hidden="true" title=""></a>num_available_processors()</h3>
<p><strong>Status: Under Discussion</strong></p>
<p>This proposes a native function to get the number of available processors. It’s mainly useful for parallel work scheduling, like choosing a default worker count.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$workers</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">num_available_processors</span><span style="color: #ABB2BF;">() ?? </span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;Workers: {</span><span style="color: #E06C75;">$workers</span><span style="color: #98C379;">}</span></div><div class='line'><span style="color: #98C379;">&quot;</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<p>The <code>?? 1</code> fallback matters because the RFC allows returning <code>null</code> in some situations. Don’t assume it always matches CPU affinity limits unless the RFC explicitly guarantees it.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/num_available_processors">https://wiki.php.net/rfc/num_available_processors</a></p>
<h3><a id="drop-32-bit-builds" href="#drop-32-bit-builds" class="" aria-hidden="true" title=""></a>Drop 32-bit builds</h3>
<p><strong>Status: Under Discussion</strong></p>
<p>This proposes stopping official 32-bit builds. If you’re deploying to very old systems this can be a breaking change, but most modern hosting and containers are already 64-bit.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/drop_32bit_support">https://wiki.php.net/rfc/drop_32bit_support</a></p>
<h3><a id="json-schema-validation-support" href="#json-schema-validation-support" class="" aria-hidden="true" title=""></a>JSON Schema validation support</h3>
<p><strong>Status: Under Discussion</strong></p>
<p>This proposes adding JSON Schema support to the JSON extension. The RFC describes schema objects (created from schema text) and validation integrated with existing JSON error handling. If you validate API payloads against schemas today using libraries, this would be a standard option.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/json_schema_validation">https://wiki.php.net/rfc/json_schema_validation</a></p>
<h3><a id="packunpack-endianness-modifiers-for-signed-integers" href="#packunpack-endianness-modifiers-for-signed-integers" class="" aria-hidden="true" title=""></a>pack()/unpack() endianness modifiers for signed integers</h3>
<p><strong>Status: Under Discussion</strong></p>
<p>This proposes extending <code>pack()</code> and <code>unpack()</code> format strings to support endianness modifiers on signed integer formats. The goal is to avoid manual bit shifting when you need signed little endian or big endian integers.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/pack-unpack-endianness-signed-integers-support">https://wiki.php.net/rfc/pack-unpack-endianness-signed-integers-support</a></p>
<h3><a id="context-managers" href="#context-managers" class="" aria-hidden="true" title=""></a>Context managers</h3>
<p><strong>Status: In Discussion</strong></p>
<p>This proposes a <code>using (...) { ... }</code> style construct to guarantee cleanup at the end of a block. The core idea is “acquire something, run code, always release it”, without manually writing <code>try/finally</code> in every place. The RFC examples focus on file handles and transactions.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/context-managers">https://wiki.php.net/rfc/context-managers</a></p>
<h3><a id="true-async" href="#true-async" class="" aria-hidden="true" title=""></a>True Async</h3>
<p><strong>Status: Under discussion</strong></p>
<p>This is a broader proposal to define a standard async model and engine level support that extensions can hook into. It includes a base RFC and related RFCs for scope and an engine API. This is ambitious, and it’s the kind of RFC that can take multiple release cycles if it lands at all.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/true_async">https://wiki.php.net/rfc/true_async</a></p>
<h3><a id="true-async-engine-api" href="#true-async-engine-api" class="" aria-hidden="true" title=""></a>True Async engine API</h3>
<p><strong>Status: Under discussion</strong></p>
<p>This is a companion RFC that focuses on an engine level API for pluggable schedulers, reactors, and thread pools. Think of it as infrastructure to make async implementations possible without hard-wiring PHP to one event loop.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/true_async_engine_api">https://wiki.php.net/rfc/true_async_engine_api</a></p>
<h3><a id="true-async-scope-and-structured-concurrency" href="#true-async-scope-and-structured-concurrency" class="" aria-hidden="true" title=""></a>True Async scope and structured concurrency</h3>
<p><strong>Status: Under discussion</strong></p>
<p>This extends the True Async proposal with scoped lifetimes for coroutines and structured concurrency concepts. The key idea is tying concurrent work to a scope so cancellation and cleanup are automatic when a scope ends.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/true_async_scope">https://wiki.php.net/rfc/true_async_scope</a></p>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>You now have a realistic release window for PHP 8.6 based on the recent late-November cadence. We covered the features already accepted or in implementation, including partial function application and clamp(). We grouped every other currently proposed RFC for PHP 8.6 that is still draft or under discussion, with a short description of what it would change. As votes happen, the only reliable source of truth is each RFC’s status, so keep an eye on which items move to Accepted or Implemented.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 16 Dec 2025 19:52:03 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Downloading files from URLs in Laravel]]></title>
                <link>https://nabilhassen.com/laravel-download-file-from-url</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#handling-file-downloads-from-urls-in-laravel">Handling file downloads from URLs in Laravel</a></li>
<li><a href="#basic-controller-setup">Basic controller setup</a></li>
<li><a href="#directly-streaming-a-remote-url-to-the-browser">Directly streaming a remote URL to the browser</a></li>
<li><a href="#downloading-a-file-from-a-url-and-storing-it-on-disk">Downloading a file from a URL and storing it on disk</a></li>
<li><a href="#streaming-a-url-directly-into-storage-using-http-sink">Streaming a URL directly into storage using HTTP sink</a></li>
<li><a href="#letting-the-user-download-the-stored-file">Letting the user download the stored file</a></li>
<li><a href="#combining-remote-download-and-user-download-in-one-request">Combining remote download and user download in one request</a></li>
<li><a href="#using-queues-or-cron-jobs-to-download-from-urls">Using queues or cron jobs to download from URLs</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="handling-file-downloads-from-urls-in-laravel" href="#handling-file-downloads-from-urls-in-laravel" class="" aria-hidden="true" title=""></a>Handling file downloads from URLs in Laravel</h2>
<p>In this article you will see how to download files from external URLs in a Laravel application.
You will do this both to save the file on your server and to send it to the user as a download.
Everything happens inside normal Laravel code, for example in controllers or jobs.
We will focus only on practical, copy pasteable patterns you can adapt to your own project.</p>
<h2><a id="basic-controller-setup" href="#basic-controller-setup" class="" aria-hidden="true" title=""></a>Basic controller setup</h2>
<p>All the examples below assume you are calling a controller method from a route. For example:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// routes/web.php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Http\Controllers\</span><span style="color: #E5C07B;">FileDownloadController</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Route</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">Route</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;/download-remote&#39;</span><span style="color: #ABB2BF;">, [</span><span style="color: #E5C07B;">FileDownloadController</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;downloadRemote&#39;</span><span style="color: #ABB2BF;">]);</span></div><div class='line'><span style="color: #E5C07B;">Route</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;/cache-remote&#39;</span><span style="color: #ABB2BF;">, [</span><span style="color: #E5C07B;">FileDownloadController</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;cacheRemote&#39;</span><span style="color: #ABB2BF;">]);</span></div></code></pre>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// app/Http/Controllers/FileDownloadController.php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">namespace</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">App\Http\Controllers</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Http\</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Http</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Storage</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">FileDownloadController</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Controller</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// methods will go here</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>You do not have to structure your code exactly like this, but having a dedicated controller keeps the examples clear.</p>
<h2><a id="directly-streaming-a-remote-url-to-the-browser" href="#directly-streaming-a-remote-url-to-the-browser" class="" aria-hidden="true" title=""></a>Directly streaming a remote URL to the browser</h2>
<p>Sometimes you just want to take a remote file URL and let the user download it through your Laravel app, without storing it on disk. This is common when you proxy downloads through your app for authentication or logging.</p>
<p>You can do this with <code>response()-&gt;streamDownload()</code> and a plain PHP stream:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// app/Http/Controllers/FileDownloadController.php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">downloadRemote</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">query</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;url&#39;</span><span style="color: #ABB2BF;">); </span><span style="color: #7F848E;">// example: https://example.com/file.pdf</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">!</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #61AFEF;">abort</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">400</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;Missing url parameter&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$fileName</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">basename</span><span style="color: #ABB2BF;">(</span><span style="color: #56B6C2;">parse_url</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">PHP_URL_PATH</span><span style="color: #ABB2BF;">)) </span><span style="color: #C678DD;">?:</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;downloaded-file&#39;</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">response</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">streamDownload</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> () </span><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$read</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">fopen</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;r&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">!</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$read</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #61AFEF;">abort</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">502</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;Unable to open remote file&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">        }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">while</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">!</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">feof</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$read</span><span style="color: #ABB2BF;">)) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">fread</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$read</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">1024</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">*</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">1024</span><span style="color: #ABB2BF;">); </span><span style="color: #7F848E;">// 1 MB chunks</span></div><div class='line'><span style="color: #ABB2BF;">        }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #56B6C2;">fclose</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$read</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }, </span><span style="color: #E06C75;">$fileName</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>What this does:</p>
<ul>
<li>Reads the <code>url</code> query parameter from the request.</li>
<li>Uses <code>streamDownload</code> to stream the remote file directly to the browser.</li>
<li>Uses <code>fopen</code> and <code>fread</code> in a loop so the file is not fully loaded into memory.</li>
<li>Picks a filename from the URL path, or falls back to <code>downloaded-file</code>.</li>
</ul>
<p>Edge cases to be aware of:</p>
<ul>
<li><code>allow_url_fopen</code> must be enabled in PHP for <code>fopen($url, 'r')</code> to work.</li>
<li>If the remote server is slow or unreachable, your request will also be slow or fail.</li>
<li>You might want to add your own authorization logic before allowing the download.</li>
</ul>
<h2><a id="downloading-a-file-from-a-url-and-storing-it-on-disk" href="#downloading-a-file-from-a-url-and-storing-it-on-disk" class="" aria-hidden="true" title=""></a>Downloading a file from a URL and storing it on disk</h2>
<p>Very often you want to fetch a remote file once, store it somewhere in your storage disk, then serve it from there. This is handy for caching remote assets, invoices, reports, and similar files.</p>
<p>A simple approach is to use the Laravel HTTP client and the Storage facade.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// app/Http/Controllers/FileDownloadController.php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">cacheRemote</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">query</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;url&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">!</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #61AFEF;">abort</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">400</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;Missing url parameter&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$response</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Http</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">timeout</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">30</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">!</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$response</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">successful</span><span style="color: #ABB2BF;">()) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #61AFEF;">abort</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">502</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;Failed to download remote file&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$extension</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">pathinfo</span><span style="color: #ABB2BF;">(</span><span style="color: #56B6C2;">parse_url</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">PHP_URL_PATH</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">??</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">PATHINFO_EXTENSION</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$fileName</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;remote_&#39;</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">time</span><span style="color: #ABB2BF;">() </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$extension</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">?</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;.{</span><span style="color: #E06C75;">$extension</span><span style="color: #98C379;">}&quot;</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">:</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$path</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;downloads/{</span><span style="color: #E06C75;">$fileName</span><span style="color: #98C379;">}&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E5C07B;">Storage</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">disk</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;local&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">put</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$path</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$response</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">body</span><span style="color: #ABB2BF;">());</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">response</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">json</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;stored_as&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E06C75;">$path</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;disk&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;local&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ]);</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>What this does:</p>
<ul>
<li>Uses the HTTP client to GET the remote URL with a timeout.</li>
<li>Checks <code>successful()</code> so you do not store error pages as files.</li>
<li>Derives a simple extension from the URL path.</li>
<li>Writes the raw response body to <code>storage/app/downloads/...</code> using the <code>local</code> disk.</li>
<li>Returns a small JSON payload with where the file was stored.</li>
</ul>
<p>For typical small and medium files this is fine. For very large files this approach reads the full file into memory once, so use the streaming approach in the next section if that matters.</p>
<h2><a id="streaming-a-url-directly-into-storage-using-http-sink" href="#streaming-a-url-directly-into-storage-using-http-sink" class="" aria-hidden="true" title=""></a>Streaming a URL directly into storage using HTTP sink</h2>
<p>For large files you usually do not want to hold the entire file in memory. Laravel's HTTP client is built on top of Guzzle, which supports a <code>sink</code> option that streams the response directly into a file.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// app/Http/Controllers/FileDownloadController.php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> GuzzleHttp\Psr7\</span><span style="color: #E5C07B;">Utils</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">cacheRemoteStreamed</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">query</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;url&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">!</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #61AFEF;">abort</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">400</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;Missing url parameter&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$extension</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">pathinfo</span><span style="color: #ABB2BF;">(</span><span style="color: #56B6C2;">parse_url</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">PHP_URL_PATH</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">??</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">PATHINFO_EXTENSION</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$fileName</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;remote_&#39;</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">time</span><span style="color: #ABB2BF;">() </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$extension</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">?</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;.{</span><span style="color: #E06C75;">$extension</span><span style="color: #98C379;">}&quot;</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">:</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$relativePath</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;downloads/{</span><span style="color: #E06C75;">$fileName</span><span style="color: #98C379;">}&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$absolutePath</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Storage</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">disk</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;local&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">path</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$relativePath</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$resource</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Utils</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">tryFopen</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$absolutePath</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;w&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E5C07B;">Http</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">withOptions</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;sink&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E06C75;">$resource</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;timeout&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">60</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ])-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">response</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">json</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;stored_as&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E06C75;">$relativePath</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;disk&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;local&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ]);</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>What this does:</p>
<ul>
<li>Creates a writable file handle inside the <code>local</code> disk root (by default <code>storage/app/private/downloads/...</code>).</li>
<li>Passes that handle to the HTTP client via the <code>sink</code> option.</li>
<li>Guzzle streams the response into the file as it arrives.</li>
<li>Memory usage stays low even for large files.</li>
</ul>
<p>If you prefer, you can pass a full file path string instead of a resource to <code>sink</code>, and Guzzle will open the file for you.</p>
<h2><a id="letting-the-user-download-the-stored-file" href="#letting-the-user-download-the-stored-file" class="" aria-hidden="true" title=""></a>Letting the user download the stored file</h2>
<p>Once the file is stored in a disk, you usually want to let the user download it. If you stored the file using <code>Storage</code> on an internal disk (for example <code>local</code>), the simplest way is <code>Storage::download()</code>.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// app/Http/Controllers/FileDownloadController.php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">downloadCached</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$path</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">query</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;path&#39;</span><span style="color: #ABB2BF;">); </span><span style="color: #7F848E;">// for example downloads/remote_1700000000.pdf</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">!</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$path</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #61AFEF;">abort</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">400</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;Missing path parameter&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">!</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Storage</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">disk</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;local&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">exists</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$path</span><span style="color: #ABB2BF;">)) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #61AFEF;">abort</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">404</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;File not found&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Storage</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">disk</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;local&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">download</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$path</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>What this does:</p>
<ul>
<li>Reads the <code>path</code> that was returned when you cached the file.</li>
<li>Checks if the file exists on the <code>local</code> disk.</li>
<li>Returns a download response that forces the browser to download the file.</li>
</ul>
<p>You can also override the download filename and headers:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Storage</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">disk</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;local&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">download</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$path</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;report.pdf&#39;</span><span style="color: #ABB2BF;">, [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;Content-Type&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;application/pdf&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">]);</span></div></code></pre>
<h2><a id="combining-remote-download-and-user-download-in-one-request" href="#combining-remote-download-and-user-download-in-one-request" class="" aria-hidden="true" title=""></a>Combining remote download and user download in one request</h2>
<p>Sometimes you want to fetch the file from a URL and immediately send it to the browser once, without keeping a copy. You can combine the HTTP client and <code>streamDownload</code> for this.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// app/Http/Controllers/FileDownloadController.php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">proxyRemote</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">query</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;url&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">!</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #61AFEF;">abort</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">400</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;Missing url parameter&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$fileName</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">basename</span><span style="color: #ABB2BF;">(</span><span style="color: #56B6C2;">parse_url</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">PHP_URL_PATH</span><span style="color: #ABB2BF;">)) </span><span style="color: #C678DD;">?:</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;downloaded-file&#39;</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$response</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Http</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">timeout</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">60</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">!</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$response</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">successful</span><span style="color: #ABB2BF;">()) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #61AFEF;">abort</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">502</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;Failed to download remote file&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$contentType</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$response</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">header</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;Content-Type&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;application/octet-stream&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">response</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">streamDownload</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> () </span><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$response</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$response</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">body</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">    }, </span><span style="color: #E06C75;">$fileName</span><span style="color: #ABB2BF;">, [</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;Content-Type&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E06C75;">$contentType</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ]);</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>What this does:</p>
<ul>
<li>Fetches the remote URL using the HTTP client.</li>
<li>Validates that the response was successful.</li>
<li>Uses the remote <code>Content-Type</code> header when sending the file to the browser.</li>
<li>Wraps the body in a <code>streamDownload</code> so the browser gets a proper attachment download.</li>
</ul>
<p>This approach is fine for small or moderate file sizes. For very large files you should stick with the streaming variant that does not hold the whole response body in memory.</p>
<h2><a id="using-queues-or-cron-jobs-to-download-from-urls" href="#using-queues-or-cron-jobs-to-download-from-urls" class="" aria-hidden="true" title=""></a>Using queues or cron jobs to download from URLs</h2>
<p>If downloading the remote file takes a long time, you usually do not want to block a normal web request. A common pattern is:</p>
<ul>
<li>The HTTP request dispatches a job that downloads and stores the remote file using one of the cache methods above.</li>
<li>The job writes the path to the database.</li>
<li>A separate controller action later exposes the file via <code>Storage::download()</code>.</li>
</ul>
<p>The exact queue and scheduling setup depends on your application, but you reuse the same <code>cacheRemote</code> or <code>cacheRemoteStreamed</code> code inside your job class.</p>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>You have seen how to download files from external URLs inside a Laravel application.
You can stream remote files directly to the browser, cache them to storage, or do both.
You also know how to handle small files with simple <code>Http::get</code> calls and large files with the HTTP sink option.
With these patterns you can cover most real world &quot;download from URL&quot; requirements without extra packages.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Thu, 04 Dec 2025 16:42:19 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Pause and resume queue workers in Laravel]]></title>
                <link>https://nabilhassen.com/laravel-pause-resume-queues</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#how-to-pause-and-resume-queue-workers-in-laravel">How to pause and resume queue workers in Laravel</a></li>
<li><a href="#what-it-means-to-pause-a-queue">What it means to pause a queue</a></li>
<li><a href="#pausing-and-resuming-queues-with-artisan">Pausing and resuming queues with Artisan</a>
<ul>
<li><a href="#starting-a-worker-for-a-specific-connection-and-queue">Starting a worker for a specific connection and queue</a></li>
<li><a href="#pausing-a-queue-from-the-cli">Pausing a queue from the CLI</a></li>
<li><a href="#resuming-a-queue-from-the-cli">Resuming a queue from the CLI</a></li>
</ul>
</li>
<li><a href="#pausing-and-resuming-queues-programmatically">Pausing and resuming queues programmatically</a>
<ul>
<li><a href="#indefinitely-pausing-a-queue-in-code">Indefinitely pausing a queue in code</a></li>
<li><a href="#pausing-a-queue-for-a-fixed-amount-of-time">Pausing a queue for a fixed amount of time</a></li>
<li><a href="#example-pausing-a-queue-when-an-external-api-returns-429">Example: pausing a queue when an external API returns 429</a></li>
<li><a href="#checking-whether-a-queue-is-paused">Checking whether a queue is paused</a></li>
<li><a href="#how-cli-and-code-based-pausing-work-together">How CLI and code based pausing work together</a></li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="how-to-pause-and-resume-queue-workers-in-laravel" href="#how-to-pause-and-resume-queue-workers-in-laravel" class="" aria-hidden="true" title=""></a>How to pause and resume queue workers in Laravel</h2>
<p>In this guide, you will learn how to pause and resume Laravel queue workers on demand.
We will work in the context of long running <code>queue:work</code> processes managed from the CLI.
You will see how to target specific connections and queues when pausing workers.
You will also see how to pause queues indefinitely or for a fixed amount of time from both Artisan and application code.</p>
<h2><a id="what-it-means-to-pause-a-queue" href="#what-it-means-to-pause-a-queue" class="" aria-hidden="true" title=""></a>What it means to pause a queue</h2>
<p>Before touching any commands, it helps to be precise about what a &quot;paused&quot; queue actually does in Laravel:</p>
<ul>
<li>Pausing is <strong>per queue and per connection</strong>, not global for all queues.</li>
<li>Workers that are already running <strong>finish the job they are currently processing</strong>.</li>
<li>Once the current job finishes, workers <strong>stop pulling new jobs</strong> from the paused queue.</li>
<li>The worker process itself <strong>keeps running</strong>; it does not exit or get killed.</li>
<li>When the queue is resumed, workers immediately start pulling jobs again from that queue.</li>
</ul>
<p>So pausing is a way to temporarily put a queue on hold without touching your process manager or worker processes.</p>
<h2><a id="pausing-and-resuming-queues-with-artisan" href="#pausing-and-resuming-queues-with-artisan" class="" aria-hidden="true" title=""></a>Pausing and resuming queues with Artisan</h2>
<p>The most direct way to pause and resume queues is via Artisan. This is usually what you will do in production shells or deployment scripts.</p>
<h3><a id="starting-a-worker-for-a-specific-connection-and-queue" href="#starting-a-worker-for-a-specific-connection-and-queue" class="" aria-hidden="true" title=""></a>Starting a worker for a specific connection and queue</h3>
<p>First, assume you have a worker processing a queue. For example:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">queue:work</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">database</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--queue=default</span></div></code></pre>
<p>This worker uses the <code>database</code> queue connection and listens to the <code>default</code> queue.
The connection name comes from <code>config/queue.php</code>, and the queue name is whatever you configured or used when dispatching jobs.
As long as this process is running, it will keep picking up jobs from the <code>database</code> connection's <code>default</code> queue.</p>
<h3><a id="pausing-a-queue-from-the-cli" href="#pausing-a-queue-from-the-cli" class="" aria-hidden="true" title=""></a>Pausing a queue from the CLI</h3>
<p>To pause a queue, you use the <code>queue:pause</code> command and pass a <strong>single argument</strong> in the <code>connection:queue</code> format:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">queue:pause</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">database:default</span></div></code></pre>
<p>Key points:</p>
<ul>
<li><code>database</code> is the <strong>connection name</strong>.</li>
<li><code>default</code> is the <strong>queue name</strong>.</li>
<li>Any workers processing jobs from <code>database</code> / <code>default</code> will finish their current job.</li>
<li>After finishing that job, they will <strong>not</strong> fetch any new jobs from that queue until it is resumed.</li>
</ul>
<p>If you are using Redis with a custom queue name, pausing that queue looks like this:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">queue:pause</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">redis:emails</span></div></code></pre>
<p>Workers that are listening on <code>redis</code> and processing the <code>emails</code> queue will stop taking new jobs from <code>emails</code>, but can continue to process other queues if they are configured to listen to multiple queues.</p>
<h3><a id="resuming-a-queue-from-the-cli" href="#resuming-a-queue-from-the-cli" class="" aria-hidden="true" title=""></a>Resuming a queue from the CLI</h3>
<p>To resume job processing on a paused queue, you use <code>queue:continue</code> with the same <code>connection:queue</code> syntax:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">queue:continue</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">database:default</span></div></code></pre>
<p>After this command runs:</p>
<ul>
<li>Workers that were idle because <code>database:default</code> was paused will start pulling new jobs again from that queue.</li>
<li>Jobs that accumulated on <code>database</code> / <code>default</code> while it was paused will now be processed as normal.</li>
</ul>
<p>You can do the same for any other connection and queue combination. For example:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">queue:continue</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">redis:emails</span></div></code></pre>
<p>This resume command works regardless of whether the queue was paused via Artisan or via application code, since both go through the same underlying queue manager.</p>
<h2><a id="pausing-and-resuming-queues-programmatically" href="#pausing-and-resuming-queues-programmatically" class="" aria-hidden="true" title=""></a>Pausing and resuming queues programmatically</h2>
<p>Sometimes you want to pause or resume a queue <strong>from your application code</strong> instead of the CLI. For example, you might want to pause a queue when an external API rate limit is hit, or when an admin flips a feature flag in a dashboard.</p>
<p>For that, Laravel exposes queue pausing APIs via the <code>Queue</code> facade and the underlying <code>QueueManager</code> class.</p>
<h3><a id="indefinitely-pausing-a-queue-in-code" href="#indefinitely-pausing-a-queue-in-code" class="" aria-hidden="true" title=""></a>Indefinitely pausing a queue in code</h3>
<p>To pause a queue indefinitely from code, you can call <code>Queue::pause</code> with a connection and queue name:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">namespace</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">App\Http\Controllers</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Http\</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Queue</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">QueueAdminController</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">pauseDefaultDatabaseQueue</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// Pause the &quot;default&quot; queue on the &quot;database&quot; connection indefinitely</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Queue</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">pause</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;database&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;default&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">response</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">json</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #98C379;">&#39;status&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;ok&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #98C379;">&#39;message&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;database:default queue paused&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        ]);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>What matters in this example:</p>
<ul>
<li><code>Queue::pause('database', 'default')</code> pauses the queue identified by that <strong>connection</strong> and <strong>queue</strong>.</li>
<li>The pause is <strong>indefinite</strong>. The queue stays paused until you explicitly resume it.</li>
<li>You can call this from anywhere in your app: controllers, commands, services, or jobs.</li>
</ul>
<p>To resume the same queue from code, call <code>Queue::resume</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">Queue</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">resume</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;database&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;default&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>You can safely call <code>Queue::resume</code> even if the queue is not currently paused. It simply ensures the paused flag is cleared.</p>
<h3><a id="pausing-a-queue-for-a-fixed-amount-of-time" href="#pausing-a-queue-for-a-fixed-amount-of-time" class="" aria-hidden="true" title=""></a>Pausing a queue for a fixed amount of time</h3>
<p>Laravel also lets you pause a queue <strong>for a specific duration</strong> using <code>Queue::pauseFor</code>.</p>
<p>This method accepts three arguments:</p>
<ul>
<li>
<p>The <strong>connection name</strong>.</p>
</li>
<li>
<p>The <strong>queue name</strong>.</p>
</li>
<li>
<p>A <strong>TTL</strong> (time to live) value that can be:</p>
<ul>
<li>An integer number of seconds.</li>
<li>A <code>DateTimeInterface</code> instance.</li>
<li>A <code>DateInterval</code> instance.</li>
</ul>
</li>
</ul>
<p>Here is a simple example that pauses a queue for 60 seconds:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Queue</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Pause for 60 seconds</span></div><div class='line'><span style="color: #E5C07B;">Queue</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">pauseFor</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;redis&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;default&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">60</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>You can also express the pause using a <code>DateTimeInterface</code> by giving the exact moment when the pause should expire:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Queue</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Pause until five minutes from now</span></div><div class='line'><span style="color: #E5C07B;">Queue</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">pauseFor</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;redis&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;default&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #61AFEF;">now</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">addMinutes</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">5</span><span style="color: #ABB2BF;">));</span></div></code></pre>
<p>Or using a <code>DateInterval</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DateInterval</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Queue</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Pause for 45 seconds via DateInterval</span></div><div class='line'><span style="color: #E5C07B;">Queue</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">pauseFor</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;redis&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;default&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DateInterval</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;PT45S&#39;</span><span style="color: #ABB2BF;">));</span></div></code></pre>
<p>When you use <code>pauseFor</code>:</p>
<ul>
<li>Laravel sets an internal flag that marks the queue as paused for the given TTL.</li>
<li>While the flag is active, workers do not pull new jobs from that queue after finishing what they are currently processing.</li>
<li>Once the TTL expires, the flag automatically disappears and workers will treat the queue as active again.</li>
<li>You do not have to call <code>Queue::resume</code> when the TTL expires, although you can still call it manually if you want to resume earlier.</li>
</ul>
<h3><a id="example-pausing-a-queue-when-an-external-api-returns-429" href="#example-pausing-a-queue-when-an-external-api-returns-429" class="" aria-hidden="true" title=""></a>Example: pausing a queue when an external API returns 429</h3>
<p>A very practical use case for <code>pauseFor</code> is handling rate limited APIs that return HTTP 429 with a <code>Retry-After</code> header.</p>
<p>Here is a simplified example inside a job that consumes such an API:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">namespace</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">App\Jobs</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Bus\</span><span style="color: #E5C07B;">Queueable</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Contracts\Queue\</span><span style="color: #E5C07B;">ShouldQueue</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Foundation\Bus\</span><span style="color: #E5C07B;">Dispatchable</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Queue\</span><span style="color: #E5C07B;">InteractsWithQueue</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Queue\</span><span style="color: #E5C07B;">SerializesModels</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Http</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Queue</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">SyncExternalData</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">implements</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">ShouldQueue</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Dispatchable</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">InteractsWithQueue</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">Queueable</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">SerializesModels</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">handle</span><span style="color: #ABB2BF;">(): </span><span style="color: #E5C07B;">void</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$response</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Http</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;https://example.com/api/data&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$response</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">status</span><span style="color: #ABB2BF;">() </span><span style="color: #56B6C2;">===</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">429</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E06C75;">$retryAfter</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">int</span><span style="color: #ABB2BF;">) </span><span style="color: #E06C75;">$response</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">header</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;Retry-After&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">60</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #7F848E;">// Pause the queue that is processing this job for the Retry-After period</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E5C07B;">Queue</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">pauseFor</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">queueConnection</span><span style="color: #ABB2BF;">(), </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">queueName</span><span style="color: #ABB2BF;">(), </span><span style="color: #E06C75;">$retryAfter</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #7F848E;">// Optionally release this job so it can be retried later</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">release</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$retryAfter</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">        }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// Normal processing logic for successful responses...</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">queueConnection</span><span style="color: #ABB2BF;">(): </span><span style="color: #E5C07B;">string</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">connection</span><span style="color: #ABB2BF;"> ?? </span><span style="color: #61AFEF;">config</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;queue.default&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">queueName</span><span style="color: #ABB2BF;">(): </span><span style="color: #E5C07B;">string</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">queue</span><span style="color: #ABB2BF;"> ?? </span><span style="color: #98C379;">&#39;default&#39;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Important details here:</p>
<ul>
<li><code>Queue::pauseFor(...)</code> is called with the same connection and queue that this job is running on.</li>
<li>The TTL is taken from the <code>Retry-After</code> header when available, or defaults to 60 seconds.</li>
<li><code>release($retryAfter)</code> tells the queue to retry the job after the same delay, so processing resumes when the pause ends.</li>
<li>Other jobs on the same queue will also be paused until the TTL expires.</li>
</ul>
<p>You can adapt this pattern to any situation where you need to back off a whole queue for a while.</p>
<h3><a id="checking-whether-a-queue-is-paused" href="#checking-whether-a-queue-is-paused" class="" aria-hidden="true" title=""></a>Checking whether a queue is paused</h3>
<p>Sometimes you just want to know if a queue is currently paused so you can make a decision in code. For that, you can use <code>Queue::isPaused</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Queue</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Queue</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">isPaused</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;redis&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;default&#39;</span><span style="color: #ABB2BF;">)) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// Maybe skip dispatching some jobs or show a warning in the UI</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>This method returns <code>true</code> if the queue is paused (either indefinitely or until a future time) and <code>false</code> otherwise.</p>
<h3><a id="how-cli-and-code-based-pausing-work-together" href="#how-cli-and-code-based-pausing-work-together" class="" aria-hidden="true" title=""></a>How CLI and code based pausing work together</h3>
<p>The Artisan commands and the <code>Queue</code> facade both use the same underlying queue manager and the same pause state.</p>
<p>That means:</p>
<ul>
<li>You can pause a queue from code with <code>Queue::pause</code> or <code>Queue::pauseFor</code> and then resume it with <code>php artisan queue:continue</code>.</li>
<li>You can pause with <code>php artisan queue:pause</code> and then resume later from code using <code>Queue::resume</code>.</li>
<li><code>Queue::isPaused</code> reflects the state regardless of how the pause was initiated.</li>
</ul>
<p>Because the pause state is shared, you do not need to worry about different mechanisms conflicting with each other.</p>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>You have seen how Laravel lets you pause and resume specific queues without stopping worker processes.
You can control queue pausing from Artisan using <code>queue:pause</code> and <code>queue:continue</code> with a simple <code>connection:queue</code> argument.
You can also pause queues indefinitely or for precise durations in code using the <code>Queue</code> facade, and check the current pause state when needed.
With these tools you can integrate pausing deeply into your workflows, deployments, and rate limiting strategies without touching your worker supervision setup.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Wed, 03 Dec 2025 21:53:15 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Apache configuration essentials for Laravel apps]]></title>
                <link>https://nabilhassen.com/laravel-apache-configuration</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#how-to-configure-apache-for-laravel">How to configure Apache for Laravel</a></li>
<li><a href="#apache-requirements-laravel-expects">Apache requirements Laravel expects</a>
<ul>
<li><a href="#enable-the-rewrite-module">Enable the rewrite module</a></li>
<li><a href="#allow-htaccess-overrides-in-the-project-directory">Allow htaccess overrides in the project directory</a></li>
</ul>
</li>
<li><a href="#default-laravel-htaccess-in-the-public-directory">Default Laravel htaccess in the public directory</a></li>
<li><a href="#apache-virtual-host-for-a-single-laravel-application">Apache virtual host for a single Laravel application</a>
<ul>
<li><a href="#adding-an-https-virtual-host-for-laravel">Adding an https virtual host for Laravel</a></li>
</ul>
</li>
<li><a href="#local-development-virtual-host-for-laravel">Local development virtual host for Laravel</a></li>
<li><a href="#multiple-laravel-applications-on-one-apache-server">Multiple Laravel applications on one Apache server</a></li>
<li><a href="#serving-laravel-from-a-subdirectory">Serving Laravel from a subdirectory</a>
<ul>
<li><a href="#using-an-alias-for-the-subdirectory">Using an alias for the subdirectory</a></li>
<li><a href="#using-htaccess-in-the-main-document-root">Using htaccess in the main document root</a></li>
</ul>
</li>
<li><a href="#apache-configuration-when-you-only-control-htaccess">Apache configuration when you only control htaccess</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="how-to-configure-apache-for-laravel" href="#how-to-configure-apache-for-laravel" class="" aria-hidden="true" title=""></a>How to configure Apache for Laravel</h2>
<p>In this guide you will configure Apache so it serves a Laravel application correctly through the public index.php front controller. You will see how this works for a single domain, multiple projects, subdirectories, and shared hosting environments. Everything happens at the Apache level using virtual host files and htaccess rules, not php artisan serve. By the end you can point a browser at your domain and hit Laravel routes without touching the public path in the url.</p>
<h2><a id="apache-requirements-laravel-expects" href="#apache-requirements-laravel-expects" class="" aria-hidden="true" title=""></a>Apache requirements Laravel expects</h2>
<p>Laravel does not need exotic Apache modules, but it does rely heavily on url rewriting and htaccess support.
Here is the minimal Apache setup you should have before worrying about virtual hosts.</p>
<h3><a id="enable-the-rewrite-module" href="#enable-the-rewrite-module" class="" aria-hidden="true" title=""></a>Enable the rewrite module</h3>
<p>On Debian or Ubuntu based systems you usually enable the rewrite module with:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">sudo </span><span style="color: #98C379;">a2enmod</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">rewrite</span></div><div class='line'><span style="color: #ABB2BF;">sudo </span><span style="color: #98C379;">systemctl</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">reload</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">apache2</span></div></code></pre>
<p>Run these commands in the server terminal as a user with sudo access.
On other distributions make sure the rewrite module is loaded in the main Apache configuration file, for example /etc/httpd/conf/httpd.conf, using a LoadModule directive.
Without rewrite support Laravel routes will not work and every non existing file request will return a raw Apache 404.</p>
<h3><a id="allow-htaccess-overrides-in-the-project-directory" href="#allow-htaccess-overrides-in-the-project-directory" class="" aria-hidden="true" title=""></a>Allow htaccess overrides in the project directory</h3>
<p>Laravel ships with a public/.htaccess file that contains its rewrite rules.
Apache must be allowed to read and use that file.
In a typical Debian or Ubuntu configuration you adjust the main directory block inside /etc/apache2/apache2.conf:</p>
<pre><code data-theme="one-dark-pro" data-lang="apache" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">&lt;Directory </span><span style="color: #98C379;">/var/www/</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">Options</span><span style="color: #ABB2BF;"> Indexes FollowSymLinks</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">AllowOverride</span><span style="color: #ABB2BF;"> All</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">Require</span><span style="color: #ABB2BF;"> all granted</span></div><div class='line'><span style="color: #ABB2BF;">&lt;/Directory&gt;</span></div></code></pre>
<p>The important line here is AllowOverride All which tells Apache to honor htaccess files under that path.
If this is set to None then Laravel rewrite rules will be ignored even if the module is enabled.</p>
<p>If your Laravel project lives somewhere else, for example in /var/www/myapp, you can scope the rule more tightly by adding a dedicated block to apache2.conf or your main Apache config:</p>
<pre><code data-theme="one-dark-pro" data-lang="apache" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">&lt;Directory </span><span style="color: #98C379;">/var/www/myapp/public</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">Options</span><span style="color: #ABB2BF;"> Indexes FollowSymLinks</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">AllowOverride</span><span style="color: #ABB2BF;"> All</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">Require</span><span style="color: #ABB2BF;"> all granted</span></div><div class='line'><span style="color: #ABB2BF;">&lt;/Directory&gt;</span></div></code></pre>
<h2><a id="default-laravel-htaccess-in-the-public-directory" href="#default-laravel-htaccess-in-the-public-directory" class="" aria-hidden="true" title=""></a>Default Laravel htaccess in the public directory</h2>
<p>Laravel expects Apache to point to the public directory as the document root.
Inside that directory it uses htaccess to route requests into index.php.
Create or edit the file public/.htaccess in your Laravel project and put this inside it:</p>
<pre><code data-theme="one-dark-pro" data-lang="apache" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">&lt;IfModule </span><span style="color: #98C379;">mod_rewrite.c</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">RewriteEngine</span><span style="color: #ABB2BF;"> On</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">RewriteCond</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">%{REQUEST_FILENAME}</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">!-d</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">RewriteCond</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">%{REQUEST_FILENAME}</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">!-f</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">RewriteRule</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">^</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">index.php</span><span style="color: #ABB2BF;"> [L]</span></div><div class='line'><span style="color: #ABB2BF;">&lt;/IfModule&gt;</span></div></code></pre>
<p>This does three things:</p>
<ul>
<li>Turns the rewrite engine on for that directory.</li>
<li>If the requested path is not an existing directory and not an existing file, it rewrites the request to index.php.</li>
<li>Lets Apache serve real files and directories directly without touching Laravel.</li>
</ul>
<p>As long as Apache has AllowOverride All for the public directory and the rewrite module is enabled, you normally do not need to change this file.</p>
<h2><a id="apache-virtual-host-for-a-single-laravel-application" href="#apache-virtual-host-for-a-single-laravel-application" class="" aria-hidden="true" title=""></a>Apache virtual host for a single Laravel application</h2>
<p>This is the most common production setup: one domain pointing to one Laravel application.
The key is to make Apache serve the public directory as the document root, never the project root.</p>
<p>Example virtual host on a Debian or Ubuntu Apache install.
Create a new site file such as /etc/apache2/sites-available/example.conf and put this inside it:</p>
<pre><code data-theme="one-dark-pro" data-lang="apache" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">&lt;VirtualHost </span><span style="color: #98C379;">*:80</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">ServerName</span><span style="color: #ABB2BF;"> example.com</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">ServerAlias</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">www.example.com</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">DocumentRoot</span><span style="color: #ABB2BF;"> /var/www/example/current/public</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    &lt;Directory </span><span style="color: #98C379;">/var/www/example/current/public</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">AllowOverride</span><span style="color: #ABB2BF;"> All</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">Require</span><span style="color: #ABB2BF;"> all granted</span></div><div class='line'><span style="color: #ABB2BF;">    &lt;/Directory&gt;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">ErrorLog</span><span style="color: #ABB2BF;"> ${APACHE_LOG_DIR}/example_error.log</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">CustomLog</span><span style="color: #ABB2BF;"> ${APACHE_LOG_DIR}/example_access.log combined</span></div><div class='line'><span style="color: #ABB2BF;">&lt;/VirtualHost&gt;</span></div></code></pre>
<p>Important parts in this configuration:</p>
<ul>
<li>You save this virtual host in a site file such as /etc/apache2/sites-available/example.conf and enable it with sudo a2ensite example.conf.</li>
<li>DocumentRoot points to the Laravel public directory, not to the project root.</li>
<li>The Directory block for that path allows htaccess so the Laravel rewrite rules are active.</li>
<li>ServerName and ServerAlias tell Apache which host headers should hit this application.</li>
</ul>
<p>On Debian or Ubuntu you typically save this file as /etc/apache2/sites-available/example.conf, enable it, then reload:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">sudo </span><span style="color: #98C379;">a2ensite</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">example.conf</span></div><div class='line'><span style="color: #ABB2BF;">sudo </span><span style="color: #98C379;">systemctl</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">reload</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">apache2</span></div></code></pre>
<p>For other distributions the file location and helper commands differ, but the VirtualHost content is the same.</p>
<h3><a id="adding-an-https-virtual-host-for-laravel" href="#adding-an-https-virtual-host-for-laravel" class="" aria-hidden="true" title=""></a>Adding an https virtual host for Laravel</h3>
<p>If you have an ssl certificate for your domain, you pair the http virtual host with an https one.
The only Laravel specific detail is that the document root and directory rules are identical.</p>
<p>Add a second VirtualHost block to the same site definition file, for example /etc/apache2/sites-available/example.conf:</p>
<pre><code data-theme="one-dark-pro" data-lang="apache" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">&lt;VirtualHost </span><span style="color: #98C379;">*:443</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">ServerName</span><span style="color: #ABB2BF;"> example.com</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">ServerAlias</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">www.example.com</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">DocumentRoot</span><span style="color: #ABB2BF;"> /var/www/example/current/public</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    &lt;Directory </span><span style="color: #98C379;">/var/www/example/current/public</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">AllowOverride</span><span style="color: #ABB2BF;"> All</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">Require</span><span style="color: #ABB2BF;"> all granted</span></div><div class='line'><span style="color: #ABB2BF;">    &lt;/Directory&gt;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">SSLEngine</span><span style="color: #ABB2BF;"> on</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">SSLCertificateFile</span><span style="color: #ABB2BF;">    /etc/ssl/certs/example.crt</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">SSLCertificateKeyFile</span><span style="color: #ABB2BF;"> /etc/ssl/private/example.key</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">ErrorLog</span><span style="color: #ABB2BF;"> ${APACHE_LOG_DIR}/example_ssl_error.log</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">CustomLog</span><span style="color: #ABB2BF;"> ${APACHE_LOG_DIR}/example_ssl_access.log combined</span></div><div class='line'><span style="color: #ABB2BF;">&lt;/VirtualHost&gt;</span></div></code></pre>
<p>As long as both virtual hosts share the same document root and directory rules, Laravel does not care whether the request came in over http or https.</p>
<h2><a id="local-development-virtual-host-for-laravel" href="#local-development-virtual-host-for-laravel" class="" aria-hidden="true" title=""></a>Local development virtual host for Laravel</h2>
<p>For local work you may want a clean domain like myapp.test instead of using php artisan serve or appending /public to URLs.
The structure is almost identical to the production virtual host, just with a development oriented path and domain.</p>
<p>Example on a typical Linux workstation:</p>
<p>Create a new virtual host file such as /etc/apache2/sites-available/myapp.test.conf and place this inside it:</p>
<pre><code data-theme="one-dark-pro" data-lang="apache" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">&lt;VirtualHost </span><span style="color: #98C379;">*:80</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">ServerName</span><span style="color: #ABB2BF;"> myapp.test</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">DocumentRoot</span><span style="color: #ABB2BF;"> /home/username/dev/myapp/public</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    &lt;Directory </span><span style="color: #98C379;">/home/username/dev/myapp/public</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">AllowOverride</span><span style="color: #ABB2BF;"> All</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">Require</span><span style="color: #ABB2BF;"> all granted</span></div><div class='line'><span style="color: #ABB2BF;">    &lt;/Directory&gt;</span></div><div class='line'><span style="color: #ABB2BF;">&lt;/VirtualHost&gt;</span></div></code></pre>
<p>Enable the site and reload Apache, for example with sudo a2ensite myapp.test.conf and sudo systemctl reload apache2.</p>
<p>Then add an entry to your local hosts file so the domain resolves locally.
On Linux and macOS edit /etc/hosts, on Windows edit C:\Windows\System32\drivers\etc\hosts, and add:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">127.0.0.1   myapp.test</span></div></code></pre>
<p>After reloading Apache you can browse to <a rel="nofollow noopener" target="_blank" href="http://myapp.test">http://myapp.test</a> and hit your Laravel routes directly.</p>
<h2><a id="multiple-laravel-applications-on-one-apache-server" href="#multiple-laravel-applications-on-one-apache-server" class="" aria-hidden="true" title=""></a>Multiple Laravel applications on one Apache server</h2>
<p>If you host several Laravel projects on the same Apache instance, you usually create one virtual host per domain or subdomain so that each application stays isolated.
The only Laravel specific rule stays the same each time: document root must be the public directory.</p>
<p>Example with two applications on the same server, each defined in its own site file under /etc/apache2/sites-available or inside a single vhosts file, depending on your layout:</p>
<pre><code data-theme="one-dark-pro" data-lang="apache" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">&lt;VirtualHost </span><span style="color: #98C379;">*:80</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">ServerName</span><span style="color: #ABB2BF;"> crm.example.com</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">DocumentRoot</span><span style="color: #ABB2BF;"> /var/www/crm/current/public</span></div><div class='line'><span style="color: #ABB2BF;">    &lt;Directory </span><span style="color: #98C379;">/var/www/crm/current/public</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">AllowOverride</span><span style="color: #ABB2BF;"> All</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">Require</span><span style="color: #ABB2BF;"> all granted</span></div><div class='line'><span style="color: #ABB2BF;">    &lt;/Directory&gt;</span></div><div class='line'><span style="color: #ABB2BF;">&lt;/VirtualHost&gt;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">&lt;VirtualHost </span><span style="color: #98C379;">*:80</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">ServerName</span><span style="color: #ABB2BF;"> shop.example.com</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">DocumentRoot</span><span style="color: #ABB2BF;"> /var/www/shop/current/public</span></div><div class='line'><span style="color: #ABB2BF;">    &lt;Directory </span><span style="color: #98C379;">/var/www/shop/current/public</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">AllowOverride</span><span style="color: #ABB2BF;"> All</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">Require</span><span style="color: #ABB2BF;"> all granted</span></div><div class='line'><span style="color: #ABB2BF;">    &lt;/Directory&gt;</span></div><div class='line'><span style="color: #ABB2BF;">&lt;/VirtualHost&gt;</span></div></code></pre>
<p>Each Laravel application is isolated, has its own logs, and can be deployed independently while Apache keeps the rules simple.</p>
<h2><a id="serving-laravel-from-a-subdirectory" href="#serving-laravel-from-a-subdirectory" class="" aria-hidden="true" title=""></a>Serving Laravel from a subdirectory</h2>
<p>Sometimes you cannot dedicate a full domain or subdomain to Laravel.
Instead you might need to serve it under a path like example.com/app.
Laravel is fine with this as long as Apache routes that path into the public directory.</p>
<h3><a id="using-an-alias-for-the-subdirectory" href="#using-an-alias-for-the-subdirectory" class="" aria-hidden="true" title=""></a>Using an alias for the subdirectory</h3>
<p>A clean approach is to keep the main site document root as is and use an alias for the Laravel path.
Edit the existing VirtualHost definition for example.com, usually in /etc/apache2/sites-available/example.conf or the equivalent file, and adjust it like this:</p>
<pre><code data-theme="one-dark-pro" data-lang="apache" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">&lt;VirtualHost </span><span style="color: #98C379;">*:80</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">ServerName</span><span style="color: #ABB2BF;"> example.com</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">DocumentRoot</span><span style="color: #ABB2BF;"> /var/www/html</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">Alias</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">/app</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">/var/www/app/current/public</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    &lt;Directory </span><span style="color: #98C379;">/var/www/app/current/public</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">AllowOverride</span><span style="color: #ABB2BF;"> All</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">Require</span><span style="color: #ABB2BF;"> all granted</span></div><div class='line'><span style="color: #ABB2BF;">    &lt;/Directory&gt;</span></div><div class='line'><span style="color: #ABB2BF;">&lt;/VirtualHost&gt;</span></div></code></pre>
<p>Here is what happens:</p>
<ul>
<li>Requests to example.com still hit the main document root /var/www/html.</li>
<li>Requests whose path starts with slash app are internally mapped to the Laravel public directory.</li>
<li>The directory block again allows htaccess so the framework rewrite rules run correctly.</li>
</ul>
<p>Laravel will see the application at the /app path, so route URLs will automatically include that prefix when you use URL helpers.</p>
<h3><a id="using-htaccess-in-the-main-document-root" href="#using-htaccess-in-the-main-document-root" class="" aria-hidden="true" title=""></a>Using htaccess in the main document root</h3>
<p>If you do not want or cannot edit the main virtual host, you can place rewrite rules in the document root htaccess file that forward a specific path to Laravel.
This is common when a control panel manages Apache and only exposes htaccess.</p>
<p>Example htaccess placed in the main document root that sends /app requests into Laravel.
Create or edit the .htaccess file in your main document root, for example /var/www/html/.htaccess or public_html/.htaccess, and add:</p>
<pre><code data-theme="one-dark-pro" data-lang="apache" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">RewriteEngine</span><span style="color: #ABB2BF;"> On</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">RewriteCond</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">%{REQUEST_URI}</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">^/app</span></div><div class='line'><span style="color: #C678DD;">RewriteRule</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">^app/(.*)$</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">/app/public/$1</span><span style="color: #ABB2BF;"> [L]</span></div></code></pre>
<p>Combined with the default Laravel htaccess inside the public directory, this lets users access the application at example.com slash app without ever seeing the public segment.</p>
<h2><a id="apache-configuration-when-you-only-control-htaccess" href="#apache-configuration-when-you-only-control-htaccess" class="" aria-hidden="true" title=""></a>Apache configuration when you only control htaccess</h2>
<p>On many shared hosting environments you do not have direct access to Apache virtual host files.
Instead you upload files into a document root such as public_html and control behavior with htaccess.
You can still run Laravel this way while keeping public as the web entry point.</p>
<p>Assume the host gives you a document root at /home/user/public_html and you have installed Laravel directly inside that directory.
You will end up with a public_html/public directory that contains index.php and assets.
The goal is to hide the public segment from visitors.</p>
<p>Create or edit /home/user/public_html/.htaccess with rules that pass everything into the Laravel public directory:</p>
<pre><code data-theme="one-dark-pro" data-lang="apache" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">RewriteEngine</span><span style="color: #ABB2BF;"> On</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">RewriteCond</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">%{REQUEST_URI}</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">!^/public</span></div><div class='line'><span style="color: #C678DD;">RewriteRule</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">^(.*)$</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">public/$1</span><span style="color: #ABB2BF;"> [L]</span></div></code></pre>
<p>Then ensure the Laravel public directory keeps its own .htaccess file, using the minimal rules shown earlier.
The flow looks like this:</p>
<ul>
<li>The root htaccess rewrites all requests to the public directory.</li>
<li>Once the request lands in public, Laravel rewrite rules send non file and non directory requests to index.php.</li>
<li>You do not touch or move the framework core files out of their default locations.</li>
</ul>
<p>If Laravel is installed in a subdirectory of the hosting document root, adjust the target path inside the rule accordingly.</p>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>Apache only needs a small amount of configuration to serve a Laravel application correctly. The central idea in every setup is that the document root or rewrite target must always be the Laravel public directory. You can reach that goal with direct virtual host files, alias rules, or htaccess only setups on shared hosting. Once Apache is pointing at public and rewrite support is active, Laravel takes over routing and your application behaves the same in every environment.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Mon, 01 Dec 2025 19:45:36 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Get request headers in PHP]]></title>
                <link>https://nabilhassen.com/php-get-request-headers</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#how-to-get-http-request-headers-in-php">How to Get HTTP Request Headers in PHP</a></li>
<li><a href="#using-getallheaders-and-apacherequestheaders">Using getallheaders and apache_request_headers</a>
<ul>
<li><a href="#basic-usage-of-getallheaders">Basic usage of getallheaders</a></li>
<li><a href="#fallback-polyfill-for-getallheaders">Fallback polyfill for getallheaders</a></li>
<li><a href="#accessing-a-single-header-via-getallheaders">Accessing a single header via getallheaders</a></li>
</ul>
</li>
<li><a href="#reading-request-headers-from-server">Reading request headers from $_SERVER</a>
<ul>
<li><a href="#reading-specific-headers-from-server">Reading specific headers from $_SERVER</a></li>
<li><a href="#building-a-full-header-list-from-server">Building a full header list from $_SERVER</a></li>
</ul>
</li>
<li><a href="#quick-note-about-environment-and-cli">Quick note about environment and CLI</a></li>
</ul>
<h2><a id="how-to-get-http-request-headers-in-php" href="#how-to-get-http-request-headers-in-php" class="" aria-hidden="true" title=""></a>How to Get HTTP Request Headers in PHP</h2>
<p>You want to read HTTP request headers from PHP code running behind a web server. This guide walks through the practical ways to do that: directly via <code>$_SERVER</code>, using <code>getallheaders</code> or <code>apache_request_headers</code>, and via PSR-7 request objects that many modern frameworks use.</p>
<h2><a id="using-getallheaders-and-apacherequestheaders" href="#using-getallheaders-and-apacherequestheaders" class="" aria-hidden="true" title=""></a>Using getallheaders and apache_request_headers</h2>
<p>PHP also provides functions that return all request headers directly as an associative array.</p>
<ul>
<li><code>getallheaders()</code></li>
<li><code>apache_request_headers()</code></li>
</ul>
<p><code>getallheaders</code> is an alias of <code>apache_request_headers</code> and both fetch all HTTP request headers from the current request.</p>
<h3><a id="basic-usage-of-getallheaders" href="#basic-usage-of-getallheaders" class="" aria-hidden="true" title=""></a>Basic usage of getallheaders</h3>
<p>If <code>getallheaders</code> is available in your environment, this is usually the easiest way to see everything the client sent:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$headers</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">getallheaders</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">foreach</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$headers</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">as</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$name</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$name</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;: &#39;</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">PHP_EOL</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>What this does:</p>
<ul>
<li>Calls <code>getallheaders()</code> to retrieve an associative array of all headers.</li>
<li>Iterates and prints each header.</li>
<li>Header names come back in a normalized form (for example <code>Accept-Language</code>, <code>User-Agent</code>, <code>Content-Type</code>).</li>
</ul>
<p>When this is appropriate:</p>
<ul>
<li>You are running under Apache, FastCGI, or FPM where these functions are available.</li>
<li>You do not want to deal with the <code>$_SERVER</code> naming convention manually.</li>
<li>You want a full dump of headers for debugging or logging.</li>
</ul>
<p>In some environments (for example plain CLI, or PHP built without the Apache related extension) these functions may not exist, and calling them would trigger a fatal error.</p>
<h3><a id="fallback-polyfill-for-getallheaders" href="#fallback-polyfill-for-getallheaders" class="" aria-hidden="true" title=""></a>Fallback polyfill for getallheaders</h3>
<p>On servers where <code>getallheaders</code> is missing (for example some nginx setups), a common pattern is to provide a compatible function that rebuilds the headers from <code>$_SERVER</code>.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">!function_exists</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;getallheaders&#39;</span><span style="color: #ABB2BF;">)) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">getallheaders</span><span style="color: #ABB2BF;">(): </span><span style="color: #E5C07B;">array</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$headers</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [];</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">foreach</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$_SERVER</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">as</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$name</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #61AFEF;">str_starts_with</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$name</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;HTTP_&#39;</span><span style="color: #ABB2BF;">)) {</span></div><div class='line'><span style="color: #ABB2BF;">                </span><span style="color: #E06C75;">$headerName</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">substr</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$name</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">5</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">                </span><span style="color: #E06C75;">$headerName</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">str_replace</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;_&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39; &#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$headerName</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">                </span><span style="color: #E06C75;">$headerName</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">ucwords</span><span style="color: #ABB2BF;">(</span><span style="color: #56B6C2;">strtolower</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$headerName</span><span style="color: #ABB2BF;">));</span></div><div class='line'><span style="color: #ABB2BF;">                </span><span style="color: #E06C75;">$headerName</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">str_replace</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39; &#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;-&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$headerName</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">                </span><span style="color: #E06C75;">$headers</span><span style="color: #ABB2BF;">[</span><span style="color: #E06C75;">$headerName</span><span style="color: #ABB2BF;">] </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">            }</span></div><div class='line'><span style="color: #ABB2BF;">        }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">isset</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$_SERVER</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;CONTENT_TYPE&#39;</span><span style="color: #ABB2BF;">])) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E06C75;">$headers</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;Content-Type&#39;</span><span style="color: #ABB2BF;">] </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$_SERVER</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;CONTENT_TYPE&#39;</span><span style="color: #ABB2BF;">];</span></div><div class='line'><span style="color: #ABB2BF;">        }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">isset</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$_SERVER</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;CONTENT_LENGTH&#39;</span><span style="color: #ABB2BF;">])) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E06C75;">$headers</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;Content-Length&#39;</span><span style="color: #ABB2BF;">] </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$_SERVER</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;CONTENT_LENGTH&#39;</span><span style="color: #ABB2BF;">];</span></div><div class='line'><span style="color: #ABB2BF;">        }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$headers</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">foreach</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">getallheaders</span><span style="color: #ABB2BF;">() </span><span style="color: #56B6C2;">as</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$name</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$name</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;: &#39;</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">PHP_EOL</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Why this is useful:</p>
<ul>
<li>Your application can call <code>getallheaders()</code> unconditionally.</li>
<li>On hosts that provide the native function, you get the built-in implementation.</li>
<li>On hosts that do not, you still get a compatible behavior based on <code>$_SERVER</code>.</li>
</ul>
<p>Note on <code>Authorization</code>:</p>
<ul>
<li><code>getallheaders</code> often includes the <code>Authorization</code> header where <code>$_SERVER</code> alone does not.</li>
<li>If you care about auth headers, test this behavior on your specific server and PHP setup.</li>
</ul>
<h3><a id="accessing-a-single-header-via-getallheaders" href="#accessing-a-single-header-via-getallheaders" class="" aria-hidden="true" title=""></a>Accessing a single header via getallheaders</h3>
<p>Request header names are case insensitive, but the array keys returned by <code>getallheaders</code> have a specific casing (for example <code>User-Agent</code>). To avoid guessing, you can normalize them before lookup.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'><span style="color: #E06C75;">$headers</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">getallheaders</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Normalize keys to lowercase for case insensitive lookup</span></div><div class='line'><span style="color: #E06C75;">$headersLower</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">array_change_key_case</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$headers</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">CASE_LOWER</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$userAgent</span><span style="color: #ABB2BF;">    </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$headersLower</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;user-agent&#39;</span><span style="color: #ABB2BF;">]    ?? </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #E06C75;">$authHeader</span><span style="color: #ABB2BF;">   </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$headersLower</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;authorization&#39;</span><span style="color: #ABB2BF;">] ?? </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;User-Agent: &#39;</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$userAgent</span><span style="color: #ABB2BF;"> ?? </span><span style="color: #98C379;">&#39;[none]&#39;</span><span style="color: #ABB2BF;">) </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">PHP_EOL</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;Authorization: &#39;</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$authHeader</span><span style="color: #ABB2BF;"> ?? </span><span style="color: #98C379;">&#39;[none]&#39;</span><span style="color: #ABB2BF;">) </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">PHP_EOL</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<p>What matters here:</p>
<ul>
<li><code>array_change_key_case</code> creates a new array with lowercase keys.</li>
<li>You can then look up any header using a consistent key, like <code>'authorization'</code>.</li>
<li>This pattern avoids subtle bugs when a server or extension uses slightly different header name capitalization.</li>
</ul>
<h2><a id="reading-request-headers-from-server" href="#reading-request-headers-from-server" class="" aria-hidden="true" title=""></a>Reading request headers from $_SERVER</h2>
<p>PHP exposes incoming request headers through the <code>$_SERVER</code> superglobal. For most headers, PHP creates keys that:</p>
<ul>
<li>Start with <code>HTTP_</code></li>
<li>Use uppercase letters</li>
<li>Replace hyphens with underscores</li>
</ul>
<p>For example, the header:</p>
<pre><code data-theme="one-dark-pro" data-lang="http" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">Accept-Language: en-US,en;q=0.9</span></div></code></pre>
<p>is usually available as:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$_SERVER</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;HTTP_ACCEPT_LANGUAGE&#39;</span><span style="color: #ABB2BF;">];</span></div></code></pre>
<p>This behavior is documented in the PHP manual, which explains that request headers are mapped to <code>$_SERVER</code> entries following this naming pattern.</p>
<h3><a id="reading-specific-headers-from-server" href="#reading-specific-headers-from-server" class="" aria-hidden="true" title=""></a>Reading specific headers from $_SERVER</h3>
<p>Minimal example that reads a few common headers and a custom one:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// Common request headers</span></div><div class='line'><span style="color: #E06C75;">$acceptLanguage</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$_SERVER</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;HTTP_ACCEPT_LANGUAGE&#39;</span><span style="color: #ABB2BF;">] ?? </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #E06C75;">$userAgent</span><span style="color: #ABB2BF;">      </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$_SERVER</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;HTTP_USER_AGENT&#39;</span><span style="color: #ABB2BF;">] ?? </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Custom header: X-Requested-With</span></div><div class='line'><span style="color: #E06C75;">$requestedWith</span><span style="color: #ABB2BF;">  </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$_SERVER</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;HTTP_X_REQUESTED_WITH&#39;</span><span style="color: #ABB2BF;">] ?? </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;Accept-Language: &quot;</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$acceptLanguage</span><span style="color: #ABB2BF;"> ?? </span><span style="color: #98C379;">&#39;[none]&#39;</span><span style="color: #ABB2BF;">) </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">PHP_EOL</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;User-Agent: &quot;</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$userAgent</span><span style="color: #ABB2BF;"> ?? </span><span style="color: #98C379;">&#39;[none]&#39;</span><span style="color: #ABB2BF;">) </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">PHP_EOL</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;X-Requested-With: &quot;</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$requestedWith</span><span style="color: #ABB2BF;"> ?? </span><span style="color: #98C379;">&#39;[none]&#39;</span><span style="color: #ABB2BF;">) </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">PHP_EOL</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<p>What this does:</p>
<ul>
<li>Reads values from <code>$_SERVER</code> using the <code>HTTP_</code> prefix and uppercase names with underscores.</li>
<li>Uses the null coalescing operator <code>??</code> so the script does not throw notices if a header is missing.</li>
<li>Prints each header as plain text.</li>
</ul>
<p>Directly using <code>$_SERVER</code> is simple and works in any SAPI where PHP exposed the header as an environment variable. However, you have to know the exact key name or build it yourself.</p>
<h3><a id="building-a-full-header-list-from-server" href="#building-a-full-header-list-from-server" class="" aria-hidden="true" title=""></a>Building a full header list from $_SERVER</h3>
<p>If you want all headers but cannot rely on <code>getallheaders</code>, you can reconstruct them by scanning <code>$_SERVER</code> for keys that start with <code>HTTP_</code>.</p>
<p>Here is a small helper that:</p>
<ul>
<li>Turns <code>HTTP_ACCEPT_LANGUAGE</code> into <code>Accept-Language</code></li>
<li>Collects all such headers into an associative array</li>
<li>Adds <code>Content-Type</code> and <code>Content-Length</code>, which may be exposed without the <code>HTTP_</code> prefix</li>
</ul>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">headers_from_server</span><span style="color: #ABB2BF;">(): </span><span style="color: #E5C07B;">array</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$headers</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [];</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">foreach</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$_SERVER</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">as</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$name</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #61AFEF;">str_starts_with</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$name</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;HTTP_&#39;</span><span style="color: #ABB2BF;">)) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E06C75;">$headerName</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">substr</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$name</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">5</span><span style="color: #ABB2BF;">); </span><span style="color: #7F848E;">// remove &quot;HTTP_&quot;</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E06C75;">$headerName</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">str_replace</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;_&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39; &#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$headerName</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E06C75;">$headerName</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">ucwords</span><span style="color: #ABB2BF;">(</span><span style="color: #56B6C2;">strtolower</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$headerName</span><span style="color: #ABB2BF;">));</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E06C75;">$headerName</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">str_replace</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39; &#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;-&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$headerName</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E06C75;">$headers</span><span style="color: #ABB2BF;">[</span><span style="color: #E06C75;">$headerName</span><span style="color: #ABB2BF;">] </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">        }</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// Some headers are not prefixed with HTTP_</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">isset</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$_SERVER</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;CONTENT_TYPE&#39;</span><span style="color: #ABB2BF;">])) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$headers</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;Content-Type&#39;</span><span style="color: #ABB2BF;">] </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$_SERVER</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;CONTENT_TYPE&#39;</span><span style="color: #ABB2BF;">];</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">isset</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$_SERVER</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;CONTENT_LENGTH&#39;</span><span style="color: #ABB2BF;">])) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$headers</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;Content-Length&#39;</span><span style="color: #ABB2BF;">] </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$_SERVER</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;CONTENT_LENGTH&#39;</span><span style="color: #ABB2BF;">];</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$headers</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$headers</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">headers_from_server</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">foreach</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$headers</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">as</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$name</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$name</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;: &#39;</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">PHP_EOL</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Points to notice:</p>
<ul>
<li><code>str_starts_with</code> requires PHP 8.</li>
<li>The transformation normalizes header names into the common <code>Title-Case-Format</code>.</li>
<li>This gives you a consistent array of headers even in environments where <code>getallheaders</code> is not defined.</li>
</ul>
<p>Keep in mind that some server setups may still hide specific headers (for example <code>Authorization</code>) unless configured to forward them into the CGI environment.</p>
<h2><a id="quick-note-about-environment-and-cli" href="#quick-note-about-environment-and-cli" class="" aria-hidden="true" title=""></a>Quick note about environment and CLI</h2>
<p>Request headers only exist for real HTTP requests. If you run your script from the command line:</p>
<ul>
<li><code>$_SERVER</code> will not contain meaningful HTTP header entries for a normal CLI invocation.</li>
<li><code>getallheaders</code> or <code>apache_request_headers</code> may not even be defined or may not return anything useful if there is no actual HTTP request in progress.</li>
</ul>
<p>So any code that relies on headers should either:</p>
<ul>
<li>Be executed only in an HTTP context, or</li>
<li>Be defensive and handle the case where headers are missing or functions are not available.</li>
</ul>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Thu, 27 Nov 2025 17:14:15 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Get domain name in PHP]]></title>
                <link>https://nabilhassen.com/php-get-domain-name</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#extract-domain-in-php-from-url-email-or-current-page">Extract domain in PHP: From URL, Email or Current Page</a></li>
<li><a href="#getting-the-current-pages-domain">Getting the current page’s domain</a></li>
<li><a href="#extracting-domain-from-a-url-string">Extracting domain from a URL string</a></li>
<li><a href="#get-domain-without-subdomain">Get domain without subdomain</a></li>
<li><a href="#extracting-domain-from-an-email-address">Extracting domain from an email address</a></li>
<li><a href="#caveats-edge-cases-and-best-practices">Caveats, edge cases, and best practices</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="extract-domain-in-php-from-url-email-or-current-page" href="#extract-domain-in-php-from-url-email-or-current-page" class="" aria-hidden="true" title=""></a>Extract domain in PHP: From URL, Email or Current Page</h2>
<p>In backend PHP development, extracting domain names is often required for tasks such as building canonical URLs, parsing user-supplied links or emails, routing, logging, or validation. In this article, we cover how to obtain domain names in PHP in several real-world contexts: from the current request, from a URL string, or from an email address. We also cover how to handle scheme (http/https) and optionally remove subdomains to get the “base” or registrable domain.</p>
<h2><a id="getting-the-current-pages-domain" href="#getting-the-current-pages-domain" class="" aria-hidden="true" title=""></a>Getting the current page’s domain</h2>
<p>To retrieve the domain used in the current request, the site address where your PHP code is running, you can rely on PHP’s <code>$_SERVER</code> superglobal variables:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$scheme</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">!empty</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$_SERVER</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;HTTPS&#39;</span><span style="color: #ABB2BF;">]) </span><span style="color: #56B6C2;">&amp;&amp;</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$_SERVER</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;HTTPS&#39;</span><span style="color: #ABB2BF;">] </span><span style="color: #56B6C2;">!==</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;off&#39;</span><span style="color: #ABB2BF;">) </span><span style="color: #C678DD;">?</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;https&#39;</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">:</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;http&#39;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #E06C75;">$host</span><span style="color: #ABB2BF;">   </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$_SERVER</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;HTTP_HOST&#39;</span><span style="color: #ABB2BF;">] ?? </span><span style="color: #E06C75;">$_SERVER</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;SERVER_NAME&#39;</span><span style="color: #ABB2BF;">];</span></div><div class='line'><span style="color: #E06C75;">$domain</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$scheme</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;://&#39;</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$host</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$domain</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<p>Explanation:</p>
<ul>
<li><code>$_SERVER['HTTP_HOST']</code> gives the host header sent by the client (could include port).</li>
<li>As a fallback, <code>$_SERVER['SERVER_NAME']</code> can be used if <code>HTTP_HOST</code> is not set.</li>
<li>We detect the scheme (HTTPS or HTTP) to build a full URL including protocol.</li>
</ul>
<p>This approach yields the exact domain (and optionally port) the user used to request the page. It’s commonly used for generating canonical URLs or redirects.</p>
<p><strong>Security note</strong>: Because <code>HTTP_HOST</code> is derived from a client-supplied header, it can be spoofed. For security-sensitive tasks (authentication, token generation, access control), avoid trusting <code>HTTP_HOST</code>. Use a fixed configuration value or server-controlled name instead.</p>
<h2><a id="extracting-domain-from-a-url-string" href="#extracting-domain-from-a-url-string" class="" aria-hidden="true" title=""></a>Extracting domain from a URL string</h2>
<p>When you have a URL (from user input, configuration, referral data, etc.) and you want to extract its domain, PHP’s built-in <code>parse_url()</code> is the standard tool:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;https://www.example.com/path/page.php?foo=bar&#39;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #E06C75;">$host</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">parse_url</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">PHP_URL_HOST</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$host</span><span style="color: #ABB2BF;">; </span><span style="color: #7F848E;">// e.g. &quot;www.example.com&quot;</span></div></code></pre>
<p><code>parse_url()</code> parses a URL into components (scheme, host, path, query, fragment, etc.). Using the <code>PHP_URL_HOST</code> option returns the host (domain) component as a string.</p>
<p>This works reliably when the input is a full, valid URL.</p>
<p><strong>Limitations and caveats</strong>:</p>
<ul>
<li>If the URL lacks a scheme (e.g. <code>&quot;example.com/path&quot;</code>), <code>parse_url()</code> may misinterpret the string as a relative path and fail to extract a host.</li>
<li>If the URL is malformed or not properly encoded, parsing may produce unexpected results or return <code>null</code>.</li>
</ul>
<p>Hence, when dealing with user-supplied or external input, it is wise to first validate or normalize the URL (for example by ensuring it has a scheme) before calling <code>parse_url()</code>.</p>
<h2><a id="get-domain-without-subdomain" href="#get-domain-without-subdomain" class="" aria-hidden="true" title=""></a>Get domain without subdomain</h2>
<p>By default, <code>parse_url()</code> returns the full host including any subdomains. For example, from <code>https://sub.www.example.co.uk</code>, you’ll get <code>sub.www.example.co.uk</code>. Often you want only the “base” or “registrable” domain (e.g. <code>example.co.uk</code>).</p>
<p>A naive way to strip subdomains might look like this:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$host</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">parse_url</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">PHP_URL_HOST</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$host</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">preg_replace</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">&#39;/</span><span style="color: #C678DD;">^</span><span style="color: #E06C75;">www</span><span style="color: #56B6C2;">\.</span><span style="color: #E06C75;">/i&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$host</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>This handles the common case of a “<a rel="nofollow noopener" target="_blank" href="http://www.%E2%80%9D">www.”</a> prefix. However, this approach fails when:</p>
<ul>
<li>The subdomain is not “www” (e.g. <code>api.example.com</code>, <code>blog.example.co.uk</code>).</li>
<li>The domain has a multi-part TLD (e.g. <code>.co.uk</code>, <code>.org.au</code>), where simply taking the last two labels may be incorrect.</li>
<li>There are deeper subdomains (e.g. <code>a.b.c.example.com</code>).</li>
</ul>
<p>Because of these issues, reliably extracting the base domain from arbitrary hosts is nontrivial. A fully correct solution needs awareness of the public suffix list (all valid TLDs and multi-part TLDs). Without that, any regex or heuristic-based method will be brittle.</p>
<p>If precise domain extraction is critical in your application, use a well-maintained, public-suffix aware library. If not, the heuristic approach may suffice but be aware of its limitations.</p>
<h2><a id="extracting-domain-from-an-email-address" href="#extracting-domain-from-an-email-address" class="" aria-hidden="true" title=""></a>Extracting domain from an email address</h2>
<p>Email addresses have a simple structure: <code>local-part@domain</code>. To get the domain part in PHP:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$email</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;user@example.com&#39;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">filter_var</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$email</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">FILTER_VALIDATE_EMAIL</span><span style="color: #ABB2BF;">)) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$domain</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">explode</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;@&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$email</span><span style="color: #ABB2BF;">)[</span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">];</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$domain</span><span style="color: #ABB2BF;">; </span><span style="color: #7F848E;">// &quot;example.com&quot;</span></div><div class='line'><span style="color: #ABB2BF;">} </span><span style="color: #C678DD;">else</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// invalid email</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Alternatively:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$domain</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">substr</span><span style="color: #ABB2BF;">(</span><span style="color: #56B6C2;">strstr</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$email</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;@&#39;</span><span style="color: #ABB2BF;">),</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>Important points:</p>
<ul>
<li>Validate the email format first using <code>filter_var(..., FILTER_VALIDATE_EMAIL)</code> before extraction.</li>
<li>This method returns exactly what is after the <code>@</code>. If the email is nonstandard (contains multiple <code>@</code>, or extra data), further validation or sanitization may be required.</li>
</ul>
<p>This method is straightforward and works well when you trust or validate email input.</p>
<h2><a id="caveats-edge-cases-and-best-practices" href="#caveats-edge-cases-and-best-practices" class="" aria-hidden="true" title=""></a>Caveats, edge cases, and best practices</h2>
<ul>
<li>Subdomain stripping is error-prone. Regex or naive splitting on “.” may fail for multi-level TLDs or complex hosts. Use a public-suffix aware approach when accuracy matters.</li>
<li>Server-provided host data (especially <code>HTTP_HOST</code>) comes from client headers, avoid trusting it for security-critical code.</li>
<li>Always validate and sanitize external input (URLs and emails) before parsing. For instance, ensure a URL has a scheme and is well-formed before using <code>parse_url()</code>.</li>
<li>Be aware of internationalized domain names (IDN). Plain string or regex operations may not handle non-ASCII domain names; IDN/Punycode handling may be needed depending on use case.</li>
</ul>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>PHP provides effective, built-in tools to extract domain names in typical web use cases:</p>
<ul>
<li>Use <code>$_SERVER['HTTP_HOST']</code> (with scheme detection) for the current request domain.</li>
<li>Use <code>parse_url()</code> to parse a URL string and extract the host.</li>
<li>Use simple string manipulation or <code>explode('@')</code> to extract domain from an email address.</li>
<li>For extracting a registrable domain (without subdomains), rely on a public-suffix aware library rather than naive string hacks.</li>
</ul>
<p>While simple cases are easy, edge cases (subdomains, multi-level TLDs, malformed input) require careful handling. For robust, production-ready code, validate inputs and prefer library-based parsing when domain correctness matters.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Wed, 26 Nov 2025 20:53:16 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[PHP: Calculate date differences in days, hours, and more]]></title>
                <link>https://nabilhassen.com/php-date-difference</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#date-differences-calculations-in-php">Date Differences Calculations in PHP</a></li>
<li><a href="#using-datetime-and-diff">Using DateTime and diff</a></li>
<li><a href="#difference-in-days">Difference in Days</a></li>
<li><a href="#difference-in-hours">Difference in Hours</a></li>
<li><a href="#difference-in-months">Difference in Months</a></li>
<li><a href="#difference-in-seconds">Difference in Seconds</a></li>
<li><a href="#difference-in-years">Difference in Years</a></li>
<li><a href="#difference-from-now">Difference From Now</a></li>
<li><a href="#difference-in-minutes">Difference in Minutes</a></li>
<li><a href="#difference-in-hours-and-minutes">Difference in Hours and Minutes</a></li>
<li><a href="#summary-of-recommended-approaches">Summary of Recommended Approaches</a></li>
</ul>
<h2><a id="date-differences-calculations-in-php" href="#date-differences-calculations-in-php" class="" aria-hidden="true" title=""></a>Date Differences Calculations in PHP</h2>
<p>Date calculations are essential for tasks such as scheduling, expiration checks, analytics, and time based validation. PHP provides accurate and reliable tools for these operations through DateTime, DateInterval, and timestamps. In this blog post, I'll demonstrate how to calculate date differences in every common unit with concise examples.</p>
<h2><a id="using-datetime-and-diff" href="#using-datetime-and-diff" class="" aria-hidden="true" title=""></a>Using DateTime and diff</h2>
<p>DateTime represents a point in time. The diff method compares two DateTime objects and returns a DateInterval.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$date1</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DateTime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;2024-01-01&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$date2</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DateTime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;2024-02-10&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$interval</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$date1</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">diff</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$date2</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>A DateInterval exposes properties such as y, m, d, h, i, s. It handles leap years, month boundaries, and daylight changes automatically.</p>
<h2><a id="difference-in-days" href="#difference-in-days" class="" aria-hidden="true" title=""></a>Difference in Days</h2>
<p>Using diff:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$date1</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DateTime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;2024-01-01&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$date2</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DateTime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;2024-01-20&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$days</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$date1</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">diff</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$date2</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #E06C75;">days</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$days</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<p>The days property returns the total difference in days.</p>
<p>Using timestamps:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$seconds</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">abs</span><span style="color: #ABB2BF;">(</span><span style="color: #56B6C2;">strtotime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;2024-01-01&#39;</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">-</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">strtotime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;2024-01-20&#39;</span><span style="color: #ABB2BF;">));</span></div><div class='line'><span style="color: #E06C75;">$days</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">intdiv</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$seconds</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">86400</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$days</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<p>Use timestamps when you only need complete day counts without calendar rules.</p>
<h2><a id="difference-in-hours" href="#difference-in-hours" class="" aria-hidden="true" title=""></a>Difference in Hours</h2>
<p>Using DateInterval:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$date1</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DateTime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;2024-01-01 00:00&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$date2</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DateTime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;2024-01-02 05:00&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$diff</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$date1</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">diff</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$date2</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$hours</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$diff</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">days</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">*</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">24</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">+</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$diff</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">h</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$hours</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<p>Using timestamps:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$seconds</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">abs</span><span style="color: #ABB2BF;">(</span><span style="color: #56B6C2;">strtotime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;2024-01-01 00:00&#39;</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">-</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">strtotime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;2024-01-02 05:00&#39;</span><span style="color: #ABB2BF;">));</span></div><div class='line'><span style="color: #E06C75;">$hours</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">intdiv</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$seconds</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">3600</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$hours</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<h2><a id="difference-in-months" href="#difference-in-months" class="" aria-hidden="true" title=""></a>Difference in Months</h2>
<p>The DateInterval exposes years and months. Total months is years multiplied by 12 plus months.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$date1</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DateTime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;2023-01-01&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$date2</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DateTime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;2024-04-01&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$diff</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$date1</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">diff</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$date2</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$months</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$diff</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">y</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">*</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">12</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">+</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$diff</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">m</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$months</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<p>DateInterval correctly accounts for varying month lengths.</p>
<h2><a id="difference-in-seconds" href="#difference-in-seconds" class="" aria-hidden="true" title=""></a>Difference in Seconds</h2>
<p>Using timestamps is the simplest method.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$seconds</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">abs</span><span style="color: #ABB2BF;">(</span><span style="color: #56B6C2;">strtotime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;2024-01-01 12:00&#39;</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">-</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">strtotime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;2024-01-01 12:10&#39;</span><span style="color: #ABB2BF;">));</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$seconds</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<p>Use timestamps when you need exact second-level differences.</p>
<h2><a id="difference-in-years" href="#difference-in-years" class="" aria-hidden="true" title=""></a>Difference in Years</h2>
<p>DateInterval automatically handles leap years.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$date1</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DateTime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;2020-02-29&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$date2</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DateTime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;2024-02-28&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$years</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$date1</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">diff</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$date2</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #E06C75;">y</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$years</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<h2><a id="difference-from-now" href="#difference-from-now" class="" aria-hidden="true" title=""></a>Difference From Now</h2>
<p>Comparing any date to the current moment:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$target</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DateTime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;2024-12-25&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$now</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DateTime</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #E06C75;">$daysFromNow</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$now</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">diff</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$target</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #E06C75;">days</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$daysFromNow</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<p>This produces the total number of days from today to the target date.</p>
<h2><a id="difference-in-minutes" href="#difference-in-minutes" class="" aria-hidden="true" title=""></a>Difference in Minutes</h2>
<p>Using timestamps:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$seconds</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">abs</span><span style="color: #ABB2BF;">(</span><span style="color: #56B6C2;">strtotime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;2024-01-01 12:00&#39;</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">-</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">strtotime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;2024-01-01 12:45&#39;</span><span style="color: #ABB2BF;">));</span></div><div class='line'><span style="color: #E06C75;">$minutes</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">intdiv</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$seconds</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">60</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$minutes</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<p>Converting from DateInterval:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$diff</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> (</span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DateTime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;12:00&#39;</span><span style="color: #ABB2BF;">))-&gt;</span><span style="color: #61AFEF;">diff</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DateTime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;12:45&#39;</span><span style="color: #ABB2BF;">));</span></div><div class='line'><span style="color: #E06C75;">$minutes</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$diff</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">h</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">*</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">60</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">+</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$diff</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">i</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$minutes</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<h2><a id="difference-in-hours-and-minutes" href="#difference-in-hours-and-minutes" class="" aria-hidden="true" title=""></a>Difference in Hours and Minutes</h2>
<p>DateInterval can format the result directly.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$date1</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DateTime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;2024-01-01 08:00&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$date2</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DateTime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;2024-01-01 12:45&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$date1</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">diff</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$date2</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">format</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;%h hours %i minutes&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>Or compute total minutes and split:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$seconds</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">abs</span><span style="color: #ABB2BF;">(</span><span style="color: #56B6C2;">strtotime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;08:00&#39;</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">-</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">strtotime</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;12:45&#39;</span><span style="color: #ABB2BF;">));</span></div><div class='line'><span style="color: #E06C75;">$totalMinutes</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">intdiv</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$seconds</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">60</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$hours</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">intdiv</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$totalMinutes</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">60</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$minutes</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$totalMinutes</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">%</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">60</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$hours</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39; hours &#39;</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$minutes</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39; minutes&#39;</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<h2><a id="summary-of-recommended-approaches" href="#summary-of-recommended-approaches" class="" aria-hidden="true" title=""></a>Summary of Recommended Approaches</h2>
<p><code>DateTime</code> with <code>diff</code> is ideal for calendar aware calculations such as months, years, and full date comparisons. Timestamps are ideal for raw elapsed seconds, minutes, and hours when calendar rules are irrelevant. Use the <code>DateInterval</code> format method for clean combined output such as hours and minutes.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Wed, 19 Nov 2025 20:20:35 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Date format validation in Laravel]]></title>
                <link>https://nabilhassen.com/laravel-date-format-validation</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#validating-date-formats-in-laravel">Validating Date Formats in Laravel</a></li>
<li><a href="#basic-date-validation-rules">Basic Date Validation Rules</a>
<ul>
<li><a href="#the-date-rule">The date Rule</a></li>
<li><a href="#the-dateformat-rule">The date_format Rule</a></li>
<li><a href="#difference-between-date-and-dateformat">Difference Between date And date_format</a></li>
</ul>
</li>
<li><a href="#validating-dates-with-dateformat">Validating Dates With date_format</a>
<ul>
<li><a href="#single-format-example">Single Format Example</a></li>
<li><a href="#multiple-accepted-formats">Multiple Accepted Formats</a></li>
<li><a href="#common-format-patterns">Common Format Patterns</a></li>
</ul>
</li>
<li><a href="#time-and-datetime-validation">Time And DateTime Validation</a>
<ul>
<li><a href="#validating-combined-date-and-time">Validating Combined Date And Time</a></li>
<li><a href="#validating-full-timestamps">Validating Full Timestamps</a></li>
<li><a href="#partial-datetime-inputs-with-requiredwith">Partial Datetime Inputs With required_with</a></li>
</ul>
</li>
<li><a href="#validating-iso-8601-date-formats">Validating ISO 8601 Date Formats</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="validating-date-formats-in-laravel" href="#validating-date-formats-in-laravel" class="" aria-hidden="true" title=""></a>Validating Date Formats in Laravel</h2>
<p>Validating date formats is essential when accepting user input that depends on accurate scheduling, calculations, or storage. Laravel provides clear, powerful validation rules for dates. Laravel developers often struggle to understand which rule to use, how strict validation should be, and how to enforce specific formats.</p>
<h2><a id="basic-date-validation-rules" href="#basic-date-validation-rules" class="" aria-hidden="true" title=""></a>Basic Date Validation Rules</h2>
<h3><a id="the-date-rule" href="#the-date-rule" class="" aria-hidden="true" title=""></a>The <code>date</code> Rule</h3>
<p>The <code>date</code> rule checks if the value can be parsed into a valid date by PHP’s strtotime function or Carbon. It does not enforce a particular format.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;start_date&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;required|date&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">]);</span></div></code></pre>
<p>This ensures the input is a valid date but does not restrict how it is formatted.</p>
<h3><a id="the-dateformat-rule" href="#the-dateformat-rule" class="" aria-hidden="true" title=""></a>The <code>date_format</code> Rule</h3>
<p>The <code>date_format</code> rule checks if the value exactly matches a specified format.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;start_date&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;required|date_format:Y-m-d&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">]);</span></div></code></pre>
<p>The value must match the format exactly.</p>
<h3><a id="difference-between-date-and-dateformat" href="#difference-between-date-and-dateformat" class="" aria-hidden="true" title=""></a>Difference Between <code>date</code> And <code>date_format</code></h3>
<p>The <code>date</code> rule checks if the value is a real date. The <code>date_format</code> rule checks if the format matches. These rules serve different purposes.</p>
<h2><a id="validating-dates-with-dateformat" href="#validating-dates-with-dateformat" class="" aria-hidden="true" title=""></a>Validating Dates With <code>date_format</code></h2>
<h3><a id="single-format-example" href="#single-format-example" class="" aria-hidden="true" title=""></a>Single Format Example</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;event_date&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;required|date_format:d/m/Y&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">]);</span></div></code></pre>
<p>Accepts only values like <code>25/01/2025</code>.</p>
<h3><a id="multiple-accepted-formats" href="#multiple-accepted-formats" class="" aria-hidden="true" title=""></a>Multiple Accepted Formats</h3>
<p>Use comma-separated syntax to match one of the given formats.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;event_date&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;required|date_format:d/m/Y,m/d/Y&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">]);</span></div></code></pre>
<p>Laravel requires the value to match any of the formats in the <code>date_format</code> rule. In this case, it accepts both <code>25/01/2025</code> and <code>01/25/2025</code>.</p>
<h3><a id="common-format-patterns" href="#common-format-patterns" class="" aria-hidden="true" title=""></a>Common Format Patterns</h3>
<p>Y - four digit year
m - two digit month
d - two digit day
H - hours
i - minutes
s - seconds</p>
<h2><a id="time-and-datetime-validation" href="#time-and-datetime-validation" class="" aria-hidden="true" title=""></a>Time And DateTime Validation</h2>
<h3><a id="validating-combined-date-and-time" href="#validating-combined-date-and-time" class="" aria-hidden="true" title=""></a>Validating Combined Date And Time</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;scheduled_at&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;required|date_format:Y-m-d H:i&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">]);</span></div></code></pre>
<h3><a id="validating-full-timestamps" href="#validating-full-timestamps" class="" aria-hidden="true" title=""></a>Validating Full Timestamps</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;timestamp&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;required|date_format:Y-m-d H:i:s&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">]);</span></div></code></pre>
<h3><a id="partial-datetime-inputs-with-requiredwith" href="#partial-datetime-inputs-with-requiredwith" class="" aria-hidden="true" title=""></a>Partial Datetime Inputs With required_with</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;date&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;required_with:time|date_format:Y-m-d&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;time&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;required_with:date|date_format:H:i&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">]);</span></div></code></pre>
<h2><a id="validating-iso-8601-date-formats" href="#validating-iso-8601-date-formats" class="" aria-hidden="true" title=""></a>Validating ISO 8601 Date Formats</h2>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;published_at&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;required|date_format:Y-m-d\TH:i:sP&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">]);</span></div></code></pre>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>Use either <code>date</code> to check if the value is a real date or <code>date_format</code> to enforce strict formatting, not both.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 18 Nov 2025 21:33:20 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Phone number validation in Laravel]]></title>
                <link>https://nabilhassen.com/laravel-phone-number-validation</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#validate-phone-numbers-in-laravel">Validate Phone Numbers in Laravel</a></li>
<li><a href="#basic-phone-number-validation-using-built-in-rules">Basic Phone Number Validation Using Built In Rules</a>
<ul>
<li><a href="#using-the-required-and-numeric-rules">Using the required and numeric rules</a></li>
<li><a href="#using-regex-for-simple-patterns">Using regex for simple patterns</a></li>
<li><a href="#best-practices-when-using-regex">Best practices when using regex</a></li>
</ul>
</li>
<li><a href="#international-phone-number-validation">International Phone Number Validation</a>
<ul>
<li><a href="#understanding-e164-formatting">Understanding E.164 formatting</a></li>
<li><a href="#regex-for-e164-in-laravel-validation">Regex for E.164 in Laravel validation</a></li>
<li><a href="#common-pitfalls">Common pitfalls</a></li>
</ul>
</li>
<li><a href="#using-custom-validation-rules">Using Custom Validation Rules</a>
<ul>
<li><a href="#creating-a-custom-rule">Creating a custom rule</a></li>
<li><a href="#implementing-passes-and-message">Implementing passes and message</a></li>
<li><a href="#using-the-custom-rule-inside-form-requests">Using the custom rule inside Form Requests</a></li>
</ul>
</li>
<li><a href="#validating-phone-numbers-in-form-requests">Validating Phone Numbers in Form Requests</a>
<ul>
<li><a href="#centralizing-validation-logic">Centralizing validation logic</a></li>
<li><a href="#example-formrequest-with-phone-rules">Example FormRequest with phone rules</a></li>
<li><a href="#custom-messages-and-attribute-naming">Custom messages and attribute naming</a></li>
</ul>
</li>
<li><a href="#using-third-party-libraries-for-advanced-validation">Using Third Party Libraries for Advanced Validation</a>
<ul>
<li><a href="#when-to-use-a-library">When to use a library</a></li>
<li><a href="#example-using-the-propaganistaslaravel-phone-package">Example using the propaganistas/laravel-phone package</a></li>
</ul>
</li>
<li><a href="#summary">Summary</a></li>
</ul>
<h2><a id="validate-phone-numbers-in-laravel" href="#validate-phone-numbers-in-laravel" class="" aria-hidden="true" title=""></a>Validate Phone Numbers in Laravel</h2>
<p>Phone number validation is a common requirement in modern applications. Clean and accurate phone data ensures reliable communication, proper user identity verification, and consistent database formatting. Laravel provides flexible tools for validating both simple and complex phone formats through built in rules, regex, custom rules, and third party libraries.</p>
<h2><a id="basic-phone-number-validation-using-built-in-rules" href="#basic-phone-number-validation-using-built-in-rules" class="" aria-hidden="true" title=""></a>Basic Phone Number Validation Using Built In Rules</h2>
<h3><a id="using-the-required-and-numeric-rules" href="#using-the-required-and-numeric-rules" class="" aria-hidden="true" title=""></a>Using the required and numeric rules</h3>
<p>For basic numeric phone input:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;phone&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span><span style="color: #98C379;">&#39;required&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;numeric&#39;</span><span style="color: #ABB2BF;">],</span></div><div class='line'><span style="color: #ABB2BF;">]);</span></div></code></pre>
<p>This ensures the value contains only digits. It is useful for local formats without symbols or country codes.</p>
<h3><a id="using-regex-for-simple-patterns" href="#using-regex-for-simple-patterns" class="" aria-hidden="true" title=""></a>Using regex for simple patterns</h3>
<p>Regex allows basic structure enforcement. For example, a ten digit local number:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;phone&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span><span style="color: #98C379;">&#39;required&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;regex:/^[0-9]{10}$/&#39;</span><span style="color: #ABB2BF;">],</span></div><div class='line'><span style="color: #ABB2BF;">]);</span></div></code></pre>
<h3><a id="best-practices-when-using-regex" href="#best-practices-when-using-regex" class="" aria-hidden="true" title=""></a>Best practices when using regex</h3>
<ul>
<li>Keep patterns minimal and readable.</li>
<li>Avoid overly strict patterns that reject valid real world formats.</li>
<li>Escape characters correctly to avoid unintended matches.</li>
</ul>
<h2><a id="international-phone-number-validation" href="#international-phone-number-validation" class="" aria-hidden="true" title=""></a>International Phone Number Validation</h2>
<h3><a id="understanding-e164-formatting" href="#understanding-e164-formatting" class="" aria-hidden="true" title=""></a>Understanding E.164 formatting</h3>
<p>E.164 is the global standard for phone numbers. It requires a leading plus sign followed by up to fifteen digits. Example: +15551234567.</p>
<h3><a id="regex-for-e164-in-laravel-validation" href="#regex-for-e164-in-laravel-validation" class="" aria-hidden="true" title=""></a>Regex for E.164 in Laravel validation</h3>
<p>A reliable E.164 pattern:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;phone&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span><span style="color: #98C379;">&#39;required&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;regex:/^\+[1-9][0-9]{1,14}$/&#39;</span><span style="color: #ABB2BF;">],</span></div><div class='line'><span style="color: #ABB2BF;">]);</span></div></code></pre>
<p>Explanation:</p>
<ul>
<li>The value must start with a plus sign.</li>
<li>The first digit cannot be zero.</li>
<li>The number can contain up to fifteen digits.</li>
</ul>
<h3><a id="common-pitfalls" href="#common-pitfalls" class="" aria-hidden="true" title=""></a>Common pitfalls</h3>
<ul>
<li>Allowing spaces or punctuation when using E.164.</li>
<li>Accepting country codes starting with zero.</li>
<li>Forgetting to anchor the regex pattern at the start and end of the string.</li>
</ul>
<h2><a id="using-custom-validation-rules" href="#using-custom-validation-rules" class="" aria-hidden="true" title=""></a>Using Custom Validation Rules</h2>
<h3><a id="creating-a-custom-rule" href="#creating-a-custom-rule" class="" aria-hidden="true" title=""></a>Creating a custom rule</h3>
<p>Generate a rule class:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">make:rule</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">PhoneNumber</span></div></code></pre>
<h3><a id="implementing-passes-and-message" href="#implementing-passes-and-message" class="" aria-hidden="true" title=""></a>Implementing passes and message</h3>
<p>Example rule enforcing E.164:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">namespace</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">App\Rules</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Contracts\Validation\</span><span style="color: #E5C07B;">Rule</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">PhoneNumber</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">implements</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Rule</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">passes</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$attribute</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">preg_match</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">&#39;/</span><span style="color: #C678DD;">^</span><span style="color: #56B6C2;">\+</span><span style="color: #E06C75;">[1-9][0-9]{1,14}</span><span style="color: #C678DD;">$</span><span style="color: #E06C75;">/&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">) </span><span style="color: #56B6C2;">===</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">message</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;The :attribute field must be a valid phone number.&#39;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="using-the-custom-rule-inside-form-requests" href="#using-the-custom-rule-inside-form-requests" class="" aria-hidden="true" title=""></a>Using the custom rule inside Form Requests</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">rules</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;phone&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> \App\Rules\</span><span style="color: #E5C07B;">PhoneNumber</span><span style="color: #ABB2BF;">],</span></div><div class='line'><span style="color: #ABB2BF;">    ];</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>This encapsulates validation logic and keeps controllers clean.</p>
<h2><a id="validating-phone-numbers-in-form-requests" href="#validating-phone-numbers-in-form-requests" class="" aria-hidden="true" title=""></a>Validating Phone Numbers in Form Requests</h2>
<h3><a id="centralizing-validation-logic" href="#centralizing-validation-logic" class="" aria-hidden="true" title=""></a>Centralizing validation logic</h3>
<p>Form Requests provide a dedicated location for validation. They improve maintainability and support custom messages, authorization, and reusable rules.</p>
<h3><a id="example-formrequest-with-phone-rules" href="#example-formrequest-with-phone-rules" class="" aria-hidden="true" title=""></a>Example FormRequest with phone rules</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">namespace</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">App\Http\Requests</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Foundation\Http\</span><span style="color: #E5C07B;">FormRequest</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">StoreUserRequest</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">FormRequest</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">rules</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #98C379;">&#39;phone&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span><span style="color: #98C379;">&#39;required&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;regex:/^\+[1-9][0-9]{1,14}$/&#39;</span><span style="color: #ABB2BF;">],</span></div><div class='line'><span style="color: #ABB2BF;">        ];</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="custom-messages-and-attribute-naming" href="#custom-messages-and-attribute-naming" class="" aria-hidden="true" title=""></a>Custom messages and attribute naming</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">messages</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;phone.regex&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Enter a valid E.164 phone number.&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ];</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">attributes</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;phone&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;phone number&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ];</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h2><a id="using-third-party-libraries-for-advanced-validation" href="#using-third-party-libraries-for-advanced-validation" class="" aria-hidden="true" title=""></a>Using Third Party Libraries for Advanced Validation</h2>
<h3><a id="when-to-use-a-library" href="#when-to-use-a-library" class="" aria-hidden="true" title=""></a>When to use a library</h3>
<p>Use a library when you need country specific formatting, parsing, normalization, or validation beyond simple regex. This is helpful when supporting multiple regions.</p>
<h3><a id="example-using-the-propaganistaslaravel-phone-package" href="#example-using-the-propaganistaslaravel-phone-package" class="" aria-hidden="true" title=""></a>Example using the propaganistas/laravel-phone package</h3>
<p>Install the <a rel="nofollow noopener" target="_blank" href="https://github.com/Propaganistas/Laravel-Phone">package</a>:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">require</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">propaganistas/laravel-phone</span></div></code></pre>
<p>Validate a phone number for a specific country:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;phone&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span><span style="color: #98C379;">&#39;required&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;phone:US&#39;</span><span style="color: #ABB2BF;">],</span></div><div class='line'><span style="color: #ABB2BF;">]);</span></div></code></pre>
<p>Validate an international phone number:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;phone&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span><span style="color: #98C379;">&#39;required&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;phone:INTERNATIONAL&#39;</span><span style="color: #ABB2BF;">],</span></div><div class='line'><span style="color: #ABB2BF;">]);</span></div></code></pre>
<p>Validate multiple possible countries:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;phone&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span><span style="color: #98C379;">&#39;required&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;phone:US,CA&#39;</span><span style="color: #ABB2BF;">],</span></div><div class='line'><span style="color: #ABB2BF;">]);</span></div></code></pre>
<h2><a id="summary" href="#summary" class="" aria-hidden="true" title=""></a>Summary</h2>
<p>Laravel offers powerful options for validating phone numbers ranging from simple digit checks to advanced international validation. Developers can use built in rules for straightforward cases, regex for structured formats, custom rules for complex logic, and external libraries for global accuracy. These tools allow applications to collect clean, consistent, and reliable phone data across diverse regions and use cases.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Mon, 17 Nov 2025 22:51:38 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Get domain from URL in PHP]]></title>
                <link>https://nabilhassen.com/php-get-domain-from-url</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#how-to-get-the-domain-from-a-url-in-php">How to Get the Domain from a URL in PHP</a></li>
<li><a href="#using-parseurl-recommended">Using parse_url() (Recommended)</a>
<ul>
<li><a href="#example">Example:</a></li>
</ul>
</li>
<li><a href="#removing-subdomains-to-get-the-root-domain">Removing Subdomains to Get the Root Domain</a>
<ul>
<li><a href="#example-1">Example:</a></li>
</ul>
</li>
<li><a href="#using-regular-expressions-quick-but-limited">Using Regular Expressions (Quick but Limited)</a>
<ul>
<li><a href="#example-2">Example:</a></li>
</ul>
</li>
</ul>
<h2><a id="how-to-get-the-domain-from-a-url-in-php" href="#how-to-get-the-domain-from-a-url-in-php" class="" aria-hidden="true" title=""></a>How to Get the Domain from a URL in PHP</h2>
<p>Extracting a domain from a URL is a common need in PHP, whether you’re validating inputs, filtering analytics data, or handling redirects. PHP provides several reliable ways to do this, from built-in functions to regular expressions. This guide explains all the practical approaches, including how to remove subdomains when necessary.</p>
<h2><a id="using-parseurl-recommended" href="#using-parseurl-recommended" class="" aria-hidden="true" title=""></a>Using <code>parse_url()</code> (Recommended)</h2>
<p>The simplest and most reliable method is to use PHP’s built-in <a rel="nofollow noopener" target="_blank" href="https://www.php.net/manual/en/function.parse-url.php"><code>parse_url()</code></a> function, which breaks a URL into its components.</p>
<h3><a id="example" href="#example" class="" aria-hidden="true" title=""></a>Example:</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;https://blog.example.co.uk/article?id=10&#39;</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$host</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">parse_url</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">PHP_URL_HOST</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$host</span><span style="color: #ABB2BF;">; </span><span style="color: #7F848E;">// Output: blog.example.co.uk</span></div></code></pre>
<p>This retrieves the <strong>full host</strong> (including subdomains). It’s ideal for general use cases where you need the entire hostname.</p>
<h2><a id="removing-subdomains-to-get-the-root-domain" href="#removing-subdomains-to-get-the-root-domain" class="" aria-hidden="true" title=""></a>Removing Subdomains to Get the Root Domain</h2>
<p>When you only need the root domain (for example, <code>example.co.uk</code> instead of <code>blog.example.co.uk</code>), you can split the host and extract the last two or three parts intelligently.</p>
<h3><a id="example-1" href="#example-1" class="" aria-hidden="true" title=""></a>Example:</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;https://blog.example.co.uk&#39;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #E06C75;">$host</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">parse_url</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">PHP_URL_HOST</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$parts</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">explode</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;.&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$host</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$count</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">count</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$parts</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$count</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">&gt;</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">2</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$domain</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$parts</span><span style="color: #ABB2BF;">[</span><span style="color: #E06C75;">$count</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">-</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">2</span><span style="color: #ABB2BF;">] </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;.&#39;</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$parts</span><span style="color: #ABB2BF;">[</span><span style="color: #E06C75;">$count</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">-</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">];</span></div><div class='line'><span style="color: #ABB2BF;">} </span><span style="color: #C678DD;">else</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$domain</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$host</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$domain</span><span style="color: #ABB2BF;">; </span><span style="color: #7F848E;">// Output: example.co.uk</span></div></code></pre>
<p>This works well for most standard domain structures, though country-code TLDs (like <code>.co.uk</code>, <code>.com.au</code>) may need extra handling depending on your requirements.</p>
<h2><a id="using-regular-expressions-quick-but-limited" href="#using-regular-expressions-quick-but-limited" class="" aria-hidden="true" title=""></a>Using Regular Expressions (Quick but Limited)</h2>
<p>You can also use a regex for simple extraction, though it’s not as reliable for complex domains.</p>
<h3><a id="example-2" href="#example-2" class="" aria-hidden="true" title=""></a>Example:</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;https://store.blog.example.com/path&#39;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #56B6C2;">preg_match</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">&#39;/</span><span style="color: #C678DD;">^</span><span style="color: #E06C75;">(?:https?:</span><span style="color: #56B6C2;">\/\/</span><span style="color: #E06C75;">)?(?:[^@\/\n]</span><span style="color: #C678DD;">+</span><span style="color: #E06C75;">@)?(?:www</span><span style="color: #56B6C2;">\.</span><span style="color: #E06C75;">)?([^:\/\n]</span><span style="color: #C678DD;">+</span><span style="color: #E06C75;">)/&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$matches</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$matches</span><span style="color: #ABB2BF;">[</span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">]; </span><span style="color: #7F848E;">// Output: store.blog.example.com</span></div></code></pre>
<p>You can further process <code>$matches[1]</code> using the earlier subdomain-removal logic to isolate the root domain.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Wed, 12 Nov 2025 21:11:35 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[How to get the current URL in Laravel]]></title>
                <link>https://nabilhassen.com/laravel-get-current-url</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#retrieve-the-current-url-in-laravel">Retrieve the Current URL in Laravel</a></li>
<li><a href="#get-current-url-without-query-paramteres">Get Current URL Without Query Paramteres</a></li>
<li><a href="#getting-the-full-url-including-query-parameters">Getting the Full URL Including Query Parameters</a></li>
<li><a href="#using-the-request-instance">Using the Request Instance</a>
<ul>
<li><a href="#get-the-current-url-without-query">Get the Current URL (without query)</a></li>
<li><a href="#get-the-full-url-with-query">Get the Full URL (with query)</a></li>
<li><a href="#get-only-the-path">Get Only the Path</a></li>
</ul>
</li>
<li><a href="#summary-reference">Summary Reference</a></li>
</ul>
<h2><a id="retrieve-the-current-url-in-laravel" href="#retrieve-the-current-url-in-laravel" class="" aria-hidden="true" title=""></a>Retrieve the Current URL in Laravel</h2>
<p>Accessing the current URL is a common requirement in Laravel applications whether for redirects, logging, analytics, or conditional logic. Laravel provides simple, expressive methods for retrieving the current URL, its full version with query strings, the base root, and even the previous page URL.</p>
<h2><a id="get-current-url-without-query-paramteres" href="#get-current-url-without-query-paramteres" class="" aria-hidden="true" title=""></a>Get Current URL Without Query Paramteres</h2>
<p>Laravel’s <code>URL</code> facade and the <code>url()</code> helper give you quick access to URL methods.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">URL</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Get the current URL (without query parameters)</span></div><div class='line'><span style="color: #E06C75;">$currentUrl</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">URL</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">current</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p><strong>Example:</strong>
If your browser is at <code>https://example.com/posts?page=2</code>, <code>URL::current()</code> returns:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">https://example.com/posts</span></div></code></pre>
<p>The global helper syntax works the same:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$currentUrl</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">url</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">current</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>Both produce the same result.</p>
<h2><a id="getting-the-full-url-including-query-parameters" href="#getting-the-full-url-including-query-parameters" class="" aria-hidden="true" title=""></a>Getting the Full URL Including Query Parameters</h2>
<p>To include query parameters in the result, use the <code>full()</code> method.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$fullUrl</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">URL</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">full</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p><strong>Example output:</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">https://example.com/posts?page=2&amp;sort=latest</span></div></code></pre>
<p>You can also use the <code>Request</code> instance for the same:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$fullUrl</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">request</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">fullUrl</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>Both return the complete URL including query strings.</p>
<h2><a id="using-the-request-instance" href="#using-the-request-instance" class="" aria-hidden="true" title=""></a>Using the <code>Request</code> Instance</h2>
<p>The <code>Request</code> object provides several methods for interacting with the URL and path.</p>
<h3><a id="get-the-current-url-without-query" href="#get-the-current-url-without-query" class="" aria-hidden="true" title=""></a>Get the Current URL (without query)</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$plainUrl</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">request</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">url</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>Equivalent to <code>URL::current()</code>.</p>
<h3><a id="get-the-full-url-with-query" href="#get-the-full-url-with-query" class="" aria-hidden="true" title=""></a>Get the Full URL (with query)</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$fullUrl</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">request</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">fullUrl</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>Equivalent to <code>URL::full()</code>.</p>
<h3><a id="get-only-the-path" href="#get-only-the-path" class="" aria-hidden="true" title=""></a>Get Only the Path</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$path</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">request</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">path</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p><strong>Example:</strong>
<code>https://example.com/posts/42</code> → <code>posts/42</code></p>
<h2><a id="summary-reference" href="#summary-reference" class="" aria-hidden="true" title=""></a>Summary Reference</h2>
<table>
<thead>
<tr>
<th>Method</th>
<th>Returns</th>
<th>Includes Query String</th>
<th>Source</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>URL::current()</code></td>
<td>Current URL</td>
<td>No</td>
<td>URL Facade</td>
</tr>
<tr>
<td><code>URL::full()</code></td>
<td>Full URL</td>
<td>Yes</td>
<td>URL Facade</td>
</tr>
<tr>
<td><code>request()-&gt;url()</code></td>
<td>Current URL</td>
<td>No</td>
<td>Request</td>
</tr>
<tr>
<td><code>request()-&gt;fullUrl()</code></td>
<td>Full URL</td>
<td>Yes</td>
<td>Request</td>
</tr>
<tr>
<td><code>request()-&gt;path()</code></td>
<td>Path only</td>
<td>N/A</td>
<td>Request</td>
</tr>
</tbody>
</table>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 11 Nov 2025 22:03:12 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Service Pattern in Laravel: Why it is meaningless]]></title>
                <link>https://nabilhassen.com/laravel-service-pattern-issues</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#why-the-service-pattern-is-a-mess-in-laravel-projects">Why the Service Pattern Is a Mess in Laravel Projects</a></li>
<li><a href="#the-core-problem-it-lost-its-meaning">The Core Problem: It Lost Its Meaning</a>
<ul>
<li><a href="#1-repository-like-services">1. Repository-like Services</a></li>
<li><a href="#2-sub-controller-services">2. Sub-Controller Services</a></li>
<li><a href="#3-model-action-services">3. Model Action Services</a></li>
<li><a href="#4-utility-or-services">4. Utility or Services</a></li>
<li><a href="#5-3rd-party-integration-services">5. 3rd-Party Integration Services</a></li>
</ul>
</li>
<li><a href="#why-this-is-dangerous">Why This Is Dangerous</a></li>
<li><a href="#the-better-approach-use-the-right-pattern-for-the-right-job">The Better Approach: Use the Right Pattern for the Right Job</a></li>
<li><a href="#example-clean-structure-without-the-service-mess">Example: Clean Structure Without the Service Mess</a></li>
<li><a href="#final-thoughts">Final Thoughts</a></li>
</ul>
<h2><a id="why-the-service-pattern-is-a-mess-in-laravel-projects" href="#why-the-service-pattern-is-a-mess-in-laravel-projects" class="" aria-hidden="true" title=""></a>Why the Service Pattern Is a Mess in Laravel Projects</h2>
<p>The <strong>Service Pattern</strong> started as a noble idea: separating business logic from controllers to keep things clean. But in real-world Laravel projects, it has become one of the most abused and misunderstood architectural choices. What was meant to bring clarity often ends up turning into a dumping ground for misplaced logic.</p>
<p>Let’s break down why this happens, how it leads to code chaos, and what better patterns you can use instead.</p>
<h2><a id="the-core-problem-it-lost-its-meaning" href="#the-core-problem-it-lost-its-meaning" class="" aria-hidden="true" title=""></a>The Core Problem: It Lost Its Meaning</h2>
<p>In Laravel projects, the term <em>Service</em> has become a catch-all label. When developers aren’t sure where to place logic, they often create a “service” class as a quick fix. Over time, these classes grow without structure or purpose.</p>
<p>Here’s what happens in practice:</p>
<h3><a id="1-repository-like-services" href="#1-repository-like-services" class="" aria-hidden="true" title=""></a>1. Repository-like Services</h3>
<p>Developers use a “service” to handle database queries, duplicating what a proper repository pattern (i.e. Eloquent) is meant for.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// app/Services/UserService.php</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">UserService</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">all</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">all</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">active</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">where</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;active&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">true</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>This doesn’t add value, it’s just an unnecessary wrapper around the model. In Laravel, <strong>you don’t need the repository pattern at all</strong>. Eloquent ORM already <em>is</em> your repository layer. It provides query abstraction, data mapping, and expressive syntax out of the box.</p>
<p>The logic should live directly in the model using <strong>query scopes</strong> or <strong>custom query builders</strong>.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// app/Models/User.php</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Model</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">scopeActive</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$query</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$query</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">where</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;active&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">true</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">active</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>Cleaner, readable, and perfectly aligned with Laravel’s conventions. There’s no need for an extra repository or service layer to wrap Eloquent.</p>
<h3><a id="2-sub-controller-services" href="#2-sub-controller-services" class="" aria-hidden="true" title=""></a>2. Sub-Controller Services</h3>
<p>Some developers offload all controller work into a service class. The controller becomes an empty shell, while the service becomes a bloated pseudo-controller.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// app/Services/UserService.php</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">UserService</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">store</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">array</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">create</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">UserRegistered</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">dispatch</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// more user creation logic ...</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// app/Http/Controllers/UserController.php</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">UserController</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">store</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">UserService</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$service</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$service</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">store</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validated</span><span style="color: #ABB2BF;">());</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Do this instead:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// app/Actions/CreateUser.php</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">CreateUser</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">execute</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">array</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">User</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">create</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// app/Http/Controllers/UserController.php</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">UserController</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">store</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">StoreUserRequest</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">CreateUser</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$action</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$action</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">execute</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validated</span><span style="color: #ABB2BF;">());</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">UserRegistered</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">dispatch</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">response</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">json</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="3-model-action-services" href="#3-model-action-services" class="" aria-hidden="true" title=""></a>3. Model Action Services</h3>
<p>A common misuse of the service pattern is the <strong>“Model Action Service”</strong> approach where developers group every operation related to a single model into one giant class.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// app/Services/UserService.php</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">UserService</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">create</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">array</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">) { ... }</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">deactivate</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">) { ... }</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">update</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">) { ... }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>At first glance, it looks organized because everything about the <code>User</code> model is in one place. But as the project grows, this becomes a <strong>bloated, unmaintainable class</strong>. Each method deals with different concerns such as business logic, notifications, integrations, and state changes, all jammed together.</p>
<p>Instead, use the <strong>Action Pattern</strong> to separate each behavior into its own focused class.</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">app/</span></div><div class='line'><span style="color: #abb2bf;">├── Actions/</span></div><div class='line'><span style="color: #abb2bf;">│   ├── ActivateUser.php</span></div><div class='line'><span style="color: #abb2bf;">│   ├── DeactivateUser.php</span></div><div class='line'><span style="color: #abb2bf;">│   ├── PromoteUser.php</span></div><div class='line'><span style="color: #abb2bf;">│   └── SendWelcomeEmail.php</span></div></code></pre>
<p>Each action handles one job and one job only, which makes your code:</p>
<ul>
<li>Easier to test</li>
<li>Simpler to reason about</li>
<li>Consistent in structure</li>
</ul>
<p>Example:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// app/Actions/ActivateUser.php</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">ActivateUser</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">execute</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">User</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">update</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;active&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">true</span><span style="color: #ABB2BF;">]);</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Then in your controller or service layer:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">activate</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">ActivateUser</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$action</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">response</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">json</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$action</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">execute</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">));</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>This separation keeps logic modular, predictable, and perfectly aligned with Laravel’s clean architecture style.</p>
<h3><a id="4-utility-or-services" href="#4-utility-or-services" class="" aria-hidden="true" title=""></a>4. Utility or Services</h3>
<p>Another frequent misuse is turning service classes into <strong>utility containers</strong>, generic helpers that perform unrelated, cross-cutting tasks.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// app/Services/HelperService.php</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">HelperService</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">formatDate</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$date</span><span style="color: #ABB2BF;">) { ... }</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">slugify</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$string</span><span style="color: #ABB2BF;">) { ... }</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">toMoneyFormat</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">) { ... }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>At first, it seems convenient to centralize “handy” functions. But the moment you start adding random helpers here, this class becomes a <strong>miscellaneous landfill</strong>, a vague “service” that belongs nowhere.</p>
<p>A better approach:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">app/</span></div><div class='line'><span style="color: #abb2bf;">├── Utilities/</span></div><div class='line'><span style="color: #abb2bf;">│   ├── CurrencyConverter.php</span></div><div class='line'><span style="color: #abb2bf;">│   └── HtmlToMarkdownConverter.php</span></div></code></pre>
<p>Each helper has a <strong>clear, single responsibility</strong> and descriptive name.</p>
<p>The key idea is: <strong>Utilities are not services</strong>. They are helpers that are lightweight, context-agnostic tools and deserve their own proper home.</p>
<h3><a id="5-3rd-party-integration-services" href="#5-3rd-party-integration-services" class="" aria-hidden="true" title=""></a>5. 3rd-Party Integration Services</h3>
<p>Integration logic (like Stripe or AWS) often ends up in generic “services,” again adding confusion.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// app/Services/StripeService.php</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">StripeService</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">charge</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$amount</span><span style="color: #ABB2BF;">) { ... }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>These belong in a dedicated <strong>Integrations</strong> namespace or directory.</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">app/</span></div><div class='line'><span style="color: #abb2bf;">├── Integrations/</span></div><div class='line'><span style="color: #abb2bf;">│   └── Stripe/</span></div><div class='line'><span style="color: #abb2bf;">│       ├── StripeClient.php</span></div><div class='line'><span style="color: #abb2bf;">│       ├── StripeCharge.php</span></div><div class='line'><span style="color: #abb2bf;">│       └── StripeWebhookHandler.php</span></div></code></pre>
<p>Each integration gets a proper structure and purpose.</p>
<h2><a id="why-this-is-dangerous" href="#why-this-is-dangerous" class="" aria-hidden="true" title=""></a>Why This Is Dangerous</h2>
<p>When the Service pattern becomes a catch-all:</p>
<ul>
<li><strong>Naming loses meaning</strong> – “What does this service actually do?” becomes a common question.</li>
<li><strong>Maintenance becomes painful</strong> – Changing logic means hunting through arbitrary service methods.</li>
<li><strong>Testing is harder</strong> – Overly generic classes depend on too many parts of the app.</li>
<li><strong>Team communication breaks</strong> – Every developer has a different interpretation of “service.”</li>
</ul>
<h2><a id="the-better-approach-use-the-right-pattern-for-the-right-job" href="#the-better-approach-use-the-right-pattern-for-the-right-job" class="" aria-hidden="true" title=""></a>The Better Approach: Use the Right Pattern for the Right Job</h2>
<p>Laravel gives you the flexibility to organize your logic cleanly. Instead of one vague “service” layer, use specific patterns and naming that convey intent.</p>
<table>
<thead>
<tr>
<th>Misuse</th>
<th>Problem</th>
<th>Correct Pattern</th>
<th>Directory Example</th>
</tr>
</thead>
<tbody>
<tr>
<td>Repository-like Services</td>
<td>Duplicate data logic</td>
<td><strong>Use Eloquent ORM (built-in Repository)</strong></td>
<td><code>app/Models/User.php</code></td>
</tr>
<tr>
<td>Sub-Controller Services</td>
<td>Bloated, misplaced HTTP logic</td>
<td><strong>Action Pattern</strong></td>
<td><code>app/Actions/CreateUser.php</code></td>
</tr>
<tr>
<td>Model Action Services</td>
<td>Mixed domain behaviors in one class</td>
<td><strong>Action Pattern</strong></td>
<td><code>app/Actions/ActivateUser.php</code></td>
</tr>
<tr>
<td>Utility/Support Services</td>
<td>Dumping ground for helpers</td>
<td><strong>Support Classes / Helpers</strong></td>
<td><code>app/Support/DateHelper.php</code></td>
</tr>
<tr>
<td>Third-Party Integration Services</td>
<td>Mixed integration and domain logic</td>
<td><strong>Integration Layer</strong></td>
<td><code>app/Integrations/Stripe/StripeCharge.php</code></td>
</tr>
</tbody>
</table>
<h2><a id="example-clean-structure-without-the-service-mess" href="#example-clean-structure-without-the-service-mess" class="" aria-hidden="true" title=""></a>Example: Clean Structure Without the Service Mess</h2>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">app/</span></div><div class='line'><span style="color: #abb2bf;">├── Actions/</span></div><div class='line'><span style="color: #abb2bf;">│   └── CreateUser.php</span></div><div class='line'><span style="color: #abb2bf;">├── Http/</span></div><div class='line'><span style="color: #abb2bf;">│   └── Controllers/</span></div><div class='line'><span style="color: #abb2bf;">│       └── UserController.php</span></div><div class='line'><span style="color: #abb2bf;">├── Integrations/</span></div><div class='line'><span style="color: #abb2bf;">│   └── Stripe/</span></div><div class='line'><span style="color: #abb2bf;">│       └── StripeCharge.php</span></div><div class='line'><span style="color: #abb2bf;">├── Models/</span></div><div class='line'><span style="color: #abb2bf;">│   └── User.php</span></div><div class='line'><span style="color: #abb2bf;">└── Utilities/</span></div><div class='line'><span style="color: #abb2bf;">    └── CurrencyConverter.php</span></div></code></pre>
<p>With this structure, you always know where to place logic and where to find it later. There’s no need for a generic “Service” directory at all.</p>
<h2><a id="final-thoughts" href="#final-thoughts" class="" aria-hidden="true" title=""></a>Final Thoughts</h2>
<p>The Service pattern became a mess in Laravel because it stopped meaning anything. It turned into a garbage bin for code developers didn’t know where to put. The solution isn’t to keep refining the “service” concept, it’s to <strong>stop using it as a default</strong>.</p>
<p>Use <strong>Eloquent ORM</strong> as your repository, <strong>Actions</strong> for actions performed on models, <strong>Integrations</strong> for external APIs, and <strong>Support</strong> for shared helpers or utilities. Let structure and naming communicate intent. That’s how you build Laravel projects that stay clean, maintainable, and scalable.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 11 Nov 2025 02:33:40 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Pest vs PHPUnit: How Pest modernizes PHP testing]]></title>
                <link>https://nabilhassen.com/pest-vs-phpunit</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#phpunit-vs-pest-php-testing-framework-comparison">PHPUnit vs Pest: PHP Testing Framework Comparison</a></li>
<li><a href="#expectations-api-with-fluent-chaining-and-custom-extensions">Expectations API with fluent chaining and custom extensions</a></li>
<li><a href="#functional-test-style-with-describe-it-higher-order-tests">Functional test style with describe, it, higher order tests</a></li>
<li><a href="#datasets-that-read-naturally-inline">Datasets that read naturally inline</a></li>
<li><a href="#file-and-suite-configuration-via-pest-helpers">File and suite configuration via Pest helpers</a></li>
<li><a href="#lifecycle-hooks-expressed-as-closures-across-files-or-globally">Lifecycle hooks expressed as closures across files or globally</a></li>
<li><a href="#grouping-with-fluent-api-and-directory-level-grouping">Grouping with fluent API and directory level grouping</a></li>
<li><a href="#browser-testing-built-on-playwright">Browser testing built on Playwright</a></li>
<li><a href="#architecture-testing">Architecture testing</a></li>
<li><a href="#snapshot-testing">Snapshot testing</a></li>
<li><a href="#type-coverage-reporting">Type coverage reporting</a></li>
<li><a href="#profanity-checker-and-more">Profanity checker and more</a></li>
<li><a href="#filtering-and-running-tests-with-fluent-chains-in-code">Filtering and running tests with fluent chains in code</a></li>
<li><a href="#side-by-side-summary">Side by side summary</a></li>
<li><a href="#practical-starter-templates">Practical starter templates</a>
<ul>
<li><a href="#convert-a-phpunit-assertion-to-a-pest-expectation">Convert a PHPUnit assertion to a Pest expectation</a></li>
<li><a href="#add-a-reusable-expectation">Add a reusable expectation</a></li>
<li><a href="#attach-a-base-testcase-and-a-trait-across-a-folder">Attach a base TestCase and a trait across a folder</a></li>
<li><a href="#define-architecture-rules">Define architecture rules</a></li>
<li><a href="#add-a-snapshot-check">Add a snapshot check</a></li>
<li><a href="#minimal-browser-test">Minimal browser test</a></li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="phpunit-vs-pest-php-testing-framework-comparison" href="#phpunit-vs-pest-php-testing-framework-comparison" class="" aria-hidden="true" title=""></a>PHPUnit vs Pest: PHP Testing Framework Comparison</h2>
<p>Testing is a non-negotiable part of modern PHP development. Among the most widely used frameworks, PHPUnit and Pest stand out as the dominant choices. Both are powerful, reliable, and actively maintained but they differ significantly in philosophy, syntax, and developer experience.</p>
<p>PHPUnit is the long-established standard in PHP testing, powering most enterprise and open-source test suites. It follows a traditional, class-based structure familiar to Java or .NET developers.</p>
<p>Pest, on the other hand, is a newer testing framework built on top of PHPUnit. It redefines PHP testing with a simpler, expressive, and elegant syntax while maintaining full PHPUnit compatibility.</p>
<h2><a id="expectations-api-with-fluent-chaining-and-custom-extensions" href="#expectations-api-with-fluent-chaining-and-custom-extensions" class="" aria-hidden="true" title=""></a>Expectations API with fluent chaining and custom extensions</h2>
<p>Pest introduces <code>expect()</code> with readable matchers and a first class way to create your own expectations. PHPUnit relies on assertion methods and custom constraints but has no built in fluent expectation layer.</p>
<p>Example</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// Pest</span></div><div class='line'><span style="color: #61AFEF;">expect</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">toBe</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;John&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #E06C75;">not</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">toBeEmpty</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Custom expectation in tests/Pest.php</span></div><div class='line'><span style="color: #61AFEF;">expect</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">extend</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;toBeAdult&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> () {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">toBeGreaterThanOrEqual</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">18</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Usage</span></div><div class='line'><span style="color: #61AFEF;">expect</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">age</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">toBeAdult</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h2><a id="functional-test-style-with-describe-it-higher-order-tests" href="#functional-test-style-with-describe-it-higher-order-tests" class="" aria-hidden="true" title=""></a>Functional test style with describe, it, higher order tests</h2>
<p>Pest adds <code>describe()</code> and <code>it()</code> helpers and a higher order testing mode that removes boilerplate closures for common flows. PHPUnit stays class based and does not offer these helpers.</p>
<p>Example</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// Pest</span></div><div class='line'><span style="color: #61AFEF;">describe</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;sum&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">function</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">()</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">    it</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;adds integers&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">function</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">()</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">        expect</span><span style="color: #ABB2BF;">(</span><span style="color: #61AFEF;">sum</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">2</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">3</span><span style="color: #ABB2BF;">))-&gt;</span><span style="color: #61AFEF;">toBe</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">5</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #ABB2BF;">});</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Higher order style example</span></div><div class='line'><span style="color: #61AFEF;">test</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;home page&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;/&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">assertOk</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">assertSee</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;Welcome&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<h2><a id="datasets-that-read-naturally-inline" href="#datasets-that-read-naturally-inline" class="" aria-hidden="true" title=""></a>Datasets that read naturally inline</h2>
<p>Pest provides inline datasets and named datasets via <code>-&gt;with(...)</code>. PHPUnit has data providers, but the inline, fluent dataset style is a Pest convenience feature.</p>
<p>Example</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #61AFEF;">it</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;accepts valid emails&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">function</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">string</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$email</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">    expect</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$email</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">toMatch</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">&#39;/@/&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">})-&gt;</span><span style="color: #61AFEF;">with</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;jane@example.com&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;john@acme.org&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">]);</span></div></code></pre>
<h2><a id="file-and-suite-configuration-via-pest-helpers" href="#file-and-suite-configuration-via-pest-helpers" class="" aria-hidden="true" title=""></a>File and suite configuration via Pest helpers</h2>
<p>Pest lets you bind a base test case, traits, and groups to files or directories using <code>pest()-&gt;extend()</code>, <code>pest()-&gt;use()</code>, and <code>-&gt;in()</code>. PHPUnit config is XML oriented and class based. The fluent per directory binding is Pest specific.</p>
<p>Example</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// tests/Pest.php</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Tests\</span><span style="color: #E5C07B;">TestCase</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Foundation\Testing\</span><span style="color: #E5C07B;">RefreshDatabase</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">pest</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">extend</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">TestCase</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">use</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">RefreshDatabase</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">in</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;Feature&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<h2><a id="lifecycle-hooks-expressed-as-closures-across-files-or-globally" href="#lifecycle-hooks-expressed-as-closures-across-files-or-globally" class="" aria-hidden="true" title=""></a>Lifecycle hooks expressed as closures across files or globally</h2>
<p>Pest has <code>beforeEach</code>, <code>afterEach</code>, <code>beforeAll</code>, <code>afterAll</code> hooks with a functional style and global registration in <code>tests/Pest.php</code>. PHPUnit offers setup and teardown methods but not the closure based, global hook ergonomics.</p>
<p>Example</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #61AFEF;">beforeEach</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">()</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">user</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">factory</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">create</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">afterAll</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">()</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #7F848E;">// clean up external resources</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div></code></pre>
<h2><a id="grouping-with-fluent-api-and-directory-level-grouping" href="#grouping-with-fluent-api-and-directory-level-grouping" class="" aria-hidden="true" title=""></a>Grouping with fluent API and directory level grouping</h2>
<p>Pest adds <code>-&gt;group('name')</code> and directory wide grouping through <code>pest()-&gt;group()-&gt;in()</code>. PHPUnit uses annotations or attributes but not the same fluent helpers.</p>
<p>Example</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #61AFEF;">test</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;slow path&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">fn</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">()</span><span style="color: #61AFEF;"> =&gt; </span><span style="color: #7F848E;">/* ... */</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">group</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;slow&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Directory level</span></div><div class='line'><span style="color: #61AFEF;">pest</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">group</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;feature&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">in</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;Feature&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<h2><a id="browser-testing-built-on-playwright" href="#browser-testing-built-on-playwright" class="" aria-hidden="true" title=""></a>Browser testing built on Playwright</h2>
<p>Pest v4 adds browser testing through an official plugin with simple <code>visit()</code> flows, screenshots, and visual regression helpers. PHPUnit does not include browser automation out of the box.</p>
<p>Example</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #61AFEF;">it</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;welcomes the user&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">function</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">()</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E06C75;">$page</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> visit</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;/&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E06C75;">$page</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertSee</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;Welcome&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div></code></pre>
<h2><a id="architecture-testing" href="#architecture-testing" class="" aria-hidden="true" title=""></a>Architecture testing</h2>
<p>Write rules that enforce boundaries and naming by namespace or function patterns. This is a built in capability in Pest docs through the Architecture Testing section. PHPUnit has no native architecture rule DSL.</p>
<p>Example</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #61AFEF;">arch</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">expect</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;App</span><span style="color: #56B6C2;">\\</span><span style="color: #98C379;">Http</span><span style="color: #56B6C2;">\\</span><span style="color: #98C379;">Controllers&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">toUse</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;App</span><span style="color: #56B6C2;">\\</span><span style="color: #98C379;">Http</span><span style="color: #56B6C2;">\\</span><span style="color: #98C379;">Requests&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<h2><a id="snapshot-testing" href="#snapshot-testing" class="" aria-hidden="true" title=""></a>Snapshot testing</h2>
<p>Simple snapshot matching with a dedicated storage folder managed by Pest. PHPUnit does not ship a snapshot feature.</p>
<p>Example</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #61AFEF;">it</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;renders contact page&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">function</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">()</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E06C75;">$response</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;/contact&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #61AFEF;">    expect</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$response</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">toMatchSnapshot</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div></code></pre>
<h2><a id="type-coverage-reporting" href="#type-coverage-reporting" class="" aria-hidden="true" title=""></a>Type coverage reporting</h2>
<p>A plugin that reports type coverage without executing tests. PHPUnit does not provide this metric natively.</p>
<p>Command</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">require</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--dev</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">pestphp/pest-plugin-type-coverage</span></div><div class='line'><span style="color: #ABB2BF;">./vendor/bin/pest </span><span style="color: #D19A66;">--type-coverage</span></div></code></pre>
<h2><a id="profanity-checker-and-more" href="#profanity-checker-and-more" class="" aria-hidden="true" title=""></a>Profanity checker and more</h2>
<p>Additional official plugins like Profanity and Stress testing are documented and integrate via the same fluent CLI options. PHPUnit does not have official equivalents.</p>
<h2><a id="filtering-and-running-tests-with-fluent-chains-in-code" href="#filtering-and-running-tests-with-fluent-chains-in-code" class="" aria-hidden="true" title=""></a>Filtering and running tests with fluent chains in code</h2>
<p>Beyond CLI flags, Pest lets you chain helpers like <code>-&gt;group()</code> at call sites and use expressive <code>describe</code> based scoping. PHPUnit filtering is attribute or CLI driven and remains class centric.</p>
<h2><a id="side-by-side-summary" href="#side-by-side-summary" class="" aria-hidden="true" title=""></a>Side by side summary</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Pest</th>
<th>PHPUnit</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Expectations API</strong></td>
<td>Fluent <code>expect()</code> API with custom expectations via <code>expect()-&gt;extend()</code></td>
<td>Traditional assertion methods using <code>$this-&gt;assert*()</code></td>
</tr>
<tr>
<td><strong>Test Structure</strong></td>
<td><code>describe()</code> and <code>it()</code> helpers for behavior-driven tests</td>
<td>Class-based <code>TestCase</code> structure with methods</td>
</tr>
<tr>
<td><strong>Datasets</strong></td>
<td>Inline and named datasets using <code>-&gt;with()</code></td>
<td>Data providers defined as separate methods</td>
</tr>
<tr>
<td><strong>Suite Configuration</strong></td>
<td>Fluent configuration with <code>pest()-&gt;extend()</code>, <code>pest()-&gt;use()</code>, <code>-&gt;in()</code></td>
<td>XML-based configuration or annotations</td>
</tr>
<tr>
<td><strong>Hooks</strong></td>
<td>Closure-based <code>beforeEach</code>, <code>afterEach</code>, <code>beforeAll</code>, <code>afterAll</code> (global or file-level)</td>
<td>Method-based <code>setUp()</code> and <code>tearDown()</code> in classes</td>
</tr>
<tr>
<td><strong>Grouping</strong></td>
<td>Fluent <code>-&gt;group()</code> and directory-level grouping</td>
<td>Grouping via annotations or attributes</td>
</tr>
<tr>
<td><strong>Plugins</strong></td>
<td>Official plugins for browser, architecture, snapshot, type coverage, profanity, and more</td>
<td>No official plugin ecosystem; relies on external tools</td>
</tr>
</tbody>
</table>
<h2><a id="practical-starter-templates" href="#practical-starter-templates" class="" aria-hidden="true" title=""></a>Practical starter templates</h2>
<h3><a id="convert-a-phpunit-assertion-to-a-pest-expectation" href="#convert-a-phpunit-assertion-to-a-pest-expectation" class="" aria-hidden="true" title=""></a>Convert a PHPUnit assertion to a Pest expectation</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// PHPUnit</span></div><div class='line'><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertSame</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">5</span><span style="color: #ABB2BF;">, </span><span style="color: #61AFEF;">sum</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">2</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">3</span><span style="color: #ABB2BF;">));</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Pest</span></div><div class='line'><span style="color: #61AFEF;">expect</span><span style="color: #ABB2BF;">(</span><span style="color: #61AFEF;">sum</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">2</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">3</span><span style="color: #ABB2BF;">))-&gt;</span><span style="color: #61AFEF;">toBe</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">5</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<h3><a id="add-a-reusable-expectation" href="#add-a-reusable-expectation" class="" aria-hidden="true" title=""></a>Add a reusable expectation</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// tests/Pest.php</span></div><div class='line'><span style="color: #61AFEF;">expect</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">extend</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;toBeUuid&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> () {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">toMatch</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">&#39;/</span><span style="color: #C678DD;">^</span><span style="color: #E06C75;">[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}</span><span style="color: #C678DD;">$</span><span style="color: #E06C75;">/i&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// usage</span></div><div class='line'><span style="color: #61AFEF;">expect</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$id</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">toBeUuid</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h3><a id="attach-a-base-testcase-and-a-trait-across-a-folder" href="#attach-a-base-testcase-and-a-trait-across-a-folder" class="" aria-hidden="true" title=""></a>Attach a base TestCase and a trait across a folder</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// tests/Pest.php</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Tests\</span><span style="color: #E5C07B;">TestCase</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Foundation\Testing\</span><span style="color: #E5C07B;">RefreshDatabase</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">pest</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">extend</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">TestCase</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">use</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">RefreshDatabase</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">in</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;Feature&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<h3><a id="define-architecture-rules" href="#define-architecture-rules" class="" aria-hidden="true" title=""></a>Define architecture rules</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #61AFEF;">arch</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">preset</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">php</span><span style="color: #ABB2BF;">();      </span><span style="color: #7F848E;">// start with sensible defaults</span></div><div class='line'><span style="color: #61AFEF;">arch</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">expect</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;App</span><span style="color: #56B6C2;">\\</span><span style="color: #98C379;">Models&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">toOnlyBeUsedIn</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;App</span><span style="color: #56B6C2;">\\</span><span style="color: #98C379;">Services&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<h3><a id="add-a-snapshot-check" href="#add-a-snapshot-check" class="" aria-hidden="true" title=""></a>Add a snapshot check</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #61AFEF;">it</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;has a contact page&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">function</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">()</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E06C75;">$response</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;/contact&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    expect</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$response</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">toMatchSnapshot</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div></code></pre>
<h3><a id="minimal-browser-test" href="#minimal-browser-test" class="" aria-hidden="true" title=""></a>Minimal browser test</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #61AFEF;">it</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;may welcome the user&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">function</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">()</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E06C75;">$page</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> visit</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;/&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E06C75;">$page</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertSee</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;Welcome&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div></code></pre>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>Pest offers more features in addition to the ones I covered in this blog post. Choose PHPUnit when you want the classic class based xUnit core. Choose Pest if you want the same engine with an expressive API, functional test style, and an official plugin ecosystem that covers browser automation, architecture rules, snapshots, and type coverage out of the box.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Wed, 05 Nov 2025 20:18:51 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Rollback a specific migration file in Laravel]]></title>
                <link>https://nabilhassen.com/laravel-rollback-specific-migration</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#how-to-rollback-specific-migration-files-in-laravel">How to Rollback Specific Migration Files in Laravel</a></li>
<li><a href="#understanding-laravel-migration-rollbacks">Understanding Laravel Migration Rollbacks</a></li>
<li><a href="#rollback-a-specific-migration-file">Rollback a Specific Migration File</a>
<ul>
<li><a href="#how-it-works">How It Works</a></li>
</ul>
</li>
<li><a href="#rollback-multiple-specific-migration-files">Rollback Multiple Specific Migration Files</a></li>
<li><a href="#reset-or-refresh-specific-migration-files">Reset or Refresh Specific Migration Files</a>
<ul>
<li><a href="#reset-specific-migration">Reset Specific Migration</a></li>
<li><a href="#refresh-specific-migration">Refresh Specific Migration</a></li>
</ul>
</li>
</ul>
<h2><a id="how-to-rollback-specific-migration-files-in-laravel" href="#how-to-rollback-specific-migration-files-in-laravel" class="" aria-hidden="true" title=""></a>How to Rollback Specific Migration Files in Laravel</h2>
<p>Rolling back migrations is a normal part of Laravel development. You might add a migration, test it, and then need to undo only that specific change without affecting others. Laravel makes this possible through the <code>--path</code> option, allowing you to target individual migration files precisely.</p>
<h2><a id="understanding-laravel-migration-rollbacks" href="#understanding-laravel-migration-rollbacks" class="" aria-hidden="true" title=""></a>Understanding Laravel Migration Rollbacks</h2>
<p>Laravel migrations are version-controlled database schema files. When you run <code>php artisan migrate</code>, each migration file is executed in order, and its name is recorded in the <code>migrations</code> table.</p>
<p>To undo migrations, Laravel provides the following key commands:</p>
<ul>
<li><code>php artisan migrate:rollback</code></li>
<li><code>php artisan migrate:reset</code></li>
<li><code>php artisan migrate:refresh</code></li>
</ul>
<p>Each can be combined with the <code>--path</code> option to rollback specific files instead of all migrations.</p>
<h2><a id="rollback-a-specific-migration-file" href="#rollback-a-specific-migration-file" class="" aria-hidden="true" title=""></a>Rollback a Specific Migration File</h2>
<p>If you want to rollback a <strong>single specific migration</strong>, use the <code>migrate:rollback</code> command with the <code>--path</code> option.</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">migrate:rollback</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--path=/database/migrations/2024_11_04_123456_create_orders_table.php</span></div></code></pre>
<h3><a id="how-it-works" href="#how-it-works" class="" aria-hidden="true" title=""></a>How It Works</h3>
<ul>
<li>The <code>--path</code> option tells Laravel which migration file to target.</li>
<li>The path should be <strong>relative to the base Laravel project directory</strong>.</li>
<li>Laravel will execute the <code>down()</code> method of that specific migration file only.</li>
</ul>
<p>This is the most direct and correct way to rollback one migration without touching others.</p>
<h2><a id="rollback-multiple-specific-migration-files" href="#rollback-multiple-specific-migration-files" class="" aria-hidden="true" title=""></a>Rollback Multiple Specific Migration Files</h2>
<p>You can rollback multiple specific files by specifying each <code>--path</code> argument individually:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">migrate:rollback</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">\</span></div><div class='line'><span style="color: #ABB2BF;">--path=/database/migrations/2024_11_04_123456_create_orders_table.php </span><span style="color: #56B6C2;">\</span></div><div class='line'><span style="color: #ABB2BF;">--path=/database/migrations/2024_11_04_123457_add_status_to_orders_table.php</span></div></code></pre>
<p>Each listed file will have its <code>down()</code> method executed in order, rolling back only those migrations.</p>
<h2><a id="reset-or-refresh-specific-migration-files" href="#reset-or-refresh-specific-migration-files" class="" aria-hidden="true" title=""></a>Reset or Refresh Specific Migration Files</h2>
<p>In addition to rolling back, Laravel also lets you <strong>reset</strong> or <strong>refresh</strong> specific migrations.</p>
<h3><a id="reset-specific-migration" href="#reset-specific-migration" class="" aria-hidden="true" title=""></a>Reset Specific Migration</h3>
<p>To completely reset (rollback all migrations), but limit the rollback to certain files:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">migrate:reset</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--path=/database/migrations/2024_11_04_123456_create_orders_table.php</span></div></code></pre>
<h3><a id="refresh-specific-migration" href="#refresh-specific-migration" class="" aria-hidden="true" title=""></a>Refresh Specific Migration</h3>
<p>To rollback and re-run the same migration (useful during testing):</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">migrate:refresh</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--path=/database/migrations/2024_11_04_123456_create_orders_table.php</span></div></code></pre>
<p>This command will:</p>
<ol>
<li>Run the <code>down()</code> method (rollback).</li>
<li>Immediately run the <code>up()</code> method again (reapply the migration).</li>
</ol>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 04 Nov 2025 20:22:18 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Composer: Remove or uninstall PHP packages]]></title>
                <link>https://nabilhassen.com/composer-remove-package</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#how-to-remove-or-uninstall-php-packages-using-composer">How to remove or uninstall PHP packages using Composer</a></li>
<li><a href="#remove-a-php-package-using-composer">Remove a PHP Package Using Composer</a></li>
<li><a href="#removing-multiple-php-packages-at-once-using-composer">Removing Multiple PHP Packages at Once using Composer</a></li>
<li><a href="#removing-a-development-only-php-package">Removing a Development-Only PHP Package</a></li>
<li><a href="#remove-manually-by-editing-composerjson-not-recommended">Remove Manually by Editing composer.json (Not Recommended)</a></li>
<li><a href="#verify-the-removal">Verify the Removal</a></li>
<li><a href="#common-mistakes-to-avoid">Common Mistakes to Avoid</a></li>
</ul>
<h2><a id="how-to-remove-or-uninstall-php-packages-using-composer" href="#how-to-remove-or-uninstall-php-packages-using-composer" class="" aria-hidden="true" title=""></a>How to remove or uninstall PHP packages using Composer</h2>
<p>When managing PHP dependencies, it’s essential to know not only how to install but also how to properly <strong>remove or uninstall packages</strong>. Composer provides a simple and safe way to do this while keeping your project clean and dependency-free of unused packages. This guide explains exactly how to remove packages, update dependencies, and verify changes clearly, correctly, and efficiently.</p>
<h2><a id="remove-a-php-package-using-composer" href="#remove-a-php-package-using-composer" class="" aria-hidden="true" title=""></a>Remove a PHP Package Using Composer</h2>
<p>Before removing anything, identify the package you want to uninstall to confirm that the package exists in your project before proceeding.</p>
<p>Run:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">show</span></div></code></pre>
<p>You can also search for a <strong>specific package</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">show</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">vendor/package-name</span></div></code></pre>
<p>To <strong>remove or uninstall a package</strong>, use the <code>remove</code> command:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">remove</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">vendor/package-name</span></div></code></pre>
<p><strong>What this does:</strong></p>
<ul>
<li>Uninstalls the specified package from the <code>vendor/</code> directory.</li>
<li>Removes it from your <code>composer.json</code> and <code>composer.lock</code> files.</li>
<li>Automatically updates the autoloader to reflect the change.</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">remove</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">guzzlehttp/guzzle</span></div></code></pre>
<p>Composer will update your dependency tree and display a summary of the removed package and any other dependencies that are no longer needed.</p>
<h2><a id="removing-multiple-php-packages-at-once-using-composer" href="#removing-multiple-php-packages-at-once-using-composer" class="" aria-hidden="true" title=""></a>Removing Multiple PHP Packages at Once using Composer</h2>
<p>You can remove more than one package in a single command:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">remove</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">vendor/package-one</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">vendor/package-two</span></div></code></pre>
<p>Composer will uninstall both packages and clean up dependencies that are no longer used by your project.</p>
<h2><a id="removing-a-development-only-php-package" href="#removing-a-development-only-php-package" class="" aria-hidden="true" title=""></a>Removing a Development-Only PHP Package</h2>
<p>If the package was installed as a development dependency (with the <code>--dev</code> flag), you can remove it in the same way:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">remove</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--dev</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">vendor/package-name</span></div></code></pre>
<p>This removes the package from the <code>require-dev</code> section of your <code>composer.json</code>.</p>
<h2><a id="remove-manually-by-editing-composerjson-not-recommended" href="#remove-manually-by-editing-composerjson-not-recommended" class="" aria-hidden="true" title=""></a>Remove Manually by Editing composer.json (Not Recommended)</h2>
<p>While you can manually delete a package entry from <code>composer.json</code>, it’s <strong>not recommended</strong> because:</p>
<ul>
<li>It won’t automatically update <code>composer.lock</code>.</li>
<li>It won’t clean up the <code>vendor/</code> directory.</li>
<li>It can lead to inconsistent states.</li>
</ul>
<p>If you do manually edit <code>composer.json</code>, always run:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">update</span></div></code></pre>
<p>afterward to synchronize and reinstall only the required packages.</p>
<h2><a id="verify-the-removal" href="#verify-the-removal" class="" aria-hidden="true" title=""></a>Verify the Removal</h2>
<p>After the removal process, confirm that the package is no longer listed in your dependencies:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">show</span></div></code></pre>
<p>You should also check your <code>composer.json</code> file to ensure that the package has been deleted from either the <code>require</code> or <code>require-dev</code> section.</p>
<h2><a id="common-mistakes-to-avoid" href="#common-mistakes-to-avoid" class="" aria-hidden="true" title=""></a>Common Mistakes to Avoid</h2>
<ul>
<li>
<p><strong>Forgetting to run <code>composer update</code> or <code>composer install</code> after manual edits.</strong>
Always sync your dependency files after editing.</p>
</li>
<li>
<p><strong>Removing a package that’s required by another dependency.</strong>
Composer will warn you and block removal if the package is still in use elsewhere.</p>
</li>
<li>
<p><strong>Skipping autoload updates.</strong>
If autoload references remain, run:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">dump-autoload</span></div></code></pre>
</li>
</ul>
<p>Always prefer using Composer’s built-in <code>remove</code> command instead of manual deletions. It ensures all references, autoloading, and dependency chains are properly updated keeping your PHP project stable, consistent, and lightweight.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Mon, 03 Nov 2025 21:10:55 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Rollback the last migration safely in Laravel]]></title>
                <link>https://nabilhassen.com/laravel-rollback-last-migration</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#how-to-rollback-the-last-migration-safely-in-laravel">How to Rollback the Last Migration Safely in Laravel</a></li>
<li><a href="#check-migration-status">Check Migration Status</a></li>
<li><a href="#simulate-a-rollback-without-making-changes">Simulate a Rollback Without Making Changes</a></li>
<li><a href="#rollback-the-last-migration">Rollback the Last Migration</a>
<ul>
<li><a href="#example">Example</a></li>
</ul>
</li>
<li><a href="#rollback-and-re-migrate-the-last-migration">RollBack and Re-Migrate the Last Migration</a></li>
<li><a href="#safely-rolling-back-in-production">Safely Rolling Back in Production</a>
<ul>
<li><a href="#safe-practice">Safe Practice</a></li>
</ul>
</li>
<li><a href="#final-safety-checklist">Final Safety Checklist</a></li>
</ul>
<h2><a id="how-to-rollback-the-last-migration-safely-in-laravel" href="#how-to-rollback-the-last-migration-safely-in-laravel" class="" aria-hidden="true" title=""></a>How to Rollback the Last Migration Safely in Laravel</h2>
<p>Rolling back migrations is a common part of Laravel development, especially during iterative schema changes. However, doing it incorrectly can lead to data loss or inconsistent states. This guide explains how to <strong>safely rollback the last migration</strong> in Laravel, when to use each command, and how to handle production environments properly.</p>
<h2><a id="check-migration-status" href="#check-migration-status" class="" aria-hidden="true" title=""></a>Check Migration Status</h2>
<p>Before rolling back, always confirm the current state of your migrations:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">migrate:status</span></div></code></pre>
<p>This lists all migrations with a status column (<code>Ran?</code>). It helps you verify which migrations are active and which batch they belong to.</p>
<h2><a id="simulate-a-rollback-without-making-changes" href="#simulate-a-rollback-without-making-changes" class="" aria-hidden="true" title=""></a>Simulate a Rollback Without Making Changes</h2>
<p>Laravel provides a dry-run mode using the --pretend option. This command shows the SQL statements that would be executed during a rollback without applying them.</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">migrate:rollback</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--pretend</span></div></code></pre>
<p>This is especially useful for verifying what changes will occur before actually rolling back your database. It helps prevent accidental data or schema loss.</p>
<h2><a id="rollback-the-last-migration" href="#rollback-the-last-migration" class="" aria-hidden="true" title=""></a>Rollback the Last Migration</h2>
<p>To rollback <strong>only the most recent batch</strong> of migrations (the last run), use:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">migrate:rollback</span></div></code></pre>
<p>To rollback <strong>only the last migration</strong>, use:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">migrate:rollback</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--step=1</span></div></code></pre>
<h3><a id="example" href="#example" class="" aria-hidden="true" title=""></a>Example</h3>
<p>If you’ve run three migration batches so far:</p>
<table>
<thead>
<tr>
<th>Batch</th>
<th>Migration</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2024_10_01_000000_create_users</td>
</tr>
<tr>
<td>2</td>
<td>2024_10_02_000000_create_posts</td>
</tr>
<tr>
<td>3</td>
<td>2024_10_03_000000_add_status_to_posts</td>
</tr>
<tr>
<td>3</td>
<td>2024_10_03_000000_add_slug_to_posts</td>
</tr>
</tbody>
</table>
<p>Running:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">migrate:rollback</span></div></code></pre>
<p>will undo <strong>only Batch 3</strong> removing the last two migrations.</p>
<p>While running:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">migrate:rollback</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--step=1</span></div></code></pre>
<p>will undo the last migration only (<code>2024_10_03_000000_add_slug_to_posts</code>) removing the last migration.</p>
<h2><a id="rollback-and-re-migrate-the-last-migration" href="#rollback-and-re-migrate-the-last-migration" class="" aria-hidden="true" title=""></a>RollBack and Re-Migrate the Last Migration</h2>
<p>To rollback the last batch and immediately reapply it (useful for quick iteration locally):</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">migrate:refresh</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--step=1</span></div></code></pre>
<p>This command combines rollback and migrate into one action, which is ideal for testing recent schema changes.</p>
<h2><a id="safely-rolling-back-in-production" href="#safely-rolling-back-in-production" class="" aria-hidden="true" title=""></a>Safely Rolling Back in Production</h2>
<p>In production environments, rollback actions can cause <strong>data loss</strong> or downtime.
To protect against accidental schema drops, Laravel requires confirmation:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">migrate:rollback</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--force</span></div></code></pre>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">migrate:rollback</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--step=1</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--force</span></div></code></pre>
<h3><a id="safe-practice" href="#safe-practice" class="" aria-hidden="true" title=""></a>Safe Practice</h3>
<ul>
<li>Always <strong>back up your database</strong> before rolling back in production.</li>
<li>Ensure that every migration’s <code>down()</code> method <strong>reverses changes cleanly</strong> (e.g., drops columns, foreign keys, or tables that were created in <code>up()</code>).</li>
<li>Use Laravel’s <code>Schema::hasTable()</code> and <code>Schema::hasColumn()</code> checks to make rollback methods idempotent and avoid exceptions.</li>
</ul>
<p><strong>Example Safe Down Method:</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">down</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Schema</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">hasColumn</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;posts&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;status&#39;</span><span style="color: #ABB2BF;">)) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Schema</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;posts&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Blueprint</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$table</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E06C75;">$table</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">dropColumn</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;status&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">        });</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h2><a id="final-safety-checklist" href="#final-safety-checklist" class="" aria-hidden="true" title=""></a>Final Safety Checklist</h2>
<ol>
<li><strong>Run <code>migrate:status</code></strong> to confirm which migrations you’re affecting.</li>
<li><strong>Use dry-run mode using the --pretend option</strong> to verify the changes without actually running them.</li>
<li><strong>Ensure backups</strong> are in place before rolling back.</li>
<li><strong>Double-check <code>down()</code> methods</strong> for reversibility and safety.</li>
<li>Use <code>--step</code> and <code>--force</code> flags deliberately <strong>(never blindly)</strong>.</li>
<li>For production, <strong>test rollbacks in staging</strong> first.</li>
</ol>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Thu, 23 Oct 2025 20:37:31 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[What PHP version is required for Laravel 12]]></title>
                <link>https://nabilhassen.com/laravel-12-php-version</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#required-php-version-for-laravel-12">Required PHP Version for Laravel 12</a></li>
<li><a href="#how-to-check-the-required-php-version-for-any-laravel-version">How to Check the Required PHP Version for Any Laravel Version</a></li>
<li><a href="#how-to-check-your-php-version">How to Check Your PHP Version</a></li>
<li><a href="#how-to-upgrade-php">How to Upgrade PHP</a>
<ul>
<li><a href="#on-ubuntu--debian">On Ubuntu / Debian</a></li>
<li><a href="#on-macos-homebrew">On macOS (Homebrew)</a></li>
<li><a href="#on-windows">On Windows</a></li>
</ul>
</li>
<li><a href="#verifying-compatibility-before-installing-laravel-12">Verifying Compatibility Before Installing Laravel 12</a></li>
<li><a href="#summary">Summary</a></li>
</ul>
<h2><a id="required-php-version-for-laravel-12" href="#required-php-version-for-laravel-12" class="" aria-hidden="true" title=""></a>Required PHP Version for Laravel 12</h2>
<p>Laravel 12 requires <strong>PHP 8.2 or higher</strong> to run. This version requirement aligns with Laravel's commitment to supporting modern PHP features, improved performance, and better type safety.</p>
<h2><a id="how-to-check-the-required-php-version-for-any-laravel-version" href="#how-to-check-the-required-php-version-for-any-laravel-version" class="" aria-hidden="true" title=""></a>How to Check the Required PHP Version for Any Laravel Version</h2>
<p>To check which PHP version is required for a specific Laravel release, follow these steps:</p>
<ol>
<li>Go to the <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/laravel">laravel/laravel</a> GitHub repository.</li>
<li>Switch to the branch corresponding to the version you want to check (for example, <code>12.x</code>, <code>11.x</code>, etc.).</li>
<li>Open the <code>composer.json</code> file.</li>
<li>Find the <code>require</code> section and you’ll see the PHP version requirement listed like this:</li>
</ol>
<pre><code data-theme="one-dark-pro" data-lang="json" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #98C379;">&quot;require&quot;</span><span style="color: #ABB2BF;">: {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">&quot;php&quot;</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">&quot;^8.2&quot;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #FFFFFF;">...</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>This ensures you always verify against the official and most accurate source.</p>
<h2><a id="how-to-check-your-php-version" href="#how-to-check-your-php-version" class="" aria-hidden="true" title=""></a>How to Check Your PHP Version</h2>
<p>You can quickly verify your PHP version using the following command:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #D19A66;">-v</span></div></code></pre>
<p>Example output:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">PHP 8.2.12 (cli) (built: Sep 27 2024 15:00:00) (NTS)</span></div></code></pre>
<p>If the version displayed is <strong>8.2.0 or higher</strong>, you’re ready to install Laravel 12.</p>
<h2><a id="how-to-upgrade-php" href="#how-to-upgrade-php" class="" aria-hidden="true" title=""></a>How to Upgrade PHP</h2>
<p>If your PHP version is lower than 8.2, upgrade it before creating or running a Laravel 12 project.</p>
<h3><a id="on-ubuntu--debian" href="#on-ubuntu--debian" class="" aria-hidden="true" title=""></a>On Ubuntu / Debian</h3>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">sudo </span><span style="color: #98C379;">add-apt-repository</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">ppa:ondrej/php</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">-y</span></div><div class='line'><span style="color: #ABB2BF;">sudo </span><span style="color: #98C379;">apt</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">update</span></div><div class='line'><span style="color: #ABB2BF;">sudo </span><span style="color: #98C379;">apt</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">install</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">php8.2</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">php8.2-cli</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">php8.2-common</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">php8.2-mbstring</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">php8.2-xml</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">php8.2-bcmath</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">php8.2-curl</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">php8.2-zip</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">-y</span></div></code></pre>
<h3><a id="on-macos-homebrew" href="#on-macos-homebrew" class="" aria-hidden="true" title=""></a>On macOS (Homebrew)</h3>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">brew </span><span style="color: #98C379;">update</span></div><div class='line'><span style="color: #ABB2BF;">brew </span><span style="color: #98C379;">install</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">php@8.2</span></div><div class='line'><span style="color: #ABB2BF;">brew </span><span style="color: #98C379;">link</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">php@8.2</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--force</span></div></code></pre>
<h3><a id="on-windows" href="#on-windows" class="" aria-hidden="true" title=""></a>On Windows</h3>
<ol>
<li>Download PHP 8.2 from <a rel="nofollow noopener" target="_blank" href="https://windows.php.net/download">windows.php.net/download</a>.</li>
<li>Extract it and update your system PATH variable to include the PHP directory.</li>
</ol>
<h2><a id="verifying-compatibility-before-installing-laravel-12" href="#verifying-compatibility-before-installing-laravel-12" class="" aria-hidden="true" title=""></a>Verifying Compatibility Before Installing Laravel 12</h2>
<p>If you’re installing Laravel 12 using Composer, you can confirm your PHP version meets the requirement by running:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">create-project</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">laravel/laravel</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">example-app</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;^12.0&quot;</span></div></code></pre>
<p>If your PHP version is below 8.2, Composer will show an error similar to:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">Your PHP version (8.1.12) does not satisfy that requirement.</span></div></code></pre>
<p>Upgrade your PHP installation, and rerun the command.</p>
<h2><a id="summary" href="#summary" class="" aria-hidden="true" title=""></a>Summary</h2>
<ul>
<li><strong>Required PHP version:</strong> 8.2 or higher</li>
<li><strong>Reason:</strong> Laravel 12 uses new PHP 8.2 language features</li>
<li><strong>Check PHP version:</strong> <code>php -v</code></li>
<li><strong>Check required PHP for any version:</strong> View the <code>composer.json</code> in the respective Laravel branch on GitHub</li>
<li><strong>Upgrade:</strong> Use your OS-specific package manager or installer</li>
</ul>
<p>Always ensure your environment meets Laravel’s minimum requirements to avoid compatibility issues and to take advantage of the framework’s full potential.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Wed, 22 Oct 2025 21:17:24 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Deferred Queue Driver in Laravel 12.35]]></title>
                <link>https://nabilhassen.com/laravel-deferred-queue-driver</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#introduction">Introduction</a></li>
<li><a href="#how-deferred-queue-driver-works">How deferred queue driver works</a></li>
<li><a href="#configuration">Configuration</a></li>
<li><a href="#combining-deferred-with-the-failover-queue-driver">Combining Deferred with the Failover Queue Driver</a></li>
<li><a href="#when-to-use-the-deferred-queue-driver">When to Use the Deferred Queue Driver</a></li>
<li><a href="#summary">Summary</a></li>
</ul>
<h2><a id="introduction" href="#introduction" class="" aria-hidden="true" title=""></a>Introduction</h2>
<p>Laravel 12.35 adds a new queue driver called <strong><code>deferred</code></strong>, designed to process queued jobs <strong>after</strong> the HTTP response is sent back to the client, all within the same PHP process.</p>
<p>Unlike typical queue drivers (<code>database</code>, <code>redis</code>, <code>sqs</code>, etc.) that rely on external workers, the <strong>deferred driver</strong> lets you defer non-critical tasks like sending emails, logging, or analytics, until the request is complete.</p>
<h2><a id="how-deferred-queue-driver-works" href="#how-deferred-queue-driver-works" class="" aria-hidden="true" title=""></a>How deferred queue driver works</h2>
<p>Here’s what happens under the hood when using the <code>deferred</code> queue driver:</p>
<ol>
<li>You dispatch a job normally using <code>dispatch()</code>.</li>
<li>Once the HTTP response is sent to the user, Laravel automatically processes the deferred jobs <strong>synchronously</strong> within the same PHP process after the response has been sent out to the user.</li>
</ol>
<h2><a id="configuration" href="#configuration" class="" aria-hidden="true" title=""></a>Configuration</h2>
<p>To use the deferred queue driver, add a new connection in your <code>config/queue.php</code> file:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #98C379;">&#39;connections&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;deferred&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;driver&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;deferred&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ],</span></div><div class='line'><span style="color: #ABB2BF;">],</span></div></code></pre>
<p>Set it globally in your <code>.env</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="env" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">QUEUE_CONNECTION</span><span style="color: #56B6C2;">=</span><span style="color: #98C379;">deferred</span></div></code></pre>
<p>Then, in your code, you can:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">SendWelcomeEmail</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">dispatch</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<h2><a id="combining-deferred-with-the-failover-queue-driver" href="#combining-deferred-with-the-failover-queue-driver" class="" aria-hidden="true" title=""></a>Combining Deferred with the Failover Queue Driver</h2>
<p>You can combine the <strong>deferred driver</strong> with Laravel’s <strong>failover queue driver</strong> to ensure maximum reliability.</p>
<p>In this setup, Laravel will first try to push jobs to your main <strong>database</strong> queue.
If that fails (for example, due to a temporary connection issue), it will <strong>fall back to the deferred driver</strong>, which ensures the job still runs immediately after the HTTP response is sent.</p>
<p>Here’s how to configure it in <code>config/queue.php</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #98C379;">&#39;connections&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;failover&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;driver&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;failover&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;connections&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span><span style="color: #98C379;">&#39;database&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;deferred&#39;</span><span style="color: #ABB2BF;">],</span></div><div class='line'><span style="color: #ABB2BF;">    ],</span></div><div class='line'><span style="color: #ABB2BF;">],</span></div></code></pre>
<p>Then, in your <code>.env</code> file:</p>
<pre><code data-theme="one-dark-pro" data-lang="env" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">QUEUE_CONNECTION</span><span style="color: #56B6C2;">=</span><span style="color: #98C379;">failover</span></div></code></pre>
<p>Now when you dispatch a job:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">SendWelcomeEmail</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">dispatch</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>Here’s the flow:</p>
<ol>
<li>Laravel attempts to push the job to the <strong>database</strong> queue first.</li>
<li>If the database queue connection fails, Laravel automatically <strong>falls back to the deferred driver</strong>.</li>
<li>The deferred driver ensures the job runs immediately after the response is sent to the user preventing job loss even if your main queue is down.</li>
</ol>
<p>This hybrid setup provides both <strong>reliability</strong> and <strong>speed</strong>:</p>
<ul>
<li>Jobs are normally handled by your primary queue system (e.g., database workers).</li>
<li>If it’s unavailable, they’re executed instantly after the response, thanks to the deferred fallback.</li>
</ul>
<h2><a id="when-to-use-the-deferred-queue-driver" href="#when-to-use-the-deferred-queue-driver" class="" aria-hidden="true" title=""></a>When to Use the Deferred Queue Driver</h2>
<p>The <strong>deferred queue driver</strong> is ideal for:</p>
<ul>
<li>Sending transactional emails right after a request.</li>
<li>Logging analytics or metrics post-response.</li>
<li>Broadcasting events or notifications that don’t affect the immediate user experience.</li>
<li>Any short, non-critical task that should run after the response but doesn’t need a dedicated worker.</li>
</ul>
<p>However, avoid it for:</p>
<ul>
<li>Long-running or resource-heavy jobs.</li>
<li>Tasks that require retry logic or distributed processing (use <code>redis</code>, <code>sqs</code>, or <code>database</code> instead).</li>
</ul>
<h2><a id="summary" href="#summary" class="" aria-hidden="true" title=""></a>Summary</h2>
<p>The <strong>Deferred Queue Driver</strong> introduced in <strong>Laravel 12.35</strong> provides a simple but powerful way to run queued jobs <strong>after</strong> the HTTP response is sent all without extra setup or workers.</p>
<p>When paired with the <strong>Failover Queue Driver</strong>, it creates a safe and efficient hybrid approach: immediate post-response execution with reliable fallback protection.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 21 Oct 2025 18:59:45 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[How to check your composer version]]></title>
                <link>https://nabilhassen.com/check-composer-version</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#how-to-check-composer-version-windows-macos-and-linux">How to Check Composer Version (Windows, macOS, and Linux)</a></li>
<li><a href="#check-composer-version-using-the-command-line">Check Composer Version Using the Command Line</a></li>
<li><a href="#checking-composer-version-on-different-operating-systems">Checking Composer Version on Different Operating Systems</a>
<ul>
<li><a href="#check-composer-version-in-windows">Check composer version in Windows</a></li>
<li><a href="#check-composer-version-in-macos">Check composer version in macOS</a></li>
<li><a href="#check-composer-version-in-linux-ubuntu-debian-fedora-etc">Check composer version in Linux (Ubuntu, Debian, Fedora, etc.)</a></li>
</ul>
</li>
<li><a href="#check-the-latest-composer-version-available">Check the Latest Composer Version Available</a></li>
<li><a href="#update-composer-to-the-latest-version-optional">Update Composer to the Latest Version (Optional)</a></li>
<li><a href="#tldr">TL;DR</a></li>
<li><a href="#summary">Summary</a></li>
</ul>
<h2><a id="how-to-check-composer-version-windows-macos-and-linux" href="#how-to-check-composer-version-windows-macos-and-linux" class="" aria-hidden="true" title=""></a>How to Check Composer Version (Windows, macOS, and Linux)</h2>
<p>Composer is the most widely used dependency manager for PHP, and knowing which version you’re running is essential for compatibility, troubleshooting, and staying up to date with the latest features.
This quick guide shows you how to check your Composer version across different operating systems and how to verify the latest available release.</p>
<h2><a id="check-composer-version-using-the-command-line" href="#check-composer-version-using-the-command-line" class="" aria-hidden="true" title=""></a>Check Composer Version Using the Command Line</h2>
<p>The simplest way to check your Composer version is by running the following command in your terminal or command prompt:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #D19A66;">-V</span></div></code></pre>
<p>or equivalently:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #D19A66;">--version</span></div></code></pre>
<p><strong>Example output:</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">Composer version 2.7.7 2024-08-09 21:34:12</span></div></code></pre>
<p>Both commands work the same way. The version number (<code>2.7.7</code> in this example) and the release date will be shown in the output.</p>
<h2><a id="checking-composer-version-on-different-operating-systems" href="#checking-composer-version-on-different-operating-systems" class="" aria-hidden="true" title=""></a>Checking Composer Version on Different Operating Systems</h2>
<p>Composer is a cross-platform tool, so the command to check the version is identical everywhere. However, depending on your OS, the way you access your terminal differs slightly.</p>
<h3><a id="check-composer-version-in-windows" href="#check-composer-version-in-windows" class="" aria-hidden="true" title=""></a>Check composer version in Windows</h3>
<ol>
<li>
<p>Press <strong>Win + R</strong>, type <code>cmd</code>, and press <strong>Enter</strong> to open the Command Prompt.</p>
</li>
<li>
<p>Run:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #D19A66;">-V</span></div></code></pre>
<p>If you get an error like <code>'composer' is not recognized</code>, you may need to add Composer to your system’s PATH or run it via the full path, for example:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">C:</span><span style="color: #56B6C2;">\P</span><span style="color: #98C379;">rogramData</span><span style="color: #56B6C2;">\C</span><span style="color: #98C379;">omposerSetup</span><span style="color: #56B6C2;">\b</span><span style="color: #98C379;">in</span><span style="color: #56B6C2;">\c</span><span style="color: #98C379;">omposer.phar</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">-V</span></div></code></pre>
</li>
</ol>
<h3><a id="check-composer-version-in-macos" href="#check-composer-version-in-macos" class="" aria-hidden="true" title=""></a>Check composer version in macOS</h3>
<ol>
<li>
<p>Open <strong>Terminal</strong> (via Spotlight or Applications → Utilities → Terminal).</p>
</li>
<li>
<p>Run:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #D19A66;">--version</span></div></code></pre>
</li>
</ol>
<p>If Composer was installed globally using Homebrew or the official installer, the command should work immediately.</p>
<h3><a id="check-composer-version-in-linux-ubuntu-debian-fedora-etc" href="#check-composer-version-in-linux-ubuntu-debian-fedora-etc" class="" aria-hidden="true" title=""></a>Check composer version in Linux (Ubuntu, Debian, Fedora, etc.)</h3>
<ol>
<li>
<p>Open your terminal.</p>
</li>
<li>
<p>Run:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #D19A66;">-V</span></div></code></pre>
<p>If Composer isn’t installed globally, you might need to call it using <code>php</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">composer.phar</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">-V</span></div></code></pre>
</li>
</ol>
<h2><a id="check-the-latest-composer-version-available" href="#check-the-latest-composer-version-available" class="" aria-hidden="true" title=""></a>Check the Latest Composer Version Available</h2>
<p>To compare your local version against the latest release, you can run:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">self-update</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--dry-run</span></div></code></pre>
<p><strong>Example output:</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">You are already using the latest available Composer version 2.7.7 (stable channel).</span></div></code></pre>
<p>If an update is available, the command will show the newer version number instead of the confirmation message.</p>
<p>Alternatively, you can manually check the latest version by visiting:
👉 <a rel="nofollow noopener" target="_blank" href="https://getcomposer.org/download/">https://getcomposer.org/download/</a></p>
<h2><a id="update-composer-to-the-latest-version-optional" href="#update-composer-to-the-latest-version-optional" class="" aria-hidden="true" title=""></a>Update Composer to the Latest Version (Optional)</h2>
<p>If you find that your Composer version is outdated, you can easily update it by running:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">self-update</span></div></code></pre>
<p>To update to a specific version:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">self-update</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">2.7.7</span></div></code></pre>
<p>If you’re on Windows and installed Composer via the setup wizard, simply re-run the <a rel="nofollow noopener" target="_blank" href="https://getcomposer.org/download/">Composer-Setup.exe</a> file to upgrade.</p>
<h2><a id="tldr" href="#tldr" class="" aria-hidden="true" title=""></a>TL;DR</h2>
<table>
<thead>
<tr>
<th>Task</th>
<th>Command</th>
</tr>
</thead>
<tbody>
<tr>
<td>Check Composer version</td>
<td><code>composer -V</code> or <code>composer --version</code></td>
</tr>
<tr>
<td>Check latest version available</td>
<td><code>composer self-update --dry-run</code></td>
</tr>
<tr>
<td>Update Composer</td>
<td><code>composer self-update</code></td>
</tr>
<tr>
<td>Update to a specific version</td>
<td><code>composer self-update &lt;version&gt;</code></td>
</tr>
</tbody>
</table>
<h2><a id="summary" href="#summary" class="" aria-hidden="true" title=""></a>Summary</h2>
<p>To check your Composer version, simply run <code>composer -V</code> in your terminal, it works the same on Windows, macOS, and Linux. Use <code>composer self-update --dry-run</code> to see if you’re up to date, and <code>composer self-update</code> to upgrade when needed.
Keeping Composer current ensures better performance, security, and access to the latest PHP ecosystem improvements.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 21 Oct 2025 18:13:51 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Composer: Install specific PHP package version]]></title>
                <link>https://nabilhassen.com/composer-require-specific-version</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#tldr">TL;DR</a></li>
<li><a href="#how-to-install-a-specific-php-package-version-using-composer">How to Install a Specific PHP Package Version Using Composer</a></li>
<li><a href="#basic-syntax">Basic Syntax</a></li>
<li><a href="#installing-a-version-constraint">Installing a Version Constraint</a>
<ul>
<li><a href="#common-examples">Common examples:</a></li>
</ul>
</li>
<li><a href="#installing-without-updating-other-packages">Installing Without Updating Other Packages</a></li>
<li><a href="#editing-composerjson-manually">Editing composer.json Manually</a></li>
<li><a href="#checking-available-versions">Checking Available Versions</a></li>
<li><a href="#downgrading-a-package">Downgrading a Package</a></li>
<li><a href="#installing-a-specific-version-globally">Installing a Specific Version Globally</a></li>
<li><a href="#verifying-installed-version">Verifying Installed Version</a></li>
<li><a href="#summary">Summary</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="tldr" href="#tldr" class="" aria-hidden="true" title=""></a>TL;DR</h2>
<p>To install a specific package version using Composer:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">require</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">vendor/package:version</span></div></code></pre>
<h2><a id="how-to-install-a-specific-php-package-version-using-composer" href="#how-to-install-a-specific-php-package-version-using-composer" class="" aria-hidden="true" title=""></a>How to Install a Specific PHP Package Version Using Composer</h2>
<p>When working on PHP projects, you may need to install a particular version of a package, either to maintain compatibility with your existing codebase or to match a production environment. Composer makes this simple with version constraints.</p>
<p>This guide covers <strong>all the correct and reliable ways</strong> to install a specific version of a package using Composer.</p>
<h2><a id="basic-syntax" href="#basic-syntax" class="" aria-hidden="true" title=""></a>Basic Syntax</h2>
<p>The most direct way to install a specific package version is:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">require</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">vendor/package:version</span></div></code></pre>
<p>Replace:</p>
<ul>
<li><code>vendor/package</code> with the actual package name (for example, <code>laravel/framework</code>)</li>
<li><code>version</code> with the version number you want to install.</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">require</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">monolog/monolog:2.9.1</span></div></code></pre>
<p>This installs exactly version <code>2.9.1</code> of Monolog.</p>
<p>Composer will update your <code>composer.json</code> file like this:</p>
<pre><code data-theme="one-dark-pro" data-lang="json" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #98C379;">&quot;require&quot;</span><span style="color: #ABB2BF;">: {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">&quot;monolog/monolog&quot;</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">&quot;2.9.1&quot;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>and automatically update your <code>composer.lock</code> file and install the package.</p>
<h2><a id="installing-a-version-constraint" href="#installing-a-version-constraint" class="" aria-hidden="true" title=""></a>Installing a Version Constraint</h2>
<p>Composer also allows flexible version constraints instead of a single fixed version. This is useful if you want to stay within a major or minor release line.</p>
<h3><a id="common-examples" href="#common-examples" class="" aria-hidden="true" title=""></a>Common examples:</h3>
<table>
<thead>
<tr>
<th>Constraint</th>
<th>Meaning</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>1.5.*</code></td>
<td>Any version starting with <code>1.5</code></td>
<td><code>composer require guzzlehttp/guzzle:1.5.*</code></td>
</tr>
<tr>
<td><code>^1.5</code></td>
<td>Any version <code>&gt;=1.5.0</code> but <code>&lt;2.0.0</code></td>
<td><code>composer require guzzlehttp/guzzle:^1.5</code></td>
</tr>
<tr>
<td><code>~1.5</code></td>
<td>Any version <code>&gt;=1.5.0</code> but <code>&lt;2.0.0</code>, allowing minor updates</td>
<td><code>composer require guzzlehttp/guzzle:~1.5</code></td>
</tr>
<tr>
<td><code>&gt;=1.5</code></td>
<td>Version <code>1.5</code> or higher</td>
<td><code>composer require guzzlehttp/guzzle:&gt;=1.5</code></td>
</tr>
<tr>
<td><code>1.5 - 2.0</code></td>
<td>Any version between <code>1.5</code> and <code>2.0</code> inclusive</td>
<td><code>composer require guzzlehttp/guzzle:&quot;1.5 - 2.0&quot;</code></td>
</tr>
</tbody>
</table>
<h2><a id="installing-without-updating-other-packages" href="#installing-without-updating-other-packages" class="" aria-hidden="true" title=""></a>Installing Without Updating Other Packages</h2>
<p>By default, <code>composer require</code> may trigger dependency updates.
If you want to install a specific version <strong>without updating other packages</strong>, use the <code>--no-update</code> flag:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">require</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">monolog/monolog:2.9.1</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--no-update</span></div></code></pre>
<p>This adds the requirement to <code>composer.json</code> but doesn’t install or update anything yet.</p>
<p>You can then run:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">update</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">monolog/monolog</span></div></code></pre>
<p>to install just that package according to your version constraint.</p>
<h2><a id="editing-composerjson-manually" href="#editing-composerjson-manually" class="" aria-hidden="true" title=""></a>Editing <code>composer.json</code> Manually</h2>
<p>Another approach is to manually specify the version constraint in <code>composer.json</code>, then run <code>composer update</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="json" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #98C379;">&quot;require&quot;</span><span style="color: #ABB2BF;">: {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">&quot;monolog/monolog&quot;</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">&quot;^2.8&quot;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Then install:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">update</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">monolog/monolog</span></div></code></pre>
<h2><a id="checking-available-versions" href="#checking-available-versions" class="" aria-hidden="true" title=""></a>Checking Available Versions</h2>
<p>If you’re unsure which versions are available for a package, run:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">show</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">vendor/package</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--all</span></div></code></pre>
<p>Example:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">show</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">monolog/monolog</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--all</span></div></code></pre>
<p>This displays all available versions, release dates, and dependencies, helping you choose the correct one before installation.</p>
<h2><a id="downgrading-a-package" href="#downgrading-a-package" class="" aria-hidden="true" title=""></a>Downgrading a Package</h2>
<p>To downgrade, simply require an older version:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">require</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">monolog/monolog:2.4.0</span></div></code></pre>
<p>Composer will resolve dependencies and adjust your <code>composer.lock</code> file accordingly.
If a newer version is already installed, Composer will automatically downgrade it.</p>
<h2><a id="installing-a-specific-version-globally" href="#installing-a-specific-version-globally" class="" aria-hidden="true" title=""></a>Installing a Specific Version Globally</h2>
<p>To install a specific version of a global Composer package (e.g., a CLI tool):</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">global</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">require</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">laravel/installer:^5.3</span></div></code></pre>
<p>You can verify it by running:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">global</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">show</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">laravel/installer</span></div></code></pre>
<h2><a id="verifying-installed-version" href="#verifying-installed-version" class="" aria-hidden="true" title=""></a>Verifying Installed Version</h2>
<p>To confirm the installed version of any package, run:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">show</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">vendor/package</span></div></code></pre>
<p>Example:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">show</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">monolog/monolog</span></div></code></pre>
<p>Output includes the exact installed version and metadata.</p>
<h2><a id="summary" href="#summary" class="" aria-hidden="true" title=""></a>Summary</h2>
<p>Here’s a quick reference for installing specific versions:</p>
<table>
<thead>
<tr>
<th>Task</th>
<th>Command</th>
</tr>
</thead>
<tbody>
<tr>
<td>Install an exact version</td>
<td><code>composer require vendor/package:1.2.3</code></td>
</tr>
<tr>
<td>Install a version constraint</td>
<td><code>composer require vendor/package:^1.2</code></td>
</tr>
<tr>
<td>Avoid updating other dependencies</td>
<td><code>composer require vendor/package:1.2.3 --no-update</code></td>
</tr>
<tr>
<td>Install globally</td>
<td><code>composer global require vendor/package:^1.2</code></td>
</tr>
<tr>
<td>Check available versions</td>
<td><code>composer show vendor/package --all</code></td>
</tr>
</tbody>
</table>
<hr />
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>Installing a specific PHP package version with Composer is straightforward but essential for maintaining stability and compatibility across environments. Whether you’re locking to an exact version or defining flexible constraints, Composer gives you full control over dependency management efficiently, predictably, and with precision.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Thu, 16 Oct 2025 19:25:05 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Searching in a multidimensional array in PHP]]></title>
                <link>https://nabilhassen.com/php-search-multidimensional-array</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#mastering-multidimensional-array-search-in-php">Mastering multidimensional array search in PHP</a></li>
<li><a href="#1-arraycolumn--arraysearch">1. array_column() + array_search()</a></li>
<li><a href="#2-foreach-loop">2. foreach loop</a></li>
<li><a href="#3-arrayfilter">3. array_filter()</a></li>
<li><a href="#4-recursive-search-for-deeply-nested-arrays-by-keyvalue">4. Recursive search for deeply nested arrays (by key/value)</a></li>
<li><a href="#5-recursive-search-by-value-only-any-key">5. Recursive Search by Value Only (Any Key)</a></li>
<li><a href="#6-searching-by-multiple-conditions">6. Searching by Multiple Conditions</a></li>
<li><a href="#performance--best-practices">Performance &amp; best practices</a></li>
<li><a href="#summary-table">Summary table</a></li>
</ul>
<h2><a id="mastering-multidimensional-array-search-in-php" href="#mastering-multidimensional-array-search-in-php" class="" aria-hidden="true" title=""></a>Mastering multidimensional array search in PHP</h2>
<p>Searching in a multidimensional array is a common task in PHP when working with structured data like API responses, configuration arrays, or datasets. In this article, we’ll cover all practical methods to search in a multidimensional array efficiently and accurately.</p>
<h2><a id="1-arraycolumn--arraysearch" href="#1-arraycolumn--arraysearch" class="" aria-hidden="true" title=""></a>1. <code>array_column()</code> + <code>array_search()</code></h2>
<p>Use when you have an array of associative arrays and you want the first match by a specific column.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">    [</span><span style="color: #98C379;">&#39;id&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Alice&#39;</span><span style="color: #ABB2BF;">],</span></div><div class='line'><span style="color: #ABB2BF;">    [</span><span style="color: #98C379;">&#39;id&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">2</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Bob&#39;</span><span style="color: #ABB2BF;">],</span></div><div class='line'><span style="color: #ABB2BF;">    [</span><span style="color: #98C379;">&#39;id&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">3</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Charlie&#39;</span><span style="color: #ABB2BF;">],</span></div><div class='line'><span style="color: #ABB2BF;">];</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// get the numeric key of the first element whose &#39;name&#39; === &#39;Bob&#39;</span></div><div class='line'><span style="color: #E06C75;">$keys</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">array_column</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$key</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">array_search</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;Bob&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$keys</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">true</span><span style="color: #ABB2BF;">); </span><span style="color: #7F848E;">// use strict mode when you care about types</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$key</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">!==</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">false</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;User found: ID &quot;</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;">[</span><span style="color: #E06C75;">$key</span><span style="color: #ABB2BF;">][</span><span style="color: #98C379;">&#39;id&#39;</span><span style="color: #ABB2BF;">];</span></div><div class='line'><span style="color: #ABB2BF;">} </span><span style="color: #C678DD;">else</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;User not found.&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Notes:</p>
<ul>
<li><code>array_column()</code> extracts a value column from the input; optionally you can provide a third parameter to index the returned array by another column.</li>
<li><code>array_search()</code> returns the first matching key or <code>false</code> if not found; use the third (<code>$strict</code>) parameter to force <code>===</code> comparison.</li>
</ul>
<h2><a id="2-foreach-loop" href="#2-foreach-loop" class="" aria-hidden="true" title=""></a>2. <code>foreach</code> loop</h2>
<p>When you need to search by multiple criteria or across multiple levels, a simple loop gives full control.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$products</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">    [</span><span style="color: #98C379;">&#39;id&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">10</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Laptop&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;category&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Electronics&#39;</span><span style="color: #ABB2BF;">],</span></div><div class='line'><span style="color: #ABB2BF;">    [</span><span style="color: #98C379;">&#39;id&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">11</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Desk&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;category&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Furniture&#39;</span><span style="color: #ABB2BF;">],</span></div><div class='line'><span style="color: #ABB2BF;">    [</span><span style="color: #98C379;">&#39;id&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">12</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Chair&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;category&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Furniture&#39;</span><span style="color: #ABB2BF;">],</span></div><div class='line'><span style="color: #ABB2BF;">];</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$result</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">foreach</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$products</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">as</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$product</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$product</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;id&#39;</span><span style="color: #ABB2BF;">] </span><span style="color: #56B6C2;">===</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">11</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$result</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$product</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">break</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$result</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;Product found: {</span><span style="color: #E06C75;">$result</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">]</span><span style="color: #98C379;">}&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">} </span><span style="color: #C678DD;">else</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;Product not found.&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>This approach is most flexible, you can add complex conditions, nested checks, or partial matches. It’s also easier to debug.</p>
<h2><a id="3-arrayfilter" href="#3-arrayfilter" class="" aria-hidden="true" title=""></a>3. <code>array_filter()</code></h2>
<p><code>array_filter()</code> returns all elements for which the callback returns <code>true</code>. Keys are preserved; use <code>array_values()</code> to reindex if you want a zero-based result array.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$itEmployees</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">array_filter</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$employees</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$employee</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #C678DD;">return</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">isset</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$employee</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;department&#39;</span><span style="color: #ABB2BF;">])</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">&amp;&amp;</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$employee</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;department&#39;</span><span style="color: #ABB2BF;">]</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">===</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;IT&#39;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div></code></pre>
<p><code>array_filter()</code> accepts an optional mode to pass keys to the callback; it preserves keys by default.</p>
<h2><a id="4-recursive-search-for-deeply-nested-arrays-by-keyvalue" href="#4-recursive-search-for-deeply-nested-arrays-by-keyvalue" class="" aria-hidden="true" title=""></a>4. Recursive search for deeply nested arrays (by key/value)</h2>
<p>When the structure depth is unpredictable, use a recursive function that examines each level. This example returns the first matching <em>container</em> (associative array) that contains a given <code>key =&gt; value</code> pair.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">searchArrayByKeyValue</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">array</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$haystack</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">string</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$key</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">foreach</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$haystack</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">as</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$element</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">!is_array</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$element</span><span style="color: #ABB2BF;">)) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #C678DD;">continue</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">        }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">array_key_exists</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$key</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$element</span><span style="color: #ABB2BF;">) </span><span style="color: #56B6C2;">&amp;&amp;</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$element</span><span style="color: #ABB2BF;">[</span><span style="color: #E06C75;">$key</span><span style="color: #ABB2BF;">] </span><span style="color: #56B6C2;">===</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$element</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">        }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// Recurse into nested arrays</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$found</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">searchArrayByKeyValue</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$element</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$key</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$found</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">!==</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$found</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">        }</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Implementation notes:</p>
<ul>
<li>Use <code>array_key_exists()</code> when you need to detect keys that exist with <code>null</code> values. Use <code>isset()</code> for non-null checks.</li>
<li>Use strict comparisons (<code>===</code>) unless you intentionally want type coercion.</li>
</ul>
<h2><a id="5-recursive-search-by-value-only-any-key" href="#5-recursive-search-by-value-only-any-key" class="" aria-hidden="true" title=""></a>5. Recursive Search by Value Only (Any Key)</h2>
<p>To check whether a scalar value exists anywhere in a multidimensional structure:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">inMultiArray</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$needle</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">array</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$haystack</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">bool</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">foreach</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$haystack</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">as</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">is_array</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">)) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #61AFEF;">inMultiArray</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$needle</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">)) {</span></div><div class='line'><span style="color: #ABB2BF;">                </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">true</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">            }</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #C678DD;">continue</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">        }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">===</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$needle</span><span style="color: #ABB2BF;">) { </span><span style="color: #7F848E;">// strict comparison</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">true</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">        }</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">false</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$array</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">    [</span><span style="color: #98C379;">&#39;x&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">2</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">3</span><span style="color: #ABB2BF;">]],</span></div><div class='line'><span style="color: #ABB2BF;">    [</span><span style="color: #98C379;">&#39;y&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span><span style="color: #D19A66;">4</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">5</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">6</span><span style="color: #ABB2BF;">]],</span></div><div class='line'><span style="color: #ABB2BF;">];</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">var_dump</span><span style="color: #ABB2BF;">(</span><span style="color: #61AFEF;">inMultidimensionalArray</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">5</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$array</span><span style="color: #ABB2BF;">)); </span><span style="color: #7F848E;">// true</span></div></code></pre>
<p>If you only need to test top-level values, prefer <code>in_array()</code> with the <code>$strict</code> flag. For deep structures use recursion.</p>
<h2><a id="6-searching-by-multiple-conditions" href="#6-searching-by-multiple-conditions" class="" aria-hidden="true" title=""></a>6. Searching by Multiple Conditions</h2>
<p>You can combine checks inside <code>array_filter()</code> or loops. Example using <code>array_filter()</code> to find students with <code>grade === 'A'</code> and <code>age === 18</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$students</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">    [</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Sara&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;grade&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;A&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;age&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">17</span><span style="color: #ABB2BF;">],</span></div><div class='line'><span style="color: #ABB2BF;">    [</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Tom&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;grade&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;B&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;age&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">18</span><span style="color: #ABB2BF;">],</span></div><div class='line'><span style="color: #ABB2BF;">    [</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Liam&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;grade&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;A&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;age&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">18</span><span style="color: #ABB2BF;">],</span></div><div class='line'><span style="color: #ABB2BF;">];</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$result</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">array_filter</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$students</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$student</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #C678DD;">return</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$student</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;grade&#39;</span><span style="color: #ABB2BF;">]</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">===</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;A&#39;</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">&amp;&amp;</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$student</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;age&#39;</span><span style="color: #ABB2BF;">]</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">===</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">18</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">print_r</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$result</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<h2><a id="performance--best-practices" href="#performance--best-practices" class="" aria-hidden="true" title=""></a>Performance &amp; best practices</h2>
<ul>
<li>Built-in functions (<code>array_column</code>, <code>array_search</code>, <code>array_filter</code>) are implemented in C and are often faster and clearer than equivalent PHP loops. Use them when applicable.</li>
<li>Prefer <code>===</code>/strict comparisons when comparing values from external sources to avoid surprising matches.</li>
<li><code>array_filter()</code> preserves keys, call <code>array_values()</code> if you rely on numeric, contiguous indexes.</li>
<li>For very large datasets consider using generators (<code>yield</code>) or streaming approaches rather than loading everything into memory.</li>
</ul>
<h2><a id="summary-table" href="#summary-table" class="" aria-hidden="true" title=""></a>Summary table</h2>
<table>
<thead>
<tr>
<th>Task</th>
<th align="right">Recommended approach</th>
</tr>
</thead>
<tbody>
<tr>
<td>Single-match by column (one level)</td>
<td align="right"><code>array_column()</code> + <code>array_search()</code></td>
</tr>
<tr>
<td>All matches with condition</td>
<td align="right"><code>array_filter()</code> (then <code>array_values()</code> if needed)</td>
</tr>
<tr>
<td>Complex/multi-field logic</td>
<td align="right"><code>foreach</code> with <code>break</code>/<code>continue</code></td>
</tr>
<tr>
<td>Unknown depth search by key/value</td>
<td align="right">Recursive search function</td>
</tr>
<tr>
<td>Value exists anywhere</td>
<td align="right">Recursive <code>inMultiArray()</code> or <code>in_array()</code> for shallow arrays</td>
</tr>
</tbody>
</table>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Wed, 15 Oct 2025 21:04:25 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Failover Queue Driver in Laravel 12.34]]></title>
                <link>https://nabilhassen.com/laravel-failover-queue-driver</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#failover-queue-driver">Failover Queue Driver</a></li>
<li><a href="#how-the-failover-queue-driver-works">How the Failover Queue Driver Works</a></li>
<li><a href="#defining-a-failover-queue-connection">Defining a Failover Queue Connection</a></li>
<li><a href="#setting-the-default-queue-connection">Setting the Default Queue Connection</a></li>
<li><a href="#when-to-use-the-failover-driver">When to Use the Failover Driver</a></li>
<li><a href="#summary">Summary</a></li>
</ul>
<h2><a id="failover-queue-driver" href="#failover-queue-driver" class="" aria-hidden="true" title=""></a>Failover Queue Driver</h2>
<p>In Laravel 12.34, a new <strong>failover queue driver</strong> has been introduced to improve reliability when processing jobs. It allows you to define multiple queue connections in order of priority. If the first connection fails, Laravel automatically attempts to push the job to the next available connection.</p>
<p>This feature is particularly useful in production environments where uptime and job delivery are critical.</p>
<h2><a id="how-the-failover-queue-driver-works" href="#how-the-failover-queue-driver-works" class="" aria-hidden="true" title=""></a>How the Failover Queue Driver Works</h2>
<p>The failover driver acts as a wrapper around multiple queue connections. When a job is dispatched, Laravel will attempt to push it onto the first connection. If that connection fails, it will automatically try the next one in the list until it succeeds or exhausts all configured connections.</p>
<p>This ensures that jobs are not lost if the main queue system (e.g., Redis) goes down temporarily.</p>
<h2><a id="defining-a-failover-queue-connection" href="#defining-a-failover-queue-connection" class="" aria-hidden="true" title=""></a>Defining a Failover Queue Connection</h2>
<p>You can configure the failover driver in your <code>config/queue.php</code> file. Here’s a basic example:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #98C379;">&#39;connections&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;failover&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;driver&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;failover&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;connections&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #98C379;">&#39;redis&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #98C379;">&#39;database&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        ],</span></div><div class='line'><span style="color: #ABB2BF;">    ],</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;redis&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;driver&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;redis&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;connection&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;default&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;queue&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #61AFEF;">env</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;REDIS_QUEUE&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;default&#39;</span><span style="color: #ABB2BF;">),</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;retry_after&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">90</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ],</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;database&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;driver&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;database&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;table&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;jobs&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;queue&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;default&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;retry_after&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">90</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ],</span></div><div class='line'><span style="color: #ABB2BF;">],</span></div></code></pre>
<p>In this example:</p>
<ul>
<li>Laravel will first try to push jobs to the <strong>Redis</strong> queue.</li>
<li>If Redis is unavailable, it will fall back to the <strong>database</strong> queue.</li>
</ul>
<h2><a id="setting-the-default-queue-connection" href="#setting-the-default-queue-connection" class="" aria-hidden="true" title=""></a>Setting the Default Queue Connection</h2>
<p>After defining your failover driver, you can set it as the default queue connection in your <code>.env</code> file:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">QUEUE_CONNECTION=failover</span></div></code></pre>
<p>This ensures all queued jobs will use the failover logic automatically.</p>
<h2><a id="when-to-use-the-failover-driver" href="#when-to-use-the-failover-driver" class="" aria-hidden="true" title=""></a>When to Use the Failover Driver</h2>
<p>The failover queue driver is ideal for:</p>
<ul>
<li>Applications where <strong>job reliability</strong> is essential.</li>
<li>Systems with <strong>multiple queue backends</strong> (e.g., Redis, SQS, and database).</li>
<li><strong>High-availability</strong> environments where downtime of one queue system should not interrupt job processing.</li>
</ul>
<h2><a id="summary" href="#summary" class="" aria-hidden="true" title=""></a>Summary</h2>
<p>Laravel’s failover queue driver ensures uninterrupted job dispatching by gracefully falling back to backup connections when the primary one fails. Configuring it takes only a few lines, yet it provides a significant boost in resilience for production applications.</p>
<p>For more details, refer to the <a rel="nofollow noopener" target="_blank" href="https://laravel.com/docs/12.x/queues#queue-failover">official Laravel queue failover documentation</a> and the <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/57341">framework pull request #57341</a>.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Wed, 15 Oct 2025 20:00:34 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Log File in Laravel: Location and Common Fixes]]></title>
                <link>https://nabilhassen.com/laravel-log-file</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#understanding-laravel-log-files-location-common-issues-and-best-practices">Understanding Laravel Log Files: Location, Common Issues, and Best Practices</a></li>
<li><a href="#log-file-location-and-path-in-laravel">Log File Location and Path in Laravel</a></li>
<li><a href="#fixing-permission-denied-issues">Fixing Permission Denied Issues</a>
<ul>
<li><a href="#solution">Solution:</a></li>
</ul>
</li>
<li><a href="#what-to-do-when-the-log-file-is-missing">What to Do When the Log File Is Missing</a>
<ul>
<li><a href="#to-fix-this">To fix this:</a></li>
</ul>
</li>
<li><a href="#fixing-the-could-not-be-opened-in-append-mode-error">Fixing the “Could Not Be Opened in Append Mode” Error</a>
<ul>
<li><a href="#steps-to-fix">Steps to Fix:</a></li>
</ul>
</li>
<li><a href="#configuring-laravel-to-create-a-log-file-per-day">Configuring Laravel to Create a Log File Per Day</a></li>
<li><a href="#creating-a-custom-daily-log-channel">Creating a Custom Daily Log Channel</a></li>
<li><a href="#verifying-your-log-setup">Verifying Your Log Setup</a></li>
<li><a href="#summary">Summary</a></li>
<li><a href="#final-thoughts">Final Thoughts</a></li>
</ul>
<h2><a id="understanding-laravel-log-files-location-common-issues-and-best-practices" href="#understanding-laravel-log-files-location-common-issues-and-best-practices" class="" aria-hidden="true" title=""></a>Understanding Laravel Log Files: Location, Common Issues, and Best Practices</h2>
<p>Logging is one of the most essential parts of any Laravel application. It helps you track errors, monitor system behavior, and debug effectively. Laravel uses the powerful <strong>Monolog</strong> library under the hood, offering flexible and configurable logging.</p>
<p>In this guide, we'll cover everything you need to know about Laravel log files including their location, how to resolve permission errors, what to do when logs are missing, and how to configure Laravel to create a log file per day.</p>
<h2><a id="log-file-location-and-path-in-laravel" href="#log-file-location-and-path-in-laravel" class="" aria-hidden="true" title=""></a>Log File Location and Path in Laravel</h2>
<p>By default, Laravel stores its log files inside the <code>storage/logs</code> directory. The most common file you’ll see is:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">storage/logs/laravel.log</span></div></code></pre>
<p>This is where all application logs are written unless configured otherwise.</p>
<p>You can confirm your current log configuration by checking the <code>config/logging.php</code> file. The default channel is typically set to <code>stack</code>, which includes one or more underlying channels such as <code>single</code> or <code>daily</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// config/logging.php</span></div><div class='line'><span style="color: #98C379;">&#39;default&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #61AFEF;">env</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;LOG_CHANNEL&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;stack&#39;</span><span style="color: #ABB2BF;">),</span></div></code></pre>
<p>Then, inspect the <code>stack</code> channel to see which log channels it includes:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #98C379;">&#39;stack&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;driver&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;stack&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;channels&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span><span style="color: #98C379;">&#39;single&#39;</span><span style="color: #ABB2BF;">], </span><span style="color: #7F848E;">// or [&#39;daily&#39;] depending on your setup</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;ignore_exceptions&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">false</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">],</span></div></code></pre>
<p>To verify the actual file in use, check the configuration for your target driver. For example, for the <code>single</code> driver:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #98C379;">&#39;single&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;driver&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;single&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;path&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #61AFEF;">storage_path</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;logs/laravel.log&#39;</span><span style="color: #ABB2BF;">),</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;level&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #61AFEF;">env</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;LOG_LEVEL&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;debug&#39;</span><span style="color: #ABB2BF;">),</span></div><div class='line'><span style="color: #ABB2BF;">],</span></div></code></pre>
<h2><a id="fixing-permission-denied-issues" href="#fixing-permission-denied-issues" class="" aria-hidden="true" title=""></a>Fixing Permission Denied Issues</h2>
<p>If you see an error such as:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">Could not open stream: Permission denied</span></div></code></pre>
<p>it means Laravel does not have permission to write to the log file or the <code>storage/logs</code> directory.</p>
<h3><a id="solution" href="#solution" class="" aria-hidden="true" title=""></a><strong>Solution:</strong></h3>
<p>Ensure your web server user (e.g., <code>www-data</code> on Ubuntu) has write permissions to the <code>storage</code> directory.</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">sudo </span><span style="color: #98C379;">chown</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">-R</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">www-data:www-data</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">storage</span></div><div class='line'><span style="color: #ABB2BF;">sudo </span><span style="color: #98C379;">chmod</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">-R</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">775</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">storage</span></div></code></pre>
<p>If you’re on macOS or Windows, make sure your local environment user has equivalent write access.</p>
<blockquote>
<p>⚠️ <strong>Tip:</strong> Never use <code>chmod -R 777</code> in production unless temporarily necessary. It grants full access to everyone and poses a security risk.</p>
</blockquote>
<p>If permission changes don’t take effect, remember to clear your cached configuration:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">config:clear</span></div><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">cache:clear</span></div></code></pre>
<h2><a id="what-to-do-when-the-log-file-is-missing" href="#what-to-do-when-the-log-file-is-missing" class="" aria-hidden="true" title=""></a>What to Do When the Log File Is Missing</h2>
<p>Sometimes, your <code>laravel.log</code> file may not exist often because it was deleted or Laravel hasn’t written to it yet.</p>
<h3><a id="to-fix-this" href="#to-fix-this" class="" aria-hidden="true" title=""></a><strong>To fix this:</strong></h3>
<ol>
<li>
<p>Manually create the file:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">touch </span><span style="color: #98C379;">storage/logs/laravel.log</span></div></code></pre>
</li>
<li>
<p>Ensure correct permissions:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">sudo </span><span style="color: #98C379;">chown</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">www-data:www-data</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">storage/logs/laravel.log</span></div><div class='line'><span style="color: #ABB2BF;">sudo </span><span style="color: #98C379;">chmod</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">664</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">storage/logs/laravel.log</span></div></code></pre>
</li>
<li>
<p>Try logging a test message:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">Log</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">info</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;Laravel log test message&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
</li>
</ol>
<p>If everything is configured correctly, Laravel will now start writing to the log file automatically.</p>
<hr />
<h2><a id="fixing-the-could-not-be-opened-in-append-mode-error" href="#fixing-the-could-not-be-opened-in-append-mode-error" class="" aria-hidden="true" title=""></a>Fixing the “Could Not Be Opened in Append Mode” Error</h2>
<p>This error typically looks like this:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">ErrorException: file_put_contents(/path/to/storage/logs/laravel.log): Failed to open stream: Permission denied</span></div></code></pre>
<p>It happens when Laravel tries to write logs but can’t append to the file usually due to missing permissions or directory ownership.</p>
<h3><a id="steps-to-fix" href="#steps-to-fix" class="" aria-hidden="true" title=""></a><strong>Steps to Fix:</strong></h3>
<ol>
<li>
<p>Check directory and file permissions:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">ls </span><span style="color: #D19A66;">-ld</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">storage/logs</span></div><div class='line'><span style="color: #ABB2BF;">ls </span><span style="color: #D19A66;">-l</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">storage/logs/</span></div></code></pre>
</li>
<li>
<p>Adjust permissions and ownership as needed:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">sudo </span><span style="color: #98C379;">chown</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">-R</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">www-data:www-data</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">storage/logs</span></div><div class='line'><span style="color: #ABB2BF;">sudo </span><span style="color: #98C379;">chmod</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">-R</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">775</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">storage/logs</span></div></code></pre>
</li>
<li>
<p>If the problem persists, safely recreate the log file (only if no critical writes are happening):</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">rm </span><span style="color: #98C379;">storage/logs/laravel.log</span></div><div class='line'><span style="color: #ABB2BF;">touch </span><span style="color: #98C379;">storage/logs/laravel.log</span></div><div class='line'><span style="color: #ABB2BF;">sudo </span><span style="color: #98C379;">chown</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">www-data:www-data</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">storage/logs/laravel.log</span></div></code></pre>
</li>
</ol>
<p>After this, reload your application, Laravel will resume logging as usual.</p>
<h2><a id="configuring-laravel-to-create-a-log-file-per-day" href="#configuring-laravel-to-create-a-log-file-per-day" class="" aria-hidden="true" title=""></a>Configuring Laravel to Create a Log File Per Day</h2>
<p>For better organization, Laravel supports <strong>daily log rotation</strong>. This means a new log file is created each day, making it easier to manage and review logs.</p>
<p>To enable daily logging, open <code>config/logging.php</code> and set your default log channel to <code>daily</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #98C379;">&#39;default&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #61AFEF;">env</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;LOG_CHANNEL&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;daily&#39;</span><span style="color: #ABB2BF;">),</span></div></code></pre>
<p>Then, locate and configure the <code>daily</code> channel:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #98C379;">&#39;daily&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;driver&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;daily&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;path&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #61AFEF;">storage_path</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;logs/laravel.log&#39;</span><span style="color: #ABB2BF;">),</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;level&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #61AFEF;">env</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;LOG_LEVEL&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;debug&#39;</span><span style="color: #ABB2BF;">),</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;days&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">14</span><span style="color: #ABB2BF;">, </span><span style="color: #7F848E;">// Keep logs for 14 days</span></div><div class='line'><span style="color: #ABB2BF;">],</span></div></code></pre>
<p>You can adjust the <code>days</code> value to control how long Laravel keeps old log files before deleting them. Setting <code>days</code> to <code>0</code> disables automatic deletion.</p>
<p>When configured, Laravel will automatically generate files like:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">storage/logs/laravel-2025-10-09.log</span></div><div class='line'><span style="color: #abb2bf;">storage/logs/laravel-2025-10-10.log</span></div></code></pre>
<p>If you change the <code>LOG_CHANNEL</code> in your <code>.env</code>, run:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">config:cache</span></div></code></pre>
<h2><a id="creating-a-custom-daily-log-channel" href="#creating-a-custom-daily-log-channel" class="" aria-hidden="true" title=""></a>Creating a Custom Daily Log Channel</h2>
<p>If you need separate log files (for example, one for payment operations), define a custom channel in <code>config/logging.php</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #98C379;">&#39;channels&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;payments&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;driver&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;daily&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;path&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #61AFEF;">storage_path</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;logs/payments.log&#39;</span><span style="color: #ABB2BF;">),</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;level&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;info&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;days&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">30</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ],</span></div><div class='line'><span style="color: #ABB2BF;">],</span></div></code></pre>
<p>Then use it in your code:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">Log</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">channel</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;payments&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">info</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;Payment processed successfully.&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<h2><a id="verifying-your-log-setup" href="#verifying-your-log-setup" class="" aria-hidden="true" title=""></a>Verifying Your Log Setup</h2>
<p>After making changes, test your logging configuration:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">Log</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">info</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;Daily log configuration verified successfully.&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>Then check your <code>storage/logs</code> directory, you should see a newly created log file for today.</p>
<p>You can also access the underlying Monolog instance if needed:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$monolog</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Log</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">getLogger</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h2><a id="summary" href="#summary" class="" aria-hidden="true" title=""></a>Summary</h2>
<table>
<thead>
<tr>
<th>Task</th>
<th>Command or File</th>
</tr>
</thead>
<tbody>
<tr>
<td>Default log path</td>
<td><code>storage/logs/laravel.log</code></td>
</tr>
<tr>
<td>Check config</td>
<td><code>config/logging.php</code></td>
</tr>
<tr>
<td>Fix permissions</td>
<td><code>sudo chown -R www-data:www-data storage &amp;&amp; sudo chmod -R 775 storage</code></td>
</tr>
<tr>
<td>Create missing log file</td>
<td><code>touch storage/logs/laravel.log</code></td>
</tr>
<tr>
<td>Enable daily logs</td>
<td><code>'default' =&gt; 'daily'</code> in <code>config/logging.php</code></td>
</tr>
<tr>
<td>Clear config cache</td>
<td><code>php artisan config:clear</code> / <code>php artisan config:cache</code></td>
</tr>
</tbody>
</table>
<h2><a id="final-thoughts" href="#final-thoughts" class="" aria-hidden="true" title=""></a>Final Thoughts</h2>
<p>Laravel’s logging system is robust and highly configurable. By knowing where logs are stored, how to handle permission issues, and how to configure daily or custom channels, you’ll have full control over how your application records information. This ensures cleaner debugging, easier maintenance, and reliable monitoring across all environments.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Thu, 09 Oct 2025 21:23:52 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Install Tailwind CSS in Laravel using Vite or Mix]]></title>
                <link>https://nabilhassen.com/laravel-install-tailwind-css</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#how-to-install-tailwind-css-in-laravel-vite--mix">How to install Tailwind CSS in Laravel (Vite &amp; Mix)</a></li>
<li><a href="#quick-overview">Quick overview</a></li>
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#1-install-tailwind-common-steps">1. Install Tailwind (common steps)</a></li>
<li><a href="#2-tailwind-config-template-paths">2. Tailwind config (template paths)</a></li>
<li><a href="#3-add-tailwind-directives-to-your-css">3. Add Tailwind directives to your CSS</a></li>
<li><a href="#4-vite-laravel-9-10-11-recommended">4. Vite (Laravel 9, 10, 11 recommended)</a></li>
<li><a href="#5-laravel-mix-laravel-8-and-older">5. Laravel Mix (Laravel 8 and older)</a></li>
<li><a href="#6-postcssconfigjs-what--p-creates">6. postcss.config.js (what -p creates)</a></li>
<li><a href="#7-quick-verification--troubleshooting">7. Quick verification &amp; troubleshooting</a></li>
<li><a href="#8-blade-test-snippet-quick-smoke-test">8. Blade test snippet (quick smoke test)</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="how-to-install-tailwind-css-in-laravel-vite--mix" href="#how-to-install-tailwind-css-in-laravel-vite--mix" class="" aria-hidden="true" title=""></a>How to install Tailwind CSS in Laravel (Vite &amp; Mix)</h2>
<h2><a id="quick-overview" href="#quick-overview" class="" aria-hidden="true" title=""></a>Quick overview</h2>
<ul>
<li><strong>Laravel 9+ (Vite)</strong> use Vite and Laravel’s <code>@vite</code> Blade directive. Default for modern Laravel apps.</li>
<li><strong>Laravel 8 and below (Mix / Webpack)</strong> use Laravel Mix and <code>mix()</code> Blade helper.</li>
</ul>
<h2><a id="prerequisites" href="#prerequisites" class="" aria-hidden="true" title=""></a>Prerequisites</h2>
<ul>
<li>Node.js (12.13.0+ recommended).</li>
<li>An existing Laravel project (new Laravel installation comes with Tailwind installed by default).</li>
<li><code>npm</code> initialized (<code>npm install</code> before running build commands).</li>
</ul>
<h2><a id="1-install-tailwind-common-steps" href="#1-install-tailwind-common-steps" class="" aria-hidden="true" title=""></a>1. Install Tailwind (common steps)</h2>
<p>Run in your project root:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">npm </span><span style="color: #98C379;">install</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">-D</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">tailwindcss</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">postcss</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">autoprefixer</span></div><div class='line'><span style="color: #ABB2BF;">npx </span><span style="color: #98C379;">tailwindcss</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">init</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">-p</span></div></code></pre>
<p><code>npx tailwindcss init -p</code> creates <code>tailwind.config.js</code> and <code>postcss.config.js</code>.</p>
<h2><a id="2-tailwind-config-template-paths" href="#2-tailwind-config-template-paths" class="" aria-hidden="true" title=""></a>2. Tailwind config (template paths)</h2>
<p>Tailwind needs to know which files to scan for classes. Add your Laravel resource paths:</p>
<pre><code data-theme="one-dark-pro" data-lang="js" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">/** </span><span style="color: #C678DD;">@type</span><span style="color: #7F848E;"> </span><span style="color: #E5C07B;">{import(&#39;tailwindcss&#39;).Config}</span><span style="color: #7F848E;"> */</span></div><div class='line'><span style="color: #C678DD;">export</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">default</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #E06C75;">content</span><span style="color: #ABB2BF;">: [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;./resources/**/*.blade.php&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;./resources/**/*.js&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;./resources/**/*.ts&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;./resources/**/*.vue&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">  ],</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #E06C75;">theme</span><span style="color: #ABB2BF;">: {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">extend</span><span style="color: #ABB2BF;">: {},</span></div><div class='line'><span style="color: #ABB2BF;">  },</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #E06C75;">plugins</span><span style="color: #ABB2BF;">: [],</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<blockquote>
<p>Use <code>export default</code> (ESM) <strong>or</strong> <code>module.exports = { ... }</code> (CommonJS) depending on your toolchain. Both forms are accepted by Tailwind; the ESM example above matches Tailwind’s current guides.</p>
</blockquote>
<h2><a id="3-add-tailwind-directives-to-your-css" href="#3-add-tailwind-directives-to-your-css" class="" aria-hidden="true" title=""></a>3. Add Tailwind directives to your CSS</h2>
<p>Create or overwrite <code>resources/css/app.css</code> with:</p>
<pre><code data-theme="one-dark-pro" data-lang="css" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">@tailwind</span><span style="color: #ABB2BF;"> base;</span></div><div class='line'><span style="color: #C678DD;">@tailwind</span><span style="color: #ABB2BF;"> components;</span></div><div class='line'><span style="color: #C678DD;">@tailwind</span><span style="color: #ABB2BF;"> utilities;</span></div></code></pre>
<p>This is required for Tailwind to inject its layers into your build.</p>
<h2><a id="4-vite-laravel-9-10-11-recommended" href="#4-vite-laravel-9-10-11-recommended" class="" aria-hidden="true" title=""></a>4. Vite (Laravel 9, 10, 11 recommended)</h2>
<ol>
<li>Ensure your <code>package.json</code> scripts include the standard Vite scripts (Laravel project stub does this by default):</li>
</ol>
<pre><code data-theme="one-dark-pro" data-lang="json" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #98C379;">&quot;scripts&quot;</span><span style="color: #ABB2BF;">: {</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #E06C75;">&quot;dev&quot;</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">&quot;vite&quot;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #E06C75;">&quot;build&quot;</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">&quot;vite build&quot;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<ol start="2">
<li>Confirm <code>vite.config.js</code> includes Laravel’s plugin and your entry points:</li>
</ol>
<pre><code data-theme="one-dark-pro" data-lang="js" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">import</span><span style="color: #ABB2BF;"> { </span><span style="color: #E06C75;">defineConfig</span><span style="color: #ABB2BF;"> } </span><span style="color: #C678DD;">from</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;vite&#39;</span></div><div class='line'><span style="color: #C678DD;">import</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">laravel</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">from</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;laravel-vite-plugin&#39;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">export</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">default</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">defineConfig</span><span style="color: #ABB2BF;">({</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #E06C75;">plugins</span><span style="color: #ABB2BF;">: [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #61AFEF;">laravel</span><span style="color: #ABB2BF;">({</span></div><div class='line'><span style="color: #ABB2BF;">      </span><span style="color: #E06C75;">input</span><span style="color: #ABB2BF;">: [</span><span style="color: #98C379;">&#39;resources/css/app.css&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;resources/js/app.js&#39;</span><span style="color: #ABB2BF;">],</span></div><div class='line'><span style="color: #ABB2BF;">      </span><span style="color: #E06C75;">refresh</span><span style="color: #ABB2BF;">: </span><span style="color: #D19A66;">true</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    }),</span></div><div class='line'><span style="color: #ABB2BF;">  ],</span></div><div class='line'><span style="color: #ABB2BF;">})</span></div></code></pre>
<ol start="3">
<li>Start the dev server:</li>
</ol>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">npm </span><span style="color: #98C379;">run</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">dev</span></div></code></pre>
<ol start="4">
<li>In your Blade layout (e.g. <code>resources/views/layouts/app.blade.php</code>) include assets with <code>@vite</code>:</li>
</ol>
<pre><code data-theme="one-dark-pro" data-lang="blade" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">&lt;!</span><span style="color: #E06C75;">doctype</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">html</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">&lt;</span><span style="color: #E06C75;">html</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">&lt;</span><span style="color: #E06C75;">head</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #61AFEF;">@vite</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;resources/css/app.css&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;resources/js/app.js&#39;</span><span style="color: #ABB2BF;">])</span></div><div class='line'><span style="color: #ABB2BF;">&lt;/</span><span style="color: #E06C75;">head</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">&lt;</span><span style="color: #E06C75;">body</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">class</span><span style="color: #ABB2BF;">=</span><span style="color: #98C379;">&quot;bg-gray-50&quot;</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">  &lt;</span><span style="color: #E06C75;">h1</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">class</span><span style="color: #ABB2BF;">=</span><span style="color: #98C379;">&quot;text-3xl font-bold&quot;</span><span style="color: #ABB2BF;">&gt;Tailwind + Laravel (Vite)&lt;/</span><span style="color: #E06C75;">h1</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">&lt;/</span><span style="color: #E06C75;">body</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">&lt;/</span><span style="color: #E06C75;">html</span><span style="color: #ABB2BF;">&gt;</span></div></code></pre>
<h2><a id="5-laravel-mix-laravel-8-and-older" href="#5-laravel-mix-laravel-8-and-older" class="" aria-hidden="true" title=""></a>5. Laravel Mix (Laravel 8 and older)</h2>
<ol>
<li>
<p>Install Tailwind (same as section A).</p>
</li>
<li>
<p>Configure <code>webpack.mix.js</code> to use Tailwind as a PostCSS plugin. Tailwind’s guide shows using the <code>@tailwindcss/postcss</code> helper for Mix:</p>
</li>
</ol>
<pre><code data-theme="one-dark-pro" data-lang="js" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">const</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">mix</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">require</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;laravel-mix&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">mix</span></div><div class='line'><span style="color: #ABB2BF;">  .</span><span style="color: #61AFEF;">js</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;resources/js/app.js&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;public/js&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">  .</span><span style="color: #61AFEF;">postCss</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;resources/css/app.css&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;public/css&#39;</span><span style="color: #ABB2BF;">, [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #56B6C2;">require</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;@tailwindcss/postcss&#39;</span><span style="color: #ABB2BF;">),</span></div><div class='line'><span style="color: #ABB2BF;">  ])</span></div></code></pre>
<ol start="3">
<li>Run Mix:</li>
</ol>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">npm </span><span style="color: #98C379;">run</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">dev</span></div><div class='line'><span style="color: #7F848E;"># or</span></div><div class='line'><span style="color: #ABB2BF;">npm </span><span style="color: #98C379;">run</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">production</span></div></code></pre>
<ol start="4">
<li>Include compiled assets in Blade using <code>mix()</code>:</li>
</ol>
<pre><code data-theme="one-dark-pro" data-lang="blade" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">&lt;</span><span style="color: #E06C75;">link</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">rel</span><span style="color: #ABB2BF;">=</span><span style="color: #98C379;">&quot;stylesheet&quot;</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">href</span><span style="color: #ABB2BF;">=</span><span style="color: #98C379;">&quot;</span><span style="color: #56B6C2;">{{</span><span style="color: #98C379;"> </span><span style="color: #61AFEF;">mix</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;css/app.css&#39;</span><span style="color: #ABB2BF;">)</span><span style="color: #98C379;"> </span><span style="color: #56B6C2;">}}</span><span style="color: #98C379;">&quot;</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">&lt;</span><span style="color: #E06C75;">script</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">src</span><span style="color: #ABB2BF;">=</span><span style="color: #98C379;">&quot;</span><span style="color: #56B6C2;">{{</span><span style="color: #98C379;"> </span><span style="color: #61AFEF;">mix</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;js/app.js&#39;</span><span style="color: #ABB2BF;">)</span><span style="color: #98C379;"> </span><span style="color: #56B6C2;">}}</span><span style="color: #98C379;">&quot;</span><span style="color: #ABB2BF;">&gt;&lt;/</span><span style="color: #E06C75;">script</span><span style="color: #ABB2BF;">&gt;</span></div></code></pre>
<h2><a id="6-postcssconfigjs-what--p-creates" href="#6-postcssconfigjs-what--p-creates" class="" aria-hidden="true" title=""></a>6. <code>postcss.config.js</code> (what <code>-p</code> creates)</h2>
<p>Typical <code>postcss.config.js</code> created by <code>npx tailwindcss init -p</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="js" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">module</span><span style="color: #ABB2BF;">.</span><span style="color: #E5C07B;">exports</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #E06C75;">plugins</span><span style="color: #ABB2BF;">: {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">tailwindcss</span><span style="color: #ABB2BF;">: {},</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">autoprefixer</span><span style="color: #ABB2BF;">: {},</span></div><div class='line'><span style="color: #ABB2BF;">  },</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>This is used by both Vite and Mix (PostCSS integration).</p>
<h2><a id="7-quick-verification--troubleshooting" href="#7-quick-verification--troubleshooting" class="" aria-hidden="true" title=""></a>7. Quick verification &amp; troubleshooting</h2>
<ul>
<li>If utilities don’t appear, confirm <code>content</code> paths include all your Blade/JS/TS/Vue files and rebuild.</li>
<li>Restart the dev server after changing <code>tailwind.config.js</code>.</li>
<li>Ensure your CSS file with <code>@tailwind</code> directives is actually imported by your bundler (Vite <code>input</code> or Mix <code>postCss</code>).</li>
<li>For production builds run <code>npm run build</code> (Vite) or <code>npm run production</code> (Mix).</li>
</ul>
<h2><a id="8-blade-test-snippet-quick-smoke-test" href="#8-blade-test-snippet-quick-smoke-test" class="" aria-hidden="true" title=""></a>8. Blade test snippet (quick smoke test)</h2>
<p>Add this to any Blade view to verify classes render:</p>
<pre><code data-theme="one-dark-pro" data-lang="blade" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">&lt;</span><span style="color: #E06C75;">div</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">class</span><span style="color: #ABB2BF;">=</span><span style="color: #98C379;">&quot;min-h-screen flex items-center justify-center bg-gray-100&quot;</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">  &lt;</span><span style="color: #E06C75;">div</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">class</span><span style="color: #ABB2BF;">=</span><span style="color: #98C379;">&quot;p-8 bg-white rounded shadow&quot;</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">    &lt;</span><span style="color: #E06C75;">h2</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">class</span><span style="color: #ABB2BF;">=</span><span style="color: #98C379;">&quot;text-2xl font-semibold text-sky-600&quot;</span><span style="color: #ABB2BF;">&gt;Tailwind is working&lt;/</span><span style="color: #E06C75;">h2</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">    &lt;</span><span style="color: #E06C75;">p</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">class</span><span style="color: #ABB2BF;">=</span><span style="color: #98C379;">&quot;mt-2 text-sm text-gray-600&quot;</span><span style="color: #ABB2BF;">&gt;If you see this styled, Tailwind is active.&lt;/</span><span style="color: #E06C75;">p</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">  &lt;/</span><span style="color: #E06C75;">div</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">&lt;/</span><span style="color: #E06C75;">div</span><span style="color: #ABB2BF;">&gt;</span></div></code></pre>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>This article provides the exact commands and config for installing Tailwind CSS in Laravel projects using <strong>Vite</strong> (recommended for Laravel 9+) and <strong>Mix</strong> (legacy).</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Wed, 08 Oct 2025 18:52:30 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Get route and query parameters from URL in Laravel]]></title>
                <link>https://nabilhassen.com/laravel-get-parameter-from-url</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#how-to-get-a-parameter-from-url-in-laravel">How to Get a Parameter from URL in Laravel</a></li>
<li><a href="#getting-route-parameters">Getting Route Parameters</a></li>
<li><a href="#getting-query-parameters">Getting Query Parameters</a></li>
<li><a href="#getting-parameters-in-blade-templates">Getting Parameters in Blade Templates</a></li>
<li><a href="#getting-parameters-in-middleware">Getting Parameters in Middleware</a></li>
<li><a href="#summary">Summary</a></li>
</ul>
<h2><a id="how-to-get-a-parameter-from-url-in-laravel" href="#how-to-get-a-parameter-from-url-in-laravel" class="" aria-hidden="true" title=""></a>How to Get a Parameter from URL in Laravel</h2>
<p>In Laravel, getting parameters from the URL is a common task, especially when working with routes, controllers, and requests. Whether it’s a route parameter (e.g., <code>/users/{id}</code>) or a query parameter (e.g., <code>/users?id=5</code>), Laravel provides clean, expressive ways to retrieve them.</p>
<h2><a id="getting-route-parameters" href="#getting-route-parameters" class="" aria-hidden="true" title=""></a>Getting Route Parameters</h2>
<p>Route parameters are defined in your <code>routes/web.php</code> or <code>routes/api.php</code> file. For example:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">Route</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;/users/{id}&#39;</span><span style="color: #ABB2BF;">, [</span><span style="color: #E5C07B;">UserController</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;show&#39;</span><span style="color: #ABB2BF;">]);</span></div></code></pre>
<p>In this route, <code>{id}</code> is a dynamic parameter that Laravel automatically passes to your controller method. Inside the <code>UserController</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Http\</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">show</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$id</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// You can directly use the parameter</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">findOrFail</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$id</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// You can also retrieve it from the request</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$idFromRoute</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">route</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;id&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">view</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users.show&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">compact</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;user&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;idFromRoute&#39;</span><span style="color: #ABB2BF;">));</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>If you only need the parameter and not the <code>Request</code> instance:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">show</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$id</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">findOrFail</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$id</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">view</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users.show&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">compact</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;user&#39;</span><span style="color: #ABB2BF;">));</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<blockquote>
<p><strong>Tip:</strong> When combining dependency injection (like <code>Request</code>) and route parameters, always place route parameters <em>after</em> injected dependencies.</p>
</blockquote>
<p>You can also get route parameters using the global <code>request()</code> helper:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$id</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">request</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">route</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;id&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<h2><a id="getting-query-parameters" href="#getting-query-parameters" class="" aria-hidden="true" title=""></a>Getting Query Parameters</h2>
<p>Query parameters appear after a <code>?</code> in a URL, such as <code>/users?status=active</code>.</p>
<p>Laravel provides several ways to get them:</p>
<p><strong>Using the Request instance:</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Http\</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">index</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// Get &#39;status&#39; query parameter</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$status</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">query</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;status&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;active&#39;</span><span style="color: #ABB2BF;">); </span><span style="color: #7F848E;">// default value if missing</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">where</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;status&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$status</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">view</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users.index&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">compact</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;status&#39;</span><span style="color: #ABB2BF;">));</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p><strong>Using the <code>request()</code> helper:</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$status</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">request</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">query</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;status&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>Or a shorthand version:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$status</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">request</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;status&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>To get all query parameters as an associative array:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$params</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">request</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">query</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<blockquote>
<p><strong>Note:</strong> <code>query()</code> only retrieves values from the query string (GET parameters), while <code>get()</code> may also look in POST data. Use <code>query()</code> for cleaner intent.</p>
</blockquote>
<h2><a id="getting-parameters-in-blade-templates" href="#getting-parameters-in-blade-templates" class="" aria-hidden="true" title=""></a>Getting Parameters in Blade Templates</h2>
<p>You can also access parameters directly inside Blade templates.</p>
<p><strong>Route parameter:</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="blade" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #56B6C2;">{{</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">request</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">route</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;id&#39;</span><span style="color: #ABB2BF;">) </span><span style="color: #56B6C2;">}}</span></div></code></pre>
<p><strong>Query parameter:</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="blade" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #56B6C2;">{{</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">request</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;status&#39;</span><span style="color: #ABB2BF;">) </span><span style="color: #56B6C2;">}}</span></div></code></pre>
<h2><a id="getting-parameters-in-middleware" href="#getting-parameters-in-middleware" class="" aria-hidden="true" title=""></a>Getting Parameters in Middleware</h2>
<p>If you need to read parameters before the controller runs, you can do it in middleware:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">handle</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">Closure</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$next</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$id</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">route</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;id&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$status</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">query</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;status&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// Optionally modify the request</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">merge</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;source&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;middleware&#39;</span><span style="color: #ABB2BF;">]);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$next</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h2><a id="summary" href="#summary" class="" aria-hidden="true" title=""></a>Summary</h2>
<table>
<thead>
<tr>
<th>Type</th>
<th>Example URL</th>
<th>Laravel Method</th>
</tr>
</thead>
<tbody>
<tr>
<td>Route Parameter</td>
<td><code>/users/15</code></td>
<td><code>$request-&gt;route('id')</code> or <code>$id</code> argument</td>
</tr>
<tr>
<td>Query Parameter</td>
<td><code>/users?status=active</code></td>
<td><code>$request-&gt;query('status')</code> or <code>request('status')</code></td>
</tr>
</tbody>
</table>
<p>Laravel makes retrieving both route and query parameters simple and consistent across controllers, middleware, and views. Following these official patterns ensures your code stays clean, predictable, and aligned with Laravel best practices.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 07 Oct 2025 19:55:03 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Read and load a CSV file into an array in PHP]]></title>
                <link>https://nabilhassen.com/php-csv-to-array</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#how-to-read-and-load-a-csv-file-into-an-array-in-php">How to Read and Load a CSV File Into an Array in PHP</a></li>
<li><a href="#what-is-a-csv-file">What Is a CSV File?</a></li>
<li><a href="#method-1-using-fgetcsv-the-classic-approach">Method 1: Using fgetcsv() (The Classic Approach)</a></li>
<li><a href="#method-2-converting-rows-into-associative-arrays">Method 2: Converting Rows Into Associative Arrays</a></li>
<li><a href="#method-3-using-file-with-strgetcsv">Method 3: Using file() with str_getcsv()</a></li>
<li><a href="#method-4-handling-custom-delimiters">Method 4: Handling Custom Delimiters</a></li>
<li><a href="#method-5-skipping-empty-lines-and-trimming-data">Method 5: Skipping Empty Lines and Trimming Data</a></li>
<li><a href="#method-6-reading-large-csv-files-efficiently">Method 6: Reading Large CSV Files Efficiently</a></li>
<li><a href="#bonus-converting-csv-to-a-multi-dimensional-array-function">Bonus: Converting CSV to a Multi-Dimensional Array Function</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="how-to-read-and-load-a-csv-file-into-an-array-in-php" href="#how-to-read-and-load-a-csv-file-into-an-array-in-php" class="" aria-hidden="true" title=""></a>How to Read and Load a CSV File Into an Array in PHP</h2>
<p>CSV (Comma-Separated Values) files are one of the most common ways to exchange data between applications. They’re lightweight, human-readable, and easy to work with in PHP. Whether you’re importing data from Excel, processing bulk uploads, or building a reporting tool, knowing how to <strong>read CSV file into array in PHP</strong> is an essential skill.</p>
<p>In this guide, we’ll cover different approaches to <strong>load CSV file into array in PHP</strong> using built-in functions and custom logic. By the end, you’ll have a clear understanding of when to use each method and how to handle real-world scenarios like headers, delimiters, and large files.</p>
<h2><a id="what-is-a-csv-file" href="#what-is-a-csv-file" class="" aria-hidden="true" title=""></a>What Is a CSV File?</h2>
<p>A CSV file stores tabular data in plain text. Each row represents a record, and columns are separated by a delimiter (commonly a comma, but sometimes semicolons or tabs).</p>
<p>Example <code>data.csv</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">id,name,email</span></div><div class='line'><span style="color: #abb2bf;">1,John Doe,john@example.com</span></div><div class='line'><span style="color: #abb2bf;">2,Jane Smith,jane@example.com</span></div><div class='line'><span style="color: #abb2bf;">3,Bob Lee,bob@example.com</span></div></code></pre>
<p>Our goal is to read this file in PHP and turn it into an array for easy processing.</p>
<h2><a id="method-1-using-fgetcsv-the-classic-approach" href="#method-1-using-fgetcsv-the-classic-approach" class="" aria-hidden="true" title=""></a>Method 1: Using <code>fgetcsv()</code> (The Classic Approach)</h2>
<p>The <strong>most common way to read CSV file into array in PHP</strong> is with the built-in <code>fgetcsv()</code> function. This function reads one line of the file at a time and automatically parses it into an array.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'><span style="color: #E06C75;">$csvFile</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">fopen</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&quot;data.csv&quot;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&quot;r&quot;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [];</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">while</span><span style="color: #ABB2BF;"> ((</span><span style="color: #E06C75;">$row</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">fgetcsv</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$csvFile</span><span style="color: #ABB2BF;">)) </span><span style="color: #56B6C2;">!==</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">false</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">[] </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$row</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">fclose</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$csvFile</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">print_r</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p><strong>Output:</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">Array</span></div><div class='line'><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">    [</span><span style="color: #D19A66;">0</span><span style="color: #ABB2BF;">] =&gt; </span><span style="color: #E5C07B;">Array</span><span style="color: #ABB2BF;"> ( [</span><span style="color: #D19A66;">0</span><span style="color: #ABB2BF;">] =&gt; id [</span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">] =&gt; name [</span><span style="color: #D19A66;">2</span><span style="color: #ABB2BF;">] =&gt; email )</span></div><div class='line'><span style="color: #ABB2BF;">    [</span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">] =&gt; </span><span style="color: #E5C07B;">Array</span><span style="color: #ABB2BF;"> ( [</span><span style="color: #D19A66;">0</span><span style="color: #ABB2BF;">] =&gt; </span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;"> [</span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">] =&gt; John Doe [</span><span style="color: #D19A66;">2</span><span style="color: #ABB2BF;">] =&gt; john</span><span style="color: #C678DD;">@</span><span style="color: #ABB2BF;">example</span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;">com )</span></div><div class='line'><span style="color: #ABB2BF;">    [</span><span style="color: #D19A66;">2</span><span style="color: #ABB2BF;">] =&gt; </span><span style="color: #E5C07B;">Array</span><span style="color: #ABB2BF;"> ( [</span><span style="color: #D19A66;">0</span><span style="color: #ABB2BF;">] =&gt; </span><span style="color: #D19A66;">2</span><span style="color: #ABB2BF;"> [</span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">] =&gt; Jane Smith [</span><span style="color: #D19A66;">2</span><span style="color: #ABB2BF;">] =&gt; jane</span><span style="color: #C678DD;">@</span><span style="color: #ABB2BF;">example</span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;">com )</span></div><div class='line'><span style="color: #ABB2BF;">    [</span><span style="color: #D19A66;">3</span><span style="color: #ABB2BF;">] =&gt; </span><span style="color: #E5C07B;">Array</span><span style="color: #ABB2BF;"> ( [</span><span style="color: #D19A66;">0</span><span style="color: #ABB2BF;">] =&gt; </span><span style="color: #D19A66;">3</span><span style="color: #ABB2BF;"> [</span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">] =&gt; Bob Lee [</span><span style="color: #D19A66;">2</span><span style="color: #ABB2BF;">] =&gt; bob</span><span style="color: #C678DD;">@</span><span style="color: #ABB2BF;">example</span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;">com )</span></div><div class='line'><span style="color: #ABB2BF;">)</span></div></code></pre>
<p>This method is memory-friendly because it reads line by line. It’s ideal for large CSV files.</p>
<h2><a id="method-2-converting-rows-into-associative-arrays" href="#method-2-converting-rows-into-associative-arrays" class="" aria-hidden="true" title=""></a>Method 2: Converting Rows Into Associative Arrays</h2>
<p>Often, you don’t want numeric keys (<code>[0]</code>, <code>[1]</code>, <code>[2]</code>). Instead, you want the headers (<code>id</code>, <code>name</code>, <code>email</code>) as array keys. Here’s how:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'><span style="color: #E06C75;">$csvFile</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">fopen</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&quot;data.csv&quot;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&quot;r&quot;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// First row as headers</span></div><div class='line'><span style="color: #E06C75;">$headers</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">fgetcsv</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$csvFile</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [];</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">while</span><span style="color: #ABB2BF;"> ((</span><span style="color: #E06C75;">$row</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">fgetcsv</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$csvFile</span><span style="color: #ABB2BF;">)) </span><span style="color: #56B6C2;">!==</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">false</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">[] </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">array_combine</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$headers</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$row</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">fclose</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$csvFile</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">print_r</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p><strong>Output:</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">Array</span></div><div class='line'><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">    [</span><span style="color: #D19A66;">0</span><span style="color: #ABB2BF;">] =&gt; </span><span style="color: #E5C07B;">Array</span><span style="color: #ABB2BF;"> ( [id] =&gt; </span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;"> [name] =&gt; John Doe [email] =&gt; john</span><span style="color: #C678DD;">@</span><span style="color: #ABB2BF;">example</span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;">com )</span></div><div class='line'><span style="color: #ABB2BF;">    [</span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">] =&gt; </span><span style="color: #E5C07B;">Array</span><span style="color: #ABB2BF;"> ( [id] =&gt; </span><span style="color: #D19A66;">2</span><span style="color: #ABB2BF;"> [name] =&gt; Jane Smith [email] =&gt; jane</span><span style="color: #C678DD;">@</span><span style="color: #ABB2BF;">example</span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;">com )</span></div><div class='line'><span style="color: #ABB2BF;">    [</span><span style="color: #D19A66;">2</span><span style="color: #ABB2BF;">] =&gt; </span><span style="color: #E5C07B;">Array</span><span style="color: #ABB2BF;"> ( [id] =&gt; </span><span style="color: #D19A66;">3</span><span style="color: #ABB2BF;"> [name] =&gt; Bob Lee [email] =&gt; bob</span><span style="color: #C678DD;">@</span><span style="color: #ABB2BF;">example</span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;">com )</span></div><div class='line'><span style="color: #ABB2BF;">)</span></div></code></pre>
<p>This format is much easier to work with when accessing data by column names.</p>
<h2><a id="method-3-using-file-with-strgetcsv" href="#method-3-using-file-with-strgetcsv" class="" aria-hidden="true" title=""></a>Method 3: Using <code>file()</code> with <code>str_getcsv()</code></h2>
<p>Another way to <strong>PHP load CSV file into array</strong> is combining <code>file()</code> with <code>str_getcsv()</code>. This reads the entire file into an array of strings and then parses each line.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'><span style="color: #E06C75;">$rows</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">array_map</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;str_getcsv&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">file</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;data.csv&#39;</span><span style="color: #ABB2BF;">));</span></div><div class='line'><span style="color: #56B6C2;">print_r</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$rows</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>This approach is very compact but loads the entire file into memory at once. It works great for small-to-medium CSV files but should be avoided for very large datasets.</p>
<h2><a id="method-4-handling-custom-delimiters" href="#method-4-handling-custom-delimiters" class="" aria-hidden="true" title=""></a>Method 4: Handling Custom Delimiters</h2>
<p>Not all CSV files use commas. Sometimes they use semicolons (<code>;</code>), tabs (<code>\t</code>), or even pipes (<code>|</code>).</p>
<p>You can tell <code>fgetcsv()</code> what delimiter to expect:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'><span style="color: #E06C75;">$csvFile</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">fopen</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&quot;data_semicolon.csv&quot;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&quot;r&quot;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [];</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">while</span><span style="color: #ABB2BF;"> ((</span><span style="color: #E06C75;">$row</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">fgetcsv</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$csvFile</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">1000</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&quot;;&quot;</span><span style="color: #ABB2BF;">)) </span><span style="color: #56B6C2;">!==</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">false</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">[] </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$row</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">fclose</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$csvFile</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">print_r</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>This flexibility makes <code>fgetcsv()</code> very powerful.</p>
<h2><a id="method-5-skipping-empty-lines-and-trimming-data" href="#method-5-skipping-empty-lines-and-trimming-data" class="" aria-hidden="true" title=""></a>Method 5: Skipping Empty Lines and Trimming Data</h2>
<p>Real-world CSV files are often messy. You might find blank lines, extra spaces, or incomplete rows. Here’s how to handle them:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'><span style="color: #E06C75;">$csvFile</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">fopen</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&quot;data.csv&quot;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&quot;r&quot;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [];</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">while</span><span style="color: #ABB2BF;"> ((</span><span style="color: #E06C75;">$row</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">fgetcsv</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$csvFile</span><span style="color: #ABB2BF;">)) </span><span style="color: #56B6C2;">!==</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">false</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// Skip empty lines</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">count</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$row</span><span style="color: #ABB2BF;">) </span><span style="color: #56B6C2;">==</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">&amp;&amp;</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$row</span><span style="color: #ABB2BF;">[</span><span style="color: #D19A66;">0</span><span style="color: #ABB2BF;">] </span><span style="color: #56B6C2;">===</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">continue</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// Trim spaces</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$row</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">array_map</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;trim&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$row</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">[] </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$row</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">fclose</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$csvFile</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<h2><a id="method-6-reading-large-csv-files-efficiently" href="#method-6-reading-large-csv-files-efficiently" class="" aria-hidden="true" title=""></a>Method 6: Reading Large CSV Files Efficiently</h2>
<p>When dealing with huge files (hundreds of MBs), reading everything into an array at once can exhaust memory. Instead, process rows as you read them:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'><span style="color: #E06C75;">$csvFile</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">fopen</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&quot;bigfile.csv&quot;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&quot;r&quot;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Process each row immediately</span></div><div class='line'><span style="color: #C678DD;">while</span><span style="color: #ABB2BF;"> ((</span><span style="color: #E06C75;">$row</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">fgetcsv</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$csvFile</span><span style="color: #ABB2BF;">)) </span><span style="color: #56B6C2;">!==</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">false</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// For example, insert into a database</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// insertIntoDatabase($row);</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">fclose</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$csvFile</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>This way, you never hold the entire dataset in memory.</p>
<h2><a id="bonus-converting-csv-to-a-multi-dimensional-array-function" href="#bonus-converting-csv-to-a-multi-dimensional-array-function" class="" aria-hidden="true" title=""></a>Bonus: Converting CSV to a Multi-Dimensional Array Function</h2>
<p>Here’s a reusable function to <strong>read CSV file into array in PHP</strong> with options for headers and delimiters:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">csvToArray</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$filename</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$delimiter</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;,&quot;</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$hasHeader</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">true</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">!file_exists</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$filename</span><span style="color: #ABB2BF;">) </span><span style="color: #56B6C2;">||</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">!is_readable</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$filename</span><span style="color: #ABB2BF;">)) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">false</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [];</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> ((</span><span style="color: #E06C75;">$handle</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">fopen</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$filename</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&quot;r&quot;</span><span style="color: #ABB2BF;">)) </span><span style="color: #56B6C2;">!==</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">false</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$headers</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$hasHeader</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">?</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">fgetcsv</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$handle</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">1000</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$delimiter</span><span style="color: #ABB2BF;">) </span><span style="color: #C678DD;">:</span><span style="color: #ABB2BF;"> [];</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">while</span><span style="color: #ABB2BF;"> ((</span><span style="color: #E06C75;">$row</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">fgetcsv</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$handle</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">1000</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$delimiter</span><span style="color: #ABB2BF;">)) </span><span style="color: #56B6C2;">!==</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">false</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$hasHeader</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">                </span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">[] </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">array_combine</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$headers</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$row</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">            } </span><span style="color: #C678DD;">else</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">                </span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">[] </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$row</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">            }</span></div><div class='line'><span style="color: #ABB2BF;">        }</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #56B6C2;">fclose</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$handle</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Usage</span></div><div class='line'><span style="color: #56B6C2;">print_r</span><span style="color: #ABB2BF;">(</span><span style="color: #61AFEF;">csvToArray</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&quot;data.csv&quot;</span><span style="color: #ABB2BF;">));</span></div></code></pre>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>Reading a CSV file into an array in PHP is straightforward, but the right approach depends on your use case:</p>
<ul>
<li>Use <code>fgetcsv()</code> for most scenarios (line-by-line reading).</li>
<li>Use <code>array_combine()</code> if you want associative arrays with headers.</li>
<li>Use <code>file()</code> with <code>str_getcsv()</code> for small files when you want concise code.</li>
<li>Use streaming (processing rows as they come) for very large files.</li>
</ul>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Thu, 02 Oct 2025 20:15:35 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Http::batch with hooks in Laravel 12.32]]></title>
                <link>https://nabilhassen.com/laravel-http-batch</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#new-in-laravel-1232-httpbatch">New in Laravel 12.32: Http::batch</a></li>
<li><a href="#httppool-vs-httpbatch">Http::pool vs. Http::batch</a></li>
<li><a href="#httpbatch-in-action">Http::batch in action</a></li>
<li><a href="#helper-methods-and-properties">Helper Methods and Properties</a></li>
<li><a href="#wrapup">Wrap‑up</a></li>
</ul>
<h2><a id="new-in-laravel-1232-httpbatch" href="#new-in-laravel-1232-httpbatch" class="" aria-hidden="true" title=""></a>New in Laravel 12.32: <code>Http::batch</code></h2>
<p>A new feature by <a rel="nofollow noopener" target="_blank" href="https://x.com/wendell_adriel">Wendell Adriel</a> has landed in Laravel 12.32; <strong><code>Http::batch</code></strong>, making it easier to send multiple HTTP requests concurrently with lifecycle hooks.</p>
<h2><a id="httppool-vs-httpbatch" href="#httppool-vs-httpbatch" class="" aria-hidden="true" title=""></a>Http::pool vs. Http::batch</h2>
<p>Previously, Laravel’s <code>Http::pool</code> allowed concurrent requests but lacked hooks to handle events before, during, and after execution. With <code>Http::batch</code>, you now have:</p>
<ul>
<li><strong><code>before</code></strong> – runs before any requests</li>
<li><strong><code>progress</code></strong> – runs after each successful request</li>
<li><strong><code>catch</code></strong> – runs after each failed request</li>
<li><strong><code>then</code></strong> – runs if all requests succeed</li>
<li><strong><code>finally</code></strong> – runs after all requests finish</li>
</ul>
<h2><a id="httpbatch-in-action" href="#httpbatch-in-action" class="" aria-hidden="true" title=""></a>Http::batch in action</h2>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$responses</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Http</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">batch</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">fn</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Batch</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$batch</span><span style="color: #ABB2BF;">) =&gt; [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$batch</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;http://localhost/first&#39;</span><span style="color: #ABB2BF;">),</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$batch</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;http://localhost/second&#39;</span><span style="color: #ABB2BF;">),</span></div><div class='line'><span style="color: #ABB2BF;">])-&gt;</span><span style="color: #61AFEF;">before</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Batch</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$batch</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// This runs before the first HTTP request is executed.</span></div><div class='line'><span style="color: #ABB2BF;">})-&gt;</span><span style="color: #61AFEF;">progress</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Batch</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$batch</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">int</span><span style="color: #ABB2BF;">|</span><span style="color: #E5C07B;">string</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$key</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">Response</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$response</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// This runs after each successful HTTP request from the Batch.</span></div><div class='line'><span style="color: #ABB2BF;">})-&gt;</span><span style="color: #61AFEF;">catch</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Batch</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$batch</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">int</span><span style="color: #ABB2BF;">|</span><span style="color: #E5C07B;">string</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$key</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">Response</span><span style="color: #ABB2BF;">|</span><span style="color: #E5C07B;">RequestException</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$response</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// This runs after each failed HTTP request from the Batch.</span></div><div class='line'><span style="color: #ABB2BF;">})-&gt;</span><span style="color: #61AFEF;">then</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Batch</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$batch</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">array</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$results</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// This runs ONLY IF all the HTTP requests from the Batch are successful and the batch is not cancelled.</span></div><div class='line'><span style="color: #ABB2BF;">})-&gt;</span><span style="color: #61AFEF;">finally</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Batch</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$batch</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">array</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$results</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// This runs after all the HTTP requests from the Batch finish and the batch is not cancelled.</span></div><div class='line'><span style="color: #ABB2BF;">})-&gt;</span><span style="color: #61AFEF;">send</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<blockquote>
<p><em><strong>You cannot add requests after a batch has started.</strong></em></p>
</blockquote>
<h2><a id="helper-methods-and-properties" href="#helper-methods-and-properties" class="" aria-hidden="true" title=""></a>Helper Methods and Properties</h2>
<p>Alongside the hooks, the \Illuminate\Http\Client\Batch class also offers several helpers to inspect and track the batch:</p>
<ul>
<li>$batch-&gt;totalRequests → total number of requests.</li>
<li>$batch-&gt;pendingRequests → how many are still waiting.</li>
<li>$batch-&gt;failedRequests → how many have failed.</li>
<li>$batch-&gt;processedRequests() → number of processed requests.</li>
<li>$batch-&gt;hasFailures() → returns true if there are failures.</li>
<li>$batch-&gt;finished() → returns true when all requests are done.</li>
</ul>
<h2><a id="wrapup" href="#wrapup" class="" aria-hidden="true" title=""></a>Wrap‑up</h2>
<p><code>Http::batch</code> brings a clean, expressive API for orchestrating concurrent HTTP calls. It’s perfect for multi‑service workflows, batch data fetching, and progress tracking.</p>
<p>Check out the PR for more: <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/56946">#56946</a></p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Wed, 01 Oct 2025 16:25:14 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Check Laravel version in CMD, Terminal, or Ubuntu]]></title>
                <link>https://nabilhassen.com/check-laravel-version</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#how-to-check-laravel-version-in-your-project-cmd--terminal--ubuntu">How to Check Laravel Version in Your Project (CMD / Terminal / Ubuntu)</a></li>
<li><a href="#1-check-via-artisan-fastest">1. Check via Artisan (fastest)</a></li>
<li><a href="#2-use-artisan-about">2. Use artisan about</a></li>
<li><a href="#3-using-composer">3. Using Composer</a></li>
<li><a href="#4-check-composerjson-or-composerlock">4. Check composer.json or composer.lock</a></li>
<li><a href="#5-inspect-applicationphp">5. Inspect Application.php</a></li>
<li><a href="#6-get-it-in-code">6. Get it in Code</a></li>
<li><a href="#tldr">TL;DR</a></li>
</ul>
<h2><a id="how-to-check-laravel-version-in-your-project-cmd--terminal--ubuntu" href="#how-to-check-laravel-version-in-your-project-cmd--terminal--ubuntu" class="" aria-hidden="true" title=""></a>How to Check Laravel Version in Your Project (CMD / Terminal / Ubuntu)</h2>
<p>Need to know which <strong>Laravel version</strong> your project is running? Here are the quickest ways.</p>
<h2><a id="1-check-via-artisan-fastest" href="#1-check-via-artisan-fastest" class="" aria-hidden="true" title=""></a>1. Check via Artisan (fastest)</h2>
<p>In your project root, run:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--version</span></div></code></pre>
<p>Output looks like:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">Laravel Framework 10.5.2</span></div></code></pre>
<p>👉 On Laravel Sail / Docker:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">sail </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--version</span></div></code></pre>
<h2><a id="2-use-artisan-about" href="#2-use-artisan-about" class="" aria-hidden="true" title=""></a>2. Use <code>artisan about</code></h2>
<p>Newer Laravel versions support:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">about</span></div></code></pre>
<p>This shows the version plus PHP, environment, and more.</p>
<h2><a id="3-using-composer" href="#3-using-composer" class="" aria-hidden="true" title=""></a>3. Using Composer</h2>
<p>Another quick way is via Composer:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">show</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">laravel/framework</span></div></code></pre>
<p>This will display details of the Laravel framework package, including the installed version.</p>
<h2><a id="4-check-composerjson-or-composerlock" href="#4-check-composerjson-or-composerlock" class="" aria-hidden="true" title=""></a>4. Check <code>composer.json</code> or <code>composer.lock</code></h2>
<ul>
<li>Open <code>composer.json</code> → search <code>&quot;laravel/framework&quot;</code>.</li>
<li>For the <strong>exact installed version</strong>, open <code>composer.lock</code> and search <code>&quot;laravel/framework&quot;</code>.</li>
</ul>
<h2><a id="5-inspect-applicationphp" href="#5-inspect-applicationphp" class="" aria-hidden="true" title=""></a>5. Inspect <code>Application.php</code></h2>
<p>If no terminal access:
Open
<code>vendor/laravel/framework/src/Illuminate/Foundation/Application.php</code>
and look for:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">const</span><span style="color: #ABB2BF;"> VERSION </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;9.42.1&#39;</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<h2><a id="6-get-it-in-code" href="#6-get-it-in-code" class="" aria-hidden="true" title=""></a>6. Get it in Code</h2>
<p>For debugging or admin panels:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">app</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">version</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>⚠️ Don’t expose version info publicly in production.</p>
<h2><a id="tldr" href="#tldr" class="" aria-hidden="true" title=""></a>TL;DR</h2>
<p>👉 If you just want the answer:
<strong>Run <code>php artisan --version</code> in your project root.</strong></p>
<p>The other methods are fallbacks when the CLI isn’t available.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 30 Sep 2025 19:44:00 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Laravel where LIKE queries, before & after Laravel 11/12]]></title>
                <link>https://nabilhassen.com/laravel-where-like-queries-before-after-laravel-1112</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#where-like-queries-in-laravel">Where LIKE Queries in Laravel</a></li>
<li><a href="#using-like-in-laravel-before-versions-11--12">Using LIKE in Laravel Before Versions 11 &amp; 12</a></li>
<li><a href="#using-wherelike-in-laravel-11--12">Using whereLike in Laravel 11 &amp; 12</a></li>
<li><a href="#case-insensitive-like-queries">Case Insensitive LIKE Queries</a></li>
<li><a href="#multiple-columns-like-queries">Multiple Columns LIKE Queries</a></li>
<li><a href="#summary">Summary</a></li>
</ul>
<h2><a id="where-like-queries-in-laravel" href="#where-like-queries-in-laravel" class="" aria-hidden="true" title=""></a>Where LIKE Queries in Laravel</h2>
<p>When working with databases in Laravel, one of the most common needs is to search for records using the <strong>SQL <code>LIKE</code> clause</strong>. This lets you perform partial matches—for example, finding all users whose names start with &quot;John&quot;.</p>
<p>In this post, we’ll explore how to use <strong><code>where like</code> queries in Laravel</strong>, how it worked before Laravel 11 &amp; 12, and what changed in these newer versions. We’ll also cover <strong>case-insensitive LIKE queries</strong>, <strong>multiple-column LIKE queries</strong>, and the newer <strong>whereAny / whereAll / whereNone</strong> clauses.</p>
<h2><a id="using-like-in-laravel-before-versions-11--12" href="#using-like-in-laravel-before-versions-11--12" class="" aria-hidden="true" title=""></a>Using LIKE in Laravel Before Versions 11 &amp; 12</h2>
<p>Before Laravel 11 and 12, you had to use the <strong><code>where</code> method</strong> with the <code>LIKE</code> operator manually:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// Find users whose names start with &quot;John&quot;</span></div><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">where</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;LIKE&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;John%&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Find users whose email contains &quot;gmail&quot;</span></div><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">where</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;email&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;LIKE&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;%gmail%&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h2><a id="using-wherelike-in-laravel-11--12" href="#using-wherelike-in-laravel-11--12" class="" aria-hidden="true" title=""></a>Using whereLike in Laravel 11 &amp; 12</h2>
<p>From <strong>Laravel 11 and 12</strong>, Eloquent introduced a more expressive <strong><code>whereLike</code></strong> and <strong><code>orWhereLike</code></strong> syntax:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// Find users whose names start with &quot;John&quot;</span></div><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereLike</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;John%&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Find users whose email contains &quot;gmail&quot;</span></div><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereLike</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;email&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;%gmail%&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h2><a id="case-insensitive-like-queries" href="#case-insensitive-like-queries" class="" aria-hidden="true" title=""></a>Case Insensitive LIKE Queries</h2>
<p>Whether LIKE queries are case-sensitive depends on the database collation. For example, MySQL’s <code>utf8mb4_unicode_ci</code> collation is <strong>case-insensitive</strong> by default.</p>
<p>If you want to explicitly force <strong>case-insensitive like queries</strong>, you can use <code>LOWER()</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// Case insensitive search for &quot;john&quot;</span></div><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereRaw</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;LOWER(name) LIKE ?&#39;</span><span style="color: #ABB2BF;">, [</span><span style="color: #98C379;">&#39;%john%&#39;</span><span style="color: #ABB2BF;">])-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>Or combine it with the new <code>whereLike</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereLike</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">raw</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;LOWER(name)&#39;</span><span style="color: #ABB2BF;">), </span><span style="color: #98C379;">&#39;%john%&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h2><a id="multiple-columns-like-queries" href="#multiple-columns-like-queries" class="" aria-hidden="true" title=""></a>Multiple Columns LIKE Queries</h2>
<p>Sometimes you want to search across <strong>multiple columns</strong>, such as name <strong>or</strong> email.</p>
<p><strong>Before Laravel 11 &amp; 12:</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">where</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;LIKE&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;%john%&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">             -&gt;</span><span style="color: #61AFEF;">orWhere</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;email&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;LIKE&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;%john%&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">             -&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p><strong>From Laravel 11 &amp; 12 onward:</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereAny</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;email&#39;</span><span style="color: #ABB2BF;">], </span><span style="color: #98C379;">&#39;LIKE&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;%john%&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereAll</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;email&#39;</span><span style="color: #ABB2BF;">], </span><span style="color: #98C379;">&#39;LIKE&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;%john%&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h2><a id="summary" href="#summary" class="" aria-hidden="true" title=""></a>Summary</h2>
<ul>
<li><strong>Before Laravel 11 &amp; 12:</strong> Use <code>where('column', 'LIKE', 'pattern')</code>.</li>
<li><strong>Laravel 11 &amp; 12+:</strong> Use <code>whereLike</code> and <code>orWhereLike</code> for cleaner syntax.</li>
<li><strong>Case Insensitive:</strong> Use <code>LOWER()</code> with raw queries if collation isn’t case-insensitive.</li>
<li><strong>Multiple Columns:</strong> Use <code>whereAny(['col1', 'col2'], 'LIKE' 'pattern')</code>.</li>
<li><strong>Advanced:</strong> Use <code>whereAny</code>, <code>whereAll</code>, and <code>whereNone</code> for multi-column LIKE queries with OR, AND, or NOT logic.</li>
</ul>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 30 Sep 2025 19:10:22 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Add Laravel Scheduler Command to Crontab on Ubuntu]]></title>
                <link>https://nabilhassen.com/add-laravel-scheduler-command-to-crontab-on-ubuntu</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#how-to-add-the-laravel-scheduler-command-to-crontab-on-ubuntu">How to Add the Laravel Scheduler Command to Crontab (on Ubuntu)</a></li>
<li><a href="#prerequisites--assumptions">Prerequisites &amp; assumptions</a></li>
<li><a href="#step-1-update--if-needed-install-cron">Step 1: Update &amp; (if needed) install cron</a></li>
<li><a href="#step-2-edit-the-crontab">Step 2: Edit the crontab</a></li>
<li><a href="#common-pitfalls--tips">Common pitfalls &amp; tips</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="how-to-add-the-laravel-scheduler-command-to-crontab-on-ubuntu" href="#how-to-add-the-laravel-scheduler-command-to-crontab-on-ubuntu" class="" aria-hidden="true" title=""></a>How to Add the Laravel Scheduler Command to Crontab (on Ubuntu)</h2>
<p>When building Laravel applications, many background tasks (e.g. cleanup jobs, sending queued emails, recurring reports) are best managed via Laravel’s built‑in scheduler. But to make the scheduler run automatically, you need to hook it into the system cron on your server. In this post, I’ll walk through how to do that on Ubuntu.</p>
<h2><a id="prerequisites--assumptions" href="#prerequisites--assumptions" class="" aria-hidden="true" title=""></a>Prerequisites &amp; assumptions</h2>
<p>Before proceeding, this guide assumes:</p>
<ul>
<li>You already have a working Laravel project on Ubuntu (e.g. in <code>/var/www/…</code> or some directory).</li>
<li>You have shell / SSH access with sudo (or at least enough rights to edit crontab for a user).</li>
<li><code>cron</code> service is installed or can be installed.</li>
<li>PHP CLI is accessible from the command line (e.g. <code>php</code> works).</li>
</ul>
<h2><a id="step-1-update--if-needed-install-cron" href="#step-1-update--if-needed-install-cron" class="" aria-hidden="true" title=""></a>Step 1: Update &amp; (if needed) install cron</h2>
<p>It’s good practice to ensure your system is up to date, and to confirm cron is installed and running.</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">sudo </span><span style="color: #98C379;">apt-get</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">update</span></div><div class='line'><span style="color: #ABB2BF;">sudo </span><span style="color: #98C379;">apt-get</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">upgrade</span></div></code></pre>
<p>Then install cron if it’s not already:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">sudo </span><span style="color: #98C379;">apt-get</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">install</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">cron</span></div></code></pre>
<p>After installation, check the status:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">systemctl </span><span style="color: #98C379;">status</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">cron</span></div></code></pre>
<p>You should see something like “active (running)”.
If it's not running, you may start it:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">sudo </span><span style="color: #98C379;">systemctl</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">enable</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">cron</span></div><div class='line'><span style="color: #ABB2BF;">sudo </span><span style="color: #98C379;">systemctl</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">start</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">cron</span></div></code></pre>
<h2><a id="step-2-edit-the-crontab" href="#step-2-edit-the-crontab" class="" aria-hidden="true" title=""></a>Step 2: Edit the crontab</h2>
<p>To schedule Laravel’s scheduler, you’ll add a cron entry that runs every minute. Usually you won’t need to touch the system <code>/etc/crontab</code> (unless you're root or managing many users). Instead, edit the crontab for the relevant user (often the same user under which your web server or application runs).</p>
<p>Run:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">crontab </span><span style="color: #D19A66;">-e</span></div></code></pre>
<p>If it’s your first time doing this, it may prompt you to choose an editor (like nano, vim, etc.).</p>
<p>In the crontab file, add this line:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">* * * * * cd /path-to-your-project &amp;&amp; php artisan schedule:run &gt;&gt; /dev/null 2&gt;&amp;1</span></div></code></pre>
<p>Make sure to replace <code>/path-to-your-project</code> with your actual path (for example, <code>/var/www/html/your-laravel-app</code>).</p>
<p>After editing, save and exit. Cron will pick up the change automatically.</p>
<h2><a id="common-pitfalls--tips" href="#common-pitfalls--tips" class="" aria-hidden="true" title=""></a>Common pitfalls &amp; tips</h2>
<table>
<thead>
<tr>
<th>Issue</th>
<th>Description / Fix</th>
</tr>
</thead>
<tbody>
<tr>
<td>Wrong path</td>
<td>If <code>cd</code> points to a non-existent directory, cron will fail silently. Double-check absolute path.</td>
</tr>
<tr>
<td>Wrong PHP binary</td>
<td>Sometimes the CLI PHP version is different or not in <code>$PATH</code>. Use full path (e.g. <code>/usr/bin/php</code>).</td>
</tr>
<tr>
<td>Permissions &amp; ownership</td>
<td>Ensure the user whose crontab you edit has permissions to run the commands and access project files.</td>
</tr>
<tr>
<td>Output flooding / emails</td>
<td>Without redirecting output, cron may send an email on every run. That’s why we use <code>&gt;&gt; /dev/null 2&gt;&amp;1</code>.</td>
</tr>
<tr>
<td>Multiple crontab entries</td>
<td>If you already have a cron for the same user, ensure this new line doesn’t conflict.</td>
</tr>
</tbody>
</table>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>Integrating Laravel’s scheduler with the system cron is a simple but essential step. Once it’s configured, your application can reliably run scheduled jobs without manual intervention. Just:</p>
<ol>
<li>Install/verify cron on Ubuntu</li>
<li>Add a cron entry (via <code>crontab -e</code>) to run <code>php artisan schedule:run</code> every minute</li>
<li>Verify everything works</li>
</ol>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Thu, 25 Sep 2025 12:08:41 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[PHP 9.0: Release Date and Features You Must Know]]></title>
                <link>https://nabilhassen.com/php-90-release-date-and-features-you-must-know</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#php-90">PHP 9.0</a></li>
<li><a href="#php-90---release-date">PHP 9.0 - Release Date</a></li>
<li><a href="#key-features-of-php-90">Key Features of PHP 9.0</a>
<ul>
<li><a href="#1-predictable-incrementdecrement----behavior">1. Predictable Increment/Decrement (++/--) Behavior</a></li>
<li><a href="#2-exceptions-for-unserialization-errors">2. Exceptions for Unserialization Errors</a></li>
<li><a href="#3-simplified-function-signatures">3. Simplified Function Signatures</a></li>
<li><a href="#4-no-autovivification-arrays-from-false">4. No Autovivification (Arrays from False)</a></li>
<li><a href="#5-simplified-string-interpolation">5. Simplified String Interpolation</a></li>
<li><a href="#6-warnings-become-fatal-errors">6. Warnings Become Fatal Errors</a></li>
<li><a href="#7-removal-of-deprecated-features">7. Removal of Deprecated Features</a></li>
<li><a href="#8-removal-of-partially-supported-callables">8. Removal of Partially Supported Callables</a></li>
<li><a href="#9-stricter-explicit-casts-no-more-fuzzy-casts">9. Stricter Explicit Casts (No More “Fuzzy” Casts)</a></li>
<li><a href="#10-implicit-bool-to-string-coercion-becomes-a-typeerror">10. Implicit Bool-to-String Coercion Becomes a TypeError</a></li>
<li><a href="#11-php-90-drops-32-bit-builds">11. PHP 9.0 Drops 32-bit Builds</a></li>
<li><a href="#12-enum-introspection-cleanup-getdeclaredenums-and-classexists-semantics">12. Enum Introspection Cleanup (get_declared_enums() and class_exists() semantics)</a></li>
<li><a href="#13-dynamic-properties-become-errors-unless-explicitly-allowed">13. Dynamic Properties Become Errors (Unless Explicitly Allowed)</a></li>
<li><a href="#14-null-to-non-nullable-internal-scalar-arguments-throws-typeerror">14. null to Non-Nullable Internal Scalar Arguments Throws TypeError</a></li>
<li><a href="#15-removal-of-utf8encode-and-utf8decode">15. Removal of utf8_encode() and utf8_decode()</a></li>
<li><a href="#16-removal-of-getpost-session-ids-usetranssid-and-the-sid-constant">16. Removal of GET/POST Session IDs, use_trans_sid, and the SID Constant</a></li>
<li><a href="#17-fuzzy-scalar-casts-become-typeerror-proposal">17. Fuzzy Scalar Casts Become TypeError (Proposal)</a></li>
</ul>
</li>
<li><a href="#how-to-prepare-and-migrate">How to Prepare and Migrate</a></li>
<li><a href="#impact-on-the-php-ecosystem">Impact on the PHP Ecosystem</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="php-90" href="#php-90" class="" aria-hidden="true" title=""></a>PHP 9.0</h2>
<p>PHP 9.0 is still in early planning, with no firm release date yet. In fact, core developers expect we’ll see PHP 8.5 and 8.6 before 9.0 arrives. In other words, the language’s evolution is gradual, but discussions and RFCs are already shaping PHP 9.0’s direction. The focus is on eliminating quirks and deprecated behaviors to make PHP code more predictable and robust. For example, one proposal is to forbid the odd behavior where incrementing a string like <code>'a9'</code> produces <code>'b0'</code>; instead PHP 9.0 will throw a <code>TypeError</code>. Similarly, silent warnings (e.g. from unserialization) will be promoted to exceptions, and deprecated features finally removed.</p>
<h2><a id="php-90---release-date" href="#php-90---release-date" class="" aria-hidden="true" title=""></a>PHP 9.0 - Release Date</h2>
<p>The PHP internals community has not yet announced a fixed release date for PHP 9.0. However, based on the typical cadence of major PHP releases (roughly every 2-3 years).</p>
<h2><a id="key-features-of-php-90" href="#key-features-of-php-90" class="" aria-hidden="true" title=""></a>Key Features of PHP 9.0</h2>
<p>PHP 9.0 introduces several major changes. Each feature below is supported by active RFCs and community discussion; here we explain them technically and show examples of the old vs. new behavior.</p>
<h3><a id="1-predictable-incrementdecrement----behavior" href="#1-predictable-incrementdecrement----behavior" class="" aria-hidden="true" title=""></a>1. Predictable Increment/Decrement (<code>++</code>/<code>--</code>) Behavior</h3>
<p>PHP has a history of surprising results with the <code>++</code> and <code>--</code> operators. In PHP 8.x, incrementing a string or boolean silently converts types. For example:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$foo</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;a9&#39;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #E06C75;">$foo</span><span style="color: #ABB2BF;">++;</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$foo</span><span style="color: #ABB2BF;">;  </span><span style="color: #7F848E;">// PHP 8.x outputs: &quot;b0&quot;</span></div></code></pre>
<p>In PHP 9.0, this will <strong>throw a <code>TypeError</code> instead</strong>. Likewise, incrementing booleans or empty strings will behave more strictly. For instance:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$bar</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">true</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #E06C75;">$bar</span><span style="color: #ABB2BF;">++;</span></div><div class='line'><span style="color: #56B6C2;">var_dump</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$bar</span><span style="color: #ABB2BF;">);  </span><span style="color: #7F848E;">// PHP 8.x: bool(true), PHP 9.0: int(2)</span></div></code></pre>
<p>and</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$baz</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;&#39;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #E06C75;">$baz</span><span style="color: #ABB2BF;">--;        </span><span style="color: #7F848E;">// In PHP 8.x this yields int(-1), but in PHP 9.0 it will throw a TypeError.</span></div></code></pre>
<p>These changes are part of the “Path to Saner Increment” RFC. The goal is to <strong>make <code>++</code>/<code>--</code> more predictable</strong>. Under PHP 9.0:</p>
<ul>
<li><strong>No more implicit string wrapping</strong> (<code>'z'++</code> or <code>'a9'++</code> won’t silently roll over).</li>
<li><strong>Booleans and <code>null</code> are treated as numeric</strong>: incrementing <code>true</code> becomes <code>2</code> rather than <code>true</code>.</li>
<li><strong>Empty strings no longer become numbers</strong> (empty string <code>''</code> will not auto-convert to 0; doing so throws an error).</li>
<li>A new helper function <code>str_increment()</code> is introduced for the old string behavior if needed.</li>
</ul>
<p>These updates eliminate many subtle bugs. In practice, if your code relied on weird auto-incrementing, you’ll need to update it. Otherwise, most modern codebases will simply find <code>++</code>/<code>--</code> safer and more consistent.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/saner-inc-dec-operators">Path to Saner Increment/Decrement operators</a></p>
<h3><a id="2-exceptions-for-unserialization-errors" href="#2-exceptions-for-unserialization-errors" class="" aria-hidden="true" title=""></a>2. Exceptions for Unserialization Errors</h3>
<p>In PHP 8.x, calling <code>unserialize()</code> on invalid data emits a warning and returns <code>false</code>. PHP 9.0 changes this to throw an exception. For example:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// PHP 8.x:</span></div><div class='line'><span style="color: #E06C75;">$result</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">unserialize</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&quot;invalid&quot;</span><span style="color: #ABB2BF;">); </span><span style="color: #7F848E;">// emits a warning: &quot;Error at offset 0&quot;, returns false</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// PHP 9.0:</span></div><div class='line'><span style="color: #E06C75;">$result</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">unserialize</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&quot;invalid&quot;</span><span style="color: #ABB2BF;">); </span><span style="color: #7F848E;">// throws UnserializationFailedException</span></div></code></pre>
<p>This is driven by the RFC “Improve unserialize() error handling”. By converting these warnings into <code>UnserializationFailedException</code>, PHP 9.0 makes error handling more explicit and secure. Developers can now use <code>try/catch</code> around <code>unserialize()</code>, avoiding hidden issues:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">try</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$obj</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">unserialize</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">} </span><span style="color: #C678DD;">catch</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">UnserializationFailedException</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$e</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// handle error gracefully</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>This change also ties into the <em>Phasing out <code>Serializable</code></em> RFC: in PHP 9.0 the old <code>Serializable</code> interface will be removed, and payloads using the legacy “C” serialization format will be rejected. In short, PHP’s serialization becomes stricter and modernized.</p>
<p>RFCs: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/improve_unserialize_error_handling">Improve unserialize() error handling</a> · <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/phase_out_serializable">Phasing out Serializable</a></p>
<h3><a id="3-simplified-function-signatures" href="#3-simplified-function-signatures" class="" aria-hidden="true" title=""></a>3. Simplified Function Signatures</h3>
<p>Several built-in functions and methods will be split or renamed for clarity. A notable example is <strong>overloaded signatures</strong>. Take <code>array_keys()</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// PHP 8.x:</span></div><div class='line'><span style="color: #E06C75;">$keys</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">array_keys</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$myArray</span><span style="color: #ABB2BF;">);                      </span><span style="color: #7F848E;">// all keys</span></div><div class='line'><span style="color: #E06C75;">$keys</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">array_keys</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$myArray</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;value&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">true</span><span style="color: #ABB2BF;">);       </span><span style="color: #7F848E;">// only keys with matching value</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// PHP 9.0 (example RFC):</span></div><div class='line'><span style="color: #E06C75;">$keys</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">array_keys</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$myArray</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$keys</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">array_keys_filter</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$myArray</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;value&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">true</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>Here, PHP 9.0 introduces a new function (e.g. <code>array_keys_filter</code>) to handle the second mode, rather than having one function do two jobs. Another example is <code>DatePeriod</code>’s constructor:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// PHP 8.x:</span></div><div class='line'><span style="color: #E06C75;">$period</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DatePeriod</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$start</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$interval</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$end</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$period</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DatePeriod</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;R4/2012-07-01T00:00:00Z/P7D&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// PHP 9.0:</span></div><div class='line'><span style="color: #E06C75;">$period</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DatePeriod</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$start</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$interval</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$end</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$period</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DatePeriod</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">createFromISO8601String</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;R4/2012-07-01T00:00:00Z/P7D&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>The advantage is clearer APIs: each function does one thing, making code easier to understand. This transition will be staged over PHP 8.x (new functions in 8.3, deprecation warnings in 8.4, removal by 9.0).</p>
<p>RFCs: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/deprecate_functions_with_overloaded_signatures">Deprecate functions with overloaded signatures</a> · <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/deprecations_php_8_1">Deprecations for PHP 8.1</a></p>
<h3><a id="4-no-autovivification-arrays-from-false" href="#4-no-autovivification-arrays-from-false" class="" aria-hidden="true" title=""></a>4. No Autovivification (Arrays from False)</h3>
<p>PHP’s “autovivification” of arrays automatically turning a <code>false</code> or <code>null</code> into an array when you append to it will be disallowed in PHP 9.0. For example:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$arr</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">false</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #E06C75;">$arr</span><span style="color: #ABB2BF;">[] </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">2</span><span style="color: #ABB2BF;">;   </span><span style="color: #7F848E;">// PHP 8.x: converts $arr to [2]</span></div></code></pre>
<p>In PHP 9.0 this will <strong>error out</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$arr</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">false</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #E06C75;">$arr</span><span style="color: #ABB2BF;">[] </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">2</span><span style="color: #ABB2BF;">;   </span><span style="color: #7F848E;">// PHP 9.0: Error - cannot use a scalar as an array</span></div></code></pre>
<p>This change comes from the “Deprecate autovivification on false” RFC. Since other scalars like <code>true</code> or <code>0</code> already error, making <code>false</code> behave the same removes a special case. It eliminates a common bug where invalid data silently turned into an array. In practice, code should now explicitly initialize arrays (e.g. <code>$arr = []</code>) before appending, rather than relying on this quirk.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/autovivification_false">Deprecate autovivification on false</a></p>
<h3><a id="5-simplified-string-interpolation" href="#5-simplified-string-interpolation" class="" aria-hidden="true" title=""></a>5. Simplified String Interpolation</h3>
<p>PHP 9.0 will streamline how variables can be inserted into strings. Currently PHP supports several syntaxes:</p>
<ul>
<li>Double quotes with simple variable: <code>&quot;$foo&quot;</code></li>
<li>Braces around variable: <code>&quot;{$foo}&quot;</code></li>
<li>Braces after dollar: <code>&quot;${foo}&quot;</code></li>
<li>Variable variables in strings: <code>&quot;${expr}&quot;</code></li>
</ul>
<p>PHP 9.0 will <strong>remove</strong> the “braces after dollar” and variable-variable syntax (the last two above). That means code like:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$foo</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;world&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;Hello </span><span style="color: #E06C75;">${foo}</span><span style="color: #98C379;">&quot;</span><span style="color: #ABB2BF;">;   </span><span style="color: #7F848E;">// This will cause an error in PHP 9.0</span></div></code></pre>
<p>will no longer be allowed. Only the standard forms remain:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;Hello </span><span style="color: #E06C75;">$foo</span><span style="color: #98C379;">&quot;</span><span style="color: #ABB2BF;">;     </span><span style="color: #7F848E;">// OK</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;Hello {</span><span style="color: #E06C75;">$foo</span><span style="color: #98C379;">}&quot;</span><span style="color: #ABB2BF;">;   </span><span style="color: #7F848E;">// OK</span></div></code></pre>
<p>The RFC “Deprecate <code>${}</code> string interpolation” explains that the <code>${}</code> syntax is confusing and rarely needed. By removing it, PHP encourages a single, clearer interpolation style. This also avoids subtle parsing issues in complex strings.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/deprecate_dollar_brace_string_interpolation">Deprecate ${} string interpolation</a></p>
<h3><a id="6-warnings-become-fatal-errors" href="#6-warnings-become-fatal-errors" class="" aria-hidden="true" title=""></a>6. Warnings Become Fatal Errors</h3>
<p>Several warnings in PHP 8.x will be escalated to errors in PHP 9.0. In particular, referencing undefined variables or properties which today emits a warning will instead produce a <strong>fatal error</strong>. For example:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// PHP 8.x:</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$undefinedVar</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #7F848E;">// Warning: Undefined variable $undefinedVar</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// PHP 9.0:</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$undefinedVar</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #7F848E;">// Fatal error: Uncaught Error: Undefined variable &#39;$undefinedVar&#39;</span></div></code></pre>
<p>This change (via RFCs “Undefined Variable Error Promotion” and “Undefined Property Error Promotion”) means lax coding patterns will break. The intent is to catch mistakes early, e.g. typos or forgotten initializations, rather than letting them slide. Other warnings could also become errors, so developers must run code with <code>E_ALL</code> and fix any notices. In short, PHP 9.0 promotes cleaner, error-free code by default.</p>
<p>RFCs: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/undefined_variable_error_promotion">Undefined variable error promotion</a> · <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/undefined_property_error_promotion">Undefined property error promotion</a></p>
<h3><a id="7-removal-of-deprecated-features" href="#7-removal-of-deprecated-features" class="" aria-hidden="true" title=""></a>7. Removal of Deprecated Features</h3>
<p>Any features deprecated in PHP 8.1-8.4 will be removed in PHP 9.0. This means updating legacy code is critical. Examples include:</p>
<ul>
<li><strong>Old-style constructors</strong> (PHP 5.x style class constructors are long gone).</li>
<li><strong>GMP and ext-specific deprecations</strong> (e.g. certain extensions phased out).</li>
<li><strong>Other array/string behavior</strong> like the autovivification and string interpolation above.</li>
</ul>
<p>The exact list comes from the RFCs for PHP 8.1, 8.2, 8.3, and 8.4 deprecations. In practice, any deprecation warning you see on PHP 8.3 now must be resolved before upgrading to 9.0. This cleanup keeps PHP modern but means <em>breaking changes</em> for older code. All deprecated functions, dynamic properties (if triggered), and legacy behavior will finally disappear.</p>
<p>RFC references: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/deprecations_php_8_1">Deprecations for PHP 8.1</a> · <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/deprecations_php_8_2">Deprecations for PHP 8.2</a> · <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/deprecations_php_8_3">Deprecations for PHP 8.3</a> · <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/deprecations_php_8_4">Deprecations for PHP 8.4</a> · <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/deprecations_php_8_5">Deprecations for PHP 8.5</a> · <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/deprecations_php_8_6">Deprecations for PHP 8.6</a></p>
<h3><a id="8-removal-of-partially-supported-callables" href="#8-removal-of-partially-supported-callables" class="" aria-hidden="true" title=""></a>8. Removal of Partially Supported Callables</h3>
<p>Some callable formats have historically been accepted by functions like <code>call_user_func()</code> and by <code>is_callable()</code>, but were never fully supported by the <code>$callable()</code> invocation syntax. PHP 9.0 is planned to <strong>remove support</strong> for these “partially supported callables,” such as:</p>
<ul>
<li><code>&quot;self::method&quot;</code>, <code>&quot;parent::method&quot;</code>, <code>&quot;static::method&quot;</code></li>
<li><code>[&quot;self&quot;, &quot;method&quot;]</code>, <code>[&quot;parent&quot;, &quot;method&quot;]</code>, <code>[&quot;static&quot;, &quot;method&quot;]</code></li>
</ul>
<p>Code that relies on these patterns will need to switch to fully supported callables (e.g. <code>Foo::class . &quot;::method&quot;</code>, <code>[Foo::class, &quot;method&quot;]</code>, or <code>[new Foo(), &quot;method&quot;]</code>).</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/deprecate_partially_supported_callables">Deprecate partially supported callables</a></p>
<h3><a id="9-stricter-explicit-casts-no-more-fuzzy-casts" href="#9-stricter-explicit-casts-no-more-fuzzy-casts" class="" aria-hidden="true" title=""></a>9. Stricter Explicit Casts (No More “Fuzzy” Casts)</h3>
<p>PHP’s explicit casts have historically allowed conversions that silently <strong>discard information</strong> (for example, turning <code>&quot;123abc&quot;</code> into <code>123</code>). A newer proposal tightens this up by <strong>deprecating fuzzy casts in PHP 8.6</strong> and making them <strong>throw <code>TypeError</code> in PHP 9.0</strong>.</p>
<p>Examples of the behavior targeted by the RFC:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// Partial string conversions (currently succeed by discarding trailing data)</span></div><div class='line'><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">int</span><span style="color: #ABB2BF;">) </span><span style="color: #98C379;">&quot;123abc&quot;</span><span style="color: #ABB2BF;">;      </span><span style="color: #7F848E;">// PHP 9.0: TypeError</span></div><div class='line'><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">float</span><span style="color: #ABB2BF;">) </span><span style="color: #98C379;">&quot;12.5foo&quot;</span><span style="color: #ABB2BF;">;  </span><span style="color: #7F848E;">// PHP 9.0: TypeError</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Scalar-to-object casts (currently create a stdClass wrapper)</span></div><div class='line'><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">object</span><span style="color: #ABB2BF;">) </span><span style="color: #D19A66;">42</span><span style="color: #ABB2BF;">;         </span><span style="color: #7F848E;">// PHP 9.0: TypeError</span></div><div class='line'><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">object</span><span style="color: #ABB2BF;">) </span><span style="color: #98C379;">&quot;hello&quot;</span><span style="color: #ABB2BF;">;   </span><span style="color: #7F848E;">// PHP 9.0: TypeError</span></div></code></pre>
<p>The goal is to align explicit cast behavior with the validation rules already used for typed parameters in non-strict mode.</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/deprecate-fuzzy-and-null-casts">Deprecate fuzzy and null casts</a></p>
<h3><a id="10-implicit-bool-to-string-coercion-becomes-a-typeerror" href="#10-implicit-bool-to-string-coercion-becomes-a-typeerror" class="" aria-hidden="true" title=""></a>10. Implicit Bool-to-String Coercion Becomes a TypeError</h3>
<p>Implicitly converting booleans to strings is being treated as a likely-bug pattern (<code>false</code> becomes <code>''</code>, <code>true</code> becomes <code>'1'</code>). The proposal is to emit <code>E_DEPRECATED</code> first and then <strong>raise it to a <code>TypeError</code> in PHP 9.0</strong>.</p>
<p>For example:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$flag</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">false</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;Value: &quot;</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$flag</span><span style="color: #ABB2BF;">; </span><span style="color: #7F848E;">// PHP 9.0: TypeError (after deprecation period)</span></div></code></pre>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/deprecate-boolean-string-coercion">Deprecate boolean to string coercion</a></p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/make_ctor_ret_void">Make constructors and destructors return void</a></p>
<h3><a id="11-php-90-drops-32-bit-builds" href="#11-php-90-drops-32-bit-builds" class="" aria-hidden="true" title=""></a>11. PHP 9.0 Drops 32-bit Builds</h3>
<p>There is an active proposal to <strong>deprecate 32-bit support in the next PHP 8.x release</strong> and <strong>fully remove 32-bit builds in PHP 9.0</strong>. That means PHP 9.0 would no longer be buildable or runnable on 32-bit environments.</p>
<p>This is primarily motivated by platform trends and by long-standing 32-bit limitations (e.g., 2GB-ish limits and timestamp range issues).</p>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/drop_32bit_support">Drop 32-bit Builds</a></p>
<h3><a id="12-enum-introspection-cleanup-getdeclaredenums-and-classexists-semantics" href="#12-enum-introspection-cleanup-getdeclaredenums-and-classexists-semantics" class="" aria-hidden="true" title=""></a>12. Enum Introspection Cleanup (<code>get_declared_enums()</code> and <code>class_exists()</code> semantics)</h3>
<p>A proposal adds a new <code>get_declared_enums()</code> function and tightens the meaning of “class” in reflection-style helpers:</p>
<ul>
<li><code>class_exists()</code> would be <strong>deprecated for enums</strong> in PHP 8.x and <strong>return <code>false</code> for enums in PHP 9.0</strong>.</li>
<li><code>get_declared_classes()</code> would stop returning enums in PHP 9.0.</li>
</ul>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">enum Status { </span><span style="color: #C678DD;">case</span><span style="color: #ABB2BF;"> Draft; }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">var_dump</span><span style="color: #ABB2BF;">(</span><span style="color: #61AFEF;">enum_exists</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Status</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">));  </span><span style="color: #7F848E;">// true</span></div><div class='line'><span style="color: #56B6C2;">var_dump</span><span style="color: #ABB2BF;">(</span><span style="color: #56B6C2;">class_exists</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Status</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)); </span><span style="color: #7F848E;">// PHP 9.0: false</span></div></code></pre>
<p>RFC: <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/get_declared_enums">Add get_declared_enums() function</a></p>
<h3><a id="13-dynamic-properties-become-errors-unless-explicitly-allowed" href="#13-dynamic-properties-become-errors-unless-explicitly-allowed" class="" aria-hidden="true" title=""></a>13. Dynamic Properties Become Errors (Unless Explicitly Allowed)</h3>
<p>In PHP, assigning to an undeclared property has historically created a <em>dynamic property</em> silently. This is now on a removal path: it was deprecated in PHP 8.2, and in <strong>PHP 9.0 it will throw an <code>Error</code></strong> unless the class explicitly opts in.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">string</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$name</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">nane</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;typo&quot;</span><span style="color: #ABB2BF;">; </span><span style="color: #7F848E;">// PHP 8.2: deprecation, PHP 9.0: Error</span></div></code></pre>
<p>To keep intentional dynamic properties, PHP introduces <code>#[AllowDynamicProperties]</code> (and <code>stdClass</code> continues to allow them). Otherwise, declare the property, use <code>__get()</code>/<code>__set()</code>, or store external data in a <code>WeakMap</code>.</p>
<p><a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/deprecate_dynamic_properties">RFC: Deprecate dynamic properties</a></p>
<h3><a id="14-null-to-non-nullable-internal-scalar-arguments-throws-typeerror" href="#14-null-to-non-nullable-internal-scalar-arguments-throws-typeerror" class="" aria-hidden="true" title=""></a>14. <code>null</code> to Non-Nullable Internal Scalar Arguments Throws <code>TypeError</code></h3>
<p>Historically, many <strong>internal</strong> functions in PHP would accept <code>null</code> for non-nullable scalar parameters in weak mode and silently coerce it (often to <code>&quot;&quot;</code>, <code>0</code>, or <code>false</code>). This behavior was deprecated in PHP 8.1 and becomes a <strong><code>TypeError</code> in PHP 9.0</strong>, matching userland function behavior.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// Example behavior change:</span></div><div class='line'><span style="color: #56B6C2;">strlen</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">); </span><span style="color: #7F848E;">// PHP 8.1+: E_DEPRECATED, PHP 9.0: TypeError</span></div></code></pre>
<p>The practical fix is to explicitly handle <code>null</code> before calling the function (or supply a default), rather than relying on implicit coercion.</p>
<p><a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/deprecate_null_to_scalar_internal_arg">RFC: Deprecate passing null to non-nullable arguments of internal functions</a></p>
<h3><a id="15-removal-of-utf8encode-and-utf8decode" href="#15-removal-of-utf8encode-and-utf8decode" class="" aria-hidden="true" title=""></a>15. Removal of <code>utf8_encode()</code> and <code>utf8_decode()</code></h3>
<p>In PHP 9.0, <code>utf8_encode()</code> and <code>utf8_decode()</code> are removed. Codebases that still use them should migrate to supported encoding conversion APIs (the RFC highlights <code>mb_convert_encoding()</code> as the primary replacement, with <code>UConverter::transcode()</code> and <code>iconv()</code> as alternatives).</p>
<p><a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/remove_utf8_decode_and_utf8_encode">RFC: Remove utf8_encode and utf8_decode</a></p>
<h3><a id="16-removal-of-getpost-session-ids-usetranssid-and-the-sid-constant" href="#16-removal-of-getpost-session-ids-usetranssid-and-the-sid-constant" class="" aria-hidden="true" title=""></a>16. Removal of GET/POST Session IDs, <code>use_trans_sid</code>, and the <code>SID</code> Constant</h3>
<p>PHP’s legacy ability to propagate session IDs via GET/POST parameters (and automatically rewrite URLs via <code>use_trans_sid</code>) is on a removal track. The related INI settings and the <code>SID</code> constant are deprecated (targeted in PHP 8.4) and are intended to be <strong>removed in PHP 9.0</strong>.</p>
<p>This pushes session handling firmly toward cookie-based sessions (or explicit, application-level fallbacks when cookies can’t be used).</p>
<p><a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/deprecate-get-post-sessions">RFC: Deprecate GET/POST sessions</a></p>
<h3><a id="17-fuzzy-scalar-casts-become-typeerror-proposal" href="#17-fuzzy-scalar-casts-become-typeerror-proposal" class="" aria-hidden="true" title=""></a>17. Fuzzy Scalar Casts Become <code>TypeError</code> (Proposal)</h3>
<p>A newer proposal (currently <strong>under discussion</strong>) targets “fuzzy” casts—cases where explicit casts discard information (like partially parsing numeric strings) or create arbitrary structures (like casting scalars to <code>(object)</code>). The RFC proposes deprecations in PHP 8.6 and converting these cases into <strong><code>TypeError</code> in PHP 9.0</strong>.</p>
<p>Examples of affected patterns include:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">int</span><span style="color: #ABB2BF;">) </span><span style="color: #98C379;">&quot;123abc&quot;</span><span style="color: #ABB2BF;">;   </span><span style="color: #7F848E;">// currently truncates to 123</span></div><div class='line'><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">float</span><span style="color: #ABB2BF;">) </span><span style="color: #98C379;">&quot;12.5foo&quot;</span><span style="color: #ABB2BF;">; </span><span style="color: #7F848E;">// currently truncates to 12.5</span></div><div class='line'><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">object</span><span style="color: #ABB2BF;">) </span><span style="color: #D19A66;">42</span><span style="color: #ABB2BF;">;        </span><span style="color: #7F848E;">// currently produces stdClass with a scalar property</span></div></code></pre>
<p>If accepted, this would further reduce “surprising” conversions and align casts with the validation rules already used for weak-mode typed parameters.</p>
<p><a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc/deprecate-fuzzy-and-null-casts">RFC: Deprecate Fuzzy Scalar Casts</a></p>
<h2><a id="how-to-prepare-and-migrate" href="#how-to-prepare-and-migrate" class="" aria-hidden="true" title=""></a>How to Prepare and Migrate</h2>
<p>Given these changes, PHP developers should start preparing now. Key recommendations include:</p>
<ul>
<li><strong>Enable strict error reporting.</strong> Run your code on PHP 8.3+ with <code>error_reporting(E_ALL)</code> and fix every warning and notice. All deprecation warnings (e.g. old constructors, array/string quirks) should be addressed immediately.</li>
<li><strong>Refactor for type predictability.</strong> Avoid relying on implicit type conversions. For example, don’t depend on <code>false</code> magically becoming an array. Initialize variables explicitly, and prefer type-safe code.</li>
<li><strong>Catch unserialization failures.</strong> Audit any calls to <code>unserialize()</code> and wrap them in <code>try/catch</code> for <code>UnserializationFailedException</code>. Remove use of <code>Serializable</code> if possible, as it will be phased out.</li>
<li><strong>Follow RFC discussions.</strong> Stay active in PHP internals and community channels. The language continues to evolve, and being aware of accepted RFCs (via <a rel="nofollow noopener" target="_blank" href="https://wiki.php.net/rfc">wiki.php.net/rfc</a>) helps you know what’s coming.</li>
<li><strong>Test on pre-release versions.</strong> When PHP 9.0 alpha/betas appear, run your test suites and applications immediately. Catching incompatibilities early is far easier than after release.</li>
<li><strong>Monitor frameworks and libraries.</strong> Update to the latest versions of frameworks (Laravel, Symfony, etc.) that support PHP 9.0 as they become available. Library authors will likely release compatibility updates once 9.0 stabilizes.</li>
</ul>
<p>Following these steps ensures a smoother upgrade path. Notably, sources emphasize <strong>fixing all deprecation warnings now</strong> and <strong>using explicit error handling</strong> so that PHP 9.0’s strictness becomes a feature, not a surprise.</p>
<h2><a id="impact-on-the-php-ecosystem" href="#impact-on-the-php-ecosystem" class="" aria-hidden="true" title=""></a>Impact on the PHP Ecosystem</h2>
<p>The PHP community and major sub-communities (Symfony, Laravel, WordPress, etc.) will need to adapt to PHP 9.0’s changes. None of our sources explicitly detail framework-specific updates, but we can extrapolate:</p>
<ul>
<li><strong>Modern frameworks (Laravel, Symfony, etc.)</strong> typically target the latest PHP versions. They are likely already writing code that assumes strict types and explicit handling. These frameworks will probably <strong>embrace PHP 9.0 quickly</strong> updating internal code to remove deprecated features and leveraging new functions/APIs.</li>
<li><strong>WordPress</strong> is more conservative, supporting many older PHP releases for backwards compatibility. As such, the WordPress core team will likely take time to prepare. We can expect WordPress 7.0 (or another major release) to raise its minimum PHP requirement. Plugins and themes will need testing: any reliance on dynamic properties or autovivification must be fixed.</li>
<li><strong>PHP-FIG and Community Standards:</strong> PSR standards and shared libraries may be updated to reflect PHP 9.0 practices.</li>
<li><strong>Education and Adoption:</strong> The community will produce guides (like this one) and migration tools (like Rector sets) to help projects upgrade.</li>
</ul>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>PHP 9.0 promises to be a <em>cleaner, more predictable language</em> than ever before. Its planned changes predictable operators, exception-based errors, streamlined syntax, and removal of legacy behavior may introduce breaking changes, but they ultimately strengthen PHP for future development. By taking action now (fixing deprecations, refactoring code, engaging with RFCs), developers can ensure a smooth transition. The end result will be PHP codebases that fail fast on genuine errors, leading to more robust web applications. As one source summarizes: “PHP 9.0 is shaping up to be a release that prioritizes predictability, stricter error handling, and cleaner syntax,” making the language <em>more modern and developer-friendly</em>.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Thu, 18 Dec 2025 21:21:07 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[How to Read and Get URL Parameters in PHP]]></title>
                <link>https://nabilhassen.com/how-to-read-and-get-url-parameters-in-php</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#getting--extracting-url-query-parameters-in-php">Getting &amp; Extracting URL Query Parameters in PHP</a></li>
<li><a href="#what-are-url-parameters--query-strings">What are URL parameters / query strings?</a></li>
<li><a href="#phps-builtin-mechanism-get">PHP’s built‑in mechanism: $_GET</a></li>
<li><a href="#extracting-from-an-arbitrary-url-string">Extracting from an arbitrary URL string</a>
<ul>
<li><a href="#parseurl--parsestr">parse_url() + parse_str()</a></li>
<li><a href="#regex-alternative">Regex alternative</a></li>
</ul>
</li>
<li><a href="#getting-the-full-current-url">Getting the full current URL</a></li>
<li><a href="#helper-functions">Helper functions</a></li>
<li><a href="#edge-cases--best-practices">Edge Cases &amp; Best Practices</a></li>
<li><a href="#summary">Summary</a></li>
</ul>
<h2><a id="getting--extracting-url-query-parameters-in-php" href="#getting--extracting-url-query-parameters-in-php" class="" aria-hidden="true" title=""></a>Getting &amp; Extracting URL Query Parameters in PHP</h2>
<p>When building PHP web applications, it's very common to need to read values passed via the URL (the “query string” or GET parameters). In this post, we'll cover:</p>
<ul>
<li>What URL parameters (query strings) are</li>
<li>How PHP makes them available</li>
<li>How to parse parameters from a URL string</li>
<li>Useful helper functions</li>
<li>Edge cases, security, and best practices</li>
</ul>
<h2><a id="what-are-url-parameters--query-strings" href="#what-are-url-parameters--query-strings" class="" aria-hidden="true" title=""></a>What are URL parameters / query strings?</h2>
<p>A URL parameter (or query string) is the portion of a URL after the <code>?</code> character, with key/value pairs separated by <code>&amp;</code>. For example:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">https://example.com/search.php?q=php&amp;lang=en&amp;page=2</span></div></code></pre>
<p>Here:</p>
<ul>
<li><code>q</code> = <code>php</code></li>
<li><code>lang</code> = <code>en</code></li>
<li><code>page</code> = <code>2</code></li>
</ul>
<p>These are traditionally accessed via <strong>HTTP GET</strong>. They allow passing small amounts of data in the URL itself.</p>
<h2><a id="phps-builtin-mechanism-get" href="#phps-builtin-mechanism-get" class="" aria-hidden="true" title=""></a>PHP’s built‑in mechanism: <code>$_GET</code></h2>
<p>The simplest and most common way to access URL parameters in PHP is via the <strong>superglobal</strong> <code>$_GET</code>. This is an associative array that PHP fills from the query string of the current request.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'><span style="color: #7F848E;">// Suppose URL is: http://mysite.com/page.php?user=alice&amp;age=30</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$_GET</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;user&#39;</span><span style="color: #ABB2BF;">];  </span><span style="color: #7F848E;">// “alice”</span></div><div class='line'><span style="color: #E06C75;">$age</span><span style="color: #ABB2BF;">  </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$_GET</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;age&#39;</span><span style="color: #ABB2BF;">];   </span><span style="color: #7F848E;">// “30”</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Better: check existence</span></div><div class='line'><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">isset</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$_GET</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;user&#39;</span><span style="color: #ABB2BF;">])) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$_GET</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;user&#39;</span><span style="color: #ABB2BF;">];</span></div><div class='line'><span style="color: #ABB2BF;">} </span><span style="color: #C678DD;">else</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'><span style="color: #BE5046;">?&gt;</span></div></code></pre>
<p>You can also use the <strong>null coalescing operator</strong> (PHP 7+):</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$_GET</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;user&#39;</span><span style="color: #ABB2BF;">] ?? </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<p>With filtering:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">filter_input</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">INPUT_GET</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;user&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">FILTER_SANITIZE_STRING</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>Notes:</p>
<ul>
<li><code>$_GET</code> works whenever a query string is present, regardless of request method.</li>
<li>Always validate and sanitize data.</li>
<li>Use <code>isset()</code>, <code>??</code>, or <code>filter_input()</code> to avoid notices.</li>
<li>Arrays (<code>?arr[]=foo&amp;arr[]=bar</code>) are automatically handled.</li>
</ul>
<h2><a id="extracting-from-an-arbitrary-url-string" href="#extracting-from-an-arbitrary-url-string" class="" aria-hidden="true" title=""></a>Extracting from an arbitrary URL string</h2>
<p>Sometimes you need to parse parameters from a URL string, not the current request. In that case:</p>
<h3><a id="parseurl--parsestr" href="#parseurl--parsestr" class="" aria-hidden="true" title=""></a><code>parse_url()</code> + <code>parse_str()</code></h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;https://example.com/path?foo=bar&amp;baz=qux&amp;arr[]=one&amp;arr[]=two&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$parts</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">parse_url</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">!empty</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$parts</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;query&#39;</span><span style="color: #ABB2BF;">])) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #56B6C2;">parse_str</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$parts</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;query&#39;</span><span style="color: #ABB2BF;">],</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$queryParams</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// [&quot;foo&quot;=&gt;&quot;bar&quot;, &quot;baz&quot;=&gt;&quot;qux&quot;, &quot;arr&quot;=&gt;[&quot;one&quot;, &quot;two&quot;] ]</span></div><div class='line'><span style="color: #ABB2BF;">} </span><span style="color: #C678DD;">else</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$queryParams</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [];</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'><span style="color: #BE5046;">?&gt;</span></div></code></pre>
<p>Or shorter:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #56B6C2;">parse_str</span><span style="color: #ABB2BF;">(</span><span style="color: #56B6C2;">parse_url</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">PHP_URL_QUERY</span><span style="color: #ABB2BF;">),</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$queryParams</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>Cautions:</p>
<ul>
<li>Don’t call <code>parse_str()</code> without the second argument, it pollutes the local scope.</li>
<li>Spaces/dots in keys become underscores.</li>
<li><code>max_input_vars</code> can limit the number of parameters parsed.</li>
</ul>
<h3><a id="regex-alternative" href="#regex-alternative" class="" aria-hidden="true" title=""></a>Regex alternative</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">preg_match</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">&quot;/[?&amp;]foo=([^&amp;]</span><span style="color: #C678DD;">+</span><span style="color: #E06C75;">)/&quot;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$matches</span><span style="color: #ABB2BF;">)) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$fooVal</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">urldecode</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$matches</span><span style="color: #ABB2BF;">[</span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">]);</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>But this is brittle, built‑ins are preferred.</p>
<h2><a id="getting-the-full-current-url" href="#getting-the-full-current-url" class="" aria-hidden="true" title=""></a>Getting the full current URL</h2>
<p>If you need the complete current request URL:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">getCurrentUrl</span><span style="color: #ABB2BF;">(): </span><span style="color: #E5C07B;">string</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$scheme</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">isset</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$_SERVER</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;HTTPS&#39;</span><span style="color: #ABB2BF;">]) </span><span style="color: #56B6C2;">&amp;&amp;</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$_SERVER</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;HTTPS&#39;</span><span style="color: #ABB2BF;">] </span><span style="color: #56B6C2;">===</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;on&#39;</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">?</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;https&quot;</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">:</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;http&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$host</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$_SERVER</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;HTTP_HOST&#39;</span><span style="color: #ABB2BF;">];</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$uri</span><span style="color: #ABB2BF;">  </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$_SERVER</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;REQUEST_URI&#39;</span><span style="color: #ABB2BF;">];</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$scheme</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;://&quot;</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$host</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$uri</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$current</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">getCurrentUrl</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$current</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #BE5046;">?&gt;</span></div></code></pre>
<p>This gives something like:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">https://example.com/search.php?lang=en&amp;q=php</span></div></code></pre>
<h2><a id="helper-functions" href="#helper-functions" class="" aria-hidden="true" title=""></a>Helper functions</h2>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">getQueryParams</span><span style="color: #ABB2BF;">(?</span><span style="color: #E5C07B;">string</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">array</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">===</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$qs</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$_SERVER</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;QUERY_STRING&#39;</span><span style="color: #ABB2BF;">] ?? </span><span style="color: #98C379;">&#39;&#39;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #56B6C2;">parse_str</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$qs</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$params</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$params</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$parts</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">parse_url</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">empty</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$parts</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;query&#39;</span><span style="color: #ABB2BF;">])) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> [];</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #56B6C2;">parse_str</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$parts</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;query&#39;</span><span style="color: #ABB2BF;">],</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$params</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$params</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">getParam</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">string</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$key</span><span style="color: #ABB2BF;">, ?</span><span style="color: #E5C07B;">string</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$default</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$params</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">getQueryParams</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$params</span><span style="color: #ABB2BF;">[</span><span style="color: #E06C75;">$key</span><span style="color: #ABB2BF;">] ?? </span><span style="color: #E06C75;">$default</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'><span style="color: #BE5046;">?&gt;</span></div></code></pre>
<p>Usage:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$params</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">getQueryParams</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&quot;https://example.com/?a=1&amp;b=2&quot;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$email</span><span style="color: #ABB2BF;">  </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">getParam</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;email&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<h2><a id="edge-cases--best-practices" href="#edge-cases--best-practices" class="" aria-hidden="true" title=""></a>Edge Cases &amp; Best Practices</h2>
<table>
<thead>
<tr>
<th>Concern</th>
<th>Tip</th>
</tr>
</thead>
<tbody>
<tr>
<td>Missing keys</td>
<td>Use <code>isset()</code>, <code>??</code>, or <code>array_key_exists</code>.</td>
</tr>
<tr>
<td>URL encoding</td>
<td>Automatically handled by PHP.</td>
</tr>
<tr>
<td>Repeated keys</td>
<td><code>parse_str()</code> keeps the last value unless <code>[]</code> syntax is used.</td>
</tr>
<tr>
<td>Many params</td>
<td>Limited by <code>max_input_vars</code>.</td>
</tr>
<tr>
<td>Security</td>
<td>Always validate and sanitize.</td>
</tr>
<tr>
<td>Malformed URLs</td>
<td>Guard against invalid inputs.</td>
</tr>
</tbody>
</table>
<h2><a id="summary" href="#summary" class="" aria-hidden="true" title=""></a>Summary</h2>
<ol>
<li>Use <code>$_GET</code> for current request parameters.</li>
<li>Use <code>parse_url()</code> + <code>parse_str()</code> for arbitrary URLs.</li>
<li>Encapsulate parsing in helpers.</li>
<li>Always validate and sanitize input.</li>
</ol>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Wed, 24 Sep 2025 19:19:52 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Laravel 12.29: Disable all global scopes except chosen]]></title>
                <link>https://nabilhassen.com/laravel-1229-disable-all-global-scopes-except-chosen</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#new-in-laravel-1229-withoutglobalscopesexcept">New in Laravel 12.29: withoutGlobalScopesExcept()</a></li>
<li><a href="#what-it-does">What it does</a></li>
<li><a href="#example">Example</a></li>
<li><a href="#why-it-matters">Why it matters</a></li>
</ul>
<h2><a id="new-in-laravel-1229-withoutglobalscopesexcept" href="#new-in-laravel-1229-withoutglobalscopesexcept" class="" aria-hidden="true" title=""></a>New in Laravel 12.29: <code>withoutGlobalScopesExcept()</code></h2>
<p>Laravel 12.29 introduces a handy new Eloquent method: <code>withoutGlobalScopesExcept()</code>. This lets you disable all global scopes on a query except the ones you explicitly want to keep.</p>
<h2><a id="what-it-does" href="#what-it-does" class="" aria-hidden="true" title=""></a>What it does</h2>
<p>Previously, you could:</p>
<ul>
<li>Use <code>withoutGlobalScope()</code> to remove one scope.</li>
<li>Use <code>withoutGlobalScopes()</code> to remove all or several scopes.</li>
</ul>
<p>Now, with:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">Post</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">withoutGlobalScopesExcept</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;tenant&#39;</span><span style="color: #ABB2BF;">])-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>You remove all global scopes <strong>except</strong> <code>tenant</code>.</p>
<h2><a id="example" href="#example" class="" aria-hidden="true" title=""></a>Example</h2>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Post</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Model</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">static</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">booted</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">static</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">addGlobalScope</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;published&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #C678DD;">fn</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$q</span><span style="color: #ABB2BF;">) =&gt; </span><span style="color: #E06C75;">$q</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">where</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;published&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">true</span><span style="color: #ABB2BF;">));</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">static</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">addGlobalScope</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;tenant&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #C678DD;">fn</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$q</span><span style="color: #ABB2BF;">) =&gt; </span><span style="color: #E06C75;">$q</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">where</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;tenant_id&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #61AFEF;">auth</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">id</span><span style="color: #ABB2BF;">()));</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Only keep the tenant scope:</span></div><div class='line'><span style="color: #E06C75;">$posts</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Post</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">withoutGlobalScopesExcept</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;tenant&#39;</span><span style="color: #ABB2BF;">])-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h2><a id="why-it-matters" href="#why-it-matters" class="" aria-hidden="true" title=""></a>Why it matters</h2>
<p>This feature makes queries more expressive and concise. Instead of manually disabling multiple scopes or re‑adding conditions, you can whitelist just the ones you need.</p>
<p>For details, see <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/56957">PR #56957</a>.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Thu, 18 Sep 2025 10:14:41 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Session Cache in Laravel 12.29]]></title>
                <link>https://nabilhassen.com/session-cache-in-laravel-1229</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#introducing-session-cache-in-laravel-1229">Introducing Session Cache in Laravel 12.29</a></li>
<li><a href="#what-is-session-cache">What is Session Cache?</a></li>
<li><a href="#when-should-you-use-it">When Should You Use It?</a></li>
<li><a href="#how-to-use-session-cache">How to Use Session Cache</a></li>
</ul>
<h2><a id="introducing-session-cache-in-laravel-1229" href="#introducing-session-cache-in-laravel-1229" class="" aria-hidden="true" title=""></a>Introducing Session Cache in Laravel 12.29</h2>
<p>Laravel 12.29 introduces a handy new feature called <strong>Session Cache</strong>, making it easier than ever to cache user-specific data that only needs to live as long as the user’s session.</p>
<p>This feature was added by <a rel="nofollow noopener" target="_blank" href="https://x.com/joaopalopess">João Lopes</a> in <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/56887">PR #56887</a>.</p>
<h2><a id="what-is-session-cache" href="#what-is-session-cache" class="" aria-hidden="true" title=""></a>What is Session Cache?</h2>
<p>The Session Cache provides a per-session scoped cache for your application. Unlike the global application cache, the data stored in session cache is:</p>
<ul>
<li>Isolated to each individual session</li>
<li>Automatically cleaned up when the session expires or is destroyed</li>
<li>Able to use all familiar Laravel cache methods, such as get, put, remember, and forget</li>
</ul>
<p>This makes it a perfect fit for storing ephemeral data that only matters during the lifetime of a session.</p>
<h2><a id="when-should-you-use-it" href="#when-should-you-use-it" class="" aria-hidden="true" title=""></a>When Should You Use It?</h2>
<p>Session Cache is ideal for temporary, user-specific data that doesn’t need to live permanently. Some examples include:</p>
<ul>
<li>Form data saved temporarily during a multi-step process.</li>
<li>Short-lived API responses tied to one user.</li>
<li>Calculations that only matter for the session.</li>
<li>Any ephemeral data tied to a user session.</li>
</ul>
<h2><a id="how-to-use-session-cache" href="#how-to-use-session-cache" class="" aria-hidden="true" title=""></a>How to Use Session Cache</h2>
<p>Accessing the session cache is simple using the <code>cache</code> method on the session instance.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// Retrieve a cached value from the session</span></div><div class='line'><span style="color: #E06C75;">$discount</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">session</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">cache</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;discount&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Store a value in the session cache with a 5-minute expiration</span></div><div class='line'><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">session</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">cache</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">put</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;discount&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">10</span><span style="color: #ABB2BF;">, </span><span style="color: #61AFEF;">now</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">addMinutes</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">5</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>The API will feel familiar to anyone who’s used Laravel’s Cache helper or facade before, with the key difference being the scope.</p>
<p>👉 Check out the full implementation in the <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/56887">pull request</a>.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Wed, 17 Sep 2025 20:05:12 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Laravel: whereBetween vs whereValueBetween vs whereBetweenColumns]]></title>
                <link>https://nabilhassen.com/laravel-wherebetween-vs-wherevaluebetween-vs-wherebetweencolumns</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#understanding-the-difference-between-wherebetween-wherebetweencolumns-and-wherevaluebetween-in-laravel">Understanding the Difference Between whereBetween, whereBetweenColumns, and whereValueBetween in Laravel</a></li>
<li><a href="#1-wherebetween">1. whereBetween</a>
<ul>
<li><a href="#example">Example</a></li>
<li><a href="#sql-translation">SQL Translation</a></li>
</ul>
</li>
<li><a href="#2-wherebetweencolumns">2. whereBetweenColumns</a>
<ul>
<li><a href="#example-1">Example</a></li>
<li><a href="#sql-translation-1">SQL Translation</a></li>
</ul>
</li>
<li><a href="#3-wherevaluebetween">3. whereValueBetween</a>
<ul>
<li><a href="#example-2">Example</a></li>
<li><a href="#sql-translation-2">SQL Translation</a></li>
</ul>
</li>
<li><a href="#quick-comparison">Quick Comparison</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="understanding-the-difference-between-wherebetween-wherebetweencolumns-and-wherevaluebetween-in-laravel" href="#understanding-the-difference-between-wherebetween-wherebetweencolumns-and-wherevaluebetween-in-laravel" class="" aria-hidden="true" title=""></a>Understanding the Difference Between <code>whereBetween</code>, <code>whereBetweenColumns</code>, and <code>whereValueBetween</code> in Laravel</h2>
<p>When working with Laravel's query builder, you'll often need to filter data based on ranges. Laravel provides three different methods to handle this: <code>whereBetween</code>, <code>whereBetweenColumns</code>, and <code>whereValueBetween</code>. While they sound similar, they serve different purposes and generate different SQL queries.</p>
<p>In this post, we'll break down the differences, show examples, and look at what each method translates to in raw SQL.</p>
<h2><a id="1-wherebetween" href="#1-wherebetween" class="" aria-hidden="true" title=""></a>1. <code>whereBetween</code></h2>
<p>The <code>whereBetween</code> method checks if a <strong>column's value</strong> falls between two fixed values.</p>
<h3><a id="example" href="#example" class="" aria-hidden="true" title=""></a>Example</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">whereBetween</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;votes&#39;</span><span style="color: #ABB2BF;">, [</span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">100</span><span style="color: #ABB2BF;">])</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h3><a id="sql-translation" href="#sql-translation" class="" aria-hidden="true" title=""></a>SQL Translation</h3>
<pre><code data-theme="one-dark-pro" data-lang="sql" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">select</span><span style="color: #ABB2BF;"> * </span><span style="color: #C678DD;">from</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">`users`</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">where</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">`votes`</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">between</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">and</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">100</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<p>✅ Use this when you want to filter a column against <strong>two constant values</strong>.</p>
<h2><a id="2-wherebetweencolumns" href="#2-wherebetweencolumns" class="" aria-hidden="true" title=""></a>2. <code>whereBetweenColumns</code></h2>
<p>The <code>whereBetweenColumns</code> method checks if a <strong>column's value</strong> falls between the values of <strong>two other columns</strong> in the same row.</p>
<h3><a id="example-1" href="#example-1" class="" aria-hidden="true" title=""></a>Example</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$patients</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;patients&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">whereBetweenColumns</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;weight&#39;</span><span style="color: #ABB2BF;">, [</span><span style="color: #98C379;">&#39;minimum_allowed_weight&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;maximum_allowed_weight&#39;</span><span style="color: #ABB2BF;">])</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h3><a id="sql-translation-1" href="#sql-translation-1" class="" aria-hidden="true" title=""></a>SQL Translation</h3>
<pre><code data-theme="one-dark-pro" data-lang="sql" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">select</span><span style="color: #ABB2BF;"> * </span><span style="color: #C678DD;">from</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">`patients`</span></div><div class='line'><span style="color: #C678DD;">where</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">`weight`</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">between</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">`minimum_allowed_weight`</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">and</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">`maximum_allowed_weight`</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<p>✅ Use this when you want to compare a column to <strong>two other column values</strong> in the same row.</p>
<h2><a id="3-wherevaluebetween" href="#3-wherevaluebetween" class="" aria-hidden="true" title=""></a>3. <code>whereValueBetween</code></h2>
<p>The <code>whereValueBetween</code> method checks if a <strong>given value</strong> falls between the values of <strong>two columns</strong> in the same row.</p>
<h3><a id="example-2" href="#example-2" class="" aria-hidden="true" title=""></a>Example</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$products</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;products&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">whereValueBetween</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">100</span><span style="color: #ABB2BF;">, [</span><span style="color: #98C379;">&#39;min_price&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;max_price&#39;</span><span style="color: #ABB2BF;">])</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h3><a id="sql-translation-2" href="#sql-translation-2" class="" aria-hidden="true" title=""></a>SQL Translation</h3>
<pre><code data-theme="one-dark-pro" data-lang="sql" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">select</span><span style="color: #ABB2BF;"> * </span><span style="color: #C678DD;">from</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">`products`</span></div><div class='line'><span style="color: #C678DD;">where</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">100</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">between</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">`min_price`</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">and</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">`max_price`</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<p>✅ Use this when you want to check if a <strong>fixed value</strong> fits between two <strong>column values</strong>.</p>
<h2><a id="quick-comparison" href="#quick-comparison" class="" aria-hidden="true" title=""></a>Quick Comparison</h2>
<table>
<thead>
<tr>
<th>Method</th>
<th>What It Compares</th>
<th>Example Use Case</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>whereBetween</code></td>
<td>Column vs. Two Fixed Values</td>
<td>Find users with votes between 1 and 100</td>
</tr>
<tr>
<td><code>whereBetweenColumns</code></td>
<td>Column vs. Two Other Columns</td>
<td>Find patients whose weight is in range</td>
</tr>
<tr>
<td><code>whereValueBetween</code></td>
<td>Fixed Value vs. Two Column Values</td>
<td>Find products where price 100 fits range</td>
</tr>
</tbody>
</table>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<ul>
<li>Use <code>whereBetween</code> when comparing a column to fixed values.</li>
<li>Use <code>whereBetweenColumns</code> when comparing a column to two other columns.</li>
<li>Use <code>whereValueBetween</code> when comparing a fixed value against two column values.</li>
</ul>
<p>Each method is suited for specific scenarios, and knowing the difference will help you write more precise and efficient queries in Laravel.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 16 Sep 2025 19:51:10 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Composer: Check PHP package versions]]></title>
                <link>https://nabilhassen.com/composer-check-php-package-versions</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#how-to-check-composer-package-version-in-php">How to Check Composer Package Version in PHP</a></li>
<li><a href="#1-check-with-composer-cli">1. Check with Composer CLI</a></li>
<li><a href="#2-check-composerlock-file">2. Check composer.lock File</a></li>
<li><a href="#3-check-vendorcomposerinstalledjson-file">3. Check vendor/composer/installed.json File</a></li>
<li><a href="#4-programmatically-in-php">4. Programmatically in PHP</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<p><strong>TL;DR:</strong> You can check a Composer package version using:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">show</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">laravel/framework</span></div></code></pre>
<h2><a id="how-to-check-composer-package-version-in-php" href="#how-to-check-composer-package-version-in-php" class="" aria-hidden="true" title=""></a>How to Check Composer Package Version in PHP</h2>
<p>When working with Composer in PHP, it’s often necessary to check which version of a package you’re using. This can be useful for debugging, upgrading, or ensuring compatibility with your codebase. In this guide, we’ll look at several ways to find the version of a Composer package.</p>
<h2><a id="1-check-with-composer-cli" href="#1-check-with-composer-cli" class="" aria-hidden="true" title=""></a>1. Check with Composer CLI</h2>
<p>The simplest way is to use Composer’s built-in command-line tools.</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">show</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">vendor/package-name</span></div></code></pre>
<p>Example:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">show</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">laravel/framework</span></div></code></pre>
<p>This will output details such as version, description, and dependencies.</p>
<p>If you want a list of all installed packages with versions:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">show</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--installed</span></div></code></pre>
<h2><a id="2-check-composerlock-file" href="#2-check-composerlock-file" class="" aria-hidden="true" title=""></a>2. Check <code>composer.lock</code> File</h2>
<p>Another way is to open the <code>composer.lock</code> file in your project root. Search for the package name and you’ll find its exact version.</p>
<p>Example snippet from <code>composer.lock</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="json" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #E06C75;">&quot;name&quot;</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">&quot;laravel/framework&quot;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #E06C75;">&quot;version&quot;</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">&quot;v12.0.1&quot;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>This ensures you’re seeing the exact version installed.</p>
<h2><a id="3-check-vendorcomposerinstalledjson-file" href="#3-check-vendorcomposerinstalledjson-file" class="" aria-hidden="true" title=""></a>3. Check <code>vendor/composer/installed.json</code> File</h2>
<p>Composer also stores installed package details in the <code>/vendor/composer/installed.json</code> file. Here you can find the version of each installed package. This file is machine-readable and can be parsed programmatically.</p>
<h2><a id="4-programmatically-in-php" href="#4-programmatically-in-php" class="" aria-hidden="true" title=""></a>4. Programmatically in PHP</h2>
<p>If you need to check a package version directly inside your PHP application, you can use <code>Composer\InstalledVersions</code> class.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">require</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">__DIR__</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;/vendor/autoload.php&#39;</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Composer\</span><span style="color: #E5C07B;">InstalledVersions</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$version</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">InstalledVersions</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">getVersion</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;laravel/framework&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;Laravel version: </span><span style="color: #E06C75;">$version</span><span style="color: #98C379;">&quot;</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<p>This method is available in Composer 2.0 and later.</p>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>You can check the version of a Composer package using:</p>
<ul>
<li>Composer CLI commands (<code>composer show</code>)</li>
<li><code>composer.lock</code> file</li>
<li><code>installed.json</code> file</li>
<li>Programmatically via <code>Composer\InstalledVersions</code></li>
</ul>
<p>For quick checks, the CLI is easiest. For automated checks inside your PHP project, use the <code>InstalledVersions</code> class.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Fri, 12 Sep 2025 19:47:04 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[PHP: Check if a string contains a substring]]></title>
                <link>https://nabilhassen.com/search-for-a-string-inside-another-string-in-php</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#how-to-check-if-a-string-contains-another-string-or-substring-in-php">How to check if a string contains another string or substring in PHP</a></li>
<li><a href="#using-strcontains-in-php-8-and-newer">Using str_contains() in PHP 8 and newer</a></li>
<li><a href="#using-strpos-and-stripos-for-position-based-checks">Using strpos() and stripos() for position-based checks</a></li>
<li><a href="#using-pregmatch-for-word-boundaries-and-pattern-rules">Using preg_match() for word boundaries and pattern rules</a></li>
<li><a href="#using-strstr-to-return-the-matched-substring-onward">Using strstr() to return the matched substring onward</a></li>
<li><a href="#quick-reference-for-choosing-the-right-method">Quick reference for choosing the right method</a></li>
<li><a href="#comprehensive-example-using-all-major-methods">Comprehensive example using all major methods</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="how-to-check-if-a-string-contains-another-string-or-substring-in-php" href="#how-to-check-if-a-string-contains-another-string-or-substring-in-php" class="" aria-hidden="true" title=""></a>How to check if a string contains another string or substring in PHP</h2>
<p>Determining whether a string contains another string, substring, word, or character is a frequent requirement in PHP. In this blog post, I'll present the most reliable and modern ways to perform this task. Each method is concise, accurate, and based on current PHP best practices.</p>
<h2><a id="using-strcontains-in-php-8-and-newer" href="#using-strcontains-in-php-8-and-newer" class="" aria-hidden="true" title=""></a>Using <code>str_contains()</code> in PHP 8 and newer</h2>
<p><code>str_contains()</code> is the simplest and most readable way to check if string contains substring or check if string contains word.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #61AFEF;">str_contains</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$haystack</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$needle</span><span style="color: #ABB2BF;">)) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;Found&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">} </span><span style="color: #C678DD;">else</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;Not found&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Key points:</p>
<ul>
<li>Returns true if the substring exists, otherwise false.</li>
<li>Ideal for most situations where you need to quickly check if string contains string.</li>
<li>If <code>$needle</code> is an empty string, the function always returns true. Validate <code>$needle</code> if that is not desired.</li>
</ul>
<p><code>str_contains()</code> is the recommended modern function and the clearest way to find in string operations.</p>
<h2><a id="using-strpos-and-stripos-for-position-based-checks" href="#using-strpos-and-stripos-for-position-based-checks" class="" aria-hidden="true" title=""></a>Using <code>strpos()</code> and <code>stripos()</code> for position-based checks</h2>
<p>For PHP versions before 8 or when you need the exact position of a match, use <code>strpos()</code>.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">strpos</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$haystack</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$needle</span><span style="color: #ABB2BF;">) </span><span style="color: #56B6C2;">!==</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">false</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;Found&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Important details:</p>
<ul>
<li>Returns the zero-based index of the match or false if not found.</li>
<li>Always use <code>!== false</code> because position 0 is valid and would otherwise be misinterpreted.</li>
<li><code>stripos()</code> performs a case-insensitive search.</li>
</ul>
<p>Use these functions when you must know where the substring occurs or when working on servers still running older PHP versions.</p>
<h2><a id="using-pregmatch-for-word-boundaries-and-pattern-rules" href="#using-pregmatch-for-word-boundaries-and-pattern-rules" class="" aria-hidden="true" title=""></a>Using <code>preg_match()</code> for word boundaries and pattern rules</h2>
<p><code>preg_match()</code> is the tool of choice when you need to check if string contains word with precise matching requirements such as whole words, case-insensitive rules, optional characters, or advanced patterns.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">preg_match</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">&#39;/example/&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$string</span><span style="color: #ABB2BF;">)) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;Found&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Capabilities:</p>
<ul>
<li>Supports full regular expressions for complex searches.</li>
<li>Add the <code>i</code> modifier for case-insensitive matching.</li>
<li>Use boundaries to ensure accurate whole-word detection.</li>
</ul>
<p>For example, to match the whole word joe but not joey:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">preg_match</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">&#39;/</span><span style="color: #56B6C2;">\b</span><span style="color: #E06C75;">joe</span><span style="color: #56B6C2;">\b</span><span style="color: #E06C75;">/i&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$string</span><span style="color: #ABB2BF;">)) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;Found whole word&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h2><a id="using-strstr-to-return-the-matched-substring-onward" href="#using-strstr-to-return-the-matched-substring-onward" class="" aria-hidden="true" title=""></a>Using <code>strstr()</code> to return the matched substring onward</h2>
<p>If you need to retrieve the portion of the string beginning at the match, use <code>strstr()</code>.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$result</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">strstr</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$string</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$needle</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$result</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">!==</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">false</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;Substring: &quot;</span><span style="color: #ABB2BF;"> </span><span style="color: #ABB2BF;">.</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$result</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Characteristics:</p>
<ul>
<li>Returns the substring starting at the first occurrence of <code>$needle</code>.</li>
<li>Returns false if not found.</li>
<li>Useful when you want to capture all text that follows the matched segment.</li>
</ul>
<h2><a id="quick-reference-for-choosing-the-right-method" href="#quick-reference-for-choosing-the-right-method" class="" aria-hidden="true" title=""></a>Quick reference for choosing the right method</h2>
<table>
<thead>
<tr>
<th>Requirement</th>
<th>Best Method</th>
</tr>
</thead>
<tbody>
<tr>
<td>Simple check in PHP 8 and newer</td>
<td><code>str_contains()</code></td>
</tr>
<tr>
<td>Need position or earlier PHP support</td>
<td><code>strpos()</code> or <code>stripos()</code></td>
</tr>
<tr>
<td>Need to check if string contains word with boundaries or regex rules</td>
<td><code>preg_match()</code></td>
</tr>
<tr>
<td>Need the substring starting from the match location</td>
<td><code>strstr()</code></td>
</tr>
</tbody>
</table>
<h2><a id="comprehensive-example-using-all-major-methods" href="#comprehensive-example-using-all-major-methods" class="" aria-hidden="true" title=""></a>Comprehensive example using all major methods</h2>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$haystack</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;The quick brown fox jumps over the lazy dog&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #E06C75;">$needle</span><span style="color: #ABB2BF;">   </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;fox&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// 1. str_contains (PHP 8+)</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">str_contains</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$haystack</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$needle</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">?</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;Found via str_contains</span><span style="color: #56B6C2;">\n</span><span style="color: #98C379;">&quot;</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">:</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;Not found</span><span style="color: #56B6C2;">\n</span><span style="color: #98C379;">&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// 2. strpos (case sensitive)</span></div><div class='line'><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">strpos</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$haystack</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$needle</span><span style="color: #ABB2BF;">) </span><span style="color: #56B6C2;">!==</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">false</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;Found via strpos</span><span style="color: #56B6C2;">\n</span><span style="color: #98C379;">&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// 3. stripos (case insensitive)</span></div><div class='line'><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">stripos</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$haystack</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$needle</span><span style="color: #ABB2BF;">) </span><span style="color: #56B6C2;">!==</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">false</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;Found via stripos</span><span style="color: #56B6C2;">\n</span><span style="color: #98C379;">&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// 4. preg_match (whole word match)</span></div><div class='line'><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">preg_match</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">&#39;/</span><span style="color: #56B6C2;">\b</span><span style="color: #E06C75;">fox</span><span style="color: #56B6C2;">\b</span><span style="color: #E06C75;">/i&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$haystack</span><span style="color: #ABB2BF;">)) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;Found via preg_match (whole word)</span><span style="color: #56B6C2;">\n</span><span style="color: #98C379;">&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// 5. strstr to return substring from match</span></div><div class='line'><span style="color: #E06C75;">$substring</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">strstr</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$haystack</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$needle</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$substring</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">!==</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">false</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;Found via strstr. Substring is: </span><span style="color: #E06C75;">$substring</span><span style="color: #56B6C2;">\n</span><span style="color: #98C379;">&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<ul>
<li><code>str_contains()</code> is the clearest and most modern solution for checking if string contains substring in PHP 8 and newer.</li>
<li>Use <code>strpos()</code> or <code>stripos()</code> when you need the match index or compatibility with older PHP versions.</li>
<li>Use <code>preg_match()</code> for whole-word matching, complex patterns, or advanced rules.</li>
<li>Handle empty needles and case differences intentionally to avoid unexpected behavior.</li>
</ul>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Fri, 14 Nov 2025 00:45:06 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Strict validation in Laravel: Accurate type checking]]></title>
                <link>https://nabilhassen.com/enforcing-strict-validation-rules-in-laravel</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#guide-to-strict-validation-rules-in-laravel">Guide to Strict Validation Rules in Laravel</a></li>
<li><a href="#boolean-validation-rule">Boolean Validation Rule</a></li>
<li><a href="#distinct-validation-rule">Distinct Validation Rule</a></li>
<li><a href="#integer-validation-rule">Integer Validation Rule</a></li>
<li><a href="#numeric-validation-rule">Numeric Validation Rule</a></li>
<li><a href="#when-to-use-strict-validation-in-laravel">When to Use Strict Validation in Laravel</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="guide-to-strict-validation-rules-in-laravel" href="#guide-to-strict-validation-rules-in-laravel" class="" aria-hidden="true" title=""></a>Guide to Strict Validation Rules in Laravel</h2>
<p>Laravel's validation system is powerful and flexible, helping developers ensure that incoming request data is properly structured and safe to use. By default, many of Laravel's validation rules perform <strong>loose checks</strong>, which means they accept values that can be cast into the desired type. However, sometimes you may need <strong>stricter validation</strong> to guarantee that the incoming values are exactly what you expect.</p>
<p>In this post, we’ll explore how to enforce strict validation rules in Laravel with examples.</p>
<h2><a id="boolean-validation-rule" href="#boolean-validation-rule" class="" aria-hidden="true" title=""></a>Boolean Validation Rule</h2>
<p>The <code>boolean</code> rule checks if a field can be cast to a boolean value. By default, Laravel accepts a wide range of inputs:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// Non-strict boolean (default)</span></div><div class='line'><span style="color: #E06C75;">$rules</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;active&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;boolean&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">];</span></div></code></pre>
<p>Accepted values: <code>true</code>, <code>false</code>, <code>1</code>, <code>0</code>, <code>'1'</code>, <code>'0'</code></p>
<p>If you want to <strong>only allow the actual boolean types</strong> (<code>true</code> or <code>false</code>), you can use the strict mode:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// Strict boolean</span></div><div class='line'><span style="color: #E06C75;">$rules</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;active&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;boolean:strict&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">];</span></div></code></pre>
<h2><a id="distinct-validation-rule" href="#distinct-validation-rule" class="" aria-hidden="true" title=""></a>Distinct Validation Rule</h2>
<p>The <code>distinct</code> rule ensures that all values in an array are unique. By default, Laravel performs <strong>loose comparisons</strong>, which may consider <code>'1'</code> and <code>1</code> as the same.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// Non-strict distinct</span></div><div class='line'><span style="color: #E06C75;">$rules</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;items.*.id&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;distinct&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">];</span></div></code></pre>
<p>If you want <strong>strict comparisons</strong>, ensuring <code>'1'</code> and <code>1</code> are treated differently, use:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// Strict distinct</span></div><div class='line'><span style="color: #E06C75;">$rules</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;items.*.id&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;distinct:strict&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">];</span></div></code></pre>
<h2><a id="integer-validation-rule" href="#integer-validation-rule" class="" aria-hidden="true" title=""></a>Integer Validation Rule</h2>
<p>The <code>integer</code> rule checks if a value is an integer. By default, it accepts integer values <strong>and numeric strings</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// Non-strict integer</span></div><div class='line'><span style="color: #E06C75;">$rules</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;age&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;integer&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">];</span></div></code></pre>
<p>Accepted values: <code>25</code>, <code>'25'</code></p>
<p>With strict validation, only actual integers are allowed:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// Strict integer</span></div><div class='line'><span style="color: #E06C75;">$rules</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;age&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;integer:strict&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">];</span></div></code></pre>
<h2><a id="numeric-validation-rule" href="#numeric-validation-rule" class="" aria-hidden="true" title=""></a>Numeric Validation Rule</h2>
<p>The <code>numeric</code> rule checks if a value is numeric. By default, it accepts numbers <strong>and numeric strings</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// Non-strict numeric</span></div><div class='line'><span style="color: #E06C75;">$rules</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;amount&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;numeric&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">];</span></div></code></pre>
<p>Accepted values: <code>100</code>, <code>'100'</code>, <code>12.5</code>, <code>'12.5'</code></p>
<p>With strict validation, only actual numbers (integer or float types) are accepted:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// Strict numeric</span></div><div class='line'><span style="color: #E06C75;">$rules</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;amount&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;numeric:strict&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">];</span></div></code></pre>
<h2><a id="when-to-use-strict-validation-in-laravel" href="#when-to-use-strict-validation-in-laravel" class="" aria-hidden="true" title=""></a>When to Use Strict Validation in Laravel</h2>
<p>Strict validation rules are especially useful when:</p>
<ul>
<li>You want to ensure strict type safety in your application.</li>
<li>Your API clients must send properly typed data.</li>
<li>You want to prevent accidental acceptance of loosely formatted input.</li>
</ul>
<p>By default, Laravel is flexible with input values, but enforcing strict validation can give you more control and reliability.</p>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>Laravel makes it easy to switch between <strong>flexible</strong> and <strong>strict</strong> validation depending on your needs. Whether you are validating booleans, integers, numeric values, or array uniqueness, the <code>:strict</code> parameter helps ensure that your data is exactly what you expect.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Fri, 14 Nov 2025 20:33:09 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Fix "SQLSTATE[HY000] [1049] Unknown database" in Laravel]]></title>
                <link>https://nabilhassen.com/fix-sqlstatehy000-1049-unknown-database-in-laravel</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#fixing-sqlstatehy000-1049-unknown-database-in-laravel--deep-dive">Fixing SQLSTATE[HY000] [1049] Unknown Database in Laravel — Deep Dive</a></li>
<li><a href="#why-laravel-might-throw-this-error">Why Laravel Might Throw This Error</a></li>
<li><a href="#step-by-step-laravelcentric-fixes">Step-by-Step Laravel‑centric Fixes</a></li>
<li><a href="#how-to-solve">How to Solve</a></li>
</ul>
<h2><a id="fixing-sqlstatehy000-1049-unknown-database-in-laravel--deep-dive" href="#fixing-sqlstatehy000-1049-unknown-database-in-laravel--deep-dive" class="" aria-hidden="true" title=""></a>Fixing <code>SQLSTATE[HY000] [1049] Unknown Database</code> in Laravel — Deep Dive</h2>
<p>When working with Laravel, one error you might see is: <em><strong>SQLSTATE[HY000] [1049] Unknown database 'mydatabase'</strong></em></p>
<p>This indicates that the database Laravel is configured to use can’t be found by MySQL/MariaDB. Below is a more robust guide, combining community wisdom, common pitfalls, and specific Laravel‑centric fixes.</p>
<h2><a id="why-laravel-might-throw-this-error" href="#why-laravel-might-throw-this-error" class="" aria-hidden="true" title=""></a>Why Laravel Might Throw This Error</h2>
<p>Here are recurring causes in Laravel setups:</p>
<ul>
<li>
<p><strong>Default database leftover in config</strong>
Laravel’s <code>config/database.php</code> often sets defaults like:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #98C379;">&#39;database&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #61AFEF;">env</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;DB_DATABASE&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;laravel&#39;</span><span style="color: #ABB2BF;">),</span></div><div class='line'><span style="color: #98C379;">&#39;username&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #61AFEF;">env</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;DB_USERNAME&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;laravel&#39;</span><span style="color: #ABB2BF;">),</span></div></code></pre>
<p>If your <code>.env</code> isn’t loaded or config is cached, Laravel may fall back to <code>laravel</code> and attempt to connect to it.</p>
</li>
<li>
<p><strong>Cached or stale configuration</strong>
Changing <code>.env</code> isn’t enough if the config is cached. You must clear Laravel’s config cache:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">cache:clear</span></div><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">config:cache</span></div></code></pre>
<p>Doing this forces Laravel to re‑read <code>.env</code> and refresh its internal settings.</p>
</li>
<li>
<p><strong>Wrong <code>.env</code> settings / port mismatch</strong>
If your MySQL server is running on a nonstandard port (e.g. 3308 instead of 3306), Laravel’s <code>DB_PORT</code> must match. Also, double-check for typos, stray spaces, or line breaks in the <code>.env</code> file.</p>
</li>
<li>
<p><strong>Database not created or dropped</strong>
If the configured database doesn’t exist on the server, Laravel will not be able to connect. Creating the database usually resolves the issue.</p>
</li>
</ul>
<h2><a id="step-by-step-laravelcentric-fixes" href="#step-by-step-laravelcentric-fixes" class="" aria-hidden="true" title=""></a>Step-by-Step Laravel‑centric Fixes</h2>
<p>Here’s a checklist you can follow to resolve this reliably:</p>
<table>
<thead>
<tr>
<th>Step</th>
<th>Action</th>
<th>Why / Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Open your <code>.env</code> and verify database details</td>
<td>Ensure <code>DB_DATABASE</code>, <code>DB_USERNAME</code>, <code>DB_PASSWORD</code>, <code>DB_HOST</code>, <code>DB_PORT</code> are exactly correct and match your MySQL setup</td>
</tr>
<tr>
<td>2</td>
<td>Create the database if missing</td>
<td><code>CREATE DATABASE my_app_db;</code> via MySQL client or admin UI</td>
</tr>
<tr>
<td>3</td>
<td>Clear Laravel’s cache and re‑cache config</td>
<td><code>php artisan cache:clear</code> and then <code>php artisan config:cache</code>, this ensures Laravel reads the new settings</td>
</tr>
<tr>
<td>4</td>
<td>Restart the development server / services</td>
<td>If running via <code>php artisan serve</code> or Docker, restart so changes apply</td>
</tr>
<tr>
<td>5</td>
<td>Validate port and host match</td>
<td>If MySQL is listening on a non‑default port, your <code>DB_PORT</code> must reflect it</td>
</tr>
<tr>
<td>6</td>
<td>Grant necessary privileges to the DB user</td>
<td><code>GRANT ALL PRIVILEGES ON my_app_db.* TO 'my_user'@'localhost'; FLUSH PRIVILEGES;</code></td>
</tr>
<tr>
<td>7</td>
<td>Run migrations</td>
<td><code>php artisan migrate</code> to boot up your schema</td>
</tr>
</tbody>
</table>
<h2><a id="how-to-solve" href="#how-to-solve" class="" aria-hidden="true" title=""></a>How to Solve</h2>
<ol>
<li>
<p><strong>Correct <code>.env</code></strong></p>
<pre><code data-theme="one-dark-pro" data-lang="env" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">DB_CONNECTION</span><span style="color: #56B6C2;">=</span><span style="color: #98C379;">mysql</span></div><div class='line'><span style="color: #E06C75;">DB_HOST</span><span style="color: #56B6C2;">=</span><span style="color: #D19A66;">127.0</span><span style="color: #ABB2BF;">.0.1</span></div><div class='line'><span style="color: #E06C75;">DB_PORT</span><span style="color: #56B6C2;">=</span><span style="color: #D19A66;">3306</span><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;"># or whatever your MySQL uses</span></div><div class='line'><span style="color: #E06C75;">DB_DATABASE</span><span style="color: #56B6C2;">=</span><span style="color: #98C379;">my_app_db</span></div><div class='line'><span style="color: #E06C75;">DB_USERNAME</span><span style="color: #56B6C2;">=</span><span style="color: #98C379;">my_user</span></div><div class='line'><span style="color: #E06C75;">DB_PASSWORD</span><span style="color: #56B6C2;">=</span><span style="color: #98C379;">secret</span></div></code></pre>
</li>
<li>
<p><strong>Ensure the database exists</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="sql" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">CREATE</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">DATABASE</span><span style="color: #ABB2BF;"> my_app_db;</span></div></code></pre>
</li>
<li>
<p><strong>Flush privileges if needed</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="sql" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">GRANT</span><span style="color: #ABB2BF;"> ALL PRIVILEGES </span><span style="color: #C678DD;">ON</span><span style="color: #ABB2BF;"> my_app_db.* </span><span style="color: #C678DD;">TO</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;my_user&#39;</span><span style="color: #ABB2BF;">@</span><span style="color: #98C379;">&#39;localhost&#39;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">FLUSH PRIVILEGES;</span></div></code></pre>
</li>
<li>
<p><strong>Clear Laravel cache and reload config</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">cache:clear</span></div><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">config:cache</span></div></code></pre>
</li>
<li>
<p><strong>Restart or reload your server / environment</strong>
If using <code>php artisan serve</code> or Docker, stop and start it again.</p>
</li>
<li>
<p><strong>Check for config overrides</strong>
Search for duplicate <code>.env</code> files or environment‐specific config paths that might override your intended settings.</p>
</li>
<li>
<p><strong>Run migrations</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">migrate</span></div></code></pre>
</li>
</ol>
<p>If after doing all these steps, you still see the error, double-check for stray spaces or hidden characters in your <code>.env</code> keys.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Thu, 25 Sep 2025 19:32:42 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[File Facade in Laravel: Unofficial Documentation]]></title>
                <link>https://nabilhassen.com/file-facade-in-laravel-unofficial-documentation</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#unveiling-laravels-file-facade">Unveiling Laravel’s File Facade</a></li>
<li><a href="#available-methods-under-file-facade">Available Methods Under File Facade</a>
<ul>
<li><a href="#existence--file-state">Existence &amp; File State</a></li>
<li><a href="#file-reading--data-extraction">File Reading &amp; Data Extraction</a></li>
<li><a href="#integrity-hashing--comparisons">Integrity, Hashing &amp; Comparisons</a></li>
<li><a href="#writing--text-modifications">Writing &amp; Text Modifications</a></li>
<li><a href="#file--directory-manipulation">File &amp; Directory Manipulation</a></li>
<li><a href="#pattern-matching--listings">Pattern Matching &amp; Listings</a></li>
<li><a href="#conditional-logic--extensibility">Conditional Logic &amp; Extensibility</a></li>
<li><a href="#facade--testing-tools">Facade &amp; Testing Tools</a></li>
</ul>
</li>
<li><a href="#code-examples-using-the-file-facade">Code Examples Using The File Facade</a></li>
<li><a href="#why-the-file-facade-deserves-your-attention">Why the File Facade Deserves Your Attention</a></li>
<li><a href="#want-the-full-breakdown">Want the Full Breakdown?</a></li>
</ul>
<h2><a id="unveiling-laravels-file-facade" href="#unveiling-laravels-file-facade" class="" aria-hidden="true" title=""></a>Unveiling Laravel’s <code>File</code> Facade</h2>
<p>The <strong><code>File</code> facade</strong> anchored in the <code>Illuminate\Support\Facades\File</code> namespace is a powerful yet understated part of Laravel’s ecosystem. Unlike the well‑documented <code>Storage</code> facade, its API is less often spotlighted, but it offers a treasure trove of file and directory operations that are perfect for daily dev workflows.</p>
<h2><a id="available-methods-under-file-facade" href="#available-methods-under-file-facade" class="" aria-hidden="true" title=""></a>Available Methods Under File Facade</h2>
<h3><a id="existence--file-state" href="#existence--file-state" class="" aria-hidden="true" title=""></a>Existence &amp; File State</h3>
<ul>
<li><code>exists(string $path)</code> / <code>missing(string $path)</code> – Confirm presence or absence of a file.</li>
<li><code>isReadable(string $path)</code>, <code>isWritable(string $path)</code>, <code>isFile(string $file)</code>, <code>isDirectory(string $directory)</code>, <code>isEmptyDirectory(string $directory, bool $ignoreDotFiles = false)</code> – State checks to avoid surprises.</li>
</ul>
<h3><a id="file-reading--data-extraction" href="#file-reading--data-extraction" class="" aria-hidden="true" title=""></a>File Reading &amp; Data Extraction</h3>
<ul>
<li><code>get(string $path, bool $lock = false)</code> – Read file content with optional locking.</li>
<li><code>json(string $path, int $flags, bool $lock = false)</code> – Read &amp; decode JSON straight off disk.</li>
<li><code>lines(string $path)</code> → returns a <strong><code>LazyCollection</code></strong> – Iterate files line‑by‑line without slurping into memory.</li>
</ul>
<h3><a id="integrity-hashing--comparisons" href="#integrity-hashing--comparisons" class="" aria-hidden="true" title=""></a>Integrity, Hashing &amp; Comparisons</h3>
<ul>
<li><code>hash(string $path, string $algorithm = 'md5')</code> – Compute file hash (MD5 default).</li>
<li><code>hasSameHash(string $firstFile, string $secondFile)</code> – Instantly compare file content equality via hash.</li>
</ul>
<h3><a id="writing--text-modifications" href="#writing--text-modifications" class="" aria-hidden="true" title=""></a>Writing &amp; Text Modifications</h3>
<ul>
<li><code>put(string $path, string $contents, bool $lock = false)</code> – Write to file with optional lock.</li>
<li><code>replace(string $path, string $content, int|null $mode = null)</code> – Overwrite entire file.</li>
<li><code>replaceInFile(array|string $search, array|string $replace, string $path)</code> – Inline search-and-replace.</li>
<li><code>prepend(string $path, string $data)</code>, <code>append(string $path, string $data, bool $lock = false)</code> – Add content at the start or end of a file.</li>
<li><code>chmod(string $path, int|null $mode = null)</code> – Change file permissions.</li>
</ul>
<h3><a id="file--directory-manipulation" href="#file--directory-manipulation" class="" aria-hidden="true" title=""></a>File &amp; Directory Manipulation</h3>
<ul>
<li>
<p><code>delete(string|array $paths)</code>, <code>move(string $path, string $target)</code>, <code>copy(string $path, string $target)</code> – CRUD essentials for files.</p>
</li>
<li>
<p><code>link(string $target, string $link)</code>, <code>relativeLink(string $target, string $link)</code> – Create absolute or relative symlinks.</p>
</li>
<li>
<p>Directory operations:</p>
<ul>
<li><code>ensureDirectoryExists(string $path, int $mode = 0755, bool $recursive = true)</code></li>
<li><code>makeDirectory(string $path, int $mode = 0755, bool $recursive = false, bool $force = false)</code></li>
<li><code>moveDirectory(string $from, string $to, bool $overwrite = false)</code></li>
<li><code>copyDirectory(string $directory, string $destination, int|null $options = null)</code></li>
<li><code>deleteDirectory(string $directory, bool $preserve = false)</code></li>
<li><code>deleteDirectories(string $directory)</code></li>
<li><code>cleanDirectory(string $directory)</code> – All the tools to safely create, copy, move, clean up, or delete directories.</li>
</ul>
</li>
</ul>
<h3><a id="pattern-matching--listings" href="#pattern-matching--listings" class="" aria-hidden="true" title=""></a>Pattern Matching &amp; Listings</h3>
<ul>
<li><code>glob(string $pattern, int $flags)</code> – Pattern-based search.</li>
<li><code>files(string $directory, bool $hidden = false)</code> / <code>allFiles(string $directory, bool $hidden = false)</code> – List files, optionally including hidden ones.</li>
<li><code>directories(string $directory)</code> – List subdirectories.</li>
</ul>
<h3><a id="conditional-logic--extensibility" href="#conditional-logic--extensibility" class="" aria-hidden="true" title=""></a>Conditional Logic &amp; Extensibility</h3>
<ul>
<li>
<p><code>when(...)</code>, <code>unless(...)</code> – Conditional workflows on file operations.</p>
</li>
<li>
<p>Laravel macro system support:</p>
<ul>
<li><code>macro(...)</code>, <code>mixin(...)</code>, <code>hasMacro(...)</code>, <code>flushMacros()</code> – Add or manage custom behavior at runtime.</li>
</ul>
</li>
</ul>
<h3><a id="facade--testing-tools" href="#facade--testing-tools" class="" aria-hidden="true" title=""></a>Facade &amp; Testing Tools</h3>
<p>Methods inherited from the base <code>Facade</code> class:</p>
<ul>
<li><code>resolved()</code>, <code>spy()</code>, <code>partialMock()</code>, <code>shouldReceive()</code>, <code>expects()</code>, <code>swap()</code>, <code>isFake()</code>, <code>getFacadeRoot()</code>, <code>getFacadeAccessor()</code>, <code>resolveFacadeInstance()</code> – useful in testing and mocking.</li>
</ul>
<h2><a id="code-examples-using-the-file-facade" href="#code-examples-using-the-file-facade" class="" aria-hidden="true" title=""></a>Code Examples Using The File Facade</h2>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// Stream file safely</span></div><div class='line'><span style="color: #E5C07B;">File</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">lines</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$path</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">each</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">fn</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$line</span><span style="color: #ABB2BF;">) =&gt; </span><span style="color: #61AFEF;">process</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$line</span><span style="color: #ABB2BF;">));</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Lock‑safe write</span></div><div class='line'><span style="color: #E5C07B;">File</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">put</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$path</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$contents</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">true</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Parse JSON</span></div><div class='line'><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">File</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">json</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$configFile</span><span style="color: #ABB2BF;">, JSON_THROW_ON_ERROR, </span><span style="color: #D19A66;">true</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Inline replacements</span></div><div class='line'><span style="color: #E5C07B;">File</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">replaceInFile</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;TODO&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;DONE&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$filePath</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Directory management</span></div><div class='line'><span style="color: #E5C07B;">File</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">ensureDirectoryExists</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$dirPath</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E5C07B;">File</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">cleanDirectory</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$dirPath</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Symlinks</span></div><div class='line'><span style="color: #E5C07B;">File</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">link</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$targetFile</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$symlink</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Custom macro</span></div><div class='line'><span style="color: #E5C07B;">File</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">macro</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;duplicateAndDelete&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$path</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E5C07B;">File</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">copy</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$path</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$path</span><span style="color: #ABB2BF;">.</span><span style="color: #98C379;">&#39;.dup&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E5C07B;">File</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">delete</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$path</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div></code></pre>
<h2><a id="why-the-file-facade-deserves-your-attention" href="#why-the-file-facade-deserves-your-attention" class="" aria-hidden="true" title=""></a>Why the <code>File</code> Facade Deserves Your Attention</h2>
<table>
<thead>
<tr>
<th>Use Case</th>
<th>Benefit</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Resource-efficient streaming</strong></td>
<td><code>lines()</code> avoids memory spikes on big files</td>
</tr>
<tr>
<td><strong>Safer concurrent operations</strong></td>
<td>Lockable reads/writes reduce race condition risks</td>
</tr>
<tr>
<td><strong>Convenient file content manipulation</strong></td>
<td>Inline search/replace, prepend/append simplify patterns</td>
</tr>
<tr>
<td><strong>Robust directory handling</strong></td>
<td>One-liners like <code>ensureDirectoryExists()</code> keep code clean</td>
</tr>
<tr>
<td><strong>Custom workflows</strong></td>
<td><code>macro()</code> and <code>when()</code> let you tailor file logic elegantly</td>
</tr>
<tr>
<td><strong>Tightly testable</strong></td>
<td>Fully integrates with Laravel’s mocking tools via facade</td>
</tr>
</tbody>
</table>
<h2><a id="want-the-full-breakdown" href="#want-the-full-breakdown" class="" aria-hidden="true" title=""></a>Want the Full Breakdown?</h2>
<p>Head over to the official Laravel API docs for the <code>File</code> facade to explore everything in detail:</p>
<p><strong><a rel="nofollow noopener" target="_blank" href="https://api.laravel.com/docs/12.x/Illuminate/Support/Facades/File.html">Illuminate\Support\Facades\File – Laravel API (v12.x)</a></strong></p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Wed, 03 Sep 2025 19:01:14 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Laravel Starter Kits List: Official and Community]]></title>
                <link>https://nabilhassen.com/laravel-starter-kits-list-official-and-community</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#laravel-starter-kits-official-and-community-options-for-developers">Laravel Starter Kits: Official and Community Options for Developers</a></li>
<li><a href="#official-laravel-starter-kits">Official Laravel Starter Kits</a>
<ul>
<li><a href="#1-livewire-starter-kit">1. Livewire Starter Kit</a></li>
<li><a href="#2-blank-livewire-starter-kit">2. Blank Livewire Starter Kit</a></li>
<li><a href="#3-vue-starter-kit">3. Vue Starter Kit</a></li>
<li><a href="#4-blank-vue-starter-kit">4. Blank Vue Starter Kit</a></li>
<li><a href="#5-react-starter-kit">5. React Starter Kit</a></li>
<li><a href="#6-blank-react-starter-kit">6. Blank React Starter Kit</a></li>
</ul>
</li>
<li><a href="#community-laravel-starter-kits">Community Laravel Starter Kits</a>
<ul>
<li><a href="#1-laraveldaily-starter-kit">1. LaravelDaily Starter Kit</a></li>
<li><a href="#2-kaido-kit">2. Kaido Kit</a></li>
<li><a href="#3-filament-jetstream">3. Filament Jetstream</a></li>
<li><a href="#4-genesis-by-devdojo">4. Genesis by DevDojo</a></li>
<li><a href="#5-larament">5. Larament</a></li>
<li><a href="#6-tallstarter">6. Tallstarter</a></li>
<li><a href="#7-larasonic-vue-and-larasonic-react">7. Larasonic Vue and Larasonic React</a></li>
<li><a href="#8-fission">8. Fission</a></li>
<li><a href="#9-fila-starter">9. Fila Starter</a></li>
<li><a href="#10-ai-chat">10. AI Chat</a></li>
<li><a href="#11-tallstackui-starter-kit">11. TallStackUI Starter Kit</a></li>
</ul>
</li>
<li><a href="#wrapping-up">Wrapping Up</a></li>
</ul>
<h2><a id="laravel-starter-kits-official-and-community-options-for-developers" href="#laravel-starter-kits-official-and-community-options-for-developers" class="" aria-hidden="true" title=""></a>Laravel Starter Kits: Official and Community Options for Developers</h2>
<p>When you start a new Laravel project, a common question is how to bootstrap the frontend stack and basic project structure quickly. Starter kits solve this by giving you a preconfigured stack that matches a specific way of building apps. In this blog post, I grouped the official Laravel starter kits and a curated set of community kits, and explained what each one actually ships with and when it is a good fit.</p>
<h2><a id="official-laravel-starter-kits" href="#official-laravel-starter-kits" class="" aria-hidden="true" title=""></a>Official Laravel Starter Kits</h2>
<p>These kits are maintained by the Laravel team. They give you modern frontend tooling with tight integration into the current Laravel ecosystem. Each one focuses on a particular frontend approach and uses Vite, TypeScript, Tailwind CSS, and Pest out of the box.</p>
<h3><a id="1-livewire-starter-kit" href="#1-livewire-starter-kit" class="" aria-hidden="true" title=""></a>1. Livewire Starter Kit</h3>
<ul>
<li><strong>Repository:</strong> <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/livewire-starter-kit">laravel/livewire-starter-kit</a></li>
<li><strong>What it provides:</strong> A Laravel application preconfigured for Livewire 3, using Flux UI for the component library, Tailwind CSS, TypeScript, and Vite. The repository offers alternate branches so you can choose between a Volt based approach or a components first Livewire setup, and there is a WorkOS branch for WorkOS powered authentication.</li>
<li><strong>Why it helps:</strong> You get a Livewire focused stack that already includes Flux UI and a modern build setup, so you can start building interactive, Blade driven interfaces without wiring the tooling and UI layer yourself. The different branches let you adopt Volt or stick with plain Livewire components depending on your preference.</li>
</ul>
<h3><a id="2-blank-livewire-starter-kit" href="#2-blank-livewire-starter-kit" class="" aria-hidden="true" title=""></a>2. Blank Livewire Starter Kit</h3>
<ul>
<li><strong>Repository:</strong> <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/blank-livewire-starter-kit">laravel/blank-livewire-starter-kit</a></li>
<li><strong>What it provides:</strong> A minimal Laravel plus Livewire 3 application that ships without a UI component library or prebuilt screens. It uses Vite, Tailwind CSS, TypeScript, and the same basic project layout as the main Livewire starter kit, but leaves design and components to you.</li>
<li><strong>Why it helps:</strong> You get a clean Livewire oriented foundation with modern tooling already in place, while keeping full control over the UI layer and design system.</li>
</ul>
<h3><a id="3-vue-starter-kit" href="#3-vue-starter-kit" class="" aria-hidden="true" title=""></a>3. Vue Starter Kit</h3>
<ul>
<li><strong>Repository:</strong> <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/vue-starter-kit">laravel/vue-starter-kit</a></li>
<li><strong>What it provides:</strong> A Laravel application configured with Inertia and Vue 3 using the Composition API, plus TypeScript, Vite, Tailwind CSS, and an opinionated set of Vue components based on shadcn vue.</li>
<li><strong>Why it helps:</strong> You get the Inertia plus Vue stack wired and ready, including a component system and build setup, so you can focus on pages and features instead of bootstrapping Inertia, Vue, and Tailwind from scratch.</li>
</ul>
<h3><a id="4-blank-vue-starter-kit" href="#4-blank-vue-starter-kit" class="" aria-hidden="true" title=""></a>4. Blank Vue Starter Kit</h3>
<ul>
<li><strong>Repository:</strong> <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/blank-vue-starter-kit">laravel/blank-vue-starter-kit</a></li>
<li><strong>What it provides:</strong> A lean Laravel application with Inertia and Vue 3 configured, using TypeScript, Vite, and Tailwind CSS, but without any preselected UI library or complex example screens.</li>
<li><strong>Why it helps:</strong> Ideal if you want the official wiring for Inertia and Vue yet intend to install your own component library or build the UI layer yourself.</li>
</ul>
<h3><a id="5-react-starter-kit" href="#5-react-starter-kit" class="" aria-hidden="true" title=""></a>5. React Starter Kit</h3>
<ul>
<li><strong>Repository:</strong> <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/react-starter-kit">laravel/react-starter-kit</a></li>
<li><strong>What it provides:</strong> A Laravel application configured with Inertia and React, plus TypeScript, Vite, Tailwind CSS, and a preconfigured component library using shadcn ui and Radix UI primitives.</li>
<li><strong>Why it helps:</strong> You get a React plus Inertia stack that already includes a modern component system and tooling, so you can build React powered interfaces on top of Laravel routing without setting up the integration yourself.</li>
</ul>
<h3><a id="6-blank-react-starter-kit" href="#6-blank-react-starter-kit" class="" aria-hidden="true" title=""></a>6. Blank React Starter Kit</h3>
<ul>
<li><strong>Repository:</strong> <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/blank-react-starter-kit">laravel/blank-react-starter-kit</a></li>
<li><strong>What it provides:</strong> A minimal Inertia plus React setup for Laravel using TypeScript, Vite, and Tailwind CSS. It provides the integration and basic layout, but no component library or complex UI presets.</li>
<li><strong>Why it helps:</strong> Good when you want the official React integration with Inertia but prefer to choose or build your own design system and components.</li>
</ul>
<h2><a id="community-laravel-starter-kits" href="#community-laravel-starter-kits" class="" aria-hidden="true" title=""></a>Community Laravel Starter Kits</h2>
<p>Community starter kits range from simple skeletons to full SaaS templates. They often add opinionated tooling, admin panels, or end user features that go beyond what the official kits cover.</p>
<h3><a id="1-laraveldaily-starter-kit" href="#1-laraveldaily-starter-kit" class="" aria-hidden="true" title=""></a>1. LaravelDaily Starter Kit</h3>
<ul>
<li><strong>Repository:</strong> <a rel="nofollow noopener" target="_blank" href="https://github.com/LaravelDaily/starter-kit">LaravelDaily/starter-kit</a></li>
<li><strong>What it provides:</strong> A Laravel project that demonstrates common application structure from the Laravel Daily tutorials. It includes authentication scaffolding, example CRUD resources, form requests, policies, basic tests, and a ready to use layout with Tailwind CSS.</li>
<li><strong>Why it helps:</strong> It doubles as a teaching resource and a practical base. You see real Laravel patterns in a complete project and can build on those patterns directly for smaller production apps.</li>
</ul>
<h3><a id="2-kaido-kit" href="#2-kaido-kit" class="" aria-hidden="true" title=""></a>2. Kaido Kit</h3>
<ul>
<li><strong>Repository:</strong> <a rel="nofollow noopener" target="_blank" href="https://github.com/siubie/kaido-kit">siubie/kaido-kit</a></li>
<li><strong>What it provides:</strong> A Laravel starter that combines an application shell with Filament. It ships with a prebuilt admin panel, layout, and example resources using Filament, along with authentication and basic navigation.</li>
<li><strong>Why it helps:</strong> You get a Filament powered admin area with Laravel wired around it from day one, which is useful when your project revolves around dashboards and back office workflows.</li>
</ul>
<h3><a id="3-filament-jetstream" href="#3-filament-jetstream" class="" aria-hidden="true" title=""></a>3. Filament Jetstream</h3>
<ul>
<li><strong>Repository:</strong> <a rel="nofollow noopener" target="_blank" href="https://github.com/stephenjude/filament-jetstream">stephenjude/filament-jetstream</a></li>
<li><strong>What it provides:</strong> A starter kit that integrates the full Laravel Jetstream feature set into a Filament panel. It brings authentication, registration, two factor authentication, session management, API tokens using Sanctum, profiles, and optional team support, all implemented through native Filament panels and components.</li>
<li><strong>Why it helps:</strong> If you plan to use Filament for your admin but still want Jetstream style features for users, this kit gives you those capabilities inside Filament without wiring Jetstream and Filament together manually.</li>
</ul>
<h3><a id="4-genesis-by-devdojo" href="#4-genesis-by-devdojo" class="" aria-hidden="true" title=""></a>4. Genesis by DevDojo</h3>
<ul>
<li><strong>Repository:</strong> <a rel="nofollow noopener" target="_blank" href="https://github.com/thedevdojo/genesis">thedevdojo/genesis</a></li>
<li><strong>What it provides:</strong> A Laravel starter kit built on the TALL stack with Folio and Volt. It ships with an index page, an about page, authentication pages with login, register, email verification, password reset, a dashboard, a profile edit screen, and a learn page that renders the README. It also includes several Blade layouts for app, marketing, and main shells plus a set of UI components and basic Pest tests for the provided pages.</li>
<li><strong>Why it helps:</strong> You get a ready made Livewire plus Folio plus Volt project with common pages and layouts already present, so you can extend those structures instead of building the marketing pages, authentication screens, and dashboard from nothing.</li>
</ul>
<h3><a id="5-larament" href="#5-larament" class="" aria-hidden="true" title=""></a>5. Larament</h3>
<ul>
<li><strong>Repository:</strong> <a rel="nofollow noopener" target="_blank" href="https://github.com/codewithdennis/larament">codewithdennis/larament</a></li>
<li><strong>What it provides:</strong> A bloat free starter kit for Laravel 12 that preconfigures Filament 4 as the admin panel. It includes <code>nunomaduro/essentials</code> for stricter defaults, development tools like Larastan, Pint, Pest, Rector, and Debugbar, an opinionated Filament panel with SPA mode, a custom login page, profile management, and multi factor authentication, plus GitHub Actions workflows for tests, PHPStan, and Pint.</li>
<li><strong>Why it helps:</strong> It is aimed at teams that want Laravel 12 and Filament 4 with a strong testing and static analysis setup already in place. You can start from a production oriented admin panel and modern quality tooling without assembling those pieces yourself.</li>
</ul>
<h3><a id="6-tallstarter" href="#6-tallstarter" class="" aria-hidden="true" title=""></a>6. Tallstarter</h3>
<ul>
<li><strong>Repository:</strong> <a rel="nofollow noopener" target="_blank" href="https://github.com/mortenebak/tallstarter">mortenebak/tallstarter</a></li>
<li><strong>What it provides:</strong> A Laravel 12 Livewire components starter kit that focuses on user, role, and permission management. It includes Flux UI components, SweetAlert based Livewire alerts, Spatie roles and permissions, strict Eloquent models, Debugbar, IDE helper, Rector, PHPStan, Pint, Pest tests, database seeders, and commands to create a super admin user.</li>
<li><strong>Why it helps:</strong> You get a Livewire based backend with authentication, roles, permissions, and a Flux powered UI ready to go. It is a practical base if you frequently build internal tools or admin heavy applications and want strict code quality tooling plus localization support from the start.</li>
</ul>
<h3><a id="7-larasonic-vue-and-larasonic-react" href="#7-larasonic-vue-and-larasonic-react" class="" aria-hidden="true" title=""></a>7. Larasonic Vue and Larasonic React</h3>
<ul>
<li><strong>Repositories:</strong>
<ul>
<li><a rel="nofollow noopener" target="_blank" href="https://github.com/shipfastlabs/larasonic-vue">shipfastlabs/larasonic-vue</a></li>
<li><a rel="nofollow noopener" target="_blank" href="https://github.com/shipfastlabs/larasonic-react">shipfastlabs/larasonic-react</a></li>
</ul>
</li>
<li><strong>What they provide:</strong> Open source SaaS starter kits built on Laravel with Inertia. The Vue variant uses Vue, Tailwind CSS, and Reka or shadcn inspired components. The React variant uses React, Tailwind CSS, and shadcn ui. Both focus on a modern SaaS style stack and include batteries such as authentication, billing integrations, settings, and other SaaS friendly features.</li>
<li><strong>Why they help:</strong> They are designed to launch SaaS products quickly. Much of the SaaS plumbing is already implemented on top of Laravel and Inertia, which lets you move straight to domain features instead of building layouts, onboarding, and account management by hand.</li>
</ul>
<h3><a id="8-fission" href="#8-fission" class="" aria-hidden="true" title=""></a>8. Fission</h3>
<ul>
<li><strong>Repository:</strong> <a rel="nofollow noopener" target="_blank" href="https://github.com/joshcirre/fission">joshcirre/fission</a></li>
<li><strong>What it provides:</strong> An opinionated Laravel starter kit that combines Folio file based routing, Volt powered Livewire components, and Flux UI. It is installed using the Laravel installer with the using flag and ships with example pages and configuration tuned for demos, tutorials, and Livewire first apps.</li>
<li><strong>Why it helps:</strong> If you like the Folio plus Volt plus Flux approach, this kit gives you a ready configured project that matches how the maintainer builds demo and tutorial applications, so you can copy that workflow instead of recreating it.</li>
</ul>
<h3><a id="9-fila-starter" href="#9-fila-starter" class="" aria-hidden="true" title=""></a>9. Fila Starter</h3>
<ul>
<li><strong>Repository:</strong> <a rel="nofollow noopener" target="_blank" href="https://github.com/raugadh/fila-starter">raugadh/fila-starter</a></li>
<li><strong>What it provides:</strong> A Filament starter kit that ships with a Filament admin panel already configured and ready for extension. It includes console commands for initializing the project, seeding, updating migrations and permissions when new resources or pages are added, and is maintained as a Filament plugin kit compatible with Filament 3 and 4.</li>
<li><strong>Why it helps:</strong> Useful when your application centers on Filament resources. You start from a preconfigured Filament setup with helper commands instead of creating the panel, roles, and basic wiring whenever you begin a new project.</li>
</ul>
<h3><a id="10-ai-chat" href="#10-ai-chat" class="" aria-hidden="true" title=""></a>10. AI Chat</h3>
<ul>
<li><strong>Repository:</strong> <a rel="nofollow noopener" target="_blank" href="https://github.com/pushpak1300/ai-chat">pushpak1300/ai-chat</a></li>
<li><strong>What it provides:</strong> A modern AI chat starter kit built with Laravel, Inertia, Vue, Tailwind CSS, and Prism. It demonstrates real time streaming AI responses using the Prism PHP SDK and includes an AI chat interface, theming, authentication, and a Laravel backend tailored for AI chat workflows.</li>
<li><strong>Why it helps:</strong> If you need to add AI chat to a Laravel app, this gives you a reference implementation with streaming, multi provider support, and a polished frontend, so you can adapt the code instead of designing the interaction model from scratch.</li>
</ul>
<h3><a id="11-tallstackui-starter-kit" href="#11-tallstackui-starter-kit" class="" aria-hidden="true" title=""></a>11. TallStackUI Starter Kit</h3>
<ul>
<li><strong>Repository:</strong> <a rel="nofollow noopener" target="_blank" href="https://github.com/tallstackui/starter-kit">tallstackui/starter-kit</a></li>
<li><strong>What it provides:</strong> A Laravel 12 starter kit built on TallStackUI and Livewire. It includes a basic user CRUD that uses TallStackUI components to show how tables, forms, and layout pieces fit together, and it is documented on the TallStackUI site as the recommended way to preview the component suite.</li>
<li><strong>Why it helps:</strong> You see TallStackUI in a real Laravel project with Livewire and can reuse the provided CRUD and layout as a foundation for applications that plan to use TallStackUI extensively.</li>
</ul>
<h2><a id="wrapping-up" href="#wrapping-up" class="" aria-hidden="true" title=""></a>Wrapping Up</h2>
<p>Official Laravel starter kits give you supported stacks for Livewire, Vue, and React, each with modern tooling and tight framework integration. Community kits build on top of that with real world concerns such as SaaS features, admin panels, strict tooling, or AI chat.</p>
<p>When you choose a starter kit, match it to your stack preference and project type:</p>
<ul>
<li>Livewire plus TALL style kits for Blade focused, server rendered apps.</li>
<li>Inertia plus Vue or React kits for SPA like experiences on top of Laravel routing.</li>
<li>Filament or TallStackUI kits for admin heavy or dashboard driven applications.</li>
<li>Specialized kits such as Larasonic or AI Chat when you need SaaS features or AI chat from day one.</li>
</ul>
<p>Picking a kit that matches both your frontend approach and your domain needs can remove most of the bootstrap work and let you focus on the parts of the application that are unique to your product.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Sat, 15 Nov 2025 21:26:04 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[routes/api.php is missing in Laravel 12: how to add it?]]></title>
                <link>https://nabilhassen.com/how-to-fix-missing-api-routes-file-in-laravel-12</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#understanding-api-routes-in-laravel-12">Understanding API Routes in Laravel 12</a></li>
<li><a href="#why-laravel-removed-apiphp-by-default">Why Laravel Removed api.php by Default</a></li>
<li><a href="#how-to-add-the-api-routes-file-in-laravel-12">How to Add the API Routes File in Laravel 12</a></li>
<li><a href="#common-issues-and-fixes">Common Issues and Fixes</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="understanding-api-routes-in-laravel-12" href="#understanding-api-routes-in-laravel-12" class="" aria-hidden="true" title=""></a>Understanding API Routes in Laravel 12</h2>
<p>If you’re building an API with <strong>Laravel 12</strong> and notice that the familiar <code>routes/api.php</code> file is missing, you’re not alone. Starting with <strong>Laravel 11</strong>, the framework no longer includes the API routes file by default.</p>
<p>This guide explains why the file was removed, how to correctly restore it, and the best practices for structuring and securing your API routes in Laravel 12.</p>
<h2><a id="why-laravel-removed-apiphp-by-default" href="#why-laravel-removed-apiphp-by-default" class="" aria-hidden="true" title=""></a>Why Laravel Removed <code>api.php</code> by Default</h2>
<p>Laravel’s design philosophy emphasizes simplicity and minimalism. Since not every application requires an API, the core team decided to <strong>exclude the <code>api.php</code> file</strong> from new installations starting in Laravel 11.</p>
<p>This change helps keep new projects lightweight. When you do need to build APIs, Laravel provides an explicit installation process to add the required routes and middleware.</p>
<h2><a id="how-to-add-the-api-routes-file-in-laravel-12" href="#how-to-add-the-api-routes-file-in-laravel-12" class="" aria-hidden="true" title=""></a>How to Add the API Routes File in Laravel 12</h2>
<p>To add the API routes setup, run the following Artisan command:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">install:api</span></div></code></pre>
<p>This command generates a new <code>routes/api.php</code> file and registers it in the application’s routing configuration. After running it, you can define your API routes exactly as in previous Laravel versions.</p>
<p>Example:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Route</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">Route</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;/users&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> () {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;John Doe&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;email&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;john@example.com&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ];</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div></code></pre>
<p>Now, visiting <code>/api/users</code> in your browser or API client returns the JSON response.</p>
<p>If you forget to run <code>php artisan install:api</code>, any references to API routes  will result in a <em>“route not found” related errors.</em></p>
<h2><a id="common-issues-and-fixes" href="#common-issues-and-fixes" class="" aria-hidden="true" title=""></a>Common Issues and Fixes</h2>
<p><strong>1. <code>api.php</code> file not found:</strong>
Run <code>php artisan install:api</code> to recreate the missing file.</p>
<p><strong>2. Route returns 404:</strong>
Check that your route is defined under the correct prefix (<code>/api/...</code>). Laravel automatically prefixes all API routes with <code>/api</code>.</p>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>If your Laravel 12 project doesn’t include <code>routes/api.php</code>, that’s intentional. The file was removed to keep the framework minimal. When you need it, simply run:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">install:api</span></div></code></pre>
<p>With this command, you restore full API scaffolding and can begin building secure, versioned, and efficient endpoints immediately.</p>
<p>Laravel’s new modular approach ensures projects stay lean while still providing everything you need for robust API development.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Thu, 06 Nov 2025 22:56:01 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Top Laravel AI Packages and Tools Guide]]></title>
                <link>https://nabilhassen.com/supercharge-laravel-development-and-apps-with-ai</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#laravel-and-ai">Laravel and AI</a></li>
<li><a href="#1-unified-llm-integration">1. Unified LLM Integration</a></li>
<li><a href="#2-ai-api-integrations">2. AI API Integrations</a></li>
<li><a href="#3-model-context-protocol-mcp-and-ai-development-tools">3. Model Context Protocol (MCP) and AI Development Tools</a></li>
<li><a href="#4-ai-powered-development-enhancements">4. AI-Powered Development Enhancements</a></li>
<li><a href="#5-specialized-ai-utilities">5. Specialized AI Utilities</a></li>
<li><a href="#bringing-it-all-together">Bringing It All Together</a></li>
</ul>
<h2><a id="laravel-and-ai" href="#laravel-and-ai" class="" aria-hidden="true" title=""></a>Laravel and AI</h2>
<p>Artificial Intelligence (AI) is increasingly shaping modern software development, and Laravel developers now have access to a growing ecosystem of tools that simplify AI integration. From model context frameworks to API clients and agent libraries, Laravel’s ecosystem enables developers to build intelligent, context-aware applications faster than ever.</p>
<p>In this blog post, I'll highlight some of the most impactful open source, Laravel AI packages, organized by category, with practical explanations of how each enhances AI development in Laravel.</p>
<h2><a id="1-unified-llm-integration" href="#1-unified-llm-integration" class="" aria-hidden="true" title=""></a>1. Unified LLM Integration</h2>
<ul>
<li><strong><a rel="nofollow noopener" target="_blank" href="https://github.com/prism-php/prism">prism-php/prism</a></strong>
Prism is a Laravel-native abstraction layer for working with Large Language Models (LLMs). It supports multiple AI providers including OpenAI, Anthropic, Ollama, DeepSeek, Mistral, xAI, and Gemini through a single interface. Developers can switch providers without altering application logic. Features include structured output via schemas, multi-modal input (text, images, audio, documents), streaming responses, and robust testing utilities. Prism remains one of the most comprehensive Laravel AI integration layers available.</li>
</ul>
<h2><a id="2-ai-api-integrations" href="#2-ai-api-integrations" class="" aria-hidden="true" title=""></a>2. AI API Integrations</h2>
<p>These packages provide seamless access to external AI services and LLMs, allowing developers to integrate advanced AI capabilities directly into Laravel applications.</p>
<ul>
<li>
<p><strong><a rel="nofollow noopener" target="_blank" href="https://github.com/openai-php/laravel">openai-php/laravel</a></strong>
A Laravel wrapper for the OpenAI API. It enables easy interaction with models like GPT for text generation, embeddings, and more. Ideal for building chatbots, summarizers, or intelligent content generators.</p>
</li>
<li>
<p><strong><a rel="nofollow noopener" target="_blank" href="https://github.com/moe-mizrak/laravel-openrouter">moe-mizrak/laravel-openrouter</a></strong>
Connects Laravel to <a rel="nofollow noopener" target="_blank" href="https://openrouter.ai">OpenRouter</a>, a unified API gateway for multiple AI providers. It offers flexibility in choosing and switching models while maintaining a consistent interface.</p>
</li>
<li>
<p><strong><a rel="nofollow noopener" target="_blank" href="https://github.com/deepseek-php/deepseek-laravel">deepseek-php/deepseek-laravel</a></strong>
Integrates DeepSeek AI models into Laravel for advanced natural language processing (NLP) and text generation, supporting customized workflows with Laravel AI tools.</p>
</li>
<li>
<p><strong><a rel="nofollow noopener" target="_blank" href="https://github.com/grok-php/laravel">grok-php/laravel</a></strong>
Adds Grok AI model integration for intelligent text-based tasks such as summarization, Q&amp;A, and contextual data extraction.</p>
</li>
<li>
<p><strong><a rel="nofollow noopener" target="_blank" href="https://github.com/qwen-php/qwen-laravel">qwen-php/qwen-laravel</a></strong>
Provides access to Alibaba’s Qwen models. An alternative LLM option with unique performance and reasoning characteristics.</p>
</li>
<li>
<p><strong><a rel="nofollow noopener" target="_blank" href="https://github.com/vectorifyai/vectorify-laravel">vectorifyai/vectorify-laravel</a></strong>
Enables vector embedding storage and querying within Laravel. Essential for implementing semantic search, recommendation engines, and retrieval-augmented generation (RAG) systems.</p>
</li>
<li>
<p><strong><a rel="nofollow noopener" target="_blank" href="https://github.com/google-gemini-php/laravel">google-gemini-php/laravel</a></strong>
A Laravel integration for Google’s Gemini API, supporting text, image, and multi-modal LLMs. It simplifies building AI-driven features like document analysis, chatbots, and intelligent assistants.</p>
</li>
</ul>
<h2><a id="3-model-context-protocol-mcp-and-ai-development-tools" href="#3-model-context-protocol-mcp-and-ai-development-tools" class="" aria-hidden="true" title=""></a>3. Model Context Protocol (MCP) and AI Development Tools</h2>
<p>These tools standardize how Laravel applications communicate with AI models, improving structure and context management in AI-driven workflows.</p>
<ul>
<li>
<p><strong><a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/mcp">laravel/mcp</a></strong>
Laravel’s official Model Context Protocol (MCP) implementation. It defines a standardized communication layer between Laravel and AI models, enabling context-aware AI responses that adapt to the current user session or request.</p>
</li>
<li>
<p><strong><a rel="nofollow noopener" target="_blank" href="https://github.com/php-mcp/laravel">php-mcp/laravel</a></strong>
A flexible MCP package for handling context-driven AI interactions across multiple providers. It supports structured prompts, context layering, and advanced orchestration of model requests.</p>
</li>
<li>
<p><strong><a rel="nofollow noopener" target="_blank" href="https://github.com/llm-agents-php/agents">llm-agents-php/agents</a></strong>
A Laravel-focused agent framework for building autonomous AI agents capable of performing tasks, chaining reasoning steps, and executing actions using Laravel services.</p>
</li>
<li>
<p><strong><a rel="nofollow noopener" target="_blank" href="https://github.com/MaestroError/LarAgent">MaestroError/LarAgent</a></strong>
An experimental framework for running LLM-based agents within Laravel. It’s ideal for creating assistants, workflow automation, and AI utilities that interact directly with your business logic.</p>
</li>
</ul>
<h2><a id="4-ai-powered-development-enhancements" href="#4-ai-powered-development-enhancements" class="" aria-hidden="true" title=""></a>4. AI-Powered Development Enhancements</h2>
<p>These Laravel AI packages help developers improve their workflow, debug faster, and optimize performance using AI-assisted tools.</p>
<ul>
<li>
<p><strong><a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/boost">laravel/boost</a></strong>
An AI-powered development assistant built by the Laravel team. Boost generates code snippets, explains framework internals, and accelerates development through intelligent suggestions.</p>
</li>
<li>
<p><strong><a rel="nofollow noopener" target="_blank" href="https://github.com/halilcosdu/laravel-slower">halilcosdu/laravel-slower</a></strong>
Identifies slow database queries and uses AI insights to recommend performance optimizations such as indexing strategies and query refactoring.</p>
</li>
<li>
<p><strong><a rel="nofollow noopener" target="_blank" href="https://github.com/HelgeSverre/extractor">HelgeSverre/extractor</a></strong>
Extracts structured data like emails, phone numbers, and custom patterns from unstructured text using AI models. Useful for automating data enrichment and cleanup within Laravel applications.</p>
</li>
</ul>
<h2><a id="5-specialized-ai-utilities" href="#5-specialized-ai-utilities" class="" aria-hidden="true" title=""></a>5. Specialized AI Utilities</h2>
<p>These packages extend Laravel with AI-driven utilities for translation, workflow automation, and content understanding.</p>
<ul>
<li>
<p><strong><a rel="nofollow noopener" target="_blank" href="https://github.com/kargnas/laravel-ai-translator">kargnas/laravel-ai-translator</a></strong>
Adds AI translation capabilities to Laravel applications. It leverages LLMs to provide dynamic, high-quality translations beyond static localization files.</p>
</li>
<li>
<p><strong><a rel="nofollow noopener" target="_blank" href="https://github.com/usecroft/laravel">usecroft/laravel</a></strong>
Integrates UseCroft, a platform for building AI-driven workflows. It allows Laravel applications to perform complex natural language processing, generate insights, and automate repetitive operations.</p>
</li>
</ul>
<h2><a id="bringing-it-all-together" href="#bringing-it-all-together" class="" aria-hidden="true" title=""></a>Bringing It All Together</h2>
<p>The Laravel AI ecosystem is expanding rapidly, empowering developers to:</p>
<ul>
<li>Integrate multiple AI providers seamlessly with <strong>Prism</strong>.</li>
<li>Access advanced language models through <strong>API wrappers</strong> like OpenAI, DeepSeek, Qwen, Grok, OpenRouter, Gemini, and Vectorify.</li>
<li>Build <strong>context-aware systems</strong> using MCP frameworks and agent-based architectures.</li>
<li>Enhance <strong>development efficiency</strong> with tools such as Boost and Slower.</li>
<li>Add <strong>AI-driven utilities</strong> for translation, semantic search, and intelligent automation.</li>
</ul>
<p>With these Laravel AI packages, as a Laravel developer, you can create smarter, more adaptive applications and optimize their own workflows through AI assistance. The ecosystem continues to evolve making now the ideal time to explore and integrate AI capabilities into your Laravel projects.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Sun, 09 Nov 2025 00:43:04 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Check Laravel Installer Version Easily]]></title>
                <link>https://nabilhassen.com/2-easy-ways-to-check-your-laravel-installer-version</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#how-to-check-laravel-installer-version">How to Check Laravel Installer Version</a></li>
<li><a href="#method-1-check-laravel-installer-version-using-the-command-line">Method 1: Check Laravel Installer Version Using the Command Line</a></li>
<li><a href="#method-2-check-laravel-installer-version-via-composer">Method 2: Check Laravel Installer Version via Composer</a></li>
<li><a href="#troubleshooting-laravel-command-not-found">Troubleshooting: Laravel Command Not Found</a>
<ul>
<li><a href="#fix">Fix</a></li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="how-to-check-laravel-installer-version" href="#how-to-check-laravel-installer-version" class="" aria-hidden="true" title=""></a>How to Check Laravel Installer Version</h2>
<p>Knowing how to <strong>check Laravel installer version</strong> on your system is essential for consistency across projects and compatibility with recent Laravel releases. In this blog post, I'll cover two reliable methods and a quick fix when the <code>laravel</code> command is not recognized.</p>
<h2><a id="method-1-check-laravel-installer-version-using-the-command-line" href="#method-1-check-laravel-installer-version-using-the-command-line" class="" aria-hidden="true" title=""></a>Method 1: Check Laravel Installer Version Using the Command Line</h2>
<p>If the Laravel installer is installed globally, run one of the following commands:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">laravel </span><span style="color: #D19A66;">-V</span></div><div class='line'><span style="color: #7F848E;"># or</span></div><div class='line'><span style="color: #ABB2BF;">laravel </span><span style="color: #D19A66;">--version</span></div></code></pre>
<p>This prints the version of the <strong>Laravel installer</strong>.</p>
<p>Example output:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">Laravel Installer 5.2.1</span></div></code></pre>
<h2><a id="method-2-check-laravel-installer-version-via-composer" href="#method-2-check-laravel-installer-version-via-composer" class="" aria-hidden="true" title=""></a>Method 2: Check Laravel Installer Version via Composer</h2>
<p>If the <code>laravel</code> command is not found or you prefer Composer, run:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">show</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">laravel/installer</span></div></code></pre>
<p>This displays package details, including the installed version. Look for the <code>versions</code> line, for example:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">versions : * 5.2.1</span></div></code></pre>
<h2><a id="troubleshooting-laravel-command-not-found" href="#troubleshooting-laravel-command-not-found" class="" aria-hidden="true" title=""></a>Troubleshooting: Laravel Command Not Found</h2>
<p>If <code>laravel -V</code> returns a command not found error, your shell cannot locate the executable.</p>
<h3><a id="fix" href="#fix" class="" aria-hidden="true" title=""></a>Fix</h3>
<p>Add Composer’s global vendor bin directory to your <code>$PATH</code>. Common locations:</p>
<table>
<thead>
<tr>
<th>Operating System</th>
<th>Global Composer Bin Path</th>
</tr>
</thead>
<tbody>
<tr>
<td>macOS</td>
<td><code>$HOME/.config/composer/vendor/bin</code> or <code>$HOME/.composer/vendor/bin</code></td>
</tr>
<tr>
<td>Windows</td>
<td><code>%USERPROFILE%\AppData\Roaming\Composer\vendor\bin</code></td>
</tr>
<tr>
<td>Linux</td>
<td><code>$HOME/.config/composer/vendor/bin</code> or <code>$HOME/.composer/vendor/bin</code></td>
</tr>
</tbody>
</table>
<p>After updating <code>$PATH</code>, restart the terminal and run:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">laravel </span><span style="color: #D19A66;">-V</span></div></code></pre>
<p>You should now see the correct installer version.</p>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>It is quick to <strong>check Laravel installer version</strong> using either <code>laravel -V</code> or <code>composer show laravel/installer</code>. If the Laravel command fails, adding Composer’s vendor bin directory to your system path resolves the issue. Verifying this regularly helps keep your environment aligned with current Laravel releases.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Sun, 09 Nov 2025 00:57:45 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Deferring Events Including Model Events in Laravel]]></title>
                <link>https://nabilhassen.com/deferring-events-including-model-events-in-laravel</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#deferring-events-in-laravel">Deferring Events in Laravel</a></li>
<li><a href="#what-are-deferred-events-in-laravel">What Are Deferred Events in Laravel?</a></li>
<li><a href="#how-to-use-eventdefer">How to Use Event::defer()</a>
<ul>
<li><a href="#what-happens-here">What happens here?</a></li>
</ul>
</li>
<li><a href="#deferring-specific-events-only">Deferring Specific Events Only</a>
<ul>
<li><a href="#explanation">Explanation:</a></li>
</ul>
</li>
<li><a href="#when-to-use-deferred-events">When to Use Deferred Events</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="deferring-events-in-laravel" href="#deferring-events-in-laravel" class="" aria-hidden="true" title=""></a>Deferring Events in Laravel</h2>
<p>Laravel provides an elegant way to handle events in your applications. But what if you want to delay the dispatching of certain events until after a block of code has finished executing? That’s where <strong>deferred events</strong> come in.</p>
<p>In this post, we’ll explore what deferred events are, why they’re useful, and how you can implement them in your Laravel applications.</p>
<h2><a id="what-are-deferred-events-in-laravel" href="#what-are-deferred-events-in-laravel" class="" aria-hidden="true" title=""></a>What Are Deferred Events in Laravel?</h2>
<p>Deferred events allow you to <strong>delay the dispatching of model events and execution of event listeners</strong> until after a specific closure has finished running. This feature is particularly useful when you need to ensure that all related database records are created and available before event listeners are triggered.</p>
<p>For example, consider a scenario where you create an <code>Order</code> and immediately create <code>OrderLineItem</code>s linked to that order. If events were dispatched immediately, your event listeners might not yet have access to all the related records.</p>
<h2><a id="how-to-use-eventdefer" href="#how-to-use-eventdefer" class="" aria-hidden="true" title=""></a>How to Use <code>Event::defer()</code></h2>
<p>Laravel makes deferring events simple with the <code>Event::defer()</code> method. You just wrap your logic inside a closure:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Models\</span><span style="color: #E5C07B;">Order</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Event</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">Event</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">defer</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> () {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$order</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Order</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">create</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;order_number&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;ORD-1001&#39;</span><span style="color: #ABB2BF;">]);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$order</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">lineItems</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">create</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;product_name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Laptop&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;quantity&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ]);</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div></code></pre>
<h3><a id="what-happens-here" href="#what-happens-here" class="" aria-hidden="true" title=""></a>What happens here?</h3>
<ul>
<li>All events triggered inside the closure will be <strong>queued up</strong>.</li>
<li>They are only dispatched <strong>after the closure completes</strong>.</li>
<li>If an exception occurs inside the closure, <strong>no events will be dispatched</strong>.</li>
</ul>
<p>This ensures event listeners run in a clean, predictable state where all related records already exist.</p>
<h2><a id="deferring-specific-events-only" href="#deferring-specific-events-only" class="" aria-hidden="true" title=""></a>Deferring Specific Events Only</h2>
<p>Sometimes you may not want to defer all events, only specific ones. Laravel allows you to do this by passing an array of event names as the second parameter to <code>defer()</code>.</p>
<p>Example:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Models\</span><span style="color: #E5C07B;">Order</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Event</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">Event</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">defer</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> () {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$order</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Order</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">create</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;order_number&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;ORD-1001&#39;</span><span style="color: #ABB2BF;">]);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$order</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">lineItems</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">create</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;product_name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Laptop&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;quantity&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ]);</span></div><div class='line'><span style="color: #ABB2BF;">}, [</span><span style="color: #98C379;">&#39;eloquent.created: &#39;</span><span style="color: #ABB2BF;">.</span><span style="color: #E5C07B;">Order</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">]);</span></div></code></pre>
<h3><a id="explanation" href="#explanation" class="" aria-hidden="true" title=""></a>Explanation:</h3>
<ul>
<li>In this case, only the <code>eloquent.created</code> event for the <code>Order</code> model will be deferred.</li>
<li>Other events (like those for the <code>OrderLineItem</code> model) will be dispatched immediately.</li>
</ul>
<h2><a id="when-to-use-deferred-events" href="#when-to-use-deferred-events" class="" aria-hidden="true" title=""></a>When to Use Deferred Events</h2>
<p>You might want to defer events when:</p>
<ul>
<li>Creating related records where listeners depend on all records being available.</li>
<li>Running bulk insert operations that should only trigger events after completion.</li>
<li>Avoiding inconsistent state issues in event listeners.</li>
</ul>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>Deferred events in Laravel provide a powerful way to manage when your events are fired. By using <code>Event::defer()</code>, you can ensure that listeners always have access to the final, complete state of your data.</p>
<p>Whether you defer all events in a block of code or only specific ones, this feature can help you build more reliable and predictable event-driven applications in Laravel.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Mon, 18 Aug 2025 20:13:50 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Laravel 13: New Features, Release Date, Install Now]]></title>
                <link>https://nabilhassen.com/laravel-13-new-features-release-date-install-now</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#early-look-at-laravel-13">Early Look at Laravel 13</a></li>
<li><a href="#laravel-13---release-date-and-schedule">Laravel 13 - Release Date and Schedule</a></li>
<li><a href="#new-features-in-laravel-13">New Features in Laravel 13</a>
<ul>
<li><a href="#symfony-74--80-support">Symfony 7.4 &amp; 8.0 support</a></li>
<li><a href="#cache-touch-method">Cache touch() method</a></li>
<li><a href="#subdomain-routing-order">Subdomain routing order</a></li>
<li><a href="#model-boot-time-restrictions">Model boot-time restrictions</a></li>
<li><a href="#php-83-requirement">PHP 8.3 requirement</a></li>
<li><a href="#http-client-pool-default-concurrency">HTTP client pool default concurrency</a></li>
<li><a href="#safer-requestget-behavior-symfony-parity">Safer Request::get() behavior (Symfony parity)</a></li>
<li><a href="#mysql-grammar-delete--join-with-order-by--limit">MySQL grammar: DELETE … JOIN with ORDER BY + LIMIT</a></li>
<li><a href="#managers-bind-manager-instances-to-custom-driver-closures">Managers: bind manager instances to custom driver closures</a></li>
<li><a href="#polymorphic-pivot-table-naming-plural">Polymorphic pivot table naming (plural)</a></li>
<li><a href="#queue-events-jobattempted-now-exposes-the-actual-exception">Queue events: JobAttempted now exposes the actual exception</a></li>
<li><a href="#testing-cleanup-reset-str-factories-between-tests">Testing cleanup: reset Str factories between tests</a></li>
<li><a href="#hyphenated-prefixes-support">Hyphenated prefixes support</a></li>
<li><a href="#notification-polish-email-subjects">Notification polish: email subjects</a></li>
</ul>
</li>
<li><a href="#how-to-install--try-laravel-13-today">How to Install &amp; Try Laravel 13 Today</a></li>
</ul>
<h2><a id="early-look-at-laravel-13" href="#early-look-at-laravel-13" class="" aria-hidden="true" title=""></a>Early Look at Laravel 13</h2>
<p>Laravel 13 is still in development, but thanks to the framework’s support policy we know it is due in the first quarter of 2026. This blog post gives an early preview of Laravel 13’s roadmap and new features based on in-progress pull requests. I’ll update this post <em>monthly</em> as Laravel 13’s development continues, so check back for the latest changes and additions.</p>
<h2><a id="laravel-13---release-date-and-schedule" href="#laravel-13---release-date-and-schedule" class="" aria-hidden="true" title=""></a>Laravel 13 - Release Date and Schedule</h2>
<p>According to the official Support Policy, Laravel 13 is slated for release in Q1 2026. Each major version has one year and six months of bugfixes and two years of security fixes. For context, Laravel 12 was released in February 2025 and will receive bug fixes until August 13, 2026, and security fixes until February 24, 2027. In comparison, Laravel 13 will target PHP 8.3+ and is expected around Q1 2026 (with bug fixes through Q3 2027 and security fixes through Q1 2028). In other words, you have ample time to upgrade projects; Laravel 12 remains supported well into 2027.</p>
<h2><a id="new-features-in-laravel-13" href="#new-features-in-laravel-13" class="" aria-hidden="true" title=""></a>New Features in Laravel 13</h2>
<p>Laravel 13 has both groundwork &amp; cleanup, and new developer-facing features. However, several merged and proposed PRs hint at what’s coming. Key highlights include:</p>
<h3><a id="symfony-74--80-support" href="#symfony-74--80-support" class="" aria-hidden="true" title=""></a>Symfony 7.4 &amp; 8.0 support</h3>
<p>The framework is being updated to support the latest Symfony components (<a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/56029">PR #56029</a>). This means Laravel’s underlying packages (HTTP, Console, etc.) will work with Symfony 7.4 and 8.0 when 13 is released.</p>
<h3><a id="cache-touch-method" href="#cache-touch-method" class="" aria-hidden="true" title=""></a>Cache <code>touch()</code> method</h3>
<p>A new <code>Cache::touch($key)</code> (and corresponding store <code>touch</code>) has been added in <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/55954">PR #55954</a> to extend the TTL (time-to-live) of a cached item. This lets you refresh a cache key’s expiration without retrieving it.</p>
<h3><a id="subdomain-routing-order" href="#subdomain-routing-order" class="" aria-hidden="true" title=""></a>Subdomain routing order</h3>
<p>In <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/55921">PR #55921</a>, subdomain routes are now registered <em>before</em> routes without domains. This change ensures routes tied to specific subdomains take priority during routing.</p>
<h3><a id="model-boot-time-restrictions" href="#model-boot-time-restrictions" class="" aria-hidden="true" title=""></a>Model boot-time restrictions</h3>
<p><a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/55685">PR #55685</a> prevents new Eloquent model instances from being created during the <code>boot()</code> method of a model. In practice, this hardens model boot logic by disallowing instantiation of other models (which can cause unexpected side effects) while the current model is booting.</p>
<h3><a id="php-83-requirement" href="#php-83-requirement" class="" aria-hidden="true" title=""></a>PHP 8.3 requirement</h3>
<p>Laravel 13 will bump its minimum PHP version to <strong>8.3</strong> (up from 8.2). In other words, the entire codebase is being upgraded to PHP 8.3, dropping old polyfills and backward-compat hacks to streamline the framework and “let it move faster.” (See <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/54763">PR #54763</a>).</p>
<h3><a id="http-client-pool-default-concurrency" href="#http-client-pool-default-concurrency" class="" aria-hidden="true" title=""></a>HTTP client pool default concurrency</h3>
<p>In <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/57972">PR #57972</a>, <code>PendingRequest::pool()</code> now defaults to <strong>2</strong> for concurrency. This avoids the footgun where developers may think pooled requests are concurrent but they end up executing serially when concurrency is left <code>null</code>.</p>
<h3><a id="safer-requestget-behavior-symfony-parity" href="#safer-requestget-behavior-symfony-parity" class="" aria-hidden="true" title=""></a>Safer <code>Request::get()</code> behavior (Symfony parity)</h3>
<p><a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/58081">PR #58081</a> aligns Laravel’s <code>Request::get()</code> behavior with Symfony to avoid breaking changes, improving compatibility as Laravel moves forward with newer Symfony components.</p>
<h3><a id="mysql-grammar-delete--join-with-order-by--limit" href="#mysql-grammar-delete--join-with-order-by--limit" class="" aria-hidden="true" title=""></a>MySQL grammar: DELETE … JOIN with ORDER BY + LIMIT</h3>
<p>In <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/57196">PR #57196</a>, Laravel’s MySQL grammar now compiles full <code>DELETE … JOIN</code> queries including <code>ORDER BY</code> and <code>LIMIT</code>, preventing MySQL delete-join batch operations from silently ignoring those clauses.</p>
<h3><a id="managers-bind-manager-instances-to-custom-driver-closures" href="#managers-bind-manager-instances-to-custom-driver-closures" class="" aria-hidden="true" title=""></a>Managers: bind manager instances to custom driver closures</h3>
<p><a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/57173">PR #57173</a> makes manager <code>extend()</code> callbacks consistently receive a bound manager instance across Laravel’s various manager classes, improving custom driver ergonomics (with upgrade notes since it’s a breaking change).</p>
<h3><a id="polymorphic-pivot-table-naming-plural" href="#polymorphic-pivot-table-naming-plural" class="" aria-hidden="true" title=""></a>Polymorphic pivot table naming (plural)</h3>
<p>In <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/56832">PR #56832</a>, Laravel improves automatic table name generation for polymorphic pivot tables by using plural names, aligning the behavior with documentation and common conventions.</p>
<h3><a id="queue-events-jobattempted-now-exposes-the-actual-exception" href="#queue-events-jobattempted-now-exposes-the-actual-exception" class="" aria-hidden="true" title=""></a>Queue events: <code>JobAttempted</code> now exposes the actual exception</h3>
<p>In <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/56148">PR #56148</a>, the <code>JobAttempted</code> event now passes the full <code>Throwable</code> instead of a boolean flag, giving listeners better context for failures. This change is targeted at Laravel 13 as a breaking change.</p>
<h3><a id="testing-cleanup-reset-str-factories-between-tests" href="#testing-cleanup-reset-str-factories-between-tests" class="" aria-hidden="true" title=""></a>Testing cleanup: reset <code>Str</code> factories between tests</h3>
<p><a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/57296">PR #57296</a> restores <code>Str</code> factories to defaults when tearing down test cases, helping prevent cross-test state leakage.</p>
<h3><a id="hyphenated-prefixes-support" href="#hyphenated-prefixes-support" class="" aria-hidden="true" title=""></a>Hyphenated prefixes support</h3>
<p><a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/56172">PR #56172</a> introduces changes related to hyphenated prefixes in areas where prefixes affect behavior, with discussion indicating breaking-change sensitivity.</p>
<h3><a id="notification-polish-email-subjects" href="#notification-polish-email-subjects" class="" aria-hidden="true" title=""></a>Notification polish: email subjects</h3>
<p><a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/57884">PR #57884</a> updates verification email subject capitalization, and <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/57882">PR #57882</a> updates the reset password notification subject.</p>
<p><em>Each of the above items links to its PR on GitHub for full details. More new features are expected to arrive later, and I will document those as they come.</em></p>
<h2><a id="how-to-install--try-laravel-13-today" href="#how-to-install--try-laravel-13-today" class="" aria-hidden="true" title=""></a>How to Install &amp; Try Laravel 13 Today</h2>
<p>Because Laravel 13 is not yet officially released, the main way to try it now is via the Laravel installer or Composer in dev mode. For example, using the Laravel installer you can run:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">laravel </span><span style="color: #98C379;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">my-app</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--dev</span></div></code></pre>
<p>Or with Composer directly:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">create-project</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--prefer-dist</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">laravel/laravel</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">my-app</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">dev-master</span></div></code></pre>
<p>This creates a new Laravel project using the <code>dev-master</code> (i.e. Laravel 13) branch. You can then <code>cd my-app</code> and use Laravel as usual (note: you’ll need PHP 8.3 installed to meet the new requirement). These steps let you experiment with the early Laravel 13 codebase. As always, be cautious using dev releases in production, but this is a great way to preview upcoming features.</p>
<p><em>All of the above is based on the current development state. I’ll continue to monitor PRs and update this post as new features land in Laravel 13. Stay tuned!</em></p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Wed, 17 Dec 2025 19:01:19 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Keep or Append Query Strings in Laravel Pagination]]></title>
                <link>https://nabilhassen.com/keep-or-append-query-strings-in-laravel-pagination</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#laravel-pagination-guide-preserve-query-string-values">Laravel Pagination Guide: Preserve Query String Values</a></li>
<li><a href="#keeping-all-current-query-string-values">Keeping All Current Query String Values</a></li>
<li><a href="#appending-specific-query-string-values">Appending Specific Query String Values</a></li>
<li><a href="#when-to-use-each-method">When to Use Each Method</a></li>
</ul>
<h2><a id="laravel-pagination-guide-preserve-query-string-values" href="#laravel-pagination-guide-preserve-query-string-values" class="" aria-hidden="true" title=""></a>Laravel Pagination Guide: Preserve Query String Values</h2>
<p>When building a Laravel application that lists data with pagination, you often need to preserve certain query parameters across pages. For example, you may have filters like <code>?sort=price</code> or <code>?category=books</code> that should remain in the pagination links as the user navigates. Laravel makes this easy with two helpful methods: <code>withQueryString()</code> and <code>appends()</code>.</p>
<h2><a id="keeping-all-current-query-string-values" href="#keeping-all-current-query-string-values" class="" aria-hidden="true" title=""></a>Keeping All Current Query String Values</h2>
<p>If you want <strong>all</strong> of the current request's query parameters to be preserved in the pagination links, you can use the <code>withQueryString()</code> method. This is especially useful when you have multiple filters and want them all carried over without manually specifying them.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Models\</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">Route</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;/users&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> () {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">paginate</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">15</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">withQueryString</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">view</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users.index&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">compact</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">));</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div></code></pre>
<p>If the current URL is:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">/users?sort=name&amp;role=admin</span></div></code></pre>
<p>The pagination links generated will look like:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">/users?page=2&amp;sort=name&amp;role=admin</span></div></code></pre>
<p>Laravel automatically merges the <code>page</code> parameter with all other existing parameters.</p>
<h2><a id="appending-specific-query-string-values" href="#appending-specific-query-string-values" class="" aria-hidden="true" title=""></a>Appending Specific Query String Values</h2>
<p>Sometimes you don't need every query parameter from the request, you just want to add a few specific ones. In that case, use the <code>appends()</code> method and pass an array of key-value pairs.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Models\</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">Route</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;/users&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> () {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">paginate</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">15</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">appends</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;sort&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;votes&#39;</span><span style="color: #ABB2BF;">]);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">view</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users.index&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">compact</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">));</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div></code></pre>
<p>Now, every pagination link will include <code>?sort=votes</code> along with the correct <code>page</code> value:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">/users?page=2&amp;sort=votes</span></div></code></pre>
<h2><a id="when-to-use-each-method" href="#when-to-use-each-method" class="" aria-hidden="true" title=""></a>When to Use Each Method</h2>
<ul>
<li><strong><code>withQueryString()</code></strong>: Use when you want <em>all</em> existing request parameters preserved automatically.</li>
<li><strong><code>appends()</code></strong>:Use when you only want to add or modify specific query parameters.</li>
</ul>
<p>Both methods help maintain filter and search state across paginated results, improving user experience by ensuring their selected options stay intact as they browse through pages.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Thu, 14 Aug 2025 19:44:29 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Install Laravel on Mac: Quick & Easy Setup Guide]]></title>
                <link>https://nabilhassen.com/install-laravel-on-mac-quick-easy-setup-guide</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#getting-started-with-laravel-on-mac">Getting Started with Laravel on Mac</a></li>
<li><a href="#installing-php-composer-and-the-laravel-installer">Installing PHP, Composer, and the Laravel Installer</a></li>
<li><a href="#installing-node--npm-on-macos">Installing Node &amp; NPM on macOS</a></li>
<li><a href="#creating-your-first-laravel-application">Creating Your First Laravel Application</a></li>
</ul>
<h2><a id="getting-started-with-laravel-on-mac" href="#getting-started-with-laravel-on-mac" class="" aria-hidden="true" title=""></a>Getting Started with Laravel on Mac</h2>
<p>Laravel is a powerful PHP framework that makes web application development smooth and enjoyable. If you’re on macOS and ready to dive into Laravel, this guide will walk you through the steps to set up your environment, create your first application, and configure it for development.</p>
<h2><a id="installing-php-composer-and-the-laravel-installer" href="#installing-php-composer-and-the-laravel-installer" class="" aria-hidden="true" title=""></a>Installing PHP, Composer, and the Laravel Installer</h2>
<p>Before creating your first Laravel application, you need to have <strong>PHP</strong>, <strong>Composer</strong>, and the <strong>Laravel installer</strong> installed. Additionally, you’ll need <strong>Node &amp; NPM</strong> or <strong>Bun</strong> for compiling your application’s frontend assets.</p>
<p>If you don’t have PHP and Composer installed, run the following command to install PHP, Composer, and the Laravel installer on macOS:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">/bin/bash </span><span style="color: #D19A66;">-c</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;$(curl </span><span style="color: #D19A66;">-fsSL</span><span style="color: #98C379;"> https://php.new/install/mac/8.4)&quot;</span></div></code></pre>
<p>After installation, restart your terminal session. If you need to update PHP, Composer, and the Laravel installer later, simply re-run the same command.</p>
<p>If you already have PHP and Composer, install the Laravel installer via Composer:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">global</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">require</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">laravel/installer</span></div></code></pre>
<blockquote>
<p><strong>Tip:</strong> For a fully-featured, graphical PHP management tool, check out <strong>Laravel Herd</strong>.</p>
</blockquote>
<h2><a id="installing-node--npm-on-macos" href="#installing-node--npm-on-macos" class="" aria-hidden="true" title=""></a>Installing Node &amp; NPM on macOS</h2>
<p>Node and NPM are required to compile and manage your Laravel application's frontend assets. On macOS, the easiest way to install them is via <strong>Homebrew</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;"># Download and install Homebrew</span></div><div class='line'><span style="color: #ABB2BF;">curl </span><span style="color: #D19A66;">-o-</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh</span><span style="color: #ABB2BF;"> | bash</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;"># Download and install Node.js:</span></div><div class='line'><span style="color: #ABB2BF;">brew </span><span style="color: #98C379;">install</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">node@22</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;"># Verify the Node.js version:</span></div><div class='line'><span style="color: #ABB2BF;">node </span><span style="color: #D19A66;">-v</span><span style="color: #ABB2BF;"> </span><span style="color: #7F848E;"># Should print &quot;v22.18.0&quot;.</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;"># Verify npm version:</span></div><div class='line'><span style="color: #ABB2BF;">npm </span><span style="color: #D19A66;">-v</span><span style="color: #ABB2BF;"> </span><span style="color: #7F848E;"># Should print &quot;10.9.3&quot;.</span></div></code></pre>
<p>This will display the installed versions of Node and NPM. You can update them anytime using:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">brew </span><span style="color: #98C379;">upgrade</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">node</span></div></code></pre>
<h2><a id="creating-your-first-laravel-application" href="#creating-your-first-laravel-application" class="" aria-hidden="true" title=""></a>Creating Your First Laravel Application</h2>
<p>Once your environment is ready, create a new Laravel application:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">laravel </span><span style="color: #98C379;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">example-app</span></div></code></pre>
<p>The installer will ask you to select your preferred testing framework, database, and starter kit.</p>
<p>After creation, start the development environment:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #56B6C2;">cd</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">example-app</span></div><div class='line'><span style="color: #ABB2BF;">npm </span><span style="color: #98C379;">install</span></div><div class='line'><span style="color: #ABB2BF;">npm </span><span style="color: #98C379;">run</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">dev</span></div></code></pre>
<p>And on a serparate terminal run:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">run</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">dev</span></div></code></pre>
<p>Now visit <a rel="nofollow noopener" target="_blank" href="http://localhost:8000">http://localhost:8000</a> in your browser, and your Laravel app will be live.</p>
<p>With these steps, you’re ready to start developing with Laravel on macOS. From here, you can explore Laravel’s features, build your database models, set up routes, and create powerful web applications.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Wed, 13 Aug 2025 21:42:13 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Filament v4: What’s New and Exciting]]></title>
                <link>https://nabilhassen.com/filament-v4-whats-new-and-exciting</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#filament-v4-is-faster-smarter-and-more-flexible">Filament v4 is Faster, Smarter, and More Flexible</a></li>
<li><a href="#quick-overview-what-i-picked">Quick overview (what I picked)</a></li>
<li><a href="#why-this-matters">Why this matters</a></li>
<li><a href="#highlights-and-examples">Highlights and examples</a>
<ul>
<li><a href="#1-performance-gains--partial-rendering">1. Performance gains &amp; Partial Rendering</a></li>
<li><a href="#2-client-side-js-helpers-reduce-round-trips">2. Client-side JS helpers, reduce round trips</a></li>
<li><a href="#3-tiptap-based-rich-editor">3. TipTap-based Rich Editor</a></li>
<li><a href="#4-nested-resources-and-cleaner-organization">4. Nested resources and cleaner organization</a></li>
<li><a href="#5-tables-and-selection-ux">5. Tables and selection UX</a></li>
<li><a href="#6-authentication--security">6. Authentication &amp; Security</a></li>
<li><a href="#7-developer-ergonomics">7. Developer ergonomics</a></li>
</ul>
</li>
<li><a href="#migration--upgrade-notes">Migration &amp; upgrade notes</a></li>
<li><a href="#read-more">Read more</a></li>
</ul>
<h2><a id="filament-v4-is-faster-smarter-and-more-flexible" href="#filament-v4-is-faster-smarter-and-more-flexible" class="" aria-hidden="true" title=""></a>Filament v4 is Faster, Smarter, and More Flexible</h2>
<p>Filament v4 is stable: big performance wins, a more expressive server-driven UI, fewer round-trips to the server, and a richer set of developer-friendly primitives (TipTap rich editing, nested resources, client-side JS helpers, and more). This post highlights the most exciting changes for Laravel developers who build admin panels and internal tools with Filament.</p>
<h2><a id="quick-overview-what-i-picked" href="#quick-overview-what-i-picked" class="" aria-hidden="true" title=""></a>Quick overview (what I picked)</h2>
<ul>
<li>Major rendering and interaction performance improvements (partial rendering, fewer Blade views).</li>
<li>Tailwind CSS v4 + dynamic color system (OKLCH) and improved theming.</li>
<li>Built‑in multi‑factor authentication (TOTP apps + email codes).</li>
<li>Powerful TipTap-based rich editor: custom blocks, merge tags, HTML/JSON storage, and plugin extensibility.</li>
<li>Client-side JS helpers to eliminate unnecessary network requests: <code>hiddenJs()</code>, <code>visibleJs()</code>, <code>afterStateUpdatedJs()</code>, and <code>JsContent</code>.</li>
<li>Nested resources and better resource organization (dedicated namespaces, page <code>schema()</code> customization).</li>
<li>Tables backed by custom data + ModalTableSelect and improved bulk actions (chunked processing, grouped failure reporting).</li>
<li>Small but developer-loved ergonomics: icon enums, <code>FilamentTimezone</code>, ISO date formats, and <code>preserveFormDataWhenCreatingAnother()</code>.</li>
</ul>
<h2><a id="why-this-matters" href="#why-this-matters" class="" aria-hidden="true" title=""></a>Why this matters</h2>
<p>Filament already made it easy to build polished admin UIs in Laravel; v4 lowers the friction even more. Performance and partial rendering reduce latency for data-heavy screens. The client-side JS hooks mean reactive UI behavior can happen instantly without hitting the server. The new rich editor and table features reduce the need for custom front-end code or third‑party integrations. Combined, these updates let you ship faster, with fewer surprises.</p>
<h2><a id="highlights-and-examples" href="#highlights-and-examples" class="" aria-hidden="true" title=""></a>Highlights and examples</h2>
<p>Below I pick the features I’d call “must‑try” and explain how you might use them in real projects.</p>
<h3><a id="1-performance-gains--partial-rendering" href="#1-performance-gains--partial-rendering" class="" aria-hidden="true" title=""></a>1. Performance gains &amp; Partial Rendering</h3>
<p>Filament v4 reduces the number of Blade views and extracts repeated Tailwind groups into classes to shrink HTML output. For large tables and complex pages you should see much faster server rendering times.</p>
<p>Partial rendering: instead of re-rendering the form, only part of the form needs to react to changes.</p>
<h3><a id="2-client-side-js-helpers-reduce-round-trips" href="#2-client-side-js-helpers-reduce-round-trips" class="" aria-hidden="true" title=""></a>2. Client-side JS helpers, reduce round trips</h3>
<p>Rather than reload the entire schema on small UI changes, Filament v4 lets you evaluate expressions in the browser.</p>
<p>Examples:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">Select</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">make</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;discount_type&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">options</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;fixed&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Fixed&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;percentage&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Percentage&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ]);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">TextInput</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">make</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;discount_value&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">hiddenJs</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;$get(&quot;discount_type&quot;) !== &quot;percentage&quot;&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">TextInput</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">make</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;title&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">afterStateUpdatedJs</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;$set(&quot;slug&quot;, $state.toLowerCase().replace(/\s+/g, &quot;-&quot;))&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>You can also use <code>JsContent</code> to produce dynamic labels or below‑content text that updates instantly as the user types.</p>
<h3><a id="3-tiptap-based-rich-editor" href="#3-tiptap-based-rich-editor" class="" aria-hidden="true" title=""></a>3. TipTap-based Rich Editor</h3>
<p>Filament replaces the older editor with a TipTap-powered rich editor that’s modern, extensible and headless. Practical wins:</p>
<ul>
<li>Store content as HTML or JSON.</li>
<li>Define custom blocks for complex content layouts.</li>
<li>Add merge tags to allow editors to insert placeholders.</li>
</ul>
<h3><a id="4-nested-resources-and-cleaner-organization" href="#4-nested-resources-and-cleaner-organization" class="" aria-hidden="true" title=""></a>4. Nested resources and cleaner organization</h3>
<p>If you’ve needed full-page create and edit views for related models, nested resources give you that structure out of the box. Resource classes are also generated into dedicated namespaces by default, which keeps a growing codebase tidy.</p>
<p>Pages now expose a <code>content()</code>/<code>schema()</code>-style API so you can fully control layout and order of components.</p>
<h3><a id="5-tables-and-selection-ux" href="#5-tables-and-selection-ux" class="" aria-hidden="true" title=""></a>5. Tables and selection UX</h3>
<p>Tables can be backed by custom data sources. The new <code>ModalTableSelect</code> provides a modal backed by a full Filament table, perfect when your relationship selection needs full-text search, filters, and pagination.</p>
<p>Bulk actions received attention too: per-record authorization inside bulk actions, chunked processing for performance, and grouped failure reporting.</p>
<h3><a id="6-authentication--security" href="#6-authentication--security" class="" aria-hidden="true" title=""></a>6. Authentication &amp; Security</h3>
<p>Filament v4 includes MFA support with two built-in providers:</p>
<ul>
<li>TOTP apps</li>
<li>Email codes</li>
</ul>
<p>You can also register custom MFA providers.</p>
<h3><a id="7-developer-ergonomics" href="#7-developer-ergonomics" class="" aria-hidden="true" title=""></a>7. Developer ergonomics</h3>
<p>A few smaller additions:</p>
<ul>
<li>Heroicon enum for IDE autocompletion.</li>
<li><code>FilamentTimezone::set()</code> for consistent timezone handling.</li>
<li>ISO date-time formats.</li>
<li><code>$shouldSplitGlobalSearchTerms</code> property allows disabling splitting the global search term into individual words.</li>
<li><code>preserveFormDataWhenCreatingAnother()</code> - retain certain values when using <strong>Create and create another</strong> action.</li>
</ul>
<h2><a id="migration--upgrade-notes" href="#migration--upgrade-notes" class="" aria-hidden="true" title=""></a>Migration &amp; upgrade notes</h2>
<p>Follow the <a rel="nofollow noopener" target="_blank" href="https://filamentphp.com/docs/4.x/upgrade-guide">upgrade guide</a> closely. Watch for Tailwind v4 changes and refactor client-side behavior to use the new JS helpers.</p>
<h2><a id="read-more" href="#read-more" class="" aria-hidden="true" title=""></a>Read more</h2>
<ul>
<li><a rel="nofollow noopener" target="_blank" href="https://filamentphp.com/content/leandrocfe-whats-new-in-filament-v4">https://filamentphp.com/content/leandrocfe-whats-new-in-filament-v4</a></li>
</ul>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 12 Aug 2025 20:33:09 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Exclude Models With except() Method in Laravel 12.22]]></title>
                <link>https://nabilhassen.com/exclude-models-with-except-method-in-laravel-1222</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#laravel-1222---adds-except-method-to-eloquent-builder-for-excluding-models-from-queries">Laravel 12.22 - Adds except() Method to Eloquent Builder for Excluding Models from Queries</a></li>
<li><a href="#what-does-except-do">What Does except() Do?</a></li>
<li><a href="#why-not-modify-wherekeynot">Why Not Modify whereKeyNot()?</a></li>
<li><a href="#how-to-use-except">How to Use except()</a>
<ul>
<li><a href="#before-laravel-1222">Before Laravel 12.22</a></li>
<li><a href="#after-laravel-1222">After Laravel 12.22</a></li>
</ul>
</li>
<li><a href="#summary">Summary</a></li>
</ul>
<h2><a id="laravel-1222---adds-except-method-to-eloquent-builder-for-excluding-models-from-queries" href="#laravel-1222---adds-except-method-to-eloquent-builder-for-excluding-models-from-queries" class="" aria-hidden="true" title=""></a>Laravel 12.22 - Adds <code>except()</code> Method to Eloquent Builder for Excluding Models from Queries</h2>
<p>Laravel 12.22 introduces a new and expressive method called <code>except()</code> on the Eloquent query builder. This method makes it easy to exclude specific model instances or collections of models from your query results — helping you write cleaner, more readable code.</p>
<h2><a id="what-does-except-do" href="#what-does-except-do" class="" aria-hidden="true" title=""></a>What Does <code>except()</code> Do?</h2>
<p>The <code>except()</code> method allows you to <strong>exclude one or more model instances or collections of models</strong> from a query. Internally, it leverages the existing <code>whereKeyNot()</code> method by extracting the primary keys from the given models.</p>
<p>This means instead of manually extracting IDs and calling <code>whereKeyNot()</code>, you can now directly pass models or collections to <code>except()</code> for exclusion.</p>
<h2><a id="why-not-modify-wherekeynot" href="#why-not-modify-wherekeynot" class="" aria-hidden="true" title=""></a>Why Not Modify <code>whereKeyNot()</code>?</h2>
<p><code>whereKeyNot()</code> was originally designed to exclude records by their key or IDs only. Modifying it to handle models or collections directly would complicate its purpose and could introduce unexpected side effects for existing users.</p>
<p>The new <code>except()</code> method keeps concerns clean:</p>
<ul>
<li><strong><code>whereKeyNot()</code></strong> remains focused on keys/IDs.</li>
<li><strong><code>except()</code></strong> provides a user-friendly, expressive way to exclude models.</li>
</ul>
<h2><a id="how-to-use-except" href="#how-to-use-except" class="" aria-hidden="true" title=""></a>How to Use <code>except()</code></h2>
<h3><a id="before-laravel-1222" href="#before-laravel-1222" class="" aria-hidden="true" title=""></a>Before Laravel 12.22</h3>
<p>To exclude videos with IDs 2 and 4, you would:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$videos</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> \App\Models\</span><span style="color: #E5C07B;">Video</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">query</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">whereIn</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;id&#39;</span><span style="color: #ABB2BF;">, [</span><span style="color: #D19A66;">2</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">4</span><span style="color: #ABB2BF;">])</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$otherVideosUsingWhereKeyNot</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> \App\Models\</span><span style="color: #E5C07B;">Video</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">query</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">whereKeyNot</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$videos</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">pluck</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;id&#39;</span><span style="color: #ABB2BF;">))</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>Here you manually pluck the IDs from the collection to exclude them.</p>
<h3><a id="after-laravel-1222" href="#after-laravel-1222" class="" aria-hidden="true" title=""></a>After Laravel 12.22</h3>
<p>You can simplify the above by passing the models directly to <code>except()</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$videos</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> \App\Models\</span><span style="color: #E5C07B;">Video</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">query</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">whereIn</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;id&#39;</span><span style="color: #ABB2BF;">, [</span><span style="color: #D19A66;">2</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">4</span><span style="color: #ABB2BF;">])</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$otherVideosUsingExcept</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> \App\Models\</span><span style="color: #E5C07B;">Video</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">query</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">except</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$videos</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>This makes your intentions clearer and your code cleaner.</p>
<h2><a id="summary" href="#summary" class="" aria-hidden="true" title=""></a>Summary</h2>
<p>The new <code>except()</code> method in Laravel 12.22 is a small addition to Eloquent, improving readability and expressiveness when excluding models from queries.</p>
<ul>
<li>Pass one or many model instances or collections to exclude them.</li>
<li>Internally uses <code>whereKeyNot()</code> for efficient query filtering.</li>
<li>Keeps <code>whereKeyNot()</code> focused and unaltered.</li>
<li>Available now in Laravel 12.22 and later.</li>
<li>This method was contributed in Pull Request <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/56442">#56442</a></li>
</ul>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Fri, 08 Aug 2025 18:34:13 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Create Your Own Custom Casts in Laravel]]></title>
                <link>https://nabilhassen.com/create-your-own-custom-casts-in-laravel</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#create-custom-casts-in-laravel">Create Custom Casts in Laravel</a></li>
<li><a href="#step-1-create-a-custom-cast-class">Step 1: Create a Custom Cast Class</a></li>
<li><a href="#step-2-use-the-custom-cast-in-a-model">Step 2: Use the Custom Cast in a Model</a></li>
<li><a href="#additional-notes">Additional Notes</a></li>
</ul>
<h2><a id="create-custom-casts-in-laravel" href="#create-custom-casts-in-laravel" class="" aria-hidden="true" title=""></a>Create Custom Casts in Laravel</h2>
<p>In Laravel, Eloquent provides a simple way to cast attributes to common data types like integers, booleans, arrays, and even objects. But sometimes, the built-in casts aren’t enough. That’s where <strong>custom casts</strong> come in. They allow you to define your own logic for how a model attribute should be stored and retrieved.</p>
<p>In this post, we’ll walk through how to create and use a custom cast in Laravel.</p>
<h2><a id="step-1-create-a-custom-cast-class" href="#step-1-create-a-custom-cast-class" class="" aria-hidden="true" title=""></a>Step 1: Create a Custom Cast Class</h2>
<p>To create a custom cast, you need to implement the <code>CastsAttributes</code> interface. This interface requires two methods:</p>
<ul>
<li><code>get($model, $key, $value, $attributes)</code> – used when retrieving the value from the database</li>
<li><code>set($model, $key, $value, $attributes)</code> – used when storing the value into the database</li>
</ul>
<p>Here’s an example of a custom cast that encrypts and decrypts a value:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">namespace</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">App\Casts</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Contracts\Database\Eloquent\</span><span style="color: #E5C07B;">CastsAttributes</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Crypt</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Encrypted</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">implements</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">CastsAttributes</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$model</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$key</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$attributes</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">string</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Crypt</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">decryptString</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">set</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$model</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$key</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$attributes</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">string</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Crypt</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">encryptString</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>This cast will automatically encrypt a value before saving it to the database and decrypt it when retrieving it.</p>
<h2><a id="step-2-use-the-custom-cast-in-a-model" href="#step-2-use-the-custom-cast-in-a-model" class="" aria-hidden="true" title=""></a>Step 2: Use the Custom Cast in a Model</h2>
<p>Once your custom cast is ready, you can assign it to a model attribute using the <code>$casts</code> property:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Casts\</span><span style="color: #E5C07B;">Encrypted</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Model</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$casts</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;secret&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E5C07B;">Encrypted</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ];</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Now, whenever you access <code>$user-&gt;secret</code>, the value will be decrypted, and when you set <code>$user-&gt;secret = 'value'</code>, it will be encrypted before saving.</p>
<h2><a id="additional-notes" href="#additional-notes" class="" aria-hidden="true" title=""></a>Additional Notes</h2>
<ul>
<li>The custom cast must be a class that implements <code>CastsAttributes</code>.</li>
<li>Custom casts give you full control over how attributes behave.</li>
</ul>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Thu, 07 Aug 2025 00:38:21 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[scout:queue-import: Faster Indexing in Laravel Scout]]></title>
                <link>https://nabilhassen.com/scoutqueue-import-faster-indexing-in-laravel-scout</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#speed-up-laravel-scout-indexing-with-scoutqueue-import">Speed Up Laravel Scout Indexing with scout:queue-import</a></li>
<li><a href="#the-problem-with-scoutimport">The Problem with scout:import</a></li>
<li><a href="#the-solution-scoutqueue-import">The Solution: scout:queue-import</a></li>
<li><a href="#usage-example---php-artisan-scoutqueue-import">Usage Example - php artisan scout:queue-import</a></li>
<li><a href="#important-notes">Important Notes</a></li>
<li><a href="#why-it-matters">Why It Matters</a></li>
</ul>
<h2><a id="speed-up-laravel-scout-indexing-with-scoutqueue-import" href="#speed-up-laravel-scout-indexing-with-scoutqueue-import" class="" aria-hidden="true" title=""></a>Speed Up Laravel Scout Indexing with <code>scout:queue-import</code></h2>
<p>If you've ever waited <em>hours</em> or even <em>days</em> for <code>php artisan scout:import</code> to finish indexing your models, you're not alone. A new command coming to Laravel Scout aims to solve exactly that: <code>scout:queue-import</code>.</p>
<p>The new Artisan command contributed by <a rel="nofollow noopener" target="_blank" href="https://x.com/ste_bau">@ste_bau</a> was introduced in <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/scout/pull/929">PR #929</a>, and it's designed to make importing millions of records into your search indexes dramatically faster by leveraging your queue system more efficiently.</p>
<h2><a id="the-problem-with-scoutimport" href="#the-problem-with-scoutimport" class="" aria-hidden="true" title=""></a>The Problem with <code>scout:import</code></h2>
<p>The existing <code>scout:import</code> command loops through your entire table, loading and then indexing chunks of your models sequentially. While this works fine for smaller datasets, it's painfully slow for large applications. Even if you're using queues, jobs will be dispatched one at a time only after loading the next chunk.</p>
<h2><a id="the-solution-scoutqueue-import" href="#the-solution-scoutqueue-import" class="" aria-hidden="true" title=""></a>The Solution: <code>scout:queue-import</code></h2>
<p>The new <code>scout:queue-import</code> command changes the approach entirely. Instead of iterating through the table, it:</p>
<ol>
<li>Retrieves the <strong>MIN</strong> and <strong>MAX</strong> values of your model’s Scout key (usually the <code>id</code>).</li>
<li>Splits that range into chunks (default: 500), generating multiple ranges.</li>
<li>Dispatches a <strong>job per range</strong> to your queue workers.</li>
</ol>
<p>Because it avoids querying the entire database to fetch rows before queuing, this method is much more efficient especially when your queue workers can run in parallel. With multiple queue workers running, jobs can be processed in parallel something that's not possible with the sequential nature of the <code>scout:import</code> command.</p>
<h2><a id="usage-example---php-artisan-scoutqueue-import" href="#usage-example---php-artisan-scoutqueue-import" class="" aria-hidden="true" title=""></a>Usage Example - <code>php artisan scout:queue-import</code></h2>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">scout:queue-import</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;App</span><span style="color: #56B6C2;">\\</span><span style="color: #98C379;">Models</span><span style="color: #56B6C2;">\\</span><span style="color: #98C379;">Post&quot;</span></div></code></pre>
<p>You can also customize the chunk size:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">scout:queue-import</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;App</span><span style="color: #56B6C2;">\\</span><span style="color: #98C379;">Models</span><span style="color: #56B6C2;">\\</span><span style="color: #98C379;">Post&quot;</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--chunk=1000</span></div></code></pre>
<p>You can also customize the range:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">scout:queue-import</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;App\Models\Post&quot;</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--min=10</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--max=100</span></div></code></pre>
<h2><a id="important-notes" href="#important-notes" class="" aria-hidden="true" title=""></a>Important Notes</h2>
<ul>
<li>Your model’s Scout key <strong>must be numeric and auto-incrementing</strong>. If it isn’t, the command will throw an error and abort.</li>
<li><strong>Gaps in the ID sequence may cause jobs to index fewer records</strong> (or none at all) in that range.</li>
<li>You must have <strong>queue workers</strong> running and properly configured for the jobs to be processed.</li>
</ul>
<h2><a id="why-it-matters" href="#why-it-matters" class="" aria-hidden="true" title=""></a>Why It Matters</h2>
<p>If you're dealing with large datasets, <code>scout:queue-import</code> can be a game changer. Instead of waiting hours or days, you can reindex millions of records quickly without putting your system on pause.</p>
<p>Give it a try and speed up your search indexing workflow with Laravel Scout!</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 05 Aug 2025 20:02:05 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Safely Change Column Types in Laravel with Migrations]]></title>
                <link>https://nabilhassen.com/safely-change-column-types-in-laravel-with-migrations</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#how-to-change-column-types-with-laravel-migrations">How to Change Column Types with Laravel Migrations</a></li>
<li><a href="#step-1-optional-install-the-doctrinedbal-package">Step 1: (Optional) Install the doctrine/dbal Package</a></li>
<li><a href="#step-2-create-a-new-migration">Step 2: Create a New Migration</a></li>
<li><a href="#step-3-modify-the-column">Step 3: Modify the Column</a>
<ul>
<li><a href="#important-considerations">Important Considerations</a></li>
</ul>
</li>
<li><a href="#step-4-run-the-migration">Step 4: Run the Migration</a></li>
<li><a href="#summary">Summary</a></li>
</ul>
<h2><a id="how-to-change-column-types-with-laravel-migrations" href="#how-to-change-column-types-with-laravel-migrations" class="" aria-hidden="true" title=""></a>How to Change Column Types with Laravel Migrations</h2>
<p>Sometimes, you need to <strong>change a column’s data type</strong> in your database. For example, maybe you want to change a column from <code>string</code> to <code>integer</code>, or from <code>text</code> to <code>boolean</code>. Laravel makes this possible using <strong>migrations</strong>.</p>
<p>In this post, we’ll walk you through the steps.</p>
<h2><a id="step-1-optional-install-the-doctrinedbal-package" href="#step-1-optional-install-the-doctrinedbal-package" class="" aria-hidden="true" title=""></a>Step 1: (Optional) Install the <code>doctrine/dbal</code> Package</h2>
<p>Starting from <strong>Laravel 10</strong>, you no longer need to install the <code>doctrine/dbal</code> package for most column modifications. However, if your application is running Laravel 10 and <strong>SQLite</strong> database, you still need to install it to enable column changes.</p>
<p>Run this command if you're on SQLite:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">require</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">doctrine/dbal</span></div></code></pre>
<h2><a id="step-2-create-a-new-migration" href="#step-2-create-a-new-migration" class="" aria-hidden="true" title=""></a>Step 2: Create a New Migration</h2>
<p>Use the Artisan command to create a new migration file:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">make:migration</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">change_column_type_in_users_table</span></div></code></pre>
<p>This will create a file in the <code>database/migrations</code> folder.</p>
<h2><a id="step-3-modify-the-column" href="#step-3-modify-the-column" class="" aria-hidden="true" title=""></a>Step 3: Modify the Column</h2>
<p>Open the new migration file. Inside the <code>up()</code> method, use the <code>change()</code> method on the column. In this example, we are changing the <code>age</code> column from <code>string</code> to <code>integer</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Schema</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Schema\</span><span style="color: #E5C07B;">Blueprint</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Migrations\</span><span style="color: #E5C07B;">Migration</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Migration</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">up</span><span style="color: #ABB2BF;">(): </span><span style="color: #E5C07B;">void</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Schema</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Blueprint</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$table</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E06C75;">$table</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">integer</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;age&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">change</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">        });</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">down</span><span style="color: #ABB2BF;">(): </span><span style="color: #E5C07B;">void</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Schema</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Blueprint</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$table</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E06C75;">$table</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">string</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;age&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">change</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">        });</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">};</span></div></code></pre>
<h3><a id="important-considerations" href="#important-considerations" class="" aria-hidden="true" title=""></a>Important Considerations</h3>
<ul>
<li>✅ <strong>Ensure the column exists</strong>: Make sure the column name is correct and already exists in your table.</li>
<li>⚠️ <strong>Check data compatibility</strong>: Make sure the existing data in the column can be safely converted to the new type. Otherwise, the database will throw errors.</li>
<li>🔔 <strong>Re-define all modifiers</strong>: Since Laravel 10, when modifying a column, you must explicitly include all column modifiers you want to keep (like <code>nullable()</code>, <code>default()</code>, or <code>unsigned()</code>). Missing modifiers will be dropped.</li>
</ul>
<hr />
<h2><a id="step-4-run-the-migration" href="#step-4-run-the-migration" class="" aria-hidden="true" title=""></a>Step 4: Run the Migration</h2>
<p>Now apply the migration:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">migrate</span></div></code></pre>
<h2><a id="summary" href="#summary" class="" aria-hidden="true" title=""></a>Summary</h2>
<ul>
<li>Install <code>doctrine/dbal</code> only if needed (e.g. Laravel 9 and earlier versions or for SQLite in Laravel 10)</li>
<li>Create a migration</li>
<li>Use <code>$table-&gt;type('column')-&gt;change()</code></li>
<li>Be careful to re-include modifiers like <code>nullable()</code></li>
<li>Run <code>php artisan migrate</code></li>
</ul>
<p>This is how you update column types safely in Laravel.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Fri, 01 Aug 2025 19:45:15 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[7 Ways to Get Your Domain Name (Host) in Laravel]]></title>
                <link>https://nabilhassen.com/7-ways-to-get-your-domain-name-host-in-laravel</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#accessing-domain-name-host-in-laravel">Accessing domain name (host) in Laravel</a></li>
<li><a href="#1-configappurl">1. config('app.url')</a></li>
<li><a href="#2-request-host">2. $request-&gt;host()</a></li>
<li><a href="#3-request-httphost">3. $request-&gt;httpHost()</a></li>
<li><a href="#4-request-schemeandhttphost">4. $request-&gt;schemeAndHttpHost()</a></li>
<li><a href="#5-url">5. url('')</a></li>
<li><a href="#6-urlto">6. URL::to('')</a></li>
<li><a href="#7-requestroot">7. Request::root()</a></li>
<li><a href="#final-notes">Final Notes</a></li>
</ul>
<h2><a id="accessing-domain-name-host-in-laravel" href="#accessing-domain-name-host-in-laravel" class="" aria-hidden="true" title=""></a>Accessing domain name (host) in Laravel</h2>
<p>In Laravel, there are several ways to retrieve the domain or base URL of your web application. Depending on the context (e.g., within a controller, view, or service), one method might be more appropriate than another. Here’s a rundown of different methods to get the domain or host in Laravel.</p>
<h2><a id="1-configappurl" href="#1-configappurl" class="" aria-hidden="true" title=""></a>1. <code>config('app.url')</code></h2>
<p>This returns the base URL set in your <code>.env</code> file as <code>APP_URL</code>.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// .env</span></div><div class='line'><span style="color: #ABB2BF;">APP_URL</span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;">https:</span><span style="color: #7F848E;">//example.com</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Usage</span></div><div class='line'><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">config</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;app.url&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$url</span><span style="color: #ABB2BF;">; </span><span style="color: #7F848E;">// https://example.com</span></div></code></pre>
<p>This is useful when you want to get the domain as configured in your environment settings.</p>
<h2><a id="2-request-host" href="#2-request-host" class="" aria-hidden="true" title=""></a>2. <code>$request-&gt;host()</code></h2>
<p>This method returns only the host (domain without scheme or port).</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">show</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">host</span><span style="color: #ABB2BF;">(); </span><span style="color: #7F848E;">// example.com</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Use this when you only need the domain name.</p>
<h2><a id="3-request-httphost" href="#3-request-httphost" class="" aria-hidden="true" title=""></a>3. <code>$request-&gt;httpHost()</code></h2>
<p>This returns the host including the port number, if present.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">show</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">httpHost</span><span style="color: #ABB2BF;">(); </span><span style="color: #7F848E;">// example.com or example.com:8000</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>It’s helpful when dealing with custom ports during development.</p>
<h2><a id="4-request-schemeandhttphost" href="#4-request-schemeandhttphost" class="" aria-hidden="true" title=""></a>4. <code>$request-&gt;schemeAndHttpHost()</code></h2>
<p>This returns scheme (<code>http</code> or <code>https</code>), the host, and the port number.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">show</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">schemeAndHttpHost</span><span style="color: #ABB2BF;">(); </span><span style="color: #7F848E;">// https://example.com or https://example.com:8000</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Use this when you need the full base URL including the scheme.</p>
<h2><a id="5-url" href="#5-url" class="" aria-hidden="true" title=""></a>5. <code>url('')</code></h2>
<p>This helper returns the base URL of the application.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">url</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;&#39;</span><span style="color: #ABB2BF;">); </span><span style="color: #7F848E;">// https://example.com</span></div></code></pre>
<p>It’s simple and handy, especially inside views or Blade templates.</p>
<h2><a id="6-urlto" href="#6-urlto" class="" aria-hidden="true" title=""></a>6. <code>URL::to('')</code></h2>
<p>The <code>URL</code> facade offers similar functionality to the <code>url()</code> helper.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">URL</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">URL</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">to</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;&#39;</span><span style="color: #ABB2BF;">); </span><span style="color: #7F848E;">// https://example.com</span></div></code></pre>
<p>It’s a good alternative if you prefer using facades.</p>
<h2><a id="7-requestroot" href="#7-requestroot" class="" aria-hidden="true" title=""></a>7. <code>Request::root()</code></h2>
<p>This static call returns the root URL based on the current request.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">root</span><span style="color: #ABB2BF;">(); </span><span style="color: #7F848E;">// https://example.com</span></div></code></pre>
<p>This is useful when you’re outside of controller methods but still want to access the current request context.</p>
<h2><a id="final-notes" href="#final-notes" class="" aria-hidden="true" title=""></a>Final Notes</h2>
<p>Choose the method that best fits your use case:</p>
<ul>
<li>Use <code>config('app.url')</code> for environment-based settings.</li>
<li>Use <code>$request-&gt;...</code> methods when working inside HTTP request context.</li>
<li>Use helpers or facades when outside of controllers or when writing reusable code.</li>
</ul>
<p>Understanding these options helps you write more flexible and context-aware Laravel applications.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Thu, 31 Jul 2025 19:52:10 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[kernel.php in Laravel 12: Where is it?]]></title>
                <link>https://nabilhassen.com/how-to-replace-kernelphp-in-laravel-11-and-12</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#replacing-kernel-files-in-laravel-11-and-later-versions">Replacing Kernel Files in Laravel 11 and Later Versions</a></li>
<li><a href="#http-kernel-changes-middleware-configuration">HTTP Kernel Changes: Middleware Configuration</a></li>
<li><a href="#console-kernel-changes-scheduling-and-commands">Console Kernel Changes: Scheduling and Commands</a></li>
<li><a href="#final-bootstrapappphp-example">Final bootstrap/app.php Example</a></li>
<li><a href="#kernelphp-before-vs-after">kernel.php: Before vs After</a>
<ul>
<li><a href="#before-laravel-10-and-earlier">Before (Laravel 10 and Earlier)</a></li>
<li><a href="#after-laravel-11-and-12">After (Laravel 11 and 12)</a></li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="replacing-kernel-files-in-laravel-11-and-later-versions" href="#replacing-kernel-files-in-laravel-11-and-later-versions" class="" aria-hidden="true" title=""></a>Replacing Kernel Files in Laravel 11 and Later Versions</h2>
<p>In Laravel 11 and later, the traditional <code>App\Http\Kernel</code> and <code>App\Console\Kernel</code> classes have been removed. Instead, their responsibilities have been moved to the <code>bootstrap/app.php</code> file using a new, simplified and centralized configuration approach.</p>
<p>This post walks you through how to migrate your middleware and console scheduling logic from the old Kernel classes to the new Laravel 11 and later structure.</p>
<h2><a id="http-kernel-changes-middleware-configuration" href="#http-kernel-changes-middleware-configuration" class="" aria-hidden="true" title=""></a>HTTP Kernel Changes: Middleware Configuration</h2>
<p>Previously, your middleware setup was done in <code>App\Http\Kernel</code>. You had to manage three major arrays:</p>
<ul>
<li><code>$middleware</code>: global middleware</li>
<li><code>$middlewareGroups</code>: group middleware for <code>web</code>, <code>api</code>, etc.</li>
<li><code>$middlewareAliases</code>: route middleware aliases</li>
</ul>
<p>In Laravel 11, all of this now goes into a closure inside <code>bootstrap/app.php</code>, using the <code>withMiddleware()</code> method:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">withMiddleware</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Middleware</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$middleware</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// Global middleware</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$middleware</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">append</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">EnsureTokenIsValid</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// Middleware groups</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$middleware</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">appendToGroup</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;group-name&#39;</span><span style="color: #ABB2BF;">, [</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">First</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Second</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ]);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$middleware</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">prependToGroup</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;group-name&#39;</span><span style="color: #ABB2BF;">, [</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">First</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Second</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ]);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// Middleware aliases</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$middleware</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">alias</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;subscribed&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E5C07B;">EnsureUserIsSubscribed</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span></div><div class='line'><span style="color: #ABB2BF;">    ]);</span></div><div class='line'><span style="color: #ABB2BF;">})</span></div></code></pre>
<h2><a id="console-kernel-changes-scheduling-and-commands" href="#console-kernel-changes-scheduling-and-commands" class="" aria-hidden="true" title=""></a>Console Kernel Changes: Scheduling and Commands</h2>
<p>Before Laravel 11, command scheduling was defined in the <code>App\Console\Kernel</code> class, particularly in the <code>schedule()</code> and <code>commands()</code> methods.</p>
<p>Now, both your scheduled tasks and command routes are defined in <code>routes/console.php</code>, like this:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Console\Scheduling\</span><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">command</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;inspire&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">hourly</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>There is no need to explicitly register these commands in a <code>Kernel</code> class as Laravel will automatically load them from the <code>routes/console.php</code> file, as long as you include the file via <code>withRouting()</code> in <code>bootstrap/app.php</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">withRouting</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">    web: </span><span style="color: #D19A66;">__DIR__</span><span style="color: #ABB2BF;">.</span><span style="color: #98C379;">&#39;/../routes/web.php&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    commands: </span><span style="color: #D19A66;">__DIR__</span><span style="color: #ABB2BF;">.</span><span style="color: #98C379;">&#39;/../routes/console.php&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    health: </span><span style="color: #98C379;">&#39;/up&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">)</span></div></code></pre>
<p>By default, Laravel automatically registers all commands in <code>app/Console/Commands</code>. To register commands from other directories or manually specify commands, use the <code>withCommands</code> method in <code>bootstrap/app.php</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">withCommands</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #D19A66;">__DIR__</span><span style="color: #ABB2BF;">.</span><span style="color: #98C379;">&#39;/../app/Domain/Orders/Commands&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #7F848E;">// Scan directory</span></div><div class='line'><span style="color: #ABB2BF;">    \App\Domain\Orders\Commands\</span><span style="color: #E5C07B;">SendEmails</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">, </span><span style="color: #7F848E;">// Or register specific classes</span></div><div class='line'><span style="color: #ABB2BF;">])</span></div></code></pre>
<p>When Artisan boots, it resolves and registers these commands automatically.</p>
<h2><a id="final-bootstrapappphp-example" href="#final-bootstrapappphp-example" class="" aria-hidden="true" title=""></a>Final <code>bootstrap/app.php</code> Example</h2>
<p>Here’s how a complete <code>bootstrap/app.php</code> file may look in Laravel 11 and later:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Foundation\</span><span style="color: #E5C07B;">Application</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Foundation\Configuration\</span><span style="color: #E5C07B;">Exceptions</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Foundation\Configuration\</span><span style="color: #E5C07B;">Middleware</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Application</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">configure</span><span style="color: #ABB2BF;">(basePath: </span><span style="color: #56B6C2;">dirname</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">__DIR__</span><span style="color: #ABB2BF;">))</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">withRouting</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">        web: </span><span style="color: #D19A66;">__DIR__</span><span style="color: #ABB2BF;">.</span><span style="color: #98C379;">&#39;/../routes/web.php&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        commands: </span><span style="color: #D19A66;">__DIR__</span><span style="color: #ABB2BF;">.</span><span style="color: #98C379;">&#39;/../routes/console.php&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        health: </span><span style="color: #98C379;">&#39;/up&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    )</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">withMiddleware</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Middleware</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$middleware</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// Configure middleware here (see full example above)</span></div><div class='line'><span style="color: #ABB2BF;">    })</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">withCommands</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// __DIR__.&#39;/../app/Domain/Orders/Commands&#39;,</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// \App\Console\Commands\Inspire::class,</span></div><div class='line'><span style="color: #ABB2BF;">    ])</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">withExceptions</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Exceptions</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$exceptions</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// Handle exceptions here</span></div><div class='line'><span style="color: #ABB2BF;">    })</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">create</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h2><a id="kernelphp-before-vs-after" href="#kernelphp-before-vs-after" class="" aria-hidden="true" title=""></a>kernel.php: Before vs After</h2>
<h3><a id="before-laravel-10-and-earlier" href="#before-laravel-10-and-earlier" class="" aria-hidden="true" title=""></a>Before (Laravel 10 and Earlier)</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// app/Http/Kernel.php</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Kernel</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">HttpKernel</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$middleware</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">        \App\Http\Middleware\</span><span style="color: #E5C07B;">EnsureTokenIsValid</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ];</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$middlewareGroups</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;web&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span></div><div class='line'><span style="color: #ABB2BF;">            \App\Http\Middleware\</span><span style="color: #E5C07B;">EncryptCookies</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        ],</span></div><div class='line'><span style="color: #ABB2BF;">    ];</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$middlewareAliases</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;subscribed&#39;</span><span style="color: #ABB2BF;"> =&gt; \App\Http\Middleware\</span><span style="color: #E5C07B;">EnsureUserIsSubscribed</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ];</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// app/Console/Kernel.php</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Kernel</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">ConsoleKernel</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">schedule</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$schedule</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">void</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$schedule</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">command</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;inspire&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">hourly</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">commands</span><span style="color: #ABB2BF;">(): </span><span style="color: #E5C07B;">void</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">load</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">__DIR__</span><span style="color: #ABB2BF;">.</span><span style="color: #98C379;">&#39;/Commands&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="after-laravel-11-and-12" href="#after-laravel-11-and-12" class="" aria-hidden="true" title=""></a>After (Laravel 11 and 12)</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// bootstrap/app.php</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Foundation\Configuration\</span><span style="color: #E5C07B;">Middleware</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Application</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">configure</span><span style="color: #ABB2BF;">(basePath: </span><span style="color: #56B6C2;">dirname</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">__DIR__</span><span style="color: #ABB2BF;">))</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">withRouting</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">        web: </span><span style="color: #D19A66;">__DIR__</span><span style="color: #ABB2BF;">.</span><span style="color: #98C379;">&#39;/../routes/web.php&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        commands: </span><span style="color: #D19A66;">__DIR__</span><span style="color: #ABB2BF;">.</span><span style="color: #98C379;">&#39;/../routes/console.php&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        health: </span><span style="color: #98C379;">&#39;/up&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    )</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">withMiddleware</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Middleware</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$middleware</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$middleware</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">append</span><span style="color: #ABB2BF;">(\App\Http\Middleware\</span><span style="color: #E5C07B;">EnsureTokenIsValid</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$middleware</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">alias</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #98C379;">&#39;subscribed&#39;</span><span style="color: #ABB2BF;"> =&gt; \App\Http\Middleware\</span><span style="color: #E5C07B;">EnsureUserIsSubscribed</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        ]);</span></div><div class='line'><span style="color: #ABB2BF;">    })</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">withCommands</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #D19A66;">__DIR__</span><span style="color: #ABB2BF;">.</span><span style="color: #98C379;">&#39;/../app/Console/Commands&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ])</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">create</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// routes/console.php</span></div><div class='line'><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">command</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;inspire&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">hourly</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>Laravel 11 simplified application bootstrapping by consolidating the Kernel logic into <code>bootstrap/app.php</code>. This modern approach reduces boilerplate and keeps configuration centralized, making your app more maintainable and transparent.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Fri, 17 Oct 2025 18:40:24 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[What does php artisan optimize:clear do and how?]]></title>
                <link>https://nabilhassen.com/what-does-php-artisan-optimizeclear-do-and-how</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#introduction">Introduction</a></li>
<li><a href="#what-does-optimizeclear-clear">What does optimize:clear clear?</a></li>
<li><a href="#how-to-skip-commands-run-by-optimizeclear">How to skip commands run by optimize:clear</a></li>
<li><a href="#how-laravel-package-developers-can-hook-into-optimizeclear">How Laravel package developers can hook into optimize:clear</a>
<ul>
<li><a href="#example">Example</a></li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="introduction" href="#introduction" class="" aria-hidden="true" title=""></a>Introduction</h2>
<p>When working on Laravel applications, especially during development or deployment, you often need to ensure that your application's cached files are not outdated. Laravel provides a powerful Artisan command for this exact purpose: <code>php artisan optimize:clear</code>. This command clears a variety of cached files to help prevent bugs, misconfigurations, or stale code execution.</p>
<p>But what does this command really do under the hood? How can you customize its behavior? And how can package developers integrate with it? Let’s take a closer look.</p>
<h2><a id="what-does-optimizeclear-clear" href="#what-does-optimizeclear-clear" class="" aria-hidden="true" title=""></a>What does <code>optimize:clear</code> clear?</h2>
<p>The <code>optimize:clear</code> command is responsible for clearing a set of cached files that Laravel uses to improve performance. Here are the commands it executes by default:</p>
<ul>
<li><code>config:clear</code> – Clears the cached configuration.</li>
<li><code>cache:clear</code> – Clears the application cache.</li>
<li><code>clear-compiled</code> – Clears the compiled classes.</li>
<li><code>event:clear</code> – Clears the cached events.</li>
<li><code>route:clear</code> – Clears the route cache.</li>
<li><code>view:clear</code> – Clears the compiled Blade views.</li>
</ul>
<p>Additionally, any package can contribute more commands to this list by registering their custom commands.</p>
<h2><a id="how-to-skip-commands-run-by-optimizeclear" href="#how-to-skip-commands-run-by-optimizeclear" class="" aria-hidden="true" title=""></a>How to skip commands run by <code>optimize:clear</code></h2>
<p>By default, <code>optimize:clear</code> will run all the commands listed above. However, Laravel provides a way to <strong>exclude specific commands</strong> using the <code>--except</code> option.</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">optimize:clear</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--except=views,cache</span></div></code></pre>
<p>This example skips the <code>view:clear</code> and <code>cache:clear</code> commands, but runs the rest. The option accepts a comma-separated list of keys that correspond to the task names (like <code>views</code>, <code>cache</code>, <code>routes</code>, etc.) or the full Artisan command (like <code>view:clear</code>).</p>
<p>Internally, Laravel parses the <code>--except</code> input and filters out any matching commands before executing the remaining ones.</p>
<h2><a id="how-laravel-package-developers-can-hook-into-optimizeclear" href="#how-laravel-package-developers-can-hook-into-optimizeclear" class="" aria-hidden="true" title=""></a>How Laravel package developers can hook into <code>optimize:clear</code></h2>
<p>Laravel makes it simple for package developers to hook into the <code>optimize:clear</code> process. In your package’s service provider boot method, you can call the <code>optimizes</code> method and pass your custom command signature to register it as part of the cleanup routine:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// In your package&#39;s service provider boot() method</span></div><div class='line'><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">optimizes</span><span style="color: #ABB2BF;">(clear:</span><span style="color: #98C379;">&#39;my-package:clear-cache&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>This will cause <code>optimize:clear</code> to run your custom Artisan command, unless the user explicitly skips it via the <code>--except</code> option.</p>
<h3><a id="example" href="#example" class="" aria-hidden="true" title=""></a>Example</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\</span><span style="color: #E5C07B;">ServiceProvider</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">MyPackageServiceProvider</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">ServiceProvider</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">boot</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">optimizes</span><span style="color: #ABB2BF;">(clear:</span><span style="color: #98C379;">&#39;my-package:clear-cache&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Now when a developer runs <code>php artisan optimize:clear</code>, Laravel will also run your <code>my-package:clear-cache</code> command as part of the cleanup process.</p>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>The <code>php artisan optimize:clear</code> command is more than a convenience utility, it's an extensible, customizable gateway to clearing Laravel's performance caches. Whether you're debugging a misbehaving app or deploying a fresh version to production, understanding how this command works (and how to customize or extend it) can save you time and headaches.</p>
<p>Package authors can also hook into this lifecycle, ensuring their cache-clearing logic integrates seamlessly into the Laravel developer experience.</p>
<p>Use it wisely, and keep your application running clean and smooth.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Fri, 25 Jul 2025 19:50:26 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[How to Test Laravel Socialite ]]></title>
                <link>https://nabilhassen.com/how-to-test-laravel-socialite</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#introduction">Introduction</a></li>
<li><a href="#socialite-controller-overview">Socialite Controller: Overview</a></li>
<li><a href="#laravel-socialite-authentication-test-suite">Laravel Socialite Authentication Test Suite</a></li>
<li><a href="#final-thoughts">Final Thoughts</a></li>
<li><a href="#tips-for-testing-socialite">Tips for Testing Socialite:</a></li>
</ul>
<h2><a id="introduction" href="#introduction" class="" aria-hidden="true" title=""></a>Introduction</h2>
<p>Social login is one of the most convenient ways for users to access your application. Laravel makes this simple with <strong>Laravel Socialite</strong>, a first-party package that abstracts away OAuth complexities.</p>
<p>In this post, we’ll walk through a real-world implementation of a Socialite controller and, more importantly, <strong>demystify the tests</strong> behind it. Testing third-party authentication might seem tricky, but with mocking and smart assertions, it’s absolutely doable.</p>
<h2><a id="socialite-controller-overview" href="#socialite-controller-overview" class="" aria-hidden="true" title=""></a>Socialite Controller: Overview</h2>
<p>Here is the actual <code>SocialiteController</code> class we are testing:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">declare</span><span style="color: #ABB2BF;">(strict_types</span><span style="color: #56B6C2;">=</span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">namespace</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">App\Http\Controllers\Auth</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Models\</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Auth\Events\</span><span style="color: #E5C07B;">Verified</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\</span><span style="color: #E5C07B;">UniqueConstraintViolationException</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Http\</span><span style="color: #E5C07B;">RedirectResponse</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Auth</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Validator</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\</span><span style="color: #E5C07B;">Str</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Validation\</span><span style="color: #E5C07B;">ValidationException</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Laravel\Socialite\Facades\</span><span style="color: #E5C07B;">Socialite</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">SocialiteController</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// route: /auth/{provider}/redirect</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">redirect</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">string</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$provider</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">RedirectResponse</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">(</span><span style="color: #56B6C2;">compact</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;provider&#39;</span><span style="color: #ABB2BF;">));</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Socialite</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">driver</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$provider</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">redirect</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// route: /auth/{provider}/callback</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">handleCallback</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">string</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$provider</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">RedirectResponse</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">(</span><span style="color: #56B6C2;">compact</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;provider&#39;</span><span style="color: #ABB2BF;">));</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Socialite</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">driver</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$provider</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">user</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">try</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">updateOrCreate</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">                </span><span style="color: #98C379;">&#39;provider&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E06C75;">$provider</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">                </span><span style="color: #98C379;">&#39;provider_id&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">id</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">            ], [</span></div><div class='line'><span style="color: #ABB2BF;">                </span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;"> ?? </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">nickname</span><span style="color: #ABB2BF;"> ?? </span><span style="color: #98C379;">&#39;N/A&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">                </span><span style="color: #98C379;">&#39;email&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">email</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">                </span><span style="color: #98C379;">&#39;password&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E5C07B;">Str</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">random</span><span style="color: #ABB2BF;">(),</span></div><div class='line'><span style="color: #ABB2BF;">                </span><span style="color: #98C379;">&#39;avatar_url&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">avatar</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">            ]);</span></div><div class='line'><span style="color: #ABB2BF;">        } </span><span style="color: #C678DD;">catch</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">UniqueConstraintViolationException</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$exception</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #C678DD;">throw</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">ValidationException</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">withMessages</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">                </span><span style="color: #98C379;">&#39;email&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;This email is already taken.&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">            ]);</span></div><div class='line'><span style="color: #ABB2BF;">        }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">!</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">hasVerifiedEmail</span><span style="color: #ABB2BF;">()) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">markEmailAsVerified</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #61AFEF;">event</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">new</span><span style="color: #61AFEF;"> </span><span style="color: #E5C07B;">Verified</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">));</span></div><div class='line'><span style="color: #ABB2BF;">        }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Auth</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">login</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">true</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">redirect</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">intended</span><span style="color: #ABB2BF;">(</span><span style="color: #61AFEF;">route</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;dashboard&#39;</span><span style="color: #ABB2BF;">));</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">array</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">void</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Validator</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">make</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">, [</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #98C379;">&#39;provider&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span><span style="color: #98C379;">&#39;required&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;string&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;in:github,google&#39;</span><span style="color: #ABB2BF;">],</span></div><div class='line'><span style="color: #ABB2BF;">        ])-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>This controller:</p>
<ul>
<li>Redirects the user to the OAuth provider</li>
<li>Handles the callback, updates or creates the user</li>
<li>Handles email verification if needed</li>
<li>Logs the user in</li>
</ul>
<p>Now let’s look at how we thoroughly test this logic.</p>
<h2><a id="laravel-socialite-authentication-test-suite" href="#laravel-socialite-authentication-test-suite" class="" aria-hidden="true" title=""></a>Laravel Socialite Authentication Test Suite</h2>
<p>Here is the full test file along with detailed explanations for each case:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">declare</span><span style="color: #ABB2BF;">(strict_types</span><span style="color: #56B6C2;">=</span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Models\</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Auth\Events\</span><span style="color: #E5C07B;">Verified</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\</span><span style="color: #E5C07B;">Arr</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Event</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\</span><span style="color: #E5C07B;">Str</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Laravel\Socialite\Contracts\</span><span style="color: #E5C07B;">Provider</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Laravel\Socialite\Contracts\</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">as</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">SocialiteUser</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Laravel\Socialite\Facades\</span><span style="color: #E5C07B;">Socialite</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Mockery\</span><span style="color: #E5C07B;">MockInterface</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Test: Redirects to provider</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">test</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;redirects to auth provider&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">function</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">()</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E5C07B;">$this</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #61AFEF;">route</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;socialite.redirect&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;github&#39;</span><span style="color: #ABB2BF;">))</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertValid</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertRedirect</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Test: Invalid provider name fails validation</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">test</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;provider is invalid&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">function</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">()</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E5C07B;">$this</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #61AFEF;">route</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;socialite.redirect&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E5C07B;">Str</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">random</span><span style="color: #ABB2BF;">()))</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertInvalid</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;provider&#39;</span><span style="color: #ABB2BF;">]);</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Test: Handles callback and creates a new user</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">test</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;handles callback from auth provider and creates a user&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">function</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">()</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E06C75;">$provider</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E5C07B;">Arr</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">random</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;github&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;google&#39;</span><span style="color: #ABB2BF;">]);</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E06C75;">$user</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">factory</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">unverified</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">make</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E5C07B;">Event</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">fake</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E06C75;">$socialiteUser</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">mock</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">SocialiteUser</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">function</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">MockInterface</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">use</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">id</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> fake</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">randomNumber</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">3</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">name</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">email</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">email</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">avatar</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">avatar_url</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #ABB2BF;">});</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E06C75;">$socialiteProvider</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">mock</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Provider</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">function</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">MockInterface</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">use</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$socialiteUser</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">shouldReceive</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;user&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">andReturn</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$socialiteUser</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #ABB2BF;">});</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E5C07B;">Socialite</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">shouldReceive</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;driver&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">with</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$provider</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">andReturn</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$socialiteProvider</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertDatabaseCount</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">0</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E5C07B;">$this</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #61AFEF;">route</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;socialite.callback&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$provider</span><span style="color: #ABB2BF;">))</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertRedirect</span><span style="color: #ABB2BF;">(</span><span style="color: #61AFEF;">route</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;dashboard&#39;</span><span style="color: #ABB2BF;">));</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E5C07B;">Event</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">assertDispatched</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Verified</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E5C07B;">$this</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertAuthenticated</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertDatabaseCount</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertDatabaseHas</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">[</span></div><div class='line'><span style="color: #61AFEF;">            </span><span style="color: #98C379;">&#39;provider&#39;</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">=&gt;</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$provider</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #61AFEF;">            </span><span style="color: #98C379;">&#39;provider_id&#39;</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">=&gt;</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$socialiteUser</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">id</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #61AFEF;">            </span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">=&gt;</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$socialiteUser</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #61AFEF;">            </span><span style="color: #98C379;">&#39;email&#39;</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">=&gt;</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$socialiteUser</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">email</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #61AFEF;">            </span><span style="color: #98C379;">&#39;avatar_url&#39;</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">=&gt;</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$socialiteUser</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">avatar</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">])</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertTrue</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">firstWhere</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;email&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">email</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">hasVerifiedEmail</span><span style="color: #ABB2BF;">());</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Test: Email already exists</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">test</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;user will not be created if already exists&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">function</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">()</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E06C75;">$provider</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E5C07B;">Arr</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">random</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;github&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;google&#39;</span><span style="color: #ABB2BF;">]);</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E06C75;">$user</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">factory</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">create</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertDatabaseCount</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E06C75;">$socialiteUser</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">mock</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">SocialiteUser</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">function</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">MockInterface</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">use</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">id</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> fake</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">randomNumber</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">3</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">name</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">email</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">email</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">avatar</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">avatar_url</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #ABB2BF;">});</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E06C75;">$socialiteProvider</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">mock</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Provider</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">function</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">MockInterface</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">use</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$socialiteUser</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">shouldReceive</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;user&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">andReturn</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$socialiteUser</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #ABB2BF;">});</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E5C07B;">Socialite</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">shouldReceive</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;driver&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">with</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$provider</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">andReturn</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$socialiteProvider</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E5C07B;">$this</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #61AFEF;">route</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;socialite.callback&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$provider</span><span style="color: #ABB2BF;">))</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertInvalid</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #61AFEF;">            </span><span style="color: #98C379;">&#39;email&#39;</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">=&gt;</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;This email is already taken.&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">]);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertDatabaseCount</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Test: Log in user if registered with the same provider</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">test</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;user will login and will not be created again if already registered with the same provider&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">function</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">()</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E06C75;">$user</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">factory</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">viaSocialite</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">create</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E06C75;">$newName</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> fake</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">name</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E06C75;">$socialiteUser</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">mock</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">SocialiteUser</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">function</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">MockInterface</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">use</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$newName</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">id</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">provider_id</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">name</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$newName</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">email</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">email</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">avatar</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">avatar_url</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #ABB2BF;">});</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E06C75;">$socialiteProvider</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">mock</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Provider</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">function</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">MockInterface</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">use</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$socialiteUser</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">shouldReceive</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;user&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">andReturn</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$socialiteUser</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #ABB2BF;">});</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E5C07B;">Socialite</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">shouldReceive</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;driver&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">with</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">provider</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">andReturn</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$socialiteProvider</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertDatabaseCount</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E5C07B;">$this</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #61AFEF;">route</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;socialite.callback&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">provider</span><span style="color: #ABB2BF;">))</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertRedirect</span><span style="color: #ABB2BF;">(</span><span style="color: #61AFEF;">route</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;dashboard&#39;</span><span style="color: #ABB2BF;">));</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E5C07B;">$this</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertAuthenticated</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertDatabaseCount</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertDatabaseHas</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">[</span></div><div class='line'><span style="color: #61AFEF;">            </span><span style="color: #98C379;">&#39;provider&#39;</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">=&gt;</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">provider</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #61AFEF;">            </span><span style="color: #98C379;">&#39;provider_id&#39;</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">=&gt;</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$socialiteUser</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">id</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #61AFEF;">            </span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">=&gt;</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$newName</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #61AFEF;">            </span><span style="color: #98C379;">&#39;email&#39;</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">=&gt;</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$socialiteUser</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">email</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #61AFEF;">            </span><span style="color: #98C379;">&#39;avatar_url&#39;</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">=&gt;</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$socialiteUser</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">avatar</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">]);</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// Test: Same email but different provider</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">test</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;user will not be created if already registered with another provider&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">function</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">()</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E06C75;">$user</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">factory</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">viaSocialite</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">create</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E06C75;">$provider</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> collect</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;google&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;github&#39;</span><span style="color: #ABB2BF;">])-&gt;</span><span style="color: #61AFEF;">diff</span><span style="color: #ABB2BF;">([</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">provider</span><span style="color: #ABB2BF;">])-&gt;</span><span style="color: #61AFEF;">random</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertDatabaseCount</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E06C75;">$socialiteUser</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">mock</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">SocialiteUser</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">function</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">MockInterface</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">use</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">id</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> fake</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">randomNumber</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">3</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">name</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">email</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">email</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">avatar</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">avatar_url</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #ABB2BF;">});</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E06C75;">$socialiteProvider</span><span style="color: #61AFEF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #61AFEF;"> </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">mock</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Provider</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">function</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">MockInterface</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #C678DD;">use</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$socialiteUser</span><span style="color: #ABB2BF;">)</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #E06C75;">$mock</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">shouldReceive</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;user&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">andReturn</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$socialiteUser</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #ABB2BF;">});</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E5C07B;">Socialite</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">shouldReceive</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;driver&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">with</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$provider</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">andReturn</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$socialiteProvider</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E5C07B;">$this</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #61AFEF;">route</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;socialite.callback&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$provider</span><span style="color: #ABB2BF;">))</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertInvalid</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #61AFEF;">            </span><span style="color: #98C379;">&#39;email&#39;</span><span style="color: #61AFEF;"> </span><span style="color: #ABB2BF;">=&gt;</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;This email is already taken.&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #61AFEF;">        </span><span style="color: #ABB2BF;">]);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">    </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertDatabaseCount</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div></code></pre>
<p>Each of these tests covers a real-world scenario:</p>
<ul>
<li>✅ Happy paths (successful creation, successful login)</li>
<li>❌ Failure paths (duplicate email from form or mismatched providers)</li>
<li>✨ User experience improvements (e.g., updated profile info)</li>
</ul>
<h2><a id="final-thoughts" href="#final-thoughts" class="" aria-hidden="true" title=""></a>Final Thoughts</h2>
<p>Socialite makes social logins easy, but without proper testing, you risk account conflicts, missing verification, and hard-to-debug login issues. With a few well-crafted mocks and assertions, you can simulate the entire flow and cover edge cases confidently.</p>
<h2><a id="tips-for-testing-socialite" href="#tips-for-testing-socialite" class="" aria-hidden="true" title=""></a>Tips for Testing Socialite:</h2>
<ul>
<li>Use Laravel's mocking and facades to simulate third-party services.</li>
<li>Validate both positive and negative scenarios.</li>
<li>Don’t forget to test for email duplication and provider mismatches.</li>
</ul>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 22 Jul 2025 18:38:34 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[How to Install Laravel on Linux]]></title>
                <link>https://nabilhassen.com/how-to-install-laravel-on-linux</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#introduction">Introduction</a></li>
<li><a href="#why-choose-laravel-on-linux">Why Choose Laravel on Linux?</a></li>
<li><a href="#prerequisites-for-laravel-install-on-linux">Prerequisites for Laravel Install on Linux</a></li>
<li><a href="#step-1-installing-php-composer-and-laravel-installer-on-linux">Step 1: Installing PHP, Composer, and Laravel Installer on Linux</a></li>
<li><a href="#step-2-installing-nodejs-and-npm-on-linux">Step 2: Installing Node.js and NPM on Linux</a></li>
<li><a href="#step-3-creating-a-new-laravel-project-on-linux">Step 3: Creating a New Laravel Project on Linux</a></li>
<li><a href="#step-4-set-up-your-laravel-development-environment">Step 4: Set Up Your Laravel Development Environment</a></li>
<li><a href="#step-5-configuring-your-database-on-linux">Step 5: Configuring Your Database on Linux</a></li>
</ul>
<h2><a id="introduction" href="#introduction" class="" aria-hidden="true" title=""></a>Introduction</h2>
<p>Are you looking to <strong>install Laravel on Linux</strong> for your web development projects? Laravel is one of the most popular PHP frameworks, loved for its elegant syntax and powerful features. This guide will walk you through the process step-by-step so you can get started quickly and efficiently.</p>
<h2><a id="why-choose-laravel-on-linux" href="#why-choose-laravel-on-linux" class="" aria-hidden="true" title=""></a>Why Choose Laravel on Linux?</h2>
<p>Laravel is a <strong>progressive, scalable, and community-driven</strong> web framework designed to make PHP development enjoyable and productive. Linux is an excellent environment for running Laravel applications due to its stability, security, and developer-friendly ecosystem.</p>
<p>By learning how to <strong>install Laravel on Linux</strong>, you unlock the ability to build modern, full-stack web applications or robust API backends with ease.</p>
<h2><a id="prerequisites-for-laravel-install-on-linux" href="#prerequisites-for-laravel-install-on-linux" class="" aria-hidden="true" title=""></a>Prerequisites for Laravel Install on Linux</h2>
<p>Before installing Laravel on your Linux machine, ensure you have the following installed:</p>
<ul>
<li><strong>PHP</strong> (version 8.1 or above recommended)</li>
<li><strong>Composer</strong> (PHP dependency manager)</li>
<li><strong>Node.js and NPM</strong> (for frontend asset compilation)</li>
</ul>
<p>If you don’t have PHP and Composer installed, don’t worry! Follow the steps below.</p>
<h2><a id="step-1-installing-php-composer-and-laravel-installer-on-linux" href="#step-1-installing-php-composer-and-laravel-installer-on-linux" class="" aria-hidden="true" title=""></a>Step 1: Installing PHP, Composer, and Laravel Installer on Linux</h2>
<p>Laravel requires PHP and Composer to manage its dependencies. Fortunately, you can install these tools quickly on Linux using the official <code>php.new</code> installation script:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">/bin/bash </span><span style="color: #D19A66;">-c</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;$(curl </span><span style="color: #D19A66;">-fsSL</span><span style="color: #98C379;"> https://php.new/install/linux/8.4)&quot;</span></div></code></pre>
<p>This command will:</p>
<ul>
<li>Install PHP 8.4 on your Linux system</li>
<li>Set up Composer globally</li>
<li>Install the Laravel installer globally via Composer</li>
</ul>
<p><strong>Tip:</strong> After running the command, restart your terminal session to apply changes.</p>
<p>If you already have PHP and Composer installed, simply run this command to install the Laravel installer:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">global</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">require</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">laravel/installer</span></div></code></pre>
<h2><a id="step-2-installing-nodejs-and-npm-on-linux" href="#step-2-installing-nodejs-and-npm-on-linux" class="" aria-hidden="true" title=""></a>Step 2: Installing Node.js and NPM on Linux</h2>
<p>Laravel uses Node.js and NPM to compile frontend assets like CSS and JavaScript. To install them on Linux efficiently, you can use <strong>fnm</strong> (Fast Node Manager), a lightweight Node.js version manager.</p>
<p>Follow these steps to install Node.js and NPM using fnm:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;"># Download and install fnm:</span></div><div class='line'><span style="color: #ABB2BF;">curl </span><span style="color: #D19A66;">-o-</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">https://fnm.vercel.app/install</span><span style="color: #ABB2BF;"> | bash</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;"># Download and install Node.js version 22:</span></div><div class='line'><span style="color: #ABB2BF;">fnm </span><span style="color: #98C379;">install</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">22</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;"># Verify the installed Node.js version:</span></div><div class='line'><span style="color: #ABB2BF;">node </span><span style="color: #D19A66;">-v</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;"># Verify the installed npm version:</span></div><div class='line'><span style="color: #ABB2BF;">npm </span><span style="color: #D19A66;">-v</span></div></code></pre>
<p>After running these commands, you’ll have the latest Node.js 22.x and NPM installed and ready to use for your Laravel project.</p>
<h2><a id="step-3-creating-a-new-laravel-project-on-linux" href="#step-3-creating-a-new-laravel-project-on-linux" class="" aria-hidden="true" title=""></a>Step 3: Creating a New Laravel Project on Linux</h2>
<p>Once you have the Laravel installer, you can create a new Laravel application with this simple command:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">laravel </span><span style="color: #98C379;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">example-app</span></div></code></pre>
<p>Replace <code>example-app</code> with your desired project name.</p>
<p>The installer will prompt you to choose your preferred testing framework, database, and starter kit options, making the setup process seamless.</p>
<h2><a id="step-4-set-up-your-laravel-development-environment" href="#step-4-set-up-your-laravel-development-environment" class="" aria-hidden="true" title=""></a>Step 4: Set Up Your Laravel Development Environment</h2>
<p>Navigate into your new project directory:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #56B6C2;">cd</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">example-app</span></div></code></pre>
<p>Install frontend dependencies and compile assets using npm:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">npm </span><span style="color: #98C379;">install</span><span style="color: #ABB2BF;"> &amp;&amp; npm </span><span style="color: #98C379;">run</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">build</span></div></code></pre>
<p>Then, start Laravel's development server with:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">run</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">dev</span></div></code></pre>
<p>Your Laravel application will be accessible at <a rel="nofollow noopener" target="_blank" href="http://localhost:8000">http://localhost:8000</a>.</p>
<hr />
<h2><a id="step-5-configuring-your-database-on-linux" href="#step-5-configuring-your-database-on-linux" class="" aria-hidden="true" title=""></a>Step 5: Configuring Your Database on Linux</h2>
<p>Laravel uses an SQLite database by default. However, if you want to use <strong>MySQL</strong> or <strong>PostgreSQL</strong>, update your <code>.env</code> file with your database credentials:</p>
<pre><code data-theme="one-dark-pro" data-lang="env" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">DB_CONNECTION</span><span style="color: #56B6C2;">=</span><span style="color: #98C379;">mysql</span></div><div class='line'><span style="color: #E06C75;">DB_HOST</span><span style="color: #56B6C2;">=</span><span style="color: #D19A66;">127.0</span><span style="color: #ABB2BF;">.0.1</span></div><div class='line'><span style="color: #E06C75;">DB_PORT</span><span style="color: #56B6C2;">=</span><span style="color: #D19A66;">3306</span></div><div class='line'><span style="color: #E06C75;">DB_DATABASE</span><span style="color: #56B6C2;">=</span><span style="color: #98C379;">laravel</span></div><div class='line'><span style="color: #E06C75;">DB_USERNAME</span><span style="color: #56B6C2;">=</span><span style="color: #98C379;">root</span></div><div class='line'><span style="color: #E06C75;">DB_PASSWORD</span><span style="color: #56B6C2;">=</span></div></code></pre>
<p>Then, run your database migrations to create necessary tables:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">migrate</span></div></code></pre>
<p>If you don’t have MySQL or PostgreSQL installed, consider using database management tools like <strong>DBngin</strong> or <strong>Docker</strong> on Linux for easier setup.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Fri, 18 Jul 2025 23:06:23 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[How to Create Laravel Database Notifications]]></title>
                <link>https://nabilhassen.com/how-to-create-laravel-database-notifications</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#introduction">Introduction</a></li>
<li><a href="#what-are-laravel-database-notifications">What Are Laravel Database Notifications?</a></li>
<li><a href="#step-1-add-notifiable-trait-to-the-user-model">Step 1: Add Notifiable Trait to the User Model</a></li>
<li><a href="#step-2-create-the-notification-table">Step 2: Create the Notification Table</a></li>
<li><a href="#step-3-create-a-notification-class">Step 3: Create a Notification Class</a></li>
<li><a href="#step-4-define-the-todatabase-method">Step 4: Define the toDatabase() Method</a></li>
<li><a href="#step-5-send-the-notification">Step 5: Send the Notification</a></li>
<li><a href="#step-6-retrieve-and-display-notifications">Step 6: Retrieve and Display Notifications</a></li>
<li><a href="#step-7-mark-notifications-as-read">Step 7: Mark Notifications as Read</a></li>
<li><a href="#step-8-make-notifications-queueable-optional">Step 8: Make Notifications Queueable (Optional)</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="introduction" href="#introduction" class="" aria-hidden="true" title=""></a>Introduction</h2>
<p>If you're looking to implement <strong>Laravel database notification</strong> in your Laravel application, you're in the right place. This tutorial walks you through the process of creating and sending database notifications using Laravel's built-in notification system.</p>
<h2><a id="what-are-laravel-database-notifications" href="#what-are-laravel-database-notifications" class="" aria-hidden="true" title=""></a>What Are Laravel Database Notifications?</h2>
<p>Laravel provides a unified API for sending notifications via multiple channels, including mail, SMS, Slack, and database. <strong>Database notifications</strong> are stored in your application's database and can be retrieved and displayed to users at any time.</p>
<h2><a id="step-1-add-notifiable-trait-to-the-user-model" href="#step-1-add-notifiable-trait-to-the-user-model" class="" aria-hidden="true" title=""></a>Step 1: Add Notifiable Trait to the User Model</h2>
<p>To use notifications, your <code>User</code> model must use the <code>Notifiable</code> trait:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Notifications\</span><span style="color: #E5C07B;">Notifiable</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Authenticatable</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Notifiable</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>This trait gives the user model access to helper methods for sending and managing notifications.</p>
<h2><a id="step-2-create-the-notification-table" href="#step-2-create-the-notification-table" class="" aria-hidden="true" title=""></a>Step 2: Create the Notification Table</h2>
<p>First, publish the notifications migration:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">notifications:table</span></div></code></pre>
<p>Then run the migration:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">migrate</span></div></code></pre>
<p>This creates a <code>notifications</code> table in your database that will store all your notifications.</p>
<h2><a id="step-3-create-a-notification-class" href="#step-3-create-a-notification-class" class="" aria-hidden="true" title=""></a>Step 3: Create a Notification Class</h2>
<p>Run the Artisan command to generate a notification:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">make:notification</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">NewUserRegistered</span></div></code></pre>
<p>This will create a file in <code>app/Notifications/NewUserRegistered.php</code>.</p>
<h2><a id="step-4-define-the-todatabase-method" href="#step-4-define-the-todatabase-method" class="" aria-hidden="true" title=""></a>Step 4: Define the toDatabase() Method</h2>
<p>Open <code>NewUserRegistered.php</code> and define how the notification should be stored in the database using the <code>toDatabase()</code> method:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">namespace</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">App\Notifications</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Notifications\</span><span style="color: #E5C07B;">Notification</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Models\</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">NewUserRegistered</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Notification</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$newUser</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">__construct</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$newUser</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">newUser</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$newUser</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">via</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">object</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$notifiable</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">array</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> [</span><span style="color: #98C379;">&#39;database&#39;</span><span style="color: #ABB2BF;">];</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">toDatabase</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">object</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$notifiable</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">array</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #98C379;">&#39;id&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">newUser</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">id</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">newUser</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #98C379;">&#39;email&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">newUser</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">email</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        ];</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h2><a id="step-5-send-the-notification" href="#step-5-send-the-notification" class="" aria-hidden="true" title=""></a>Step 5: Send the Notification</h2>
<p>You can send the notification to any notifiable entity (typically a <code>User</code> model):</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Models\</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Notifications\</span><span style="color: #E5C07B;">NewUserRegistered</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">find</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">); </span><span style="color: #7F848E;">// Admin user</span></div><div class='line'><span style="color: #E06C75;">$newUser</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">find</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">2</span><span style="color: #ABB2BF;">); </span><span style="color: #7F848E;">// Newly registered user</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">notify</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">NewUserRegistered</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$newUser</span><span style="color: #ABB2BF;">));</span></div></code></pre>
<p>Alternatively, you can use the <code>Notification</code> facade:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Notification</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">Notification</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">send</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">, </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">NewUserRegistered</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$newUser</span><span style="color: #ABB2BF;">));</span></div></code></pre>
<h2><a id="step-6-retrieve-and-display-notifications" href="#step-6-retrieve-and-display-notifications" class="" aria-hidden="true" title=""></a>Step 6: Retrieve and Display Notifications</h2>
<p>You can retrieve a user's notifications using the <code>notifications</code> relationship:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$notifications</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">auth</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">user</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #E06C75;">notifications</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<p>To display them:</p>
<pre><code data-theme="one-dark-pro" data-lang="blade" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">@foreach</span><span style="color: #ABB2BF;">(</span><span style="color: #61AFEF;">auth</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">user</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #E06C75;">notifications</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">as</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$notification</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    &lt;</span><span style="color: #E06C75;">div</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">class</span><span style="color: #ABB2BF;">=</span><span style="color: #98C379;">&quot;notification&quot;</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">        New user registered: </span><span style="color: #56B6C2;">{{</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$notification</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">data</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">] </span><span style="color: #56B6C2;">}}</span><span style="color: #ABB2BF;"> (</span><span style="color: #56B6C2;">{{</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$notification</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">data</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;email&#39;</span><span style="color: #ABB2BF;">] </span><span style="color: #56B6C2;">}}</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    &lt;/</span><span style="color: #E06C75;">div</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #C678DD;">@endforeach</span></div></code></pre>
<h2><a id="step-7-mark-notifications-as-read" href="#step-7-mark-notifications-as-read" class="" aria-hidden="true" title=""></a>Step 7: Mark Notifications as Read</h2>
<p>You can mark notifications as read using:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #61AFEF;">auth</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">user</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #E06C75;">unreadNotifications</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">markAsRead</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>Or mark a single notification:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$notification</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">auth</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">user</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">notifications</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">first</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #E06C75;">$notification</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">markAsRead</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h2><a id="step-8-make-notifications-queueable-optional" href="#step-8-make-notifications-queueable-optional" class="" aria-hidden="true" title=""></a>Step 8: Make Notifications Queueable (Optional)</h2>
<p>To queue a notification, implement the <code>ShouldQueue</code> interface and use the <code>Queueable</code> trait:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">namespace</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">App\Notifications</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Bus\</span><span style="color: #E5C07B;">Queueable</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Notifications\</span><span style="color: #E5C07B;">Notification</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Contracts\Queue\</span><span style="color: #E5C07B;">ShouldQueue</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Models\</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">NewUserRegistered</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Notification</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">implements</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">ShouldQueue</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Queueable</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$newUser</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">__construct</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$newUser</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">newUser</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$newUser</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">via</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">object</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$notifiable</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">array</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> [</span><span style="color: #98C379;">&#39;database&#39;</span><span style="color: #ABB2BF;">];</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">toDatabase</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">object</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$notifiable</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">array</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #98C379;">&#39;id&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">newUser</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">id</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">newUser</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #98C379;">&#39;email&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">newUser</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">email</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        ];</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<blockquote>
<p><strong>Tip</strong>: Make sure your queue worker is running with <code>php artisan queue:work</code> to process queued notifications.</p>
</blockquote>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>Creating a <strong>Laravel database notification</strong> system is clean and straightforward. Notifications are a powerful way to improve user engagement, and Laravel makes it incredibly simple to implement.</p>
<p>Feel free to extend this with broadcasting, frontend updates, or user preferences for notification types.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Wed, 16 Jul 2025 19:40:53 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Laravel Migrations: How to Rename a Table]]></title>
                <link>https://nabilhassen.com/laravel-migrations-how-to-rename-a-table</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#renaming-tables-in-laravel">Renaming Tables in Laravel</a></li>
<li><a href="#rename-the-table-using-a-new-migration">Rename the Table Using a New Migration</a></li>
</ul>
<h2><a id="renaming-tables-in-laravel" href="#renaming-tables-in-laravel" class="" aria-hidden="true" title=""></a>Renaming Tables in Laravel</h2>
<p>Renaming a table in Laravel is a common task that might arise when you're refactoring your database schema. In this post, we'll walk through how to <strong>rename a table in Laravel</strong>.</p>
<p>Let’s consider we already have the following clients table:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Migrations\</span><span style="color: #E5C07B;">Migration</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Schema\</span><span style="color: #E5C07B;">Blueprint</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Schema</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Migration</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">up</span><span style="color: #ABB2BF;">(): </span><span style="color: #E5C07B;">void</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Schema</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">create</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;clients&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Blueprint</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$table</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E06C75;">$table</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">id</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E06C75;">$table</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">string</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E06C75;">$table</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">string</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;email&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">unique</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E06C75;">$table</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">timestamps</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">        });</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">down</span><span style="color: #ABB2BF;">(): </span><span style="color: #E5C07B;">void</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Schema</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">dropIfExists</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;clients&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">};</span></div></code></pre>
<h2><a id="rename-the-table-using-a-new-migration" href="#rename-the-table-using-a-new-migration" class="" aria-hidden="true" title=""></a>Rename the Table Using a New Migration</h2>
<p>To rename the <code>clients</code> table to <code>customers</code>, we need to create a new migration file using make:migration artisan command:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">make:migration</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">rename_clients_table_to_customers_table</span></div></code></pre>
<p>Update the new migration file like so:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Migrations\</span><span style="color: #E5C07B;">Migration</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Schema</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Migration</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">up</span><span style="color: #ABB2BF;">(): </span><span style="color: #E5C07B;">void</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Schema</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">rename</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;clients&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;customers&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">down</span><span style="color: #ABB2BF;">(): </span><span style="color: #E5C07B;">void</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Schema</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">rename</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;customers&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;clients&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">};</span></div></code></pre>
<p>This migration uses Laravel’s built-in <code>Schema::rename()</code> method to rename the table from <code>clients</code> to <code>customers</code>. The <code>down()</code> method ensures you can roll back the change if needed.</p>
<p>Run the migration:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">migrate</span></div></code></pre>
<p>The <code>clients</code> table is now renamed to <code>customers</code>.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 15 Jul 2025 19:53:40 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Action Pattern in Laravel: Concept, Benefits, Best Practices]]></title>
                <link>https://nabilhassen.com/action-pattern-in-laravel-concept-benefits-best-practices</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#what-is-the-action-pattern-in-laravel">What is the Action Pattern in Laravel?</a></li>
<li><a href="#benefits-of-the-action-pattern">Benefits of the Action Pattern</a>
<ul>
<li><a href="#1-write-once-call-anywhere-context-independent">1. Write Once, Call Anywhere (Context-Independent)</a></li>
<li><a href="#2-no-irrelevant-dependency-injections">2. No Irrelevant Dependency Injections</a></li>
<li><a href="#3-easier-to-test-in-isolation">3. Easier to Test in Isolation</a></li>
</ul>
</li>
<li><a href="#best-practices">Best Practices</a>
<ul>
<li><a href="#1-structure-place-actions-under-appactions">1. Structure: Place actions under app/Actions</a></li>
<li><a href="#2-naming-convention-actionresourcephp">2. Naming Convention: {Action}{Resource}.php</a></li>
<li><a href="#3-method-name-prefer-handle">3. Method Name: Prefer handle()</a></li>
<li><a href="#4-method-parameters">4. Method Parameters</a></li>
<li><a href="#5-wrap-logic-in-dbtransaction">5. Wrap Logic in DB::transaction()</a></li>
<li><a href="#6-broadcast-events-when-necessary">6. Broadcast Events When Necessary</a></li>
<li><a href="#7-return-the-resource">7. Return the Resource</a></li>
<li><a href="#8-inject-other-actions-when-needed">8. Inject Other Actions When Needed</a></li>
</ul>
</li>
<li><a href="#more-resources">More Resources</a></li>
</ul>
<h2><a id="what-is-the-action-pattern-in-laravel" href="#what-is-the-action-pattern-in-laravel" class="" aria-hidden="true" title=""></a>What is the Action Pattern in Laravel?</h2>
<p>The Action Pattern is a simple architectural pattern used in Laravel and other PHP applications to encapsulate a single unit of logic inside a dedicated class. Typically, an action class has:</p>
<ul>
<li>A single public method most commonly named <code>handle()</code> that contains the core logic.</li>
<li>A constructor that injects any required dependencies (e.g., other actions, services, repositories).</li>
</ul>
<p>This pattern promotes cleaner, reusable, and more testable code. Action classes are generally placed under the <code>app/Actions</code> directory and are used to keep controllers, commands, and jobs slim and focused.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">namespace</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">App\Actions</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Models\</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">CreateUser</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">handle</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">array</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">User</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">create</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h2><a id="benefits-of-the-action-pattern" href="#benefits-of-the-action-pattern" class="" aria-hidden="true" title=""></a>Benefits of the Action Pattern</h2>
<h3><a id="1-write-once-call-anywhere-context-independent" href="#1-write-once-call-anywhere-context-independent" class="" aria-hidden="true" title=""></a>1. Write Once, Call Anywhere (Context-Independent)</h3>
<p>An action can be called from any context: controllers, jobs, console commands, tests, event listeners, etc.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// In a controller</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">UserController</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Controller</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">store</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">CreateUser</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$createUser</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$createUser</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">handle</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validated</span><span style="color: #ABB2BF;">());</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">response</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">json</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// In a job/command</span></div><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">handle</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">CreateUser</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$createUser</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$createUser</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">handle</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">data</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="2-no-irrelevant-dependency-injections" href="#2-no-irrelevant-dependency-injections" class="" aria-hidden="true" title=""></a>2. No Irrelevant Dependency Injections</h3>
<p>Unlike service classes with multiple unrelated methods, action classes are focused. Each class handles one task and receives only the dependencies it needs. This results in constructors that are concise and purposeful. With this approach, you avoid having a constructor filled with many injected dependencies that may only be used by a few methods.</p>
<p>Unlike service classes with multiple unrelated methods, action classes are focused. Each class handles one task and receives only the dependencies it needs. This results in constructors that are concise and purposeful.</p>
<h3><a id="3-easier-to-test-in-isolation" href="#3-easier-to-test-in-isolation" class="" aria-hidden="true" title=""></a>3. Easier to Test in Isolation</h3>
<p>Since an action encapsulates a single unit of work, it becomes easier to test independently of the HTTP layer or other services.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">test_it_creates_a_user</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$action</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">CreateUser</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$action</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">handle</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Jane Doe&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;email&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;jane@example.com&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;password&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #61AFEF;">bcrypt</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;password&#39;</span><span style="color: #ABB2BF;">),</span></div><div class='line'><span style="color: #ABB2BF;">    ]);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertDatabaseHas</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">, [</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;email&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;jane@example.com&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ]);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">assertEquals</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;Jane Doe&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h2><a id="best-practices" href="#best-practices" class="" aria-hidden="true" title=""></a>Best Practices</h2>
<h3><a id="1-structure-place-actions-under-appactions" href="#1-structure-place-actions-under-appactions" class="" aria-hidden="true" title=""></a>1. Structure: Place actions under <code>app/Actions</code></h3>
<p>Organize your action classes in the <code>app/Actions</code> directory for better discoverability.</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">app/</span></div><div class='line'><span style="color: #abb2bf;">└── Actions/</span></div><div class='line'><span style="color: #abb2bf;">    ├── CreateUser.php</span></div><div class='line'><span style="color: #abb2bf;">    ├── UpdateUser.php</span></div></code></pre>
<h3><a id="2-naming-convention-actionresourcephp" href="#2-naming-convention-actionresourcephp" class="" aria-hidden="true" title=""></a>2. Naming Convention: {Action}{Resource}.php</h3>
<p>Use a clear and consistent naming convention such as <code>CreateUser</code>, <code>UpdateProfile</code>, or <code>DeletePost</code>.</p>
<h3><a id="3-method-name-prefer-handle" href="#3-method-name-prefer-handle" class="" aria-hidden="true" title=""></a>3. Method Name: Prefer <code>handle()</code></h3>
<p>Stick with <code>handle()</code> for consistency with Laravel's jobs and listeners. Alternatives include <code>__invoke</code>, <code>execute()</code>, or <code>run()</code> but only if your team prefers a different standard.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">handle</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">array</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">User</span></div></code></pre>
<h3><a id="4-method-parameters" href="#4-method-parameters" class="" aria-hidden="true" title=""></a>4. Method Parameters</h3>
<p>Pass in either the resource and data, or just the data, depending on the use case.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// For updating existing resource</span></div><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">handle</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">array</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">User</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// For creating new resource</span></div><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">handle</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">array</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">User</span></div></code></pre>
<h3><a id="5-wrap-logic-in-dbtransaction" href="#5-wrap-logic-in-dbtransaction" class="" aria-hidden="true" title=""></a>5. Wrap Logic in <code>DB::transaction()</code></h3>
<p>If your action performs multiple operations or calls other actions, wrap the logic inside a transaction to ensure consistency.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">__construct</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">SyncUserRoles</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$syncUserRoles</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">AssignTeam</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$assignTeam</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">) {}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">handle</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">array</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">User</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">transaction</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> () </span><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">create</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// injected actions</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">syncUserRoles</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">handle</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">[</span><span style="color: #98C379;">&#39;roles&#39;</span><span style="color: #ABB2BF;">]);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">assignTeam</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">handle</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    });</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="6-broadcast-events-when-necessary" href="#6-broadcast-events-when-necessary" class="" aria-hidden="true" title=""></a>6. Broadcast Events When Necessary</h3>
<p>If your action modifies a resource and you want to notify the frontend (e.g., via Reverb or Inertia), broadcast events.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Events\</span><span style="color: #E5C07B;">UserCreated</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #61AFEF;">broadcast</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">new</span><span style="color: #61AFEF;"> </span><span style="color: #E5C07B;">UserCreated</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">))-&gt;</span><span style="color: #61AFEF;">toOthers</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h3><a id="7-return-the-resource" href="#7-return-the-resource" class="" aria-hidden="true" title=""></a>7. Return the Resource</h3>
<p>Return the modified or created resource from your action.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<h3><a id="8-inject-other-actions-when-needed" href="#8-inject-other-actions-when-needed" class="" aria-hidden="true" title=""></a>8. Inject Other Actions When Needed</h3>
<p>Action classes can depend on other actions to compose complex behavior.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">__construct</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">SyncUserRoles</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$syncUserRoles</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">AssignTeam</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$assignTeam</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">) {}</span></div></code></pre>
<h2><a id="more-resources" href="#more-resources" class="" aria-hidden="true" title=""></a>More Resources</h2>
<ul>
<li><a rel="nofollow noopener" target="_blank" href="https://youtu.be/r1480BoFulQ?si=q2p_RAsYWwBgFE3G">Laravel Actions: The Secret Sauce</a></li>
<li><a rel="nofollow noopener" target="_blank" href="https://youtu.be/pEwuymfnfXI?si=kb21lrr_z8N8-0Gn">Laravel Actions Example: with Policy, API and Unit Tests</a></li>
<li><a rel="nofollow noopener" target="_blank" href="https://youtu.be/sW8tN8cf2bE?si=5tb_BPQvKI1dOw4z">The action pattern explained</a></li>
<li><a rel="nofollow noopener" target="_blank" href="https://stitcher.io/blog/organise-by-domain#actions">https://stitcher.io/blog/organise-by-domain#actions</a></li>
</ul>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 08 Jul 2025 20:42:32 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Laravel 12.9 Introduces Memoized Cache Driver]]></title>
                <link>https://nabilhassen.com/laravel-129-introduces-memoized-cache-driver</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#basic-usage">Basic Usage</a></li>
<li><a href="#value-example">Value Example</a></li>
<li><a href="#specifying-driver">Specifying Driver</a></li>
<li><a href="#mutation-behavior">Mutation Behavior</a></li>
</ul>
<p>Laravel has added a new memoized cache driver contributed by <a rel="nofollow noopener" target="_blank" href="https://github.com/timacdonald">@timacdonald</a> that decorates existing cache drivers by storing retrieved values in memory during a request lifecycle. This allows repeated calls to the same cache key to be resolved from memory, reducing repeated calls to the underlying cache.</p>
<h3><a id="basic-usage" href="#basic-usage" class="" aria-hidden="true" title=""></a>Basic Usage</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">Cache</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;foo&#39;</span><span style="color: #ABB2BF;">);         </span><span style="color: #7F848E;">// hits the cache</span></div><div class='line'><span style="color: #E5C07B;">Cache</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;foo&#39;</span><span style="color: #ABB2BF;">);         </span><span style="color: #7F848E;">// hits the cache</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">Cache</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">memo</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;foo&#39;</span><span style="color: #ABB2BF;">); </span><span style="color: #7F848E;">// hits the cache</span></div><div class='line'><span style="color: #E5C07B;">Cache</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">memo</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;foo&#39;</span><span style="color: #ABB2BF;">); </span><span style="color: #7F848E;">// does NOT hit the cache</span></div></code></pre>
<h3><a id="value-example" href="#value-example" class="" aria-hidden="true" title=""></a>Value Example</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">Cache</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">put</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;Taylor&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E5C07B;">Cache</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">);           </span><span style="color: #7F848E;">// &quot;Taylor&quot;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">Cache</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">put</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;Tim&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E5C07B;">Cache</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">);           </span><span style="color: #7F848E;">// &quot;Tim&quot;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">Cache</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">put</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;Taylor&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E5C07B;">Cache</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">memo</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">);   </span><span style="color: #7F848E;">// &quot;Taylor&quot;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">Cache</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">put</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;Tim&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E5C07B;">Cache</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">memo</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">);   </span><span style="color: #7F848E;">// &quot;Taylor&quot;</span></div></code></pre>
<h3><a id="specifying-driver" href="#specifying-driver" class="" aria-hidden="true" title=""></a>Specifying Driver</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">Cache</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">memo</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">);          </span><span style="color: #7F848E;">// default driver</span></div><div class='line'><span style="color: #E5C07B;">Cache</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">memo</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;redis&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">);   </span><span style="color: #7F848E;">// Redis driver</span></div><div class='line'><span style="color: #E5C07B;">Cache</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">memo</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;database&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">); </span><span style="color: #7F848E;">// Database driver</span></div></code></pre>
<p>Each memoized store is isolated per driver:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">Cache</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">driver</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;redis&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">put</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;Taylor in Redis&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E5C07B;">Cache</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">driver</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;database&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">put</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;Taylor in the database&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">Cache</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">memo</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;redis&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">);    </span><span style="color: #7F848E;">// &quot;Taylor in Redis&quot;</span></div><div class='line'><span style="color: #E5C07B;">Cache</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">memo</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;database&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">); </span><span style="color: #7F848E;">// &quot;Taylor in the database&quot;</span></div></code></pre>
<h3><a id="mutation-behavior" href="#mutation-behavior" class="" aria-hidden="true" title=""></a>Mutation Behavior</h3>
<p>Memoized drivers forget cached values when mutation methods are used:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">Cache</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">memo</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">put</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;Taylor&#39;</span><span style="color: #ABB2BF;">); </span><span style="color: #7F848E;">// writes and clears memoized &#39;name&#39;</span></div><div class='line'><span style="color: #E5C07B;">Cache</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">memo</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">);           </span><span style="color: #7F848E;">// hits cache</span></div><div class='line'><span style="color: #E5C07B;">Cache</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">memo</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">);           </span><span style="color: #7F848E;">// memory</span></div></code></pre>
<p>For complete details, visit the original pull request:<br />
🔗 <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/55304">laravel/framework#55304</a></p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Thu, 17 Apr 2025 16:14:01 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Automatic Relation Loading (Eager Loading) in Laravel 12.8]]></title>
                <link>https://nabilhassen.com/automatic-relation-loading-eager-loading-in-laravel-128</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#laravel-128---automatic-relationship-loading">Laravel 12.8 - Automatic Relationship Loading</a></li>
<li><a href="#the-problem">The Problem</a></li>
<li><a href="#the-new-solution-withrelationshipautoloading">The New Solution: withRelationshipAutoloading()</a></li>
<li><a href="#morph-relations-supported">Morph Relations Supported</a></li>
<li><a href="#manual-loading-still-works">Manual Loading Still Works</a></li>
<li><a href="#global-autoloading">Global Autoloading</a></li>
</ul>
<h2><a id="laravel-128---automatic-relationship-loading" href="#laravel-128---automatic-relationship-loading" class="" aria-hidden="true" title=""></a>Laravel 12.8 - Automatic Relationship Loading</h2>
<p>A new feature has landed in Laravel contributed by <a rel="nofollow noopener" target="_blank" href="https://twitter.com/r9ray">@r9ray</a> that aims to simplify how developers handle eager loading of relationships: <strong>automatic relationship loading</strong>. Merged in <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/53655">PR #53655</a>, this feature removes the need for repetitive <code>load()</code> and <code>with()</code> calls, particularly in large projects with deeply nested or dynamic relationships.</p>
<h2><a id="the-problem" href="#the-problem" class="" aria-hidden="true" title=""></a>The Problem</h2>
<p>In large applications, managing which relationships need to be eager-loaded becomes tedious:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$projects</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">load</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;client.owner.details&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;client.customPropertyValues&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;clientContact.customPropertyValues&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;status&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;company.statuses&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;posts.authors.articles.likes&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;related.statuses&#39;</span></div><div class='line'><span style="color: #ABB2BF;">]);</span></div></code></pre>
<p>This approach is verbose, hard to maintain, and easy to get wrong—especially when relationships evolve over time or are used conditionally.</p>
<h2><a id="the-new-solution-withrelationshipautoloading" href="#the-new-solution-withrelationshipautoloading" class="" aria-hidden="true" title=""></a>The New Solution: <code>withRelationshipAutoloading()</code></h2>
<p>A more elegant approach to handling nested eager loading with the <code>withRelationshipAutoloading()</code> method. When applied to a model or collection, it <strong>automatically loads relationships whenever they are accessed</strong>, without the need for explicit <code>load()</code> or <code>with()</code> calls.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$orders</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Order</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">all</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">withRelationshipAutoloading</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">foreach</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$orders</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">as</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$order</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$order</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">client</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">owner</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">company</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>As you navigate through the relationships, Laravel silently loads the necessary data in the background—no manual calls required.</p>
<h2><a id="morph-relations-supported" href="#morph-relations-supported" class="" aria-hidden="true" title=""></a>Morph Relations Supported</h2>
<p>Polymorphic (morph) relations are fully supported. When using morphs, only the accessed type is loaded, which keeps the process efficient.</p>
<h2><a id="manual-loading-still-works" href="#manual-loading-still-works" class="" aria-hidden="true" title=""></a>Manual Loading Still Works</h2>
<p>You can still use <code>load()</code> or <code>with()</code> manually, and Laravel won't reload relationships you've already explicitly loaded.</p>
<h2><a id="global-autoloading" href="#global-autoloading" class="" aria-hidden="true" title=""></a>Global Autoloading</h2>
<p>If you want this behavior application-wide, you can enable it globally:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">Model</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">automaticallyEagerLoadRelationships</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>This saves time for teams that rely heavily on nested or dynamic relationships, reducing overhead and improving maintainability.</p>
<p>Check out the full PR here: <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/53655">laravel/framework#53655</a></p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Wed, 09 Apr 2025 13:17:58 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[New in Laravel 12.7: `whereAttachedTo()` for BelongsToMany Relationships]]></title>
                <link>https://nabilhassen.com/new-in-laravel-127-whereattachedto-for-belongstomany-relationships</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#whereattachedto-for-belongstomany-relationships">whereAttachedTo() for BelongsToMany Relationships</a></li>
<li><a href="#the-problem">The Problem</a></li>
<li><a href="#the-solution-whereattachedto">The Solution: whereAttachedTo()</a></li>
<li><a href="#examples">Examples</a></li>
</ul>
<h2><a id="whereattachedto-for-belongstomany-relationships" href="#whereattachedto-for-belongstomany-relationships" class="" aria-hidden="true" title=""></a><code>whereAttachedTo()</code> for BelongsToMany Relationships</h2>
<p>Laravel has introduced a new query builder method, <code>whereAttachedTo()</code>, contributed by <a rel="nofollow noopener" target="_blank" href="https://twitter.com/bakerkretzmar">@bakerkretzmar</a>, that simplifies querying <code>BelongsToMany</code> relationships. Merged into the framework on April 2, 2025, this feature brings a more expressive and convenient way to filter models based on their pivot table attachments.</p>
<h2><a id="the-problem" href="#the-problem" class="" aria-hidden="true" title=""></a>The Problem</h2>
<p>When dealing with many-to-many relationships in Eloquent, developers often need to filter models that are attached to a given instance or a collection of instances. This previously required manual use of <code>whereHas</code> or <code>whereIn</code> logic with nested relationship queries, which could be verbose and less readable.</p>
<h2><a id="the-solution-whereattachedto" href="#the-solution-whereattachedto" class="" aria-hidden="true" title=""></a>The Solution: <code>whereAttachedTo()</code></h2>
<p>The new <code>whereAttachedTo()</code> method provides a clean, expressive alternative. Inspired by the existing <code>whereBelongsTo()</code> method, it allows developers to query for models that are attached to a given model or set of models through a <code>BelongsToMany</code> relationship.</p>
<h2><a id="examples" href="#examples" class="" aria-hidden="true" title=""></a>Examples</h2>
<p>Before:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$tags</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Tag</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">where</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;created_at&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;&gt;&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #61AFEF;">now</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">subMonth</span><span style="color: #ABB2BF;">())-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$taggedPosts</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Post</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereHas</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;tags&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$query</span><span style="color: #ABB2BF;">) </span><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$tags</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$query</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">whereKey</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$tags</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">})-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>After:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$tags</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Tag</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">where</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;created_at&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;&gt;&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #61AFEF;">now</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">subMonth</span><span style="color: #ABB2BF;">())-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$taggedPosts</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Post</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereAttachedTo</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$tags</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>Like whereBelongsTo(), whereAttachedTo() guesses the relationship name based on Laravel conventions, but it can also be passed in manually:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$taggedPosts</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Post</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereAttachedTo</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$tags</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;tags&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 08 Apr 2025 09:24:42 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Fluent Numeric Validation and Conditional Prohibition Rules in Laravel]]></title>
                <link>https://nabilhassen.com/fluent-numeric-validation-and-conditional-prohibition-rules-in-laravel</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#fluent-numeric-validation">Fluent Numeric Validation</a></li>
<li><a href="#conditional-prohibition-rules">Conditional Prohibition Rules</a></li>
</ul>
<h2><a id="fluent-numeric-validation" href="#fluent-numeric-validation" class="" aria-hidden="true" title=""></a>Fluent Numeric Validation</h2>
<p><a rel="nofollow noopener" target="_blank" href="https://github.com/xoesae">@xoesae</a> introduced a new <code>Numeric</code> class for defining numeric validation rules in a more structured way. Previously, validation rules were defined as strings:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$rules</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;score&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;numeric|integer|multiple_of:10|lte:some_field|max:100&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">];</span></div></code></pre>
<p>Now, they can be written fluently:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Validation\Rules\</span><span style="color: #E5C07B;">Numeric</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$rules</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;score&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Numeric</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">make</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">            -&gt;</span><span style="color: #61AFEF;">integer</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">            -&gt;</span><span style="color: #61AFEF;">multipleOf</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">10</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">            -&gt;</span><span style="color: #61AFEF;">lte</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;some_field&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">            -&gt;</span><span style="color: #61AFEF;">max</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">100</span><span style="color: #ABB2BF;">),</span></div><div class='line'><span style="color: #ABB2BF;">    ],</span></div><div class='line'><span style="color: #ABB2BF;">];</span></div></code></pre>
<p>More details in PR <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/54425">#54425</a>.</p>
<h2><a id="conditional-prohibition-rules" href="#conditional-prohibition-rules" class="" aria-hidden="true" title=""></a>Conditional Prohibition Rules</h2>
<p><a rel="nofollow noopener" target="_blank" href="https://github.com/osama-98">@osama-98</a> added two new validation rules: <code>prohibited_if_accepted</code> and <code>prohibited_if_declined</code>. These rules prevent a field from being included when another field is accepted or declined.</p>
<p>For example, to prohibit the <code>reason</code> field if <code>terms</code> is accepted:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$rules</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;terms&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;accepted&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;reason&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;prohibited_if_accepted:terms&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">];</span></div></code></pre>
<p>To prohibit <code>reason</code> if <code>terms</code> is declined:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$rules</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;terms&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;declined&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;reason&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;prohibited_if_declined:terms&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">];</span></div></code></pre>
<p>More details in PR <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/54608">#54608</a>.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Thu, 20 Feb 2025 15:05:13 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[New Query Builder Methods Added in Laravel 11.43]]></title>
                <link>https://nabilhassen.com/new-query-builder-methods-added-in-laravel-1143</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#laravel-adds-withwhererelation-and-findsole-methods-to-query-builder">Laravel Adds withWhereRelation and findSole Methods to Query Builder</a></li>
<li><a href="#withwhererelation-constraining-eager-loaded-relationships">withWhereRelation: Constraining Eager-Loaded Relationships</a>
<ul>
<li><a href="#example-usage">Example Usage:</a></li>
</ul>
</li>
<li><a href="#findsole-ensuring-a-unique-record-match">findSole: Ensuring a Unique Record Match</a>
<ul>
<li><a href="#example-usage-1">Example Usage:</a></li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="laravel-adds-withwhererelation-and-findsole-methods-to-query-builder" href="#laravel-adds-withwhererelation-and-findsole-methods-to-query-builder" class="" aria-hidden="true" title=""></a>Laravel Adds <code>withWhereRelation</code> and <code>findSole</code> Methods to Query Builder</h2>
<p>Two new methods have been introduced to Laravel's query builder: <code>withWhereRelation</code> and <code>findSole</code>. These improvements make querying relationships and retrieving single records more convenient and expressive. Let's dive into how they work.</p>
<h2><a id="withwhererelation-constraining-eager-loaded-relationships" href="#withwhererelation-constraining-eager-loaded-relationships" class="" aria-hidden="true" title=""></a><code>withWhereRelation</code>: Constraining Eager-Loaded Relationships</h2>
<p>The new <code>withWhereRelation</code> method, contributed by <a rel="nofollow noopener" target="_blank" href="https://x.com/SomaiyaUtsav">@SomaiyaUtsav</a>, allows developers to apply constraints to eager-loaded relationships directly. Previously, filtering related models required separate <code>where</code> constraints after eager loading. This new method simplifies that process.</p>
<h3><a id="example-usage" href="#example-usage" class="" aria-hidden="true" title=""></a>Example Usage:</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">query</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">withWhereRelation</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;posts&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;is_published&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">true</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>This query retrieves users who have at least one published post, reducing the need for extra filtering operations.</p>
<h2><a id="findsole-ensuring-a-unique-record-match" href="#findsole-ensuring-a-unique-record-match" class="" aria-hidden="true" title=""></a><code>findSole</code>: Ensuring a Unique Record Match</h2>
<p>The <code>findSole</code> method, introduced by <a rel="nofollow noopener" target="_blank" href="https://x.com/zepfietje">@zepfietje</a>, is a more restrictive version of <code>find</code>. It ensures that exactly one record matches the given primary key. If no record is found, or if multiple records exist, an exception is thrown.</p>
<h3><a id="example-usage-1" href="#example-usage-1" class="" aria-hidden="true" title=""></a>Example Usage:</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">query</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">findSole</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$id</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>These new methods enhance Laravel's query builder by making common tasks more intuitive. <code>withWhereRelation</code> provides a cleaner way to filter related models during eager loading, while <code>findSole</code> helps enforce data integrity by ensuring a single result. Both additions contribute to Laravel’s expressive and developer-friendly approach to database querying.</p>
<p>For more details, check out the official pull requests:</p>
<ul>
<li><a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/54668">Add <code>withWhereRelation</code> method to builder</a></li>
<li><a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/54667">Add <code>findSole</code> query builder method</a></li>
</ul>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Wed, 19 Feb 2025 14:56:38 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[13 Common HTTP Errors in Laravel and How to Fix Them]]></title>
                <link>https://nabilhassen.com/13-common-http-errors-in-laravel-and-how-to-fix-them</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#common-http-status-code-errors-in-laravel-and-how-to-fix-them">Common HTTP Status Code Errors in Laravel and How to Fix Them</a></li>
<li><a href="#1-400-bad-request">1. 400 Bad Request</a></li>
<li><a href="#2-401-unauthorized">2. 401 Unauthorized</a></li>
<li><a href="#3-403-forbidden">3. 403 Forbidden</a></li>
<li><a href="#4-404-not-found">4. 404 Not Found</a></li>
<li><a href="#5-405-method-not-allowed">5. 405 Method Not Allowed</a></li>
<li><a href="#6-408-request-timeout">6. 408 Request Timeout</a></li>
<li><a href="#7-419-page-expired">7. 419 Page Expired</a></li>
<li><a href="#8-422-unprocessable-entity">8. 422 Unprocessable Entity</a></li>
<li><a href="#9-429-too-many-requests">9. 429 Too Many Requests</a></li>
<li><a href="#10-500-internal-server-error">10. 500 Internal Server Error</a></li>
<li><a href="#11-502-bad-gateway">11. 502 Bad Gateway</a></li>
<li><a href="#12-503-service-unavailable">12. 503 Service Unavailable</a></li>
<li><a href="#13-504-gateway-timeout">13. 504 Gateway Timeout</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="common-http-status-code-errors-in-laravel-and-how-to-fix-them" href="#common-http-status-code-errors-in-laravel-and-how-to-fix-them" class="" aria-hidden="true" title=""></a>Common HTTP Status Code Errors in Laravel and How to Fix Them</h2>
<p>Laravel, like any other web framework, interacts with HTTP requests and responses. While working with Laravel, you might encounter different HTTP status code errors. These errors indicate issues with client requests, authentication, server configuration, or application logic. In this article, we’ll go over <strong>13 common HTTP status code errors in Laravel</strong>, their possible causes, examples, and solutions.</p>
<h2><a id="1-400-bad-request" href="#1-400-bad-request" class="" aria-hidden="true" title=""></a>1. 400 Bad Request</h2>
<p><strong>Example:</strong> Sending an improperly formatted JSON request.</p>
<p><strong>Possible Cause:</strong> The request is malformed, contains invalid syntax, or exceeds the allowed size.</p>
<p><strong>Possible Solution:</strong> Ensure correct request formatting, validate input data, and check request headers.</p>
<h2><a id="2-401-unauthorized" href="#2-401-unauthorized" class="" aria-hidden="true" title=""></a>2. 401 Unauthorized</h2>
<p><strong>Example:</strong> Accessing an API route without a valid token.</p>
<p><strong>Possible Cause:</strong> Authentication is required but not provided or is invalid.</p>
<p><strong>Possible Solution:</strong> Use Laravel’s authentication middleware, ensure correct API tokens, and check user authentication status.</p>
<h2><a id="3-403-forbidden" href="#3-403-forbidden" class="" aria-hidden="true" title=""></a>3. 403 Forbidden</h2>
<p><strong>Example:</strong> A user tries to access the admin panel without the necessary permissions.</p>
<p><strong>Possible Cause:</strong> The request is authenticated but lacks the required authorization.</p>
<p><strong>Possible Solution:</strong> Use Laravel Gates and Policies to control access and return proper authorization responses.</p>
<h2><a id="4-404-not-found" href="#4-404-not-found" class="" aria-hidden="true" title=""></a>4. 404 Not Found</h2>
<p><strong>Example:</strong> Navigating to <code>/non-existing-route</code> in a Laravel app.</p>
<p><strong>Possible Cause:</strong> The requested route or resource does not exist.</p>
<p><strong>Possible Solution:</strong> Ensure the route is defined in <code>routes/web.php</code> or <code>routes/api.php</code>, and use <code>Route::fallback()</code> for custom handling.</p>
<h2><a id="5-405-method-not-allowed" href="#5-405-method-not-allowed" class="" aria-hidden="true" title=""></a>5. 405 Method Not Allowed</h2>
<p><strong>Example:</strong> Sending a <code>POST</code> request to a <code>GET</code> route.</p>
<p><strong>Possible Cause:</strong> The requested HTTP method is not supported by the route.</p>
<p><strong>Possible Solution:</strong> Verify the route definition and ensure the correct HTTP method is used.</p>
<h2><a id="6-408-request-timeout" href="#6-408-request-timeout" class="" aria-hidden="true" title=""></a>6. 408 Request Timeout</h2>
<p><strong>Example:</strong> A user submits a request that takes too long to process.</p>
<p><strong>Possible Cause:</strong> The request takes longer than the server’s timeout limit.</p>
<p><strong>Possible Solution:</strong> Optimize database queries, increase server timeout settings, and consider using queues for long-running tasks.</p>
<h2><a id="7-419-page-expired" href="#7-419-page-expired" class="" aria-hidden="true" title=""></a>7. 419 Page Expired</h2>
<p><strong>Example:</strong> Submitting a form after an extended period of inactivity.</p>
<p><strong>Possible Cause:</strong> CSRF token mismatch, usually due to a session timeout.</p>
<p><strong>Possible Solution:</strong> Ensure CSRF protection is implemented correctly using <code>@csrf</code> in forms, and extend session lifetime if needed.</p>
<h2><a id="8-422-unprocessable-entity" href="#8-422-unprocessable-entity" class="" aria-hidden="true" title=""></a>8. 422 Unprocessable Entity</h2>
<p><strong>Example:</strong> Submitting a form without filling required fields.</p>
<p><strong>Possible Cause:</strong> Validation errors in the request payload.</p>
<p><strong>Possible Solution:</strong> Implement Laravel’s validation rules and return proper validation error messages.</p>
<h2><a id="9-429-too-many-requests" href="#9-429-too-many-requests" class="" aria-hidden="true" title=""></a>9. 429 Too Many Requests</h2>
<p><strong>Example:</strong> A bot or user repeatedly making API calls in a short time.</p>
<p><strong>Possible Cause:</strong> Rate limiting is exceeded.</p>
<p><strong>Possible Solution:</strong> Adjust rate limiting using <code>ThrottleRequests</code> middleware.</p>
<h2><a id="10-500-internal-server-error" href="#10-500-internal-server-error" class="" aria-hidden="true" title=""></a>10. 500 Internal Server Error</h2>
<p><strong>Example:</strong> A database query fails due to missing tables.</p>
<p><strong>Possible Cause:</strong> An unhandled server-side exception or misconfiguration.</p>
<p><strong>Possible Solution:</strong> Check Laravel logs in <code>storage/logs/laravel.log</code>, debug the error, and fix any underlying issues.</p>
<h2><a id="11-502-bad-gateway" href="#11-502-bad-gateway" class="" aria-hidden="true" title=""></a>11. 502 Bad Gateway</h2>
<p><strong>Example:</strong> Nginx fails to connect to PHP-FPM.</p>
<p><strong>Possible Cause:</strong> The server received an invalid response from an upstream server.</p>
<p><strong>Possible Solution:</strong> Restart web services (<code>sudo service nginx restart</code> or <code>sudo service php-fpm restart</code>) and check server configurations.</p>
<h2><a id="12-503-service-unavailable" href="#12-503-service-unavailable" class="" aria-hidden="true" title=""></a>12. 503 Service Unavailable</h2>
<p><strong>Example:</strong> Laravel is in maintenance mode (<code>php artisan down</code>).</p>
<p><strong>Possible Cause:</strong> The application is temporarily unavailable due to maintenance or overload.</p>
<p><strong>Possible Solution:</strong> Run <code>php artisan up</code> to bring the application back online or scale server resources if overloaded.</p>
<h2><a id="13-504-gateway-timeout" href="#13-504-gateway-timeout" class="" aria-hidden="true" title=""></a>13. 504 Gateway Timeout</h2>
<p><strong>Example:</strong> A slow external API request times out.</p>
<p><strong>Possible Cause:</strong> The request to an upstream server takes too long to respond.</p>
<p><strong>Possible Solution:</strong> Optimize external API calls, increase timeout settings in the web server, and use asynchronous processing where possible.</p>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>Handling HTTP status code errors in Laravel effectively improves application reliability and user experience. By understanding the causes and solutions for each error, you can troubleshoot issues quickly and ensure a smooth-running Laravel application. Keep an eye on Laravel logs and leverage Laravel’s built-in error handling mechanisms for better debugging and maintenance.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Mon, 17 Feb 2025 08:20:04 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Laravel 11.42 Introduces New Date Query Methods]]></title>
                <link>https://nabilhassen.com/laravel-1142-introduces-new-date-query-methods</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#new-date-query-methods-in-eloquent-in-1142">New Date Query Methods in Eloquent in 11.42</a></li>
<li><a href="#new-methods-for-date-based-queries">New Methods for Date-Based Queries</a></li>
<li><a href="#how-these-methods-improve-queries">How These Methods Improve Queries</a></li>
<li><a href="#example-use-cases">Example Use Cases</a>
<ul>
<li><a href="#get-all-expired-subscriptions">Get All Expired Subscriptions</a></li>
<li><a href="#find-events-happening-now-or-in-the-future">Find Events Happening Now or in the Future</a></li>
<li><a href="#retrieve-orders-placed-in-the-past">Retrieve Orders Placed in the Past</a></li>
</ul>
</li>
<li><a href="#availability">Availability</a></li>
</ul>
<h2><a id="new-date-query-methods-in-eloquent-in-1142" href="#new-date-query-methods-in-eloquent-in-1142" class="" aria-hidden="true" title=""></a>New Date Query Methods in Eloquent in 11.42</h2>
<p>Laravel continues to enhance the developer experience with a new set of methods in the Query Builder, simplifying date-based queries. These methods, introduced in a recent pull request by <a rel="nofollow noopener" target="_blank" href="http://x.com/gonedark">Jason McCreary</a>, provide more readable and intuitive ways to filter records based on dates.</p>
<h2><a id="new-methods-for-date-based-queries" href="#new-methods-for-date-based-queries" class="" aria-hidden="true" title=""></a>New Methods for Date-Based Queries</h2>
<p>The update introduces the following methods and more:</p>
<ul>
<li><strong><code>wherePast()</code></strong>: Retrieves records where a date column is in the past.</li>
<li><strong><code>whereNowOrPast()</code></strong>: Fetches records where the date column is in the past or at the current moment.</li>
<li><strong><code>orWherePast()</code></strong>: Adds an OR condition for past dates.</li>
<li><strong><code>orWhereNowOrPast()</code></strong>: Adds an OR condition for past or present dates.</li>
<li><strong><code>whereFuture()</code></strong>: Selects records where a date column is in the future.</li>
<li><strong><code>whereNowOrFuture()</code></strong>: Finds records where the date column is in the future or at the current moment.</li>
<li><strong><code>orWhereFuture()</code></strong>: Adds an OR condition for future dates.</li>
<li><strong><code>orWhereNowOrFuture()</code></strong>: Adds an OR condition for future or present dates.</li>
</ul>
<h2><a id="how-these-methods-improve-queries" href="#how-these-methods-improve-queries" class="" aria-hidden="true" title=""></a>How These Methods Improve Queries</h2>
<p>Previously, filtering records based on relative dates required verbose <code>where</code> conditions, such as:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$pastRecords</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Model</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">where</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;date_column&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;&lt;&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #61AFEF;">now</span><span style="color: #ABB2BF;">())-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>With the new methods, the same query becomes more readable:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$pastRecords</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Model</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">wherePast</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;date_column&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>This improvement enhances both code clarity and maintainability.</p>
<h2><a id="example-use-cases" href="#example-use-cases" class="" aria-hidden="true" title=""></a>Example Use Cases</h2>
<h3><a id="get-all-expired-subscriptions" href="#get-all-expired-subscriptions" class="" aria-hidden="true" title=""></a>Get All Expired Subscriptions</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$expiredSubscriptions</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Subscription</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">wherePast</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;expires_at&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h3><a id="find-events-happening-now-or-in-the-future" href="#find-events-happening-now-or-in-the-future" class="" aria-hidden="true" title=""></a>Find Events Happening Now or in the Future</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$upcomingEvents</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Event</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereNowOrFuture</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;event_date&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h3><a id="retrieve-orders-placed-in-the-past" href="#retrieve-orders-placed-in-the-past" class="" aria-hidden="true" title=""></a>Retrieve Orders Placed in the Past</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$pastOrders</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Order</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">wherePast</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;created_at&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h2><a id="availability" href="#availability" class="" aria-hidden="true" title=""></a>Availability</h2>
<p>These methods are part of the latest Laravel 11.42 release. You can explore the full implementation in the <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/54408">Pull Request</a>.</p>
<p>With these new date query methods, Laravel makes working with date-based data more intuitive, further improving the developer experience.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Wed, 12 Feb 2025 07:14:47 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[LaraconEU 2025 - Laravel 12 release date, Cloud, Starter kits & more]]></title>
                <link>https://nabilhassen.com/laraconeu-2025-laravel-12-release-date-cloud-starter-kits-more</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#introduction">Introduction</a></li>
<li><a href="#main-announcements">Main Announcements</a>
<ul>
<li><a href="#laravel-12-release-date">Laravel 12: Release Date</a></li>
<li><a href="#laravel-cloud-the-future-of-shipping-laravel-applications">Laravel Cloud: The Future of Shipping Laravel Applications</a></li>
<li><a href="#pricing-plans-sandbox-and-production">Pricing Plans: Sandbox and Production</a></li>
<li><a href="#laravel-nightwatch-the-future-of-monitoring">Laravel Nightwatch: The Future of Monitoring</a></li>
<li><a href="#a-new-look-for-laravelcom">A New Look for Laravel.com</a></li>
<li><a href="#new-starter-kits">New Starter Kits</a></li>
<li><a href="#flux-ui-components-boosting-livewire-development">Flux UI Components: Boosting Livewire Development</a></li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="introduction" href="#introduction" class="" aria-hidden="true" title=""></a>Introduction</h2>
<p>At the recent Laracon EU, Taylor Otwell, the creator of Laravel, shared several groundbreaking updates that are set to transform how we develop, deploy, and monitor Laravel applications. From the introduction of Laravel Cloud to the early access of Laravel Nightwatch, here's a recap of everything announced that's poised to elevate the Laravel ecosystem.</p>
<h2><a id="main-announcements" href="#main-announcements" class="" aria-hidden="true" title=""></a>Main Announcements</h2>
<h3><a id="laravel-12-release-date" href="#laravel-12-release-date" class="" aria-hidden="true" title=""></a>Laravel 12: Release Date</h3>
<p>Taylor Otwell revealed that Laravel 12 will be launched on February 24, 2025. This release will be significant as it introduces zero-breaking changes, making it easier for developers to upgrade.</p>
<h3><a id="laravel-cloud-the-future-of-shipping-laravel-applications" href="#laravel-cloud-the-future-of-shipping-laravel-applications" class="" aria-hidden="true" title=""></a>Laravel Cloud: The Future of Shipping Laravel Applications</h3>
<p>On February 24th, 2025, Laravel Cloud is set to launch, marking a pivotal moment for Laravel developers. This fully managed infrastructure platform is optimized for Laravel and PHP, promising to redefine the deployment process. Laravel Cloud aims to eliminate the headaches of DevOps, server configurations, and database management, allowing developers to focus purely on shipping their applications. With features like application and database hibernation, developers can minimize costs for smaller projects, paying only for the compute they use. Every application on Laravel Cloud will receive a free domain with DDoS protection and SSL, enhancing security and ease of use.</p>
<h3><a id="pricing-plans-sandbox-and-production" href="#pricing-plans-sandbox-and-production" class="" aria-hidden="true" title=""></a>Pricing Plans: Sandbox and Production</h3>
<p><strong>Sandbox Plan:</strong> Priced at $0 per month plus usage, this plan is ideal for small projects. It includes features like application hibernation, where you don't pay for compute when your application isn't active, and free Laravel Cloud domains.</p>
<p><strong>Production Plan:</strong> For $20 per month plus usage, this plan unlocks advanced features like custom domains, larger instance sizes, extended log retention, and support for additional users. Laravel also teased business and enterprise plans with unlimited auto-scaling, dedicated compute, and more, tailored for larger scale operations.</p>
<h3><a id="laravel-nightwatch-the-future-of-monitoring" href="#laravel-nightwatch-the-future-of-monitoring" class="" aria-hidden="true" title=""></a>Laravel Nightwatch: The Future of Monitoring</h3>
<p>Laravel Nightwatch, with its early access starting next week, introduces a new era of monitoring for Laravel applications. Described as gorgeous and forward-looking, Nightwatch aims to provide developers with an intuitive and powerful way to keep an eye on their applications' health and performance.</p>
<h3><a id="a-new-look-for-laravelcom" href="#a-new-look-for-laravelcom" class="" aria-hidden="true" title=""></a>A New Look for Laravel.com</h3>
<p>Coinciding with these launches, a brand new Laravel.com website will be unveiled on February 24th. The design team has worked hard to ensure the new site not only looks modern but also enhances the user experience for developers looking for Laravel resources.</p>
<h3><a id="new-starter-kits" href="#new-starter-kits" class="" aria-hidden="true" title=""></a>New Starter Kits</h3>
<p>Also launching on the same day are new starter kits for Livewire, React, and Vue, utilizing Inertia 2.0 for React and Vue, and all incorporating Tailwind CSS. These kits are built to streamline the development process by providing developers with pre-configured setups, using popular UI component libraries where appropriate.</p>
<h3><a id="flux-ui-components-boosting-livewire-development" href="#flux-ui-components-boosting-livewire-development" class="" aria-hidden="true" title=""></a>Flux UI Components: Boosting Livewire Development</h3>
<p>In an exciting move for the community, Caleb Porzio has agreed to make a base set of Flux UI components free and open-source. This initiative is expected to supercharge Livewire development by providing developers with essential components to build applications more efficiently.</p>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>From Laravel Cloud's game-changing approach to deployment to the sleek monitoring capabilities of Nightwatch, and the introduction of new tools and resources, Laracon EU has set the stage for an exciting year ahead for Laravel developers. These advancements not only simplify the development lifecycle but also empower developers to create more robust, scalable, and secure applications. As we await the official launches, we invite you to join the conversation, share your thoughts, and prepare to explore these new features. Stay tuned for more updates, and let's continue to build the future together!</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 04 Feb 2025 19:02:40 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Integrating with Apps Behind Routers Using Reverse Proxy]]></title>
                <link>https://nabilhassen.com/integrating-with-apps-behind-routers-using-reverse-proxy</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#solving-remote-connectivity-for-a-cloud-based-pos-with-a-reverse-proxy">Solving Remote Connectivity for a Cloud-Based POS with a Reverse Proxy</a></li>
<li><a href="#exploring-possible-solutions">Exploring Possible Solutions</a>
<ul>
<li><a href="#1-port-forwarding">1. Port Forwarding</a></li>
<li><a href="#2-ngrok">2. Ngrok</a></li>
<li><a href="#3-reverse-proxy-as-a-tunnel">3. Reverse Proxy as a Tunnel</a></li>
</ul>
</li>
<li><a href="#implementing-frp-as-a-reverse-proxy">Implementing FRP as a Reverse Proxy</a></li>
<li><a href="#final-thoughts">Final Thoughts</a></li>
</ul>
<h2><a id="solving-remote-connectivity-for-a-cloud-based-pos-with-a-reverse-proxy" href="#solving-remote-connectivity-for-a-cloud-based-pos-with-a-reverse-proxy" class="" aria-hidden="true" title=""></a>Solving Remote Connectivity for a Cloud-Based POS with a Reverse Proxy</h2>
<p>I was working on a cloud-based POS web application that needed to send HTTP POST and GET requests to API endpoints provided by desktop applications sitting behind a router. The real challenge wasn't just making the requests—it was figuring out how to reliably reach those machines in the first place. Here’s how I tackled it.</p>
<h2><a id="exploring-possible-solutions" href="#exploring-possible-solutions" class="" aria-hidden="true" title=""></a>Exploring Possible Solutions</h2>
<h3><a id="1-port-forwarding" href="#1-port-forwarding" class="" aria-hidden="true" title=""></a>1. Port Forwarding</h3>
<p>The first solution that came to mind was port forwarding. However, for this to work, two conditions had to be met:</p>
<ul>
<li>The router had to support port forwarding.</li>
<li>The machines had to have static IP addresses.</li>
</ul>
<p>Unfortunately, neither condition was guaranteed. Many clients had dynamic IPs, and their routers varied, meaning some supported port forwarding while others didn’t. To address the dynamic IP issue, I considered using a dynamic DNS (DDNS) service like No-IP. This allowed us to map dynamic IPs to a static hostname. However, the inconsistency in router support for both port forwarding and DDNS made this approach unreliable across all clients.</p>
<h3><a id="2-ngrok" href="#2-ngrok" class="" aria-hidden="true" title=""></a>2. Ngrok</h3>
<p>Another option I considered was using Ngrok, which provides secure tunneling for local servers. However, we couldn't use it because:</p>
<ul>
<li>We needed more control over the solution.</li>
<li>We needed something scalable, meaning I didn’t want to create an account for every client and manage it—this would be too tiresome.</li>
<li>It wasn’t allowed in our location, making it a non-starter.</li>
</ul>
<h3><a id="3-reverse-proxy-as-a-tunnel" href="#3-reverse-proxy-as-a-tunnel" class="" aria-hidden="true" title=""></a>3. Reverse Proxy as a Tunnel</h3>
<p>Since port forwarding and Ngrok weren’t viable, I explored another option: using a reverse proxy to create a tunnel between our server and the client machines. That’s when I came across <a rel="nofollow noopener" target="_blank" href="https://github.com/fatedier/frp">FRP (Fast Reverse Proxy)</a>, a powerful tool that allows exposing local servers behind NAT or firewalls to the internet.</p>
<h2><a id="implementing-frp-as-a-reverse-proxy" href="#implementing-frp-as-a-reverse-proxy" class="" aria-hidden="true" title=""></a>Implementing FRP as a Reverse Proxy</h2>
<p>To make this work, I needed a VPS (Virtual Private Server) to act as our central reverse proxy server. Here’s how we set it up:</p>
<ol>
<li>
<p><strong>Setting Up the Reverse Proxy Server</strong><br />
We installed FRP on the VPS, which would act as a bridge between the cloud POS and client machines.</p>
</li>
<li>
<p><strong>Configuring the Client Machines</strong><br />
Each client needed to connect to the reverse proxy, so we provided them with:</p>
<ul>
<li>A configuration file that included assigning a unique subdomain to their machine.</li>
<li>Batch scripts that would automatically run on login to establish the connection.</li>
</ul>
</li>
<li>
<p><strong>Automating the Connection</strong><br />
Once a client machine was powered on and logged in, the script ensured it was automatically connected to our reverse proxy. This meant our cloud POS could now send requests to the subdomain, and the reverse proxy would route them to the correct machine.</p>
</li>
</ol>
<h2><a id="final-thoughts" href="#final-thoughts" class="" aria-hidden="true" title=""></a>Final Thoughts</h2>
<p>After considering four possible solutions:</p>
<ol>
<li><strong>Port Forwarding</strong> (Unreliable due to router support inconsistencies)</li>
<li><strong>Port Forwarding + DDNS</strong> (Better, but still inconsistent across different routers)</li>
<li><strong>Ngrok</strong> (Lacked control, scalability issues, and not allowed in our location)</li>
<li><strong>Reverse Proxy Server</strong> (Reliable and works across all setups)</li>
</ol>
<p>The reverse proxy solution proved to be the best approach. It eliminated dependency on router configurations and static IPs, providing a seamless way to connect our cloud-based POS to client machines securely and reliably.</p>
<p>This approach not only solved our connectivity challenge but also made onboarding new clients easier, as they only needed to download a couple of files and log in to their machines. Now, every time a client’s computer is turned on, it’s automatically reachable—no manual configuration required.</p>
<p>Additionally, this solution turned into a new revenue stream for us, as the company started offering it as an add-on service. Clients who needed remote access to their local POS systems could subscribe to this feature, adding more value to our offering while generating additional income.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 04 Feb 2025 08:09:10 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[How to Queue Verification Email in Laravel]]></title>
                <link>https://nabilhassen.com/how-to-queue-verification-email-in-laravel</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#step-1-create-a-queueable-verifyemail-class">Step 1: Create a Queueable VerifyEmail Class</a></li>
<li><a href="#step-2-tell-laravel-to-use-the-new-notification">Step 2: Tell Laravel to Use the New Notification</a></li>
<li><a href="#step-3-configure-the-queue-system">Step 3: Configure the Queue System</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<p>By default, Laravel sends the email verification notification synchronously when a user registers. This can slow down the registration process. A better approach is to queue the verification email, allowing the request to complete faster while the email is sent in the background. In this article, we’ll explore how to achieve that by creating a queueable <code>VerifyEmail</code> class and updating the <code>User</code> model to use it.</p>
<h2><a id="step-1-create-a-queueable-verifyemail-class" href="#step-1-create-a-queueable-verifyemail-class" class="" aria-hidden="true" title=""></a>Step 1: Create a Queueable <code>VerifyEmail</code> Class</h2>
<p>Laravel uses the <code>Illuminate\Auth\Notifications\VerifyEmail</code> notification to send verification emails. We will extend this class and make it queueable.</p>
<p>Run the following command to generate a new notification class:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">make:notification</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">QueueableVerifyEmail</span></div></code></pre>
<p>Now, open <code>app/Notifications/QueueableVerifyEmail.php</code> and modify it as follows:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">namespace</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">App\Notifications</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Auth\Notifications\</span><span style="color: #E5C07B;">VerifyEmail</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Bus\</span><span style="color: #E5C07B;">Queueable</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Contracts\Queue\</span><span style="color: #E5C07B;">ShouldQueue</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">QueueableVerifyEmail</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">VerifyEmail</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">implements</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">ShouldQueue</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Queueable</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>This ensures that the notification is queued when dispatched.</p>
<h2><a id="step-2-tell-laravel-to-use-the-new-notification" href="#step-2-tell-laravel-to-use-the-new-notification" class="" aria-hidden="true" title=""></a>Step 2: Tell Laravel to Use the New Notification</h2>
<p>Next, we need to update the <code>User</code> model to use our new <code>QueueableVerifyEmail</code> class instead of the default <code>VerifyEmail</code> notification.</p>
<p>Open <code>app/Models/User.php</code> and override the <code>sendEmailVerificationNotification</code> method:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">sendEmailVerificationNotification</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">notify</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> \App\Notifications\</span><span style="color: #E5C07B;">QueueableVerifyEmail</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Now, Laravel will send the verification email using the queued version of the notification.</p>
<h2><a id="step-3-configure-the-queue-system" href="#step-3-configure-the-queue-system" class="" aria-hidden="true" title=""></a>Step 3: Configure the Queue System</h2>
<p>To make sure queued jobs are processed, you need to configure Laravel’s queue system. If you haven't set up a queue driver yet, update your <code>.env</code> file:</p>
<pre><code data-theme="one-dark-pro" data-lang="env" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">QUEUE_CONNECTION</span><span style="color: #56B6C2;">=</span><span style="color: #98C379;">database</span></div></code></pre>
<p>Then, create the necessary database tables for queued jobs:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">queue:table</span></div><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">migrate</span></div></code></pre>
<p>Finally, start the queue worker:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">queue:listen</span></div></code></pre>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>By following these steps, Laravel will now queue the verification email when a user registers, improving performance by handling email delivery in the background. This simple adjustment can significantly enhance the user experience by making registration faster and more efficient.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Thu, 30 Jan 2025 15:11:04 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Essential Laravel Artisan Commands for Better Deployments]]></title>
                <link>https://nabilhassen.com/essential-laravel-artisan-commands-for-better-deployments</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#introduction">Introduction</a></li>
<li><a href="#1-clearing-cached-files-php-artisan-optimizeclear">1. Clearing Cached Files: php artisan optimize:clear</a></li>
<li><a href="#2-optimizing-the-application-php-artisan-optimize">2. Optimizing the Application: php artisan optimize</a></li>
<li><a href="#3-restarting-queued-jobs-php-artisan-queuerestart">3. Restarting Queued Jobs: php artisan queue:restart</a></li>
<li><a href="#4-interrupting-scheduled-tasks-php-artisan-scheduleinterrupt">4. Interrupting Scheduled Tasks: php artisan schedule:interrupt</a></li>
<li><a href="#5-clearing-scheduled-task-cache-php-artisan-scheduleclear-cache">5. Clearing Scheduled Task Cache: php artisan schedule:clear-cache</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="introduction" href="#introduction" class="" aria-hidden="true" title=""></a>Introduction</h2>
<p>Deploying a Laravel application involves several steps to ensure it performs optimally in a production environment. Laravel’s Artisan command-line tool offers powerful commands that simplify this process. In this blog post, we’ll explore five essential Artisan commands that should be part of every deployment workflow: <code>optimize:clear</code>, <code>optimize</code>, <code>queue:restart</code>, <code>schedule:interrupt</code>, and <code>schedule:clear-cache</code>.</p>
<h2><a id="1-clearing-cached-files-php-artisan-optimizeclear" href="#1-clearing-cached-files-php-artisan-optimizeclear" class="" aria-hidden="true" title=""></a>1. <strong>Clearing Cached Files: <code>php artisan optimize:clear</code></strong></h2>
<p>The <code>optimize:clear</code> command is essential for removing all cached data from your application, including configuration files, routes, compiled views, and more. During deployment, clearing these cached files ensures that your application doesn’t rely on outdated or invalid data.</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">optimize:clear</span></div></code></pre>
<p>This command ensures a clean slate for your application, reducing the risk of errors caused by stale or mismatched cache files.</p>
<h2><a id="2-optimizing-the-application-php-artisan-optimize" href="#2-optimizing-the-application-php-artisan-optimize" class="" aria-hidden="true" title=""></a>2. <strong>Optimizing the Application: <code>php artisan optimize</code></strong></h2>
<p>The <code>optimize</code> command is used to improve your application’s performance by caching critical files like configuration, routes, and events. This reduces runtime overhead and makes your application faster in production.</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">optimize</span></div></code></pre>
<p>By running this command during deployment, you ensure that the application loads these files efficiently, minimizing startup time and improving overall performance.</p>
<h2><a id="3-restarting-queued-jobs-php-artisan-queuerestart" href="#3-restarting-queued-jobs-php-artisan-queuerestart" class="" aria-hidden="true" title=""></a>3. <strong>Restarting Queued Jobs: <code>php artisan queue:restart</code></strong></h2>
<p>The <code>queue:restart</code> command ensures that your application’s queue workers reload the latest version of the codebase after deployment. This is especially important if you’ve made changes to the code that processes jobs.</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">queue:restart</span></div></code></pre>
<p>When executed, this command gracefully stops all running queue workers and automatically restarts them. Importantly, it does so without losing any jobs that are currently in the queue.</p>
<h2><a id="4-interrupting-scheduled-tasks-php-artisan-scheduleinterrupt" href="#4-interrupting-scheduled-tasks-php-artisan-scheduleinterrupt" class="" aria-hidden="true" title=""></a>4. <strong>Interrupting Scheduled Tasks: <code>php artisan schedule:interrupt</code></strong></h2>
<p>The <code>schedule:interrupt</code> command is used to safely interrupt any long-running or in-progress scheduled tasks initiated by the Laravel scheduler. This is particularly useful during deployments to prevent conflicts or overlapping tasks.</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">schedule:interrupt</span></div></code></pre>
<p>By running this command, you ensure that any ongoing tasks are halted gracefully, allowing the deployment process to proceed without risking task interference or duplication.</p>
<h2><a id="5-clearing-scheduled-task-cache-php-artisan-scheduleclear-cache" href="#5-clearing-scheduled-task-cache-php-artisan-scheduleclear-cache" class="" aria-hidden="true" title=""></a>5. <strong>Clearing Scheduled Task Cache: <code>php artisan schedule:clear-cache</code></strong></h2>
<p>Laravel’s task scheduler uses mutexes (mutual exclusion locks) to prevent tasks from overlapping when the <code>withoutOverlapping</code> method is applied. These mutexes ensure that a task doesn’t start if a previous instance of the task is still running. However, sometimes these mutexes may persist unexpectedly, which can block tasks from running even when they should.</p>
<p>The <code>schedule:clear-cache</code> command clears these mutexes, ensuring that tasks are no longer blocked by stale locks.</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">schedule:clear-cache</span></div></code></pre>
<p>This command is particularly useful during deployments to reset any lingering mutexes, allowing your scheduled tasks to run as expected without unnecessary interruptions or conflicts.</p>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>Incorporating these five Artisan commands into your deployment workflow ensures your Laravel application runs smoothly and efficiently in production. Here’s a quick summary of their purposes:</p>
<ol>
<li><strong><code>optimize:clear</code></strong>: Removes all cached files, preventing reliance on outdated or invalid data.</li>
<li><strong><code>optimize</code></strong>: Caches configuration, routes, and events for improved performance.</li>
<li><strong><code>queue:restart</code></strong>: Gracefully restarts queue workers to ensure they use the latest code.</li>
<li><strong><code>schedule:interrupt</code></strong>: Halts in-progress scheduled tasks safely to prevent overlaps during deployments.</li>
<li><strong><code>schedule:clear-cache</code></strong>: Clears stale mutexes to ensure scheduled tasks run without unnecessary blocking.</li>
</ol>
<p>By including these commands in your deployment process, you can enhance your application’s reliability, performance, and user experience.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 28 Jan 2025 07:22:47 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Simplified Grouped Aggregates in Laravel Query Builder]]></title>
                <link>https://nabilhassen.com/simplified-grouped-aggregates-in-laravel-query-builder</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#new-in-laravel-aggregate-by-group">New in Laravel: Aggregate By Group</a></li>
<li><a href="#understanding-the-problem">Understanding the Problem</a></li>
<li><a href="#introducing-grouped-aggregate-methods">Introducing Grouped Aggregate Methods</a>
<ul>
<li><a href="#example-usage">Example Usage</a></li>
<li><a href="#a-closer-look-at-each-method">A Closer Look at Each Method</a></li>
</ul>
</li>
</ul>
<p><strong>IMPORTANT NOTE</strong>: THIS PULL REQUEST WAS REVERTED ONCE AGAIN BECAUSE OF BREAKING CHANGES.</p>
<h2><a id="new-in-laravel-aggregate-by-group" href="#new-in-laravel-aggregate-by-group" class="" aria-hidden="true" title=""></a>New in Laravel: Aggregate By Group</h2>
<p>Introducing grouped aggregate methods, a noteworthy enhancement to Laravel's database query builder with <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/53679">Pull Request #53679</a>, contributed by <a rel="nofollow noopener" target="_blank" href="https://twitter.com/GromNaN">GromNaN</a>. This update adds new methods for performing grouped aggregate calculations, making database queries cleaner, more expressive, and easier to maintain.</p>
<h2><a id="understanding-the-problem" href="#understanding-the-problem" class="" aria-hidden="true" title=""></a>Understanding the Problem</h2>
<p>Before this update, performing aggregate operations like <code>count</code>, <code>sum</code>, <code>min</code>, <code>max</code>, and <code>avg</code> required a combination of <code>groupBy</code> and raw expressions. While effective, this approach was often verbose and less intuitive. For developers working on large or complex applications, such queries could quickly become error-prone and harder to read.</p>
<p>Consider this example:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$salesByCategory</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;sales&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">select</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;category_id&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">raw</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;SUM(amount) as total_sales&#39;</span><span style="color: #ABB2BF;">))</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">groupBy</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;category_id&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>While functional, this code involves raw expressions and manual grouping, which might confuse newcomers or lead to maintenance challenges.</p>
<h2><a id="introducing-grouped-aggregate-methods" href="#introducing-grouped-aggregate-methods" class="" aria-hidden="true" title=""></a>Introducing Grouped Aggregate Methods</h2>
<p>With the new methods, Laravel simplifies grouped aggregate operations by introducing the following:</p>
<ul>
<li><code>countByGroup</code></li>
<li><code>minByGroup</code></li>
<li><code>maxByGroup</code></li>
<li><code>sumByGroup</code></li>
<li><code>avgByGroup</code></li>
</ul>
<p>These methods streamline database queries by abstracting common patterns into expressive, reusable methods.</p>
<h3><a id="example-usage" href="#example-usage" class="" aria-hidden="true" title=""></a>Example Usage</h3>
<p>Here’s how you can rewrite the previous example using the new <code>sumByGroup</code> method:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$salesByCategory</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;sales&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">        -&gt;</span><span style="color: #61AFEF;">groupBy</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;category_id&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">sumByGroup</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;amount&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>This single line of code performs the same operation but is more readable and less prone to errors. It communicates intent clearly, adhering to Laravel's philosophy of elegant syntax.</p>
<h3><a id="a-closer-look-at-each-method" href="#a-closer-look-at-each-method" class="" aria-hidden="true" title=""></a>A Closer Look at Each Method</h3>
<ol>
<li>
<p><strong><code>countByGroup</code></strong>: Counts the number of records in each group.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$counts</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">groupBy</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;status&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">countByGroup</span><span style="color: #ABB2BF;">();</span></div></code></pre>
</li>
<li>
<p><strong><code>minByGroup</code></strong>: Finds the minimum value in each group.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$minSalaries</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;employees&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">groupBy</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;department_id&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">minByGroup</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;salary&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
</li>
<li>
<p><strong><code>maxByGroup</code></strong>: Determines the maximum value in each group.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$maxPrices</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;products&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">groupBy</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;category_id&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">maxByGroup</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;price&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
</li>
<li>
<p><strong><code>sumByGroup</code></strong>: Calculates the sum of values in each group.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$totalSales</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;orders&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">groupBy</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;region_id&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">sumByGroup</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;amount&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
</li>
<li>
<p><strong><code>avgByGroup</code></strong>: Computes the average value for each group.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$avgRatings</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;reviews&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">groupBy</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;product_id&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">avgByGroup</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;rating&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
</li>
</ol>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Sat, 25 Jan 2025 14:08:20 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Middleware Support for Specific Methods in Laravel 11.38]]></title>
                <link>https://nabilhassen.com/middleware-support-for-specific-methods-in-laravel-1138</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#examples-of-middlewarefor-and-withoutmiddlewarefor">Examples of middlewareFor and withoutMiddlewareFor</a>
<ul>
<li><a href="#example-1-applying-middleware-with-middlewarefor">Example 1: Applying Middleware with middlewareFor</a></li>
<li><a href="#example-2-applying-middleware-to-singleton-routes">Example 2: Applying Middleware to Singleton Routes</a></li>
<li><a href="#example-3-removing-middleware-with-withoutmiddlewarefor">Example 3: Removing Middleware with withoutMiddlewareFor</a></li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<p>In Laravel 11.38, the framework introduces two new methods, <code>middlewareFor</code> and <code>withoutMiddlewareFor</code>, allowing developers to apply or exclude middleware for specific methods in resource and singleton routes. This feature, proposed by <a rel="nofollow noopener" target="_blank" href="https://x.com/MrPunyapal">MrPunyapal</a> in <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/53313">Pull Request #53313</a>, adds precision to middleware assignment.</p>
<h2><a id="examples-of-middlewarefor-and-withoutmiddlewarefor" href="#examples-of-middlewarefor-and-withoutmiddlewarefor" class="" aria-hidden="true" title=""></a>Examples of <code>middlewareFor</code> and <code>withoutMiddlewareFor</code></h2>
<p>Below are the examples showcasing how to use these methods.</p>
<h3><a id="example-1-applying-middleware-with-middlewarefor" href="#example-1-applying-middleware-with-middlewarefor" class="" aria-hidden="true" title=""></a>Example 1: Applying Middleware with <code>middlewareFor</code></h3>
<p>You can assign middleware to specific methods within a resource route using <code>middlewareFor</code>.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Route</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">Route</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">resource</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">UserController</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">        -&gt;</span><span style="color: #61AFEF;">middlewareFor</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;show&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;auth&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">Route</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">apiResource</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">UserController</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">        -&gt;</span><span style="color: #61AFEF;">middlewareFor</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;show&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;update&#39;</span><span style="color: #ABB2BF;">], </span><span style="color: #98C379;">&#39;auth&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">Route</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">resource</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">UserController</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">middlewareFor</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;show&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;auth&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">middlewareFor</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;update&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;auth&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">Route</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">apiResource</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">UserController</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">middlewareFor</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;show&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;update&#39;</span><span style="color: #ABB2BF;">], [</span><span style="color: #98C379;">&#39;auth&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;verified&#39;</span><span style="color: #ABB2BF;">]);</span></div></code></pre>
<h3><a id="example-2-applying-middleware-to-singleton-routes" href="#example-2-applying-middleware-to-singleton-routes" class="" aria-hidden="true" title=""></a>Example 2: Applying Middleware to Singleton Routes</h3>
<p>The <code>middlewareFor</code> method works seamlessly with singleton routes as well.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Route</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">Route</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">singleton</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">UserController</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">        -&gt;</span><span style="color: #61AFEF;">middlewareFor</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;show&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;auth&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">Route</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">apiSingleton</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">UserController</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">        -&gt;</span><span style="color: #61AFEF;">middlewareFor</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;show&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;update&#39;</span><span style="color: #ABB2BF;">], </span><span style="color: #98C379;">&#39;auth&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">Route</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">singleton</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">UserController</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">middlewareFor</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;show&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;auth&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">middlewareFor</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;update&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;auth&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">Route</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">apiSingleton</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">UserController</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">middlewareFor</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;show&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;update&#39;</span><span style="color: #ABB2BF;">], [</span><span style="color: #98C379;">&#39;auth&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;verified&#39;</span><span style="color: #ABB2BF;">]);</span></div></code></pre>
<h3><a id="example-3-removing-middleware-with-withoutmiddlewarefor" href="#example-3-removing-middleware-with-withoutmiddlewarefor" class="" aria-hidden="true" title=""></a>Example 3: Removing Middleware with <code>withoutMiddlewareFor</code></h3>
<p>The <code>withoutMiddlewareFor</code> method excludes middleware from specific methods.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Route</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">Route</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">middleware</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;auth&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;verified&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;other&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">group</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> () {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E5C07B;">Route</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">resource</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">UsersController</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">withoutMiddlewareFor</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;create&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;store&#39;</span><span style="color: #ABB2BF;">], </span><span style="color: #98C379;">&#39;verified&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">        -&gt;</span><span style="color: #61AFEF;">withoutMiddlewareFor</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;index&#39;</span><span style="color: #ABB2BF;">, [</span><span style="color: #98C379;">&#39;auth&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;verified&#39;</span><span style="color: #ABB2BF;">])</span></div><div class='line'><span style="color: #ABB2BF;">        -&gt;</span><span style="color: #61AFEF;">withoutMiddlewareFor</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;destroy&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;other&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E5C07B;">Route</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">singleton</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;user&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">UserController</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">withoutMiddlewareFor</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;show&#39;</span><span style="color: #ABB2BF;">, [</span><span style="color: #98C379;">&#39;auth&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;verified&#39;</span><span style="color: #ABB2BF;">])</span></div><div class='line'><span style="color: #ABB2BF;">        -&gt;</span><span style="color: #61AFEF;">withoutMiddlewareFor</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;create&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;store&#39;</span><span style="color: #ABB2BF;">], </span><span style="color: #98C379;">&#39;verified&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">        -&gt;</span><span style="color: #61AFEF;">withoutMiddlewareFor</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;destroy&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;other&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div></code></pre>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>The new <code>middlewareFor</code> and <code>withoutMiddlewareFor</code> methods in Laravel 11.38 simplify the process of managing middleware for individual methods in resource and singleton routes. These features provide flexibility and precision in middleware assignment, enhancing the developer experience.</p>
<p>This feature is available starting in Laravel 11.38. For more details, check out the <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/53313">official pull request</a>.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Mon, 20 Jan 2025 07:52:13 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[New --except Option for Optimize Commands in Laravel 11.38]]></title>
                <link>https://nabilhassen.com/new-except-option-for-optimize-commands-in-laravel-1138</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#customizing-artisan-commands-with-the-new---except-option-in-laravel">Customizing Artisan Commands with the New --except Option in Laravel</a></li>
<li><a href="#understanding-the-problem">Understanding the Problem</a></li>
<li><a href="#the-new---except-option">The New --except Option</a>
<ul>
<li><a href="#examples">Examples</a></li>
<li><a href="#laravel-vapor-use-case">Laravel Vapor Use Case</a></li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="customizing-artisan-commands-with-the-new---except-option-in-laravel" href="#customizing-artisan-commands-with-the-new---except-option-in-laravel" class="" aria-hidden="true" title=""></a>Customizing Artisan Commands with the New <code>--except</code> Option in Laravel</h2>
<p>When managing Laravel applications, the <code>optimize</code> and <code>optimize:clear</code> Artisan commands play a crucial role in boosting performance and streamlining deployments. However, these commands have historically lacked flexibility, as they execute all optimization tasks without exception. With the latest improvement in Laravel’s framework (introduced in <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/54070">Pull Request #54070</a> by <a rel="nofollow noopener" target="_blank" href="https://github.com/jonerickson">Jon Erickson</a>), developers now have greater control over these commands with the addition of the <code>--except</code> option.</p>
<p>In this post, we’ll explore what this new feature brings to the table and how it solves challenges faced by developers during application optimization.</p>
<h2><a id="understanding-the-problem" href="#understanding-the-problem" class="" aria-hidden="true" title=""></a>Understanding the Problem</h2>
<p>Laravel’s <code>optimize</code> and <code>optimize:clear</code> commands are designed to enhance application performance by caching configurations, routes, views, and events. However, executing all these tasks together isn’t always necessary or desirable as highlighted in <a rel="nofollow noopener" target="_blank" href="https://nabilhassen.com/php-artisan-cacheclear-what-it-does-and-what-it-does-not">php artisan cache:clear - What it DOES and what it does NOT?
</a> article. Previously, there was no built-in way to exclude specific tasks from the optimization process. Developers often resorted to workarounds or manual cache management, adding complexity to deployment pipelines.</p>
<h2><a id="the-new---except-option" href="#the-new---except-option" class="" aria-hidden="true" title=""></a>The New <code>--except</code> Option</h2>
<p>The <code>--except</code> option introduces a straightforward and elegant solution to this problem. Available in both the <code>optimize</code> and <code>optimize:clear</code> commands, this feature allows developers to exclude specific optimization tasks with a simple flag.</p>
<h3><a id="examples" href="#examples" class="" aria-hidden="true" title=""></a>Examples</h3>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;"># skip events and views caching</span></div><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">optimize</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--except=events,views</span></div></code></pre>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;"># skip routes cache clearing</span></div><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">optimize:clear</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--except=routes</span></div></code></pre>
<h3><a id="laravel-vapor-use-case" href="#laravel-vapor-use-case" class="" aria-hidden="true" title=""></a>Laravel Vapor Use Case</h3>
<p>In applications deployed on Laravel Vapor, <code>route</code> caching is unsupported. By leveraging the <code>--except</code> option, now you can utilize the optimize command without triggering unsupported operations like <code>route:cache</code>.</p>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>The addition of the <code>--except</code> option to Laravel’s <code>optimize</code> and <code>optimize:clear</code> commands is a welcome enhancement that empowers developers to take greater control over application optimization. Whether you’re working on a local development environment or deploying to production, this feature simplifies workflows and ensures a more efficient process.</p>
<p>To start using this feature, make sure you’re running Laravel version 11.28 or higher. For more details, check out the official pull request <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/54070">here</a>.</p>
<p>Happy optimizing!</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Fri, 17 Jan 2025 20:34:06 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[3 Simple Ways to Use Eloquent Model Events in Laravel]]></title>
                <link>https://nabilhassen.com/3-simple-ways-to-use-eloquent-model-events-in-laravel</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#what-are-eloquent-model-events-in-laravel">What Are Eloquent Model Events in Laravel?</a></li>
<li><a href="#available-eloquent-model-events">Available Eloquent Model Events</a></li>
<li><a href="#how-to-use-eloquent-model-events">How to Use Eloquent Model Events</a>
<ul>
<li><a href="#1-using-the-dispatchesevents-property">1. Using the $dispatchesEvents Property</a></li>
<li><a href="#2-using-closures">2. Using Closures</a></li>
<li><a href="#3-using-observers">3. Using Observers</a></li>
</ul>
</li>
<li><a href="#practical-use-cases-for-model-events">Practical Use Cases for Model Events</a></li>
<li><a href="#best-practices-for-using-model-events">Best Practices for Using Model Events</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<p>Laravel's Eloquent ORM is a powerful tool for interacting with databases. One of its standout features is <strong>model events</strong>, which allow you to respond to specific actions performed on your models. In this blog post, we'll explore what Eloquent model events are, how to use them, and practical use cases—all in simple, beginner-friendly language.</p>
<h2><a id="what-are-eloquent-model-events-in-laravel" href="#what-are-eloquent-model-events-in-laravel" class="" aria-hidden="true" title=""></a>What Are Eloquent Model Events in Laravel?</h2>
<p>Eloquent model events let you execute code when certain actions happen to your models. For example, you can trigger specific logic when:</p>
<ul>
<li>A record is created or updated.</li>
<li>A record is deleted or restored.</li>
<li>A record is fetched from the database.</li>
</ul>
<p>These events help automate tasks such as logging, validating data, sending notifications, and more. Think of them as hooks you can use to tie additional functionality to the lifecycle of your database records.</p>
<h2><a id="available-eloquent-model-events" href="#available-eloquent-model-events" class="" aria-hidden="true" title=""></a>Available Eloquent Model Events</h2>
<p>Laravel provides events for various stages of a model's lifecycle:</p>
<ul>
<li><strong>retrieved</strong>: Triggered when a record is fetched from the database.</li>
<li><strong>creating</strong>: Triggered before a new record is inserted into the database.</li>
<li><strong>created</strong>: Triggered after a new record has been inserted.</li>
<li><strong>updating</strong>: Triggered before an existing record is updated.</li>
<li><strong>updated</strong>: Triggered after an existing record is updated.</li>
<li><strong>saving</strong>: Triggered before a record is saved (this applies to both creating and updating).</li>
<li><strong>saved</strong>: Triggered after a record is saved (this applies to both creating and updating).</li>
<li><strong>deleting</strong>: Triggered before a record is deleted.</li>
<li><strong>deleted</strong>: Triggered after a record is deleted.</li>
<li><strong>restoring</strong>: Triggered before a soft-deleted record is restored.</li>
<li><strong>restored</strong>: Triggered after a soft-deleted record is restored.</li>
</ul>
<p>These events give you full control over your model's behavior at each stage of its lifecycle.</p>
<h2><a id="how-to-use-eloquent-model-events" href="#how-to-use-eloquent-model-events" class="" aria-hidden="true" title=""></a>How to Use Eloquent Model Events</h2>
<p>There are three main methods to handle Eloquent model events: using the <code>$dispatchesEvents</code> property, closures, and observers.</p>
<h3><a id="1-using-the-dispatchesevents-property" href="#1-using-the-dispatchesevents-property" class="" aria-hidden="true" title=""></a>1. Using the <code>$dispatchesEvents</code> Property</h3>
<p>Laravel allows you to map model events to custom event classes using the <code>$dispatchesEvents</code> property within your model. This approach is beneficial when you want to encapsulate event handling logic in separate classes, promoting cleaner and more maintainable code. It is important to note that for the events mapped here, you should define <strong>event listeners</strong> to handle the dispatched events.</p>
<p>Here's how you can define it:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Events\</span><span style="color: #E5C07B;">UserCreated</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\</span><span style="color: #E5C07B;">Model</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Model</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$dispatchesEvents</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;created&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E5C07B;">UserCreated</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ];</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>In this example:</p>
<ul>
<li>When a new <code>User</code> model is created, the <code>UserCreated</code> event is dispatched automatically. You should also create an event listener for <code>UserCreated</code> to handle the logic associated with this event.</li>
</ul>
<h3><a id="2-using-closures" href="#2-using-closures" class="" aria-hidden="true" title=""></a>2. Using Closures</h3>
<p>For straightforward event handling, you can define closures directly within your model's <code>booted</code> method. This method is ideal for simple logic that doesn't necessitate a separate event class.</p>
<p>Example:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\</span><span style="color: #E5C07B;">Model</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Model</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">static</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">booted</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">static</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">created</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #7F848E;">// Logic to execute after a user is created</span></div><div class='line'><span style="color: #ABB2BF;">        });</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>In this setup:</p>
<ul>
<li>The closure within <code>static::created</code> executes immediately after a new user is created.</li>
</ul>
<h3><a id="3-using-observers" href="#3-using-observers" class="" aria-hidden="true" title=""></a>3. Using Observers</h3>
<p>Observers allow you to group all your event handling logic into a single class, enhancing organization, especially when dealing with multiple events or models.</p>
<ul>
<li><strong>Defining an Observer</strong></li>
</ul>
<p>You can create an observer using the Artisan command:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">make:observer</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">UserObserver</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--model=User</span></div></code></pre>
<p>This command generates an <code>UserObserver</code> class:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">namespace</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">App\Observers</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Models\</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">UserObserver</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">creating</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">username</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">strtolower</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">username</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">updating</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">isDirty</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;email&#39;</span><span style="color: #ABB2BF;">)) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #7F848E;">// Handle email changes</span></div><div class='line'><span style="color: #ABB2BF;">        }</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<ul>
<li><strong>Registering Observers</strong></li>
</ul>
<p>There are two primary methods to register observers:</p>
<p><strong>a. In <code>AppServiceProvider</code>:</strong></p>
<p>Within the <code>boot</code> method of your <code>AppServiceProvider</code>, you can register the observer:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Models\</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Observers\</span><span style="color: #E5C07B;">UserObserver</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">boot</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">observe</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">UserObserver</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p><strong>b. As a PHP Attribute:</strong></p>
<p>Alternatively, you can use PHP attributes to register observers directly within your model:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Observers\</span><span style="color: #E5C07B;">UserObserver</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\Attributes\</span><span style="color: #E5C07B;">ObservedBy</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">#[ObservedBy(</span><span style="color: #E5C07B;">UserObserver</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Model</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// Model logic</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>This method offers a concise way to associate observers with models.</p>
<h2><a id="practical-use-cases-for-model-events" href="#practical-use-cases-for-model-events" class="" aria-hidden="true" title=""></a>Practical Use Cases for Model Events</h2>
<p>Here are some scenarios where Eloquent model events shine:</p>
<ol>
<li>
<p><strong>Logging Changes</strong></p>
<ul>
<li>Track changes to important fields like user roles or account statuses.</li>
</ul>
</li>
<li>
<p><strong>Sending Notifications</strong></p>
<ul>
<li>Notify users when their profile is updated or an order status changes.</li>
</ul>
</li>
<li>
<p><strong>Maintaining Data Integrity</strong></p>
<ul>
<li>Automatically delete related records when a parent record is deleted.</li>
</ul>
</li>
<li>
<p><strong>Enforcing Business Rules</strong></p>
<ul>
<li>Prevent certain actions like deleting admin accounts.</li>
</ul>
</li>
</ol>
<h2><a id="best-practices-for-using-model-events" href="#best-practices-for-using-model-events" class="" aria-hidden="true" title=""></a>Best Practices for Using Model Events</h2>
<ol>
<li><strong>Keep Logic Simple</strong>: Avoid putting complex logic in event listeners. Instead, delegate tasks to service classes or jobs.</li>
<li><strong>Test Thoroughly</strong>: Ensure that your event listeners work correctly and don’t introduce bugs.</li>
<li><strong>Be Mindful of Performance</strong>: Long-running tasks in event listeners can slow down your application. Use Laravel’s queue system for such tasks.</li>
</ol>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>Eloquent model events are a powerful way to hook into your models' lifecycle and execute custom logic. Whether you're logging changes, sending notifications, or enforcing rules, model events make your application smarter and more efficient. By using <code>$dispatchesEvents</code>, closures, or observers, you can implement event handling in a way that best suits your application’s needs. Try adding model events to your Laravel project today and see how they simplify your workflow!</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Thu, 09 Jan 2025 08:57:54 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Laravel 11.37.0: New Query Methods for Missing Relationships]]></title>
                <link>https://nabilhassen.com/laravel-11370-new-query-methods-for-missing-relationships</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#new-query-methods-in-laravel-11370-enhancing-relation-queries">New Query Methods in Laravel 11.37.0: Enhancing Relation Queries</a></li>
<li><a href="#the-problem-handling-missing-relationships">The Problem: Handling Missing Relationships</a></li>
<li><a href="#the-solution-new-methods-for-missing-relationships">The Solution: New Methods for Missing Relationships</a>
<ul>
<li><a href="#example-1">Example 1</a></li>
<li><a href="#example-2">Example 2</a></li>
</ul>
</li>
<li><a href="#or-variants">OR Variants</a></li>
<li><a href="#supported-versions">Supported Versions</a></li>
</ul>
<h2><a id="new-query-methods-in-laravel-11370-enhancing-relation-queries" href="#new-query-methods-in-laravel-11370-enhancing-relation-queries" class="" aria-hidden="true" title=""></a>New Query Methods in Laravel 11.37.0: Enhancing Relation Queries</h2>
<p>Laravel has introduced another powerful enhancement to Eloquent in its latest <strong>11.37.0</strong> release. Thanks to a contribution by <a rel="nofollow noopener" target="_blank" href="https://github.com/andrey-helldar"><strong>Andrey Helldar</strong></a>, developers can now use the new <code>whereDoesntHaveRelation</code> and <code>whereMorphDoesntHaveRelation</code> methods to simplify queries involving relationships.</p>
<p>These additions make it significantly easier to retrieve models that <em>do not</em> have a specific relationship, providing a cleaner, more intuitive approach compared to previous workarounds.</p>
<h2><a id="the-problem-handling-missing-relationships" href="#the-problem-handling-missing-relationships" class="" aria-hidden="true" title=""></a>The Problem: Handling Missing Relationships</h2>
<p>Before this update, Laravel provided methods such as <code>whereDoesntHave</code> and <code>whereDoesntHaveMorph</code> for querying models with specific relationships. However, developers often needed verbose and complex logic to query models that lacked a relationship.</p>
<h2><a id="the-solution-new-methods-for-missing-relationships" href="#the-solution-new-methods-for-missing-relationships" class="" aria-hidden="true" title=""></a>The Solution: New Methods for Missing Relationships</h2>
<p>The <code>whereDoesntHaveRelation</code> and <code>whereMorphDoesntHaveRelation</code> methods address this gap by introducing a simple way to query models missing specific relationships.</p>
<h3><a id="example-1" href="#example-1" class="" aria-hidden="true" title=""></a>Example 1</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// Before</span></div><div class='line'><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereDoesntHave</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;comments&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$query</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$query</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">where</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;created_at&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;&gt;&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #61AFEF;">now</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">subDay</span><span style="color: #ABB2BF;">());</span></div><div class='line'><span style="color: #ABB2BF;">})-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// After</span></div><div class='line'><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereDoesntHaveRelation</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;comments&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;created_at&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;&gt;&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #61AFEF;">now</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">subDay</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereDoesntHaveRelation</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;comments&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;is_approved&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">false</span></div><div class='line'><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h3><a id="example-2" href="#example-2" class="" aria-hidden="true" title=""></a>Example 2</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// Before</span></div><div class='line'><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereDoesntHaveMorph</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;comments&#39;</span><span style="color: #ABB2BF;">, [</span><span style="color: #E5C07B;">Post</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">Video</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">], </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$query</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$query</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">where</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;created_at&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;&gt;&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #61AFEF;">now</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">subDay</span><span style="color: #ABB2BF;">());</span></div><div class='line'><span style="color: #ABB2BF;">})-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// After</span></div><div class='line'><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereMorphDoesntHaveRelation</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;comments&#39;</span><span style="color: #ABB2BF;">, [</span><span style="color: #E5C07B;">Post</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">Video</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">], </span><span style="color: #98C379;">&#39;created_at&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;&gt;&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #61AFEF;">now</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">subDay</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereMorphDoesntHaveRelation</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;comments&#39;</span><span style="color: #ABB2BF;">, [</span><span style="color: #E5C07B;">Post</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">Video</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">], </span><span style="color: #98C379;">&#39;is_approved&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">false</span></div><div class='line'><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h2><a id="or-variants" href="#or-variants" class="" aria-hidden="true" title=""></a>OR Variants</h2>
<p>In addition to these methods, Laravel also introduces their <code>OR</code> variants:</p>
<ul>
<li><code>orWhereDoesntHaveRelation</code></li>
<li><code>orWhereMorphDoesntHaveRelation</code></li>
</ul>
<p>These methods allow you to combine &quot;doesn't have relation&quot; queries with other conditions for more complex use cases.</p>
<h2><a id="supported-versions" href="#supported-versions" class="" aria-hidden="true" title=""></a>Supported Versions</h2>
<p>This feature is available starting with <strong>Laravel 11.37.0</strong>, further solidifying the framework’s focus on developer experience and clean, maintainable code. To explore the technical details, visit the <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/53996">GitHub pull request</a>.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 07 Jan 2025 07:22:31 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[How Laravel Context Works with Jobs]]></title>
                <link>https://nabilhassen.com/how-laravel-context-works-with-jobs</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#a-guide-to-using-laravel-context-to-add-more-information-to-jobs">A Guide to Using Laravel Context to Add More Information to Jobs</a></li>
<li><a href="#how-laravel-context-works-with-jobs">How Laravel Context Works with Jobs</a>
<ul>
<li><a href="#1-adding-context-to-a-request">1. Adding Context to a Request</a></li>
<li><a href="#2-dispatching-a-job-with-context">2. Dispatching a Job with Context</a></li>
<li><a href="#3-accessing-context-in-the-job">3. Accessing Context in the Job</a></li>
</ul>
</li>
<li><a href="#practical-benefits-of-using-context-with-jobs">Practical Benefits of Using Context with Jobs</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="a-guide-to-using-laravel-context-to-add-more-information-to-jobs" href="#a-guide-to-using-laravel-context-to-add-more-information-to-jobs" class="" aria-hidden="true" title=""></a>A Guide to Using Laravel Context to Add More Information to Jobs</h2>
<p>Laravel’s <strong>Context</strong> feature provides an excellent way to capture and share metadata throughout requests, jobs, and commands within an application. This allows you to track important information like user IDs, URLs, or trace IDs, and automatically inject that information into logs and jobs. This can be invaluable for debugging, monitoring, and tracing the flow of data across distributed systems.</p>
<p>In this guide, we’ll focus on how Laravel’s context feature allows you to add more information to jobs, making it easier to trace and debug background processes.</p>
<h2><a id="how-laravel-context-works-with-jobs" href="#how-laravel-context-works-with-jobs" class="" aria-hidden="true" title=""></a>How Laravel Context Works with Jobs</h2>
<p>Laravel’s context functionality works by capturing data within a <strong>context</strong> and then associating that data with specific jobs or actions in your application. When a job is dispatched, the context data is automatically shared with that job. This means that any information in the context is available to the job during its execution.</p>
<p>Let’s break it down with an example.</p>
<h3><a id="1-adding-context-to-a-request" href="#1-adding-context-to-a-request" class="" aria-hidden="true" title=""></a>1. Adding Context to a Request</h3>
<p>First, we’ll capture some information during an incoming request using middleware. This is where we’ll store data that will be later passed on to jobs when they are dispatched.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">namespace</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">App\Http\Middleware</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Closure</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Http\</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Context</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\</span><span style="color: #E5C07B;">Str</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Symfony\Component\HttpFoundation\</span><span style="color: #E5C07B;">Response</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">AddContext</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">/**</span></div><div class='line'><span style="color: #7F848E;">     * Handle an incoming request.</span></div><div class='line'><span style="color: #7F848E;">     */</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">handle</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">Closure</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$next</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">Response</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// Add URL and trace ID to the context</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Context</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">add</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;url&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">url</span><span style="color: #ABB2BF;">());</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Context</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">add</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;trace_id&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">Str</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">uuid</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">toString</span><span style="color: #ABB2BF;">());</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$next</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>In the above middleware, we’re adding the request URL and a unique trace ID to the context on every incoming request.</p>
<h3><a id="2-dispatching-a-job-with-context" href="#2-dispatching-a-job-with-context" class="" aria-hidden="true" title=""></a>2. Dispatching a Job with Context</h3>
<p>Once the context is added, you can dispatch a job as you normally would. The context data will automatically be passed along with the job:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// In our controller...</span></div><div class='line'><span style="color: #E5C07B;">ProcessPodcast</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">dispatch</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$podcast</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>The context information that was added during the request will be included when the job is dispatched. Laravel will automatically handle the <strong>dehydration</strong> (capturing context) and <strong>hydration</strong> (restoring context) of this information.</p>
<h3><a id="3-accessing-context-in-the-job" href="#3-accessing-context-in-the-job" class="" aria-hidden="true" title=""></a>3. Accessing Context in the Job</h3>
<p>Inside the job, the context data is available just like it was during the request. Here's how you can access the context within the job's <code>handle()</code> method:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Log</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">ProcessPodcast</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">implements</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">ShouldQueue</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Queueable</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// ...</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">/**</span></div><div class='line'><span style="color: #7F848E;">     * Execute the job.</span></div><div class='line'><span style="color: #7F848E;">     */</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">handle</span><span style="color: #ABB2BF;">(): </span><span style="color: #E5C07B;">void</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Log</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">info</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;Processing podcast.&#39;</span><span style="color: #ABB2BF;">, [</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #98C379;">&#39;podcast_id&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">podcast</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">id</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        ]);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// Job logic</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>When the job executes, Laravel automatically includes the context information that was captured during the request. The resulting log entry might look like this:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">Processing podcast. {&quot;podcast_id&quot;:95} {&quot;url&quot;:&quot;https://example.com/login&quot;,&quot;trace_id&quot;:&quot;e04e1a11-e75c-4db3-b5b5-cfef4ef56697&quot;}</span></div></code></pre>
<p>This log includes both the job-specific data (<code>podcast_id</code>) and the context data (<code>url</code> and <code>trace_id</code>), which allows you to trace the request and job execution together seamlessly.</p>
<h2><a id="practical-benefits-of-using-context-with-jobs" href="#practical-benefits-of-using-context-with-jobs" class="" aria-hidden="true" title=""></a>Practical Benefits of Using Context with Jobs</h2>
<ol>
<li>
<p><strong>Improved Traceability</strong>: By automatically sharing context with jobs, you can track the flow of requests through background processes and understand how different actions are interconnected.</p>
</li>
<li>
<p><strong>Better Debugging</strong>: Having access to context in your logs and jobs makes it easier to debug issues, as you have more insight into the environment and data surrounding each job execution.</p>
</li>
<li>
<p><strong>Seamless Monitoring</strong>: Context information makes it easier to monitor the health and performance of your jobs, as you can correlate logs and job executions using consistent metadata like trace IDs.</p>
</li>
</ol>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>Laravel’s <strong>Context</strong> feature offers an efficient way to add and manage metadata within your jobs. By automatically sharing context data during the lifecycle of a job, you can enhance the traceability, debugging, and monitoring of background tasks. Whether you need to pass along simple information like URLs or more complex data such as trace IDs, Laravel’s context capabilities ensure that all the relevant details are available wherever you need them.</p>
<p>Start using Laravel Context today to gain better insights into your job executions and improve your application’s robustness!</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Thu, 02 Jan 2025 12:01:32 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[How to Create Custom Contextual Attributes in Laravel]]></title>
                <link>https://nabilhassen.com/how-to-create-custom-contextual-attributes-in-laravel</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#creating-custom-contextual-attributes-in-laravel">Creating Custom Contextual Attributes in Laravel</a></li>
<li><a href="#what-are-contextual-attributes">What Are Contextual Attributes?</a></li>
<li><a href="#step-by-step-guide-creating-a-custom-contextual-attribute">Step-by-Step Guide: Creating a Custom Contextual Attribute</a>
<ul>
<li><a href="#1-define-the-attribute-class">1. Define the Attribute Class</a></li>
<li><a href="#2-use-the-attribute-in-a-class">2. Use the Attribute in a Class</a></li>
<li><a href="#3-test-the-attribute">3. Test the Attribute</a></li>
</ul>
</li>
<li><a href="#benefits-of-custom-contextual-attributes">Benefits of Custom Contextual Attributes</a></li>
<li><a href="#expanding-the-concept">Expanding the Concept</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="creating-custom-contextual-attributes-in-laravel" href="#creating-custom-contextual-attributes-in-laravel" class="" aria-hidden="true" title=""></a>Creating Custom Contextual Attributes in Laravel</h2>
<p>Laravel’s ability to seamlessly manage dependency injection makes it a developer's dream framework. One of its most powerful features is <strong>contextual attributes</strong>. While Laravel provides several built-in contextual attributes, you can create your own to make your applications even more expressive and flexible.</p>
<p>In this post, we’ll explore how to define custom contextual attributes in Laravel and use them effectively in your application.</p>
<h2><a id="what-are-contextual-attributes" href="#what-are-contextual-attributes" class="" aria-hidden="true" title=""></a>What Are Contextual Attributes?</h2>
<p>Contextual attributes allow you to inject specific values, configurations, or implementations into your classes directly through PHP attributes. They help streamline dependency injection by eliminating the need for manual contextual binding in service providers.</p>
<h2><a id="step-by-step-guide-creating-a-custom-contextual-attribute" href="#step-by-step-guide-creating-a-custom-contextual-attribute" class="" aria-hidden="true" title=""></a>Step-by-Step Guide: Creating a Custom Contextual Attribute</h2>
<p>Let’s re-create the <code>Config</code> custom attribute to inject configuration values, similar to Laravel’s built-in <code>#[Config]</code> attribute.</p>
<h3><a id="1-define-the-attribute-class" href="#1-define-the-attribute-class" class="" aria-hidden="true" title=""></a>1. Define the Attribute Class</h3>
<p>Laravel requires custom attributes to implement the <code>Illuminate\Contracts\Container\ContextualAttribute</code> interface. This ensures that the container can handle them properly.</p>
<p>Here’s the custom <code>#[AppConfig]</code> attribute:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">namespace</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">App\Attributes</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Attribute</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Contracts\Container\</span><span style="color: #E5C07B;">Container</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Contracts\Container\</span><span style="color: #E5C07B;">ContextualAttribute</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">#[Attribute(</span><span style="color: #E5C07B;">Attribute</span><span style="color: #ABB2BF;">::</span><span style="color: #D19A66;">TARGET_PARAMETER</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">AppConfig</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">implements</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">ContextualAttribute</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">__construct</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">string</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$key</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">mixed</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$default</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">null</span></div><div class='line'><span style="color: #ABB2BF;">    ) {}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">static</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">resolve</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">self</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$attribute</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">Container</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$container</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$container</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">make</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;config&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$attribute</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">key</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$attribute</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">default</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p><strong>Explanation:</strong></p>
<ul>
<li><strong>Constructor Parameters</strong>: <code>key</code> specifies the configuration key, and <code>default</code> provides a fallback if the key doesn’t exist.</li>
<li><strong>Resolve Method</strong>: Fetches the configuration value using Laravel's configuration repository (<code>config()</code> helper).</li>
</ul>
<h3><a id="2-use-the-attribute-in-a-class" href="#2-use-the-attribute-in-a-class" class="" aria-hidden="true" title=""></a>2. Use the Attribute in a Class</h3>
<p>Once defined, you can use the custom attribute in any class. Let’s inject a configuration value into a controller.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BE5046;">&lt;?php</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">namespace</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">App\Http\Controllers</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Attributes\</span><span style="color: #E5C07B;">AppConfig</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">ExampleController</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Controller</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">__construct</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">        #[AppConfig(</span><span style="color: #98C379;">&#39;app.name&#39;</span><span style="color: #ABB2BF;">)] </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">string</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$appName</span></div><div class='line'><span style="color: #ABB2BF;">    ) {}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">show</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;Application Name: {</span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">appName</span><span style="color: #98C379;">}&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Here, <code>#[AppConfig('app.name')]</code> automatically injects the value of the <code>app.name</code> configuration key into the <code>$appName</code> property.</p>
<h3><a id="3-test-the-attribute" href="#3-test-the-attribute" class="" aria-hidden="true" title=""></a>3. Test the Attribute</h3>
<p>To test this:</p>
<ol>
<li>
<p>Ensure your <code>app.name</code> key is set in <code>config/app.php</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;My Laravel App&#39;</span><span style="color: #ABB2BF;">,</span></div></code></pre>
</li>
<li>
<p>Visit the route handling the <code>show</code> method in the <code>ExampleController</code>, and you should see:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">Application Name: My Laravel App</span></div></code></pre>
</li>
</ol>
<h2><a id="benefits-of-custom-contextual-attributes" href="#benefits-of-custom-contextual-attributes" class="" aria-hidden="true" title=""></a>Benefits of Custom Contextual Attributes</h2>
<ul>
<li><strong>Reduce Boilerplate Code</strong>: No need to define bindings in service providers.</li>
<li><strong>Improve Readability</strong>: Attributes make dependencies more explicit.</li>
<li><strong>Encourage Reusability</strong>: Use the same attribute across different parts of your application.</li>
</ul>
<h2><a id="expanding-the-concept" href="#expanding-the-concept" class="" aria-hidden="true" title=""></a>Expanding the Concept</h2>
<p>This approach can be extended to create contextual attributes for other dependencies, such as:</p>
<ul>
<li>Injecting API keys.</li>
<li>Resolving feature flags.</li>
<li>Providing service-specific configurations.</li>
</ul>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>Custom contextual attributes offer a powerful way to simplify dependency injection and enhance the readability of your Laravel applications. By leveraging the <code>ContextualAttribute</code> interface, you can extend Laravel’s functionality to suit your unique project needs.</p>
<p>Try creating your own attributes today and make your Laravel codebase even more elegant and expressive!</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 31 Dec 2024 07:51:09 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[How to Install Laravel and Composer on Windows and Get Started]]></title>
                <link>https://nabilhassen.com/how-to-install-laravel-and-composer-on-windows-and-get-started</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#step-1-install-php-and-composer">Step 1: Install PHP and Composer</a></li>
<li><a href="#step-2-install-the-laravel-installer">Step 2: Install the Laravel Installer</a></li>
<li><a href="#step-3-create-a-new-laravel-application">Step 3: Create a New Laravel Application</a></li>
<li><a href="#step-4-install-nodejs-and-npm">Step 4: Install Node.js and NPM</a></li>
<li><a href="#step-5-set-up-frontend-dependencies">Step 5: Set Up Frontend Dependencies</a></li>
<li><a href="#step-6-build-frontend-assets">Step 6: Build Frontend Assets</a></li>
<li><a href="#step-7-start-the-development-server">Step 7: Start the Development Server</a></li>
<li><a href="#step-8-configure-your-environment">Step 8: Configure Your Environment</a></li>
<li><a href="#step-9-set-up-a-database-optional">Step 9: Set Up a Database (Optional)</a></li>
<li><a href="#youre-all-set">You’re All Set!</a></li>
</ul>
<p>If you’re new to Laravel and web development, getting started might seem overwhelming. But don’t worry—this guide will walk you through the process of installing Laravel 12 on a Windows system step by step. By the end, you’ll have a fully functional Laravel environment ready to build your next project.</p>
<h2><a id="step-1-install-php-and-composer" href="#step-1-install-php-and-composer" class="" aria-hidden="true" title=""></a>Step 1: Install PHP and Composer</h2>
<p>Laravel requires PHP and Composer (a dependency manager for PHP). Thankfully, there’s an easy way to install both:</p>
<ol>
<li>
<p>Open Windows PowerShell with administrator privileges.</p>
</li>
<li>
<p>Run the following command:</p>
<pre><code data-theme="one-dark-pro" data-lang="powershell" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #56B6C2;">Set-ExecutionPolicy</span><span style="color: #ABB2BF;"> Bypass </span><span style="color: #56B6C2;">-</span><span style="color: #ABB2BF;">Scope </span><span style="color: #C678DD;">Process</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">-</span><span style="color: #ABB2BF;">Force; [</span><span style="color: #C678DD;">System.Net.ServicePointManager</span><span style="color: #ABB2BF;">]::SecurityProtocol </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> [</span><span style="color: #C678DD;">System.Net.ServicePointManager</span><span style="color: #ABB2BF;">]::SecurityProtocol </span><span style="color: #56B6C2;">-bor</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">3072</span><span style="color: #ABB2BF;">; iex ((</span><span style="color: #56B6C2;">New-Object</span><span style="color: #ABB2BF;"> System.Net.WebClient).DownloadString(</span><span style="color: #98C379;">&#39;https://php.new/install/windows/8.4&#39;</span><span style="color: #ABB2BF;">))</span></div></code></pre>
<p>This command installs PHP 8.4 and Composer. Restart your terminal after installation to apply the changes.</p>
</li>
</ol>
<h2><a id="step-2-install-the-laravel-installer" href="#step-2-install-the-laravel-installer" class="" aria-hidden="true" title=""></a>Step 2: Install the Laravel Installer</h2>
<p>With Composer installed, you can now globally install the Laravel installer. Run the following command in PowerShell:</p>
<pre><code data-theme="one-dark-pro" data-lang="powershell" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer global require laravel</span><span style="color: #56B6C2;">/</span><span style="color: #ABB2BF;">installer</span></div></code></pre>
<p>This will make the <code>laravel</code> command available globally on your system.</p>
<h2><a id="step-3-create-a-new-laravel-application" href="#step-3-create-a-new-laravel-application" class="" aria-hidden="true" title=""></a>Step 3: Create a New Laravel Application</h2>
<ol>
<li>
<p>Navigate to the folder where you want to create your Laravel project. For example:</p>
<pre><code data-theme="one-dark-pro" data-lang="powershell" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">cd C:\Projects</span></div></code></pre>
</li>
<li>
<p>Create a new Laravel application by running:</p>
<pre><code data-theme="one-dark-pro" data-lang="powershell" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">laravel new example</span><span style="color: #56B6C2;">-</span><span style="color: #ABB2BF;">app</span></div></code></pre>
</li>
<li>
<p>Follow the prompts to configure your project’s testing framework, database, and starter kit.</p>
</li>
</ol>
<h2><a id="step-4-install-nodejs-and-npm" href="#step-4-install-nodejs-and-npm" class="" aria-hidden="true" title=""></a>Step 4: Install Node.js and NPM</h2>
<p>Laravel uses Node.js and NPM to manage frontend assets. Follow these steps:</p>
<ol>
<li>Download and install the latest LTS version of Node.js from <a rel="nofollow noopener" target="_blank" href="https://nodejs.org/en/download">nodejs.org</a>.</li>
<li>During installation, ensure that you select the option to include NPM (Node Package Manager).</li>
</ol>
<h2><a id="step-5-set-up-frontend-dependencies" href="#step-5-set-up-frontend-dependencies" class="" aria-hidden="true" title=""></a>Step 5: Set Up Frontend Dependencies</h2>
<ol>
<li>
<p>Navigate to your project directory:</p>
<pre><code data-theme="one-dark-pro" data-lang="powershell" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">cd example</span><span style="color: #56B6C2;">-</span><span style="color: #ABB2BF;">app</span></div></code></pre>
</li>
<li>
<p>Install the necessary frontend dependencies:</p>
<pre><code data-theme="one-dark-pro" data-lang="powershell" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">npm install</span></div></code></pre>
</li>
</ol>
<p>This installs the packages listed in your <code>package.json</code> file.</p>
<h2><a id="step-6-build-frontend-assets" href="#step-6-build-frontend-assets" class="" aria-hidden="true" title=""></a>Step 6: Build Frontend Assets</h2>
<p>After installing the dependencies, build the frontend assets by running:</p>
<pre><code data-theme="one-dark-pro" data-lang="powershell" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">npm run build</span></div></code></pre>
<p>This compiles your application’s CSS and JavaScript files.</p>
<h2><a id="step-7-start-the-development-server" href="#step-7-start-the-development-server" class="" aria-hidden="true" title=""></a>Step 7: Start the Development Server</h2>
<p>To start the Laravel development server, run:</p>
<pre><code data-theme="one-dark-pro" data-lang="powershell" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer run dev</span></div></code></pre>
<p>This command starts the local development server, queue worker, and Vite development server. Your application will be accessible at:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">http://localhost:8000</span></div></code></pre>
<h2><a id="step-8-configure-your-environment" href="#step-8-configure-your-environment" class="" aria-hidden="true" title=""></a>Step 8: Configure Your Environment</h2>
<p>Laravel uses a <code>.env</code> file in the project root to manage configuration settings like database credentials and application environment. Open this file and update it with your specific setup.</p>
<h2><a id="step-9-set-up-a-database-optional" href="#step-9-set-up-a-database-optional" class="" aria-hidden="true" title=""></a>Step 9: Set Up a Database (Optional)</h2>
<p>By default, the .env configuration file specifies that Laravel will interact with an SQLite database. If you’re comfortable using SQLite, Laravel is already set up for you. However, if you’d like to use a different database system, follow these steps:</p>
<ol>
<li>
<p>Update the <code>.env</code> file with your database settings. For example, to use MySQL:</p>
<pre><code data-theme="one-dark-pro" data-lang="text" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">DB_CONNECTION=mysql</span></div><div class='line'><span style="color: #abb2bf;">DB_HOST=127.0.0.1</span></div><div class='line'><span style="color: #abb2bf;">DB_PORT=3306</span></div><div class='line'><span style="color: #abb2bf;">DB_DATABASE=laravel</span></div><div class='line'><span style="color: #abb2bf;">DB_USERNAME=root</span></div><div class='line'><span style="color: #abb2bf;">DB_PASSWORD=</span></div></code></pre>
</li>
<li>
<p>Run migrations to create the necessary database tables:</p>
<pre><code data-theme="one-dark-pro" data-lang="powershell" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php artisan migrate</span></div></code></pre>
</li>
</ol>
<h2><a id="youre-all-set" href="#youre-all-set" class="" aria-hidden="true" title=""></a>You’re All Set!</h2>
<p>Congratulations! You’ve successfully installed Laravel 12 on your Windows system. You’re now ready to start developing your application. If you have any questions or run into issues, Laravel’s official documentation is an excellent resource to consult.</p>
<p>Welcome to Laravel!</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Fri, 15 Aug 2025 21:17:38 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Laravel Joins Explained: Clear Guide with Practical Examples]]></title>
                <link>https://nabilhassen.com/laravel-joins-explained-clear-guide-with-practical-examples</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#mastering-joins-in-laravel">Mastering Joins in Laravel</a></li>
<li><a href="#what-are-joins">What Are Joins?</a></li>
<li><a href="#1-inner-join">1. Inner Join</a></li>
<li><a href="#2-left-join-and-right-join">2. Left Join and Right Join</a>
<ul>
<li><a href="#left-join">Left Join:</a></li>
<li><a href="#right-join">Right Join:</a></li>
</ul>
</li>
<li><a href="#3-cross-join">3. Cross Join</a></li>
<li><a href="#4-advanced-join-clauses">4. Advanced Join Clauses</a>
<ul>
<li><a href="#using-oron">Using orOn:</a></li>
<li><a href="#using-where-and-orwhere">Using where and orWhere:</a></li>
</ul>
</li>
<li><a href="#5-subquery-joins">5. Subquery Joins</a></li>
<li><a href="#6-lateral-joins">6. Lateral Joins</a></li>
<li><a href="#7-unions">7. Unions</a></li>
<li><a href="#summary">Summary</a></li>
</ul>
<h2><a id="mastering-joins-in-laravel" href="#mastering-joins-in-laravel" class="" aria-hidden="true" title=""></a>Mastering Joins in Laravel</h2>
<p>Joins are a powerful tool in Laravel's query builder that let you combine data from multiple database tables. Whether you're building a simple query or something more complex, Laravel makes it easy. This guide walks you through the basics of joins, explains when to use each type, and provides clear examples.</p>
<h2><a id="what-are-joins" href="#what-are-joins" class="" aria-hidden="true" title=""></a>What Are Joins?</h2>
<p>When working with databases, you often need to fetch data that is related but stored in different tables. For example, a <code>users</code> table might store user details, while a <code>posts</code> table stores their blog posts. To combine this data in a single query, you use a <strong>join</strong>.</p>
<p>Laravel provides several types of joins:</p>
<ol>
<li><strong>Inner Join</strong></li>
<li><strong>Left Join / Right Join</strong></li>
<li><strong>Cross Join</strong></li>
<li><strong>Advanced Joins</strong></li>
<li><strong>Subquery Joins</strong></li>
<li><strong>Lateral Joins</strong></li>
<li><strong>Unions</strong></li>
</ol>
<p>Let’s explore each of these with examples.</p>
<h2><a id="1-inner-join" href="#1-inner-join" class="" aria-hidden="true" title=""></a>1. Inner Join</h2>
<p>An <strong>inner join</strong> returns only the rows where there is a match in both tables. In Laravel, you can use the <code>join</code> method:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">join</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;contacts&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;users.id&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;=&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;contacts.user_id&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">join</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;orders&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;users.id&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;=&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;orders.user_id&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">select</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users.*&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;contacts.phone&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;orders.price&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>This query joins three tables: <code>users</code>, <code>contacts</code>, and <code>orders</code>. It retrieves user details, phone numbers, and order prices where the data matches across the tables.</p>
<h2><a id="2-left-join-and-right-join" href="#2-left-join-and-right-join" class="" aria-hidden="true" title=""></a>2. Left Join and Right Join</h2>
<p>A <strong>left join</strong> returns all rows from the left table and the matching rows from the right table. A <strong>right join</strong> does the opposite. Here's how you do it in Laravel:</p>
<h3><a id="left-join" href="#left-join" class="" aria-hidden="true" title=""></a>Left Join:</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">leftJoin</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;posts&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;users.id&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;=&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;posts.user_id&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h3><a id="right-join" href="#right-join" class="" aria-hidden="true" title=""></a>Right Join:</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">rightJoin</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;posts&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;users.id&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;=&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;posts.user_id&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>Use these when you want all rows from one table, even if there's no match in the other.</p>
<h2><a id="3-cross-join" href="#3-cross-join" class="" aria-hidden="true" title=""></a>3. Cross Join</h2>
<p>A <strong>cross join</strong> creates a cartesian product, combining every row of the first table with every row of the second table. For example:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$sizes</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;sizes&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">crossJoin</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;colors&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>This query generates every possible combination of sizes and colors.</p>
<h2><a id="4-advanced-join-clauses" href="#4-advanced-join-clauses" class="" aria-hidden="true" title=""></a>4. Advanced Join Clauses</h2>
<p>Sometimes, you need more complex conditions in your joins. Use a closure to define custom constraints:</p>
<h3><a id="using-oron" href="#using-oron" class="" aria-hidden="true" title=""></a>Using <code>orOn</code>:</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">join</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;contacts&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$join</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$join</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">on</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users.id&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;=&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;contacts.user_id&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">             -&gt;</span><span style="color: #61AFEF;">orOn</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users.email&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;=&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;contacts.email&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    })</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h3><a id="using-where-and-orwhere" href="#using-where-and-orwhere" class="" aria-hidden="true" title=""></a>Using <code>where</code> and <code>orWhere</code>:</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">join</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;contacts&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$join</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$join</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">on</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users.id&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;=&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;contacts.user_id&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">             -&gt;</span><span style="color: #61AFEF;">where</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;contacts.user_id&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;&gt;&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">5</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">             -&gt;</span><span style="color: #61AFEF;">orWhere</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;contacts.is_active&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">true</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    })</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>These methods allow you to create detailed conditions, ensuring you fetch exactly the data you need.</p>
<h2><a id="5-subquery-joins" href="#5-subquery-joins" class="" aria-hidden="true" title=""></a>5. Subquery Joins</h2>
<p>You can even join a table with a subquery using the <code>joinSub</code> method. For example:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$latestPosts</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;posts&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">select</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;user_id&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">raw</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;MAX(created_at) as last_post_created_at&#39;</span><span style="color: #ABB2BF;">))</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">where</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;is_published&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">true</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">groupBy</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;user_id&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">joinSub</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$latestPosts</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;latest_posts&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$join</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$join</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">on</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users.id&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;=&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;latest_posts.user_id&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    })</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>This retrieves users along with the timestamp of their latest published post.</p>
<h2><a id="6-lateral-joins" href="#6-lateral-joins" class="" aria-hidden="true" title=""></a>6. Lateral Joins</h2>
<p>Lateral joins evaluate a subquery for each row in the main query. They are supported by PostgreSQL, MySQL &gt;= 8.0.14, and SQL Server.</p>
<p>For example:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$latestPosts</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;posts&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">select</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;id as post_id&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;title as post_title&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;created_at as post_created_at&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">whereColumn</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;user_id&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;users.id&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">orderBy</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;created_at&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;desc&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">limit</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">3</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">joinLateral</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$latestPosts</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;latest_posts&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>This query fetches each user along with their three most recent posts. Each row in the main query can produce multiple results in the joined query.</p>
<h2><a id="7-unions" href="#7-unions" class="" aria-hidden="true" title=""></a>7. Unions</h2>
<p>Sometimes, you may need to combine the results of two queries. Use the <code>union</code> method for this:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$first</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">whereNull</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;first_name&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">whereNull</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;last_name&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">union</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$first</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>If you don't want to remove duplicates, use <code>unionAll</code> instead:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;users&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">whereNull</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;last_name&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">unionAll</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$first</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h2><a id="summary" href="#summary" class="" aria-hidden="true" title=""></a>Summary</h2>
<p>Joins are essential for fetching related data efficiently. Laravel provides a variety of methods to handle different scenarios:</p>
<ul>
<li><strong>Inner Join</strong>: Matches rows in both tables.</li>
<li><strong>Left Join / Right Join</strong>: Includes unmatched rows from one table.</li>
<li><strong>Cross Join</strong>: Generates all combinations of rows from two tables.</li>
<li><strong>Advanced Joins</strong>: Allows custom conditions.</li>
<li><strong>Subquery Joins</strong>: Joins with complex subqueries.</li>
<li><strong>Lateral Joins</strong>: Subqueries that depend on each row of the main query.</li>
<li><strong>Unions</strong>: Combines results from multiple queries.</li>
</ul>
<p>By mastering these, you can handle even the most intricate data relationships in your Laravel projects. Happy coding!</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Wed, 25 Dec 2024 07:27:53 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Understanding Exception Handling in Laravel]]></title>
                <link>https://nabilhassen.com/understanding-exception-handling-in-laravel</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#understanding-the-basics-of-exception-handling-in-laravel">Understanding the Basics of Exception Handling in Laravel</a></li>
<li><a href="#setting-up-debugging">Setting Up Debugging</a></li>
<li><a href="#reporting-exceptions">Reporting Exceptions</a>
<ul>
<li><a href="#example-reporting-a-custom-exception">Example: Reporting a Custom Exception</a></li>
</ul>
</li>
<li><a href="#adding-global-context-to-logs">Adding Global Context to Logs</a>
<ul>
<li><a href="#global-context">Global Context</a></li>
<li><a href="#exception-specific-context">Exception-Specific Context</a></li>
</ul>
</li>
<li><a href="#rendering-exceptions">Rendering Exceptions</a>
<ul>
<li><a href="#example-custom-rendering-for-invalid-orders">Example: Custom Rendering for Invalid Orders</a></li>
<li><a href="#example-for-api-responses">Example: For API responses</a></li>
</ul>
</li>
<li><a href="#creating-custom-http-error-pages">Creating Custom HTTP Error Pages</a></li>
<li><a href="#using-reportable-and-renderable-exceptions">Using Reportable and Renderable Exceptions</a>
<ul>
<li><a href="#example-custom-exception-class">Example: Custom Exception Class</a></li>
</ul>
</li>
<li><a href="#throttling-exceptions">Throttling Exceptions</a></li>
<li><a href="#ignoring-exceptions">Ignoring Exceptions</a>
<ul>
<li><a href="#example-adding-exceptions-to-dontreport-list">Example: Adding Exceptions to dontReport List</a></li>
<li><a href="#example-marking-exceptions-as-non-reportable">Example: Marking Exceptions as Non-Reportable</a></li>
</ul>
</li>
<li><a href="#handling-http-exceptions">Handling HTTP Exceptions</a>
<ul>
<li><a href="#example-trigger-a-404-error">Example: Trigger a 404 Error</a></li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<p>Exception handling is an essential part of any application, allowing developers to gracefully manage errors and ensure users have a smooth experience. Laravel simplifies this process by offering a robust error and exception handling system out of the box. In this guide, we’ll explore step-by-step how to leverage Laravel's exception handling capabilities in a beginner-friendly manner.</p>
<h2><a id="understanding-the-basics-of-exception-handling-in-laravel" href="#understanding-the-basics-of-exception-handling-in-laravel" class="" aria-hidden="true" title=""></a>Understanding the Basics of Exception Handling in Laravel</h2>
<p>Laravel comes pre-configured with a robust error and exception-handling mechanism. This ensures you don’t have to start from scratch.</p>
<p>The core of this functionality is the <code>$exceptions</code> object, found in the <code>bootstrap/app.php</code> file, which controls how exceptions are <strong>reported</strong> (logged or sent to an external service) and <strong>rendered</strong> (displayed to users).</p>
<h2><a id="setting-up-debugging" href="#setting-up-debugging" class="" aria-hidden="true" title=""></a>Setting Up Debugging</h2>
<p>Laravel uses the <code>APP_DEBUG</code> variable in the <code>.env</code> file to determine how much error information to display:</p>
<ul>
<li><strong>Local Development:</strong> Set <code>APP_DEBUG=true</code> to show detailed error messages.</li>
<li><strong>Production:</strong> Always set <code>APP_DEBUG=false</code> to avoid exposing sensitive information.</li>
</ul>
<p>Update the <code>.env</code> file:</p>
<pre><code data-theme="one-dark-pro" data-lang="env" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">APP_DEBUG</span><span style="color: #56B6C2;">=</span><span style="color: #D19A66;">true</span></div></code></pre>
<h2><a id="reporting-exceptions" href="#reporting-exceptions" class="" aria-hidden="true" title=""></a>Reporting Exceptions</h2>
<p>Laravel logs exceptions automatically based on the logging configuration. To customize this behavior, you can define exception-specific reporting logic.</p>
<h3><a id="example-reporting-a-custom-exception" href="#example-reporting-a-custom-exception" class="" aria-hidden="true" title=""></a>Example: Reporting a Custom Exception</h3>
<p>In <code>bootstrap/app.php</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">withExceptions</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Exceptions</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$exceptions</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$exceptions</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">report</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">InvalidOrderException</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$e</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// Custom reporting logic</span></div><div class='line'><span style="color: #ABB2BF;">    })-&gt;</span><span style="color: #61AFEF;">stop</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div></code></pre>
<ul>
<li>Use <code>-&gt;stop()</code> to prevent default logging.</li>
<li>Return <code>false</code> in the closure to skip logging entirely.</li>
</ul>
<h2><a id="adding-global-context-to-logs" href="#adding-global-context-to-logs" class="" aria-hidden="true" title=""></a>Adding Global Context to Logs</h2>
<p>To make your logs more meaningful, you can include contextual data:</p>
<h3><a id="global-context" href="#global-context" class="" aria-hidden="true" title=""></a>Global Context</h3>
<p>Define global data that should appear in every log entry:</p>
<p>In <code>bootstrap/app.php</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">withExceptions</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Exceptions</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$exceptions</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$exceptions</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">context</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">fn</span><span style="color: #ABB2BF;"> () =&gt; [</span><span style="color: #98C379;">&#39;user_id&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #61AFEF;">auth</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">id</span><span style="color: #ABB2BF;">()]);</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div></code></pre>
<h3><a id="exception-specific-context" href="#exception-specific-context" class="" aria-hidden="true" title=""></a>Exception-Specific Context</h3>
<p>Add context to specific exceptions by defining a context method in your exception class:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">context</span><span style="color: #ABB2BF;">(): </span><span style="color: #E5C07B;">array</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> [</span><span style="color: #98C379;">&#39;order_id&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">orderId</span><span style="color: #ABB2BF;">];</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h2><a id="rendering-exceptions" href="#rendering-exceptions" class="" aria-hidden="true" title=""></a>Rendering Exceptions</h2>
<p>By default, Laravel converts exceptions into HTTP responses. You can override this behavior for specific exceptions.</p>
<h3><a id="example-custom-rendering-for-invalid-orders" href="#example-custom-rendering-for-invalid-orders" class="" aria-hidden="true" title=""></a>Example: Custom Rendering for Invalid Orders</h3>
<p>In <code>bootstrap/app.php</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Exceptions\</span><span style="color: #E5C07B;">InvalidOrderException</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Http\</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">withExceptions</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Exceptions</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$exceptions</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$exceptions</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">render</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">InvalidOrderException</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$e</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">response</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">view</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;errors.invalid-order&#39;</span><span style="color: #ABB2BF;">, [], </span><span style="color: #D19A66;">500</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    });</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div></code></pre>
<ul>
<li>The <code>render</code> method can also handle built-in exceptions like <code>NotFoundHttpException</code>.</li>
</ul>
<h3><a id="example-for-api-responses" href="#example-for-api-responses" class="" aria-hidden="true" title=""></a>Example: For API responses</h3>
<p>Render exceptions as JSON:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$exceptions</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">render</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">NotFoundHttpException</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$e</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">is</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;api/*&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">?</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">response</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">json</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;message&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Not found&#39;</span><span style="color: #ABB2BF;">], </span><span style="color: #D19A66;">404</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">:</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div></code></pre>
<h2><a id="creating-custom-http-error-pages" href="#creating-custom-http-error-pages" class="" aria-hidden="true" title=""></a>Creating Custom HTTP Error Pages</h2>
<p>Laravel lets you create custom error pages for various HTTP status codes. To customize a 404 error page:</p>
<h4><a id="steps-to-customize" href="#steps-to-customize" class="" aria-hidden="true" title=""></a>Steps to Customize:</h4>
<ol>
<li>To customize default error templates, publish them using:
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">vendor:publish</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--tag=laravel-errors</span></div></code></pre>
</li>
<li>Add your custom content to the <code>404.blade.php</code> view:
<pre><code data-theme="one-dark-pro" data-lang="blade" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">  &lt;</span><span style="color: #E06C75;">h2</span><span style="color: #ABB2BF;">&gt;</span><span style="color: #56B6C2;">{{</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$exception</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">getMessage</span><span style="color: #ABB2BF;">() </span><span style="color: #56B6C2;">}}</span><span style="color: #ABB2BF;">&lt;/</span><span style="color: #E06C75;">h2</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">&lt;</span><span style="color: #E06C75;">p</span><span style="color: #ABB2BF;">&gt;Sorry, the page you’re looking for doesn’t exist.&lt;/</span><span style="color: #E06C75;">p</span><span style="color: #ABB2BF;">&gt;</span></div></code></pre>
</li>
<li>Test the page by navigating to a non-existent route.</li>
</ol>
<p>You can also define fallback templates for groups of errors, like <code>4xx.blade.php</code> for all 4xx errors.</p>
<h2><a id="using-reportable-and-renderable-exceptions" href="#using-reportable-and-renderable-exceptions" class="" aria-hidden="true" title=""></a>Using Reportable and Renderable Exceptions</h2>
<p>Instead of defining reporting and rendering logic globally, you can implement it directly in custom exception classes.</p>
<h3><a id="example-custom-exception-class" href="#example-custom-exception-class" class="" aria-hidden="true" title=""></a>Example: Custom Exception Class</h3>
<p>Create a new exception:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">make:exception</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">InvalidOrderException</span></div></code></pre>
<p>In <code>App\Exceptions\InvalidOrderException</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">namespace</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">App\Exceptions</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Exception</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Http\</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Http\</span><span style="color: #E5C07B;">Response</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">InvalidOrderException</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Exception</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">report</span><span style="color: #ABB2BF;">(): </span><span style="color: #E5C07B;">void</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// Custom reporting logic</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">render</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">Response</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">response</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">view</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;errors.invalid-order&#39;</span><span style="color: #ABB2BF;">, [], </span><span style="color: #D19A66;">500</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h2><a id="throttling-exceptions" href="#throttling-exceptions" class="" aria-hidden="true" title=""></a>Throttling Exceptions</h2>
<p>To avoid flooding logs with duplicate errors, Laravel allows you to throttle reported exceptions.</p>
<h4><a id="example-throttling-exceptions" href="#example-throttling-exceptions" class="" aria-hidden="true" title=""></a>Example: Throttling Exceptions</h4>
<p>In <code>bootstrap/app.php</code>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\</span><span style="color: #E5C07B;">Lottery</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">withExceptions</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Exceptions</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$exceptions</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$exceptions</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">throttle</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">fn</span><span style="color: #ABB2BF;"> () =&gt; </span><span style="color: #E5C07B;">Lottery</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">odds</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">1000</span><span style="color: #ABB2BF;">));</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div></code></pre>
<ul>
<li>This ensures only one out of every 1000 identical exceptions is logged.</li>
</ul>
<h2><a id="ignoring-exceptions" href="#ignoring-exceptions" class="" aria-hidden="true" title=""></a>Ignoring Exceptions</h2>
<p>You can exclude certain exceptions from being reported by adding them to the <code>dontReport</code> list or implementing the <code>ShouldntReport</code> interface.</p>
<h3><a id="example-adding-exceptions-to-dontreport-list" href="#example-adding-exceptions-to-dontreport-list" class="" aria-hidden="true" title=""></a>Example: Adding Exceptions to <code>dontReport</code> List</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$exceptions</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">dontReport</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E5C07B;">InvalidOrderException</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">]);</span></div></code></pre>
<h3><a id="example-marking-exceptions-as-non-reportable" href="#example-marking-exceptions-as-non-reportable" class="" aria-hidden="true" title=""></a>Example: Marking Exceptions as Non-Reportable</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">namespace</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">App\Exceptions</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Exception</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Contracts\Debug\</span><span style="color: #E5C07B;">ShouldntReport</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">CustomException</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Exception</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">implements</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">ShouldntReport</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// ...</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h2><a id="handling-http-exceptions" href="#handling-http-exceptions" class="" aria-hidden="true" title=""></a>Handling HTTP Exceptions</h2>
<p>To trigger specific HTTP errors programmatically, use the <code>abort</code> helper:</p>
<h3><a id="example-trigger-a-404-error" href="#example-trigger-a-404-error" class="" aria-hidden="true" title=""></a>Example: Trigger a 404 Error</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #61AFEF;">abort</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">404</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #98C379;">&#39;Page not found&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>Laravel’s exception handling system is designed to be flexible, allowing developers to customize and control error reporting and rendering as needed. By mastering these techniques, you can ensure your application handles errors gracefully while maintaining a seamless user experience.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 24 Dec 2024 07:50:25 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Monitoring Queues in Laravel: A Step-by-Step Guide]]></title>
                <link>https://nabilhassen.com/monitoring-queues-in-laravel-a-step-by-step-guide</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#monitoring-your-queues-in-laravel-a-step-by-step-guide">Monitoring Your Queues in Laravel: A Step-by-Step Guide</a></li>
<li><a href="#step-1-schedule-the-queuemonitor-command">Step 1: Schedule the queue:monitor Command</a>
<ul>
<li><a href="#example-command">Example Command</a></li>
</ul>
</li>
<li><a href="#step-2-listen-for-the-queuebusy-event">Step 2: Listen for the QueueBusy Event</a>
<ul>
<li><a href="#add-event-listener-in-appserviceprovider">Add Event Listener in AppServiceProvider</a></li>
</ul>
</li>
<li><a href="#step-3-create-the-notification-class">Step 3: Create the Notification Class</a></li>
<li><a href="#step-4-test-the-monitoring-system">Step 4: Test the Monitoring System</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="monitoring-your-queues-in-laravel-a-step-by-step-guide" href="#monitoring-your-queues-in-laravel-a-step-by-step-guide" class="" aria-hidden="true" title=""></a>Monitoring Your Queues in Laravel: A Step-by-Step Guide</h2>
<p>When working with Laravel queues, performance can sometimes be impacted by a sudden influx of jobs. If your queue becomes overwhelmed, it can lead to extended wait times for jobs to process, which may affect your application’s responsiveness. Fortunately, Laravel offers built-in tools to help you monitor your queues and notify you if their job count exceeds a specified threshold. In this guide, we will walk through how to set up monitoring for your queues and receive notifications when they are under heavy load.</p>
<h2><a id="step-1-schedule-the-queuemonitor-command" href="#step-1-schedule-the-queuemonitor-command" class="" aria-hidden="true" title=""></a>Step 1: Schedule the <code>queue:monitor</code> Command</h2>
<p>To begin monitoring your queues, you need to use the <code>queue:monitor</code> Artisan command. This command checks the size of your queues and helps detect when they’re getting overwhelmed. You can specify which queues you want to monitor and set a threshold for the maximum number of jobs that should be allowed in each queue.</p>
<h3><a id="example-command" href="#example-command" class="" aria-hidden="true" title=""></a>Example Command</h3>
<p>In your terminal, run the following command to monitor specific queues:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">queue:monitor</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">redis:default,redis:deployments</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--max=100</span></div></code></pre>
<p>This command does the following:</p>
<ul>
<li>It monitors two queues: <code>redis:default</code> and <code>redis:deployments</code>.</li>
<li>It sets the threshold to 100 jobs. If either queue exceeds 100 jobs, an alert will be triggered.</li>
</ul>
<p>However, simply running the command is not enough to send an alert when the threshold is breached. You will need to set up an event listener to trigger notifications, which we’ll cover in the next step.</p>
<h2><a id="step-2-listen-for-the-queuebusy-event" href="#step-2-listen-for-the-queuebusy-event" class="" aria-hidden="true" title=""></a>Step 2: Listen for the <code>QueueBusy</code> Event</h2>
<p>Laravel will dispatch a <code>QueueBusy</code> event when a queue exceeds the job count threshold you set using the <code>queue:monitor</code> command. To respond to this event and send a notification, you need to listen for it in your application’s <code>AppServiceProvider</code>.</p>
<h3><a id="add-event-listener-in-appserviceprovider" href="#add-event-listener-in-appserviceprovider" class="" aria-hidden="true" title=""></a>Add Event Listener in <code>AppServiceProvider</code></h3>
<p>Open your <code>AppServiceProvider.php</code> file, which can be found in the <code>app/Providers</code> directory. In the <code>boot</code> method of this provider, you will listen for the <code>QueueBusy</code> event.</p>
<p>Here’s an example of how to do that:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Notifications\</span><span style="color: #E5C07B;">QueueHasLongWaitTime</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Queue\Events\</span><span style="color: #E5C07B;">QueueBusy</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Event</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Support\Facades\</span><span style="color: #E5C07B;">Notification</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">boot</span><span style="color: #ABB2BF;">(): </span><span style="color: #E5C07B;">void</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// Listen for the QueueBusy event</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E5C07B;">Event</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">listen</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">QueueBusy</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$event</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// Send a notification when the queue is overwhelmed</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Notification</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">route</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;mail&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;dev@example.com&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">            -&gt;</span><span style="color: #61AFEF;">notify</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">QueueHasLongWaitTime</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">                </span><span style="color: #E06C75;">$event</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">connection</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">                </span><span style="color: #E06C75;">$event</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">queue</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">                </span><span style="color: #E06C75;">$event</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">size</span></div><div class='line'><span style="color: #ABB2BF;">            ));</span></div><div class='line'><span style="color: #ABB2BF;">    });</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h2><a id="step-3-create-the-notification-class" href="#step-3-create-the-notification-class" class="" aria-hidden="true" title=""></a>Step 3: Create the Notification Class</h2>
<p>The next step is to create a notification class that will be used to send alerts. This class will specify how the notification is formatted and how it should be sent (e.g., via email).</p>
<p>Run the following Artisan command to generate the notification:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">make:notification</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">QueueHasLongWaitTime</span></div></code></pre>
<p>This will create a new notification class in the <code>app/Notifications</code> directory. Open the newly created file and define how you want the notification to be sent.</p>
<p>Here’s an example of a basic notification that sends an email:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">namespace</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">App\Notifications</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Notifications\</span><span style="color: #E5C07B;">Notification</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Notifications\Messages\</span><span style="color: #E5C07B;">MailMessage</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">QueueHasLongWaitTime</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Notification</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$connection</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$queue</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$size</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">__construct</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$connection</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$queue</span><span style="color: #ABB2BF;">, </span><span style="color: #E06C75;">$size</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">connection</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$connection</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">queue</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$queue</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">size</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$size</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">via</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$notifiable</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> [</span><span style="color: #98C379;">&#39;mail&#39;</span><span style="color: #ABB2BF;">];</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">toMail</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$notifiable</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> (</span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">MailMessage</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">            -&gt;</span><span style="color: #61AFEF;">subject</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;Queue is Overwhelmed&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">            -&gt;</span><span style="color: #61AFEF;">line</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&quot;The queue &#39;{</span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">queue</span><span style="color: #98C379;">}&#39; on connection &#39;{</span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">connection</span><span style="color: #98C379;">}&#39; has exceeded the job threshold.&quot;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">            -&gt;</span><span style="color: #61AFEF;">line</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&quot;Current job count: {</span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">size</span><span style="color: #98C379;">}&quot;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">            -&gt;</span><span style="color: #61AFEF;">line</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;Please investigate the cause of the high job count.&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>This notification will send an email to the specified address with information about the queue that exceeded the job count.</p>
<h2><a id="step-4-test-the-monitoring-system" href="#step-4-test-the-monitoring-system" class="" aria-hidden="true" title=""></a>Step 4: Test the Monitoring System</h2>
<p>Now that everything is set up, it's time to test your queue monitoring system.</p>
<ol>
<li>Trigger the <code>php artisan queue:monitor</code> command to start monitoring the queues.</li>
<li>Simulate a situation where the job count exceeds your specified threshold. You can either push a large number of jobs into the queue or adjust the threshold temporarily to trigger the event.</li>
<li>Check the email inbox specified in the notification to confirm that the alert was received.</li>
</ol>
<p>If everything is working correctly, you should see a notification email when your queue exceeds the threshold.</p>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>By following these steps, you can easily set up queue monitoring in Laravel and receive alerts when your queues are overwhelmed. This setup ensures you can take proactive measures to resolve issues before they impact your application’s performance. Monitoring your queues not only helps you avoid bottlenecks but also keeps you informed in real-time about potential issues.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Mon, 23 Dec 2024 15:42:55 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Understanding Array Validation in Laravel: A Beginner’s Guide]]></title>
                <link>https://nabilhassen.com/understanding-array-validation-in-laravel-a-beginners-guide</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#what-is-array-validation-in-laravel">What is Array Validation in Laravel?</a></li>
<li><a href="#basic-array-validation">Basic Array Validation</a></li>
<li><a href="#validating-elements-within-an-array">Validating Elements within an Array</a></li>
<li><a href="#validating-arrays-with-keys">Validating Arrays with Keys</a></li>
<li><a href="#handling-validation-errors">Handling Validation Errors</a></li>
<li><a href="#custom-validation-rules-for-arrays">Custom Validation Rules for Arrays</a></li>
<li><a href="#validating-nested-arrays">Validating Nested Arrays</a></li>
<li><a href="#tips-and-best-practices">Tips and Best Practices</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<p>Validation is a critical part of any application. It ensures that the data your application processes is accurate, reliable, and secure. In Laravel, the validation process is seamless, powerful, and easy to implement. Among the various features Laravel offers, array validation is one of the most useful yet sometimes misunderstood functionalities. In this guide, we will dive deep into Laravel’s array validation and explain it in a beginner-friendly way.</p>
<h2><a id="what-is-array-validation-in-laravel" href="#what-is-array-validation-in-laravel" class="" aria-hidden="true" title=""></a>What is Array Validation in Laravel?</h2>
<p>Array validation in Laravel allows you to validate inputs that are structured as arrays. This is particularly useful when dealing with forms or APIs that accept multiple inputs under a single field name, such as:</p>
<ul>
<li>A list of email addresses.</li>
<li>A collection of product options.</li>
<li>A set of uploaded files.</li>
</ul>
<p>For example, consider a scenario where you need to validate multiple phone numbers provided by the user as a single input. Laravel’s array validation makes this not only possible but also straightforward.</p>
<h2><a id="basic-array-validation" href="#basic-array-validation" class="" aria-hidden="true" title=""></a>Basic Array Validation</h2>
<p>Let’s start with a simple example. Suppose you have a form field named <code>items[]</code> where users can submit a list of items. To validate this input, you can specify the validation rule in your controller like this:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Http\</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">store</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #98C379;">&#39;items&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;required|array&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ]);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// Proceed with storing or processing the valid data.</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Here’s what this does:</p>
<ol>
<li><strong><code>required</code></strong>: Ensures the <code>items</code> field is present in the request.</li>
<li><strong><code>array</code></strong>: Ensures that the value of <code>items</code> is indeed an array.</li>
</ol>
<h2><a id="validating-elements-within-an-array" href="#validating-elements-within-an-array" class="" aria-hidden="true" title=""></a>Validating Elements within an Array</h2>
<p>What if you want to validate each element within the <code>items</code> array? For instance, you want to ensure each item is a string with a maximum length of 50 characters. Laravel allows you to use the dot notation for this:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;items&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;required|array&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;items.*&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;string|max:50&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">]);</span></div></code></pre>
<p>Explanation:</p>
<ul>
<li><strong><code>items.*</code></strong>: Targets each element of the <code>items</code> array.</li>
<li><strong><code>string</code></strong>: Ensures each element is a string.</li>
<li><strong><code>max:50</code></strong>: Limits the length of each string to 50 characters.</li>
</ul>
<p>If a user submits an invalid array, Laravel will return a validation error specifying the problematic element, such as <code>items.2 must not exceed 50 characters</code>.</p>
<h2><a id="validating-arrays-with-keys" href="#validating-arrays-with-keys" class="" aria-hidden="true" title=""></a>Validating Arrays with Keys</h2>
<p>In some cases, your arrays might have specific keys that need validation. For example:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;products&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;required|array&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;products.*.name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;required|string&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;products.*.price&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;required|numeric|min:0&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">]);</span></div></code></pre>
<p>Here’s what’s happening:</p>
<ul>
<li><strong><code>products</code></strong>: Ensures the <code>products</code> field is an array.</li>
<li><strong><code>products.*.name</code></strong>: Ensures each product has a <code>name</code> field that is a required string.</li>
<li><strong><code>products.*.price</code></strong>: Ensures each product has a <code>price</code> field that is a required number greater than or equal to 0.</li>
</ul>
<p>Example Input:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">[</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;products&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span></div><div class='line'><span style="color: #ABB2BF;">        [</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Laptop&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;price&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">1200</span><span style="color: #ABB2BF;">],</span></div><div class='line'><span style="color: #ABB2BF;">        [</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Mouse&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;price&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">25</span><span style="color: #ABB2BF;">]</span></div><div class='line'><span style="color: #ABB2BF;">    ]</span></div><div class='line'><span style="color: #ABB2BF;">]</span></div></code></pre>
<h2><a id="handling-validation-errors" href="#handling-validation-errors" class="" aria-hidden="true" title=""></a>Handling Validation Errors</h2>
<p>When validation fails, Laravel automatically redirects the user back to the previous page with validation errors. You can display these errors in your Blade templates using the <code>$errors</code> variable:</p>
<pre><code data-theme="one-dark-pro" data-lang="blade" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">@if </span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$errors</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">any</span><span style="color: #ABB2BF;">())</span></div><div class='line'><span style="color: #ABB2BF;">    &lt;</span><span style="color: #E06C75;">div</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">class</span><span style="color: #ABB2BF;">=</span><span style="color: #98C379;">&quot;alert alert-danger&quot;</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">        &lt;</span><span style="color: #E06C75;">ul</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #C678DD;">@foreach </span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$errors</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">all</span><span style="color: #ABB2BF;">() </span><span style="color: #56B6C2;">as</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$error</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">                &lt;</span><span style="color: #E06C75;">li</span><span style="color: #ABB2BF;">&gt;</span><span style="color: #56B6C2;">{{</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$error</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">}}</span><span style="color: #ABB2BF;">&lt;/</span><span style="color: #E06C75;">li</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #C678DD;">@endforeach</span></div><div class='line'><span style="color: #ABB2BF;">        &lt;/</span><span style="color: #E06C75;">ul</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #ABB2BF;">    &lt;/</span><span style="color: #E06C75;">div</span><span style="color: #ABB2BF;">&gt;</span></div><div class='line'><span style="color: #C678DD;">@endif</span></div></code></pre>
<p>This provides an intuitive way to inform users about any issues with their input.</p>
<h2><a id="custom-validation-rules-for-arrays" href="#custom-validation-rules-for-arrays" class="" aria-hidden="true" title=""></a>Custom Validation Rules for Arrays</h2>
<p>Sometimes, the built-in validation rules aren’t enough, and you need to implement custom logic. Laravel makes this easy by allowing you to define custom rules:</p>
<ol>
<li>
<p>Create a custom rule using the <code>php artisan</code> command:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">make:rule</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">ValidPhoneNumber</span></div></code></pre>
</li>
<li>
<p>Implement the logic in the generated rule file:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">namespace</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">App\Rules</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Closure</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Contracts\Validation\</span><span style="color: #E5C07B;">ValidationRule</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">ValidPhoneNumber</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">implements</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">ValidationRule</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">string</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$attribute</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">mixed</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">Closure</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$fail</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">void</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// Example: Check if the value matches a phone number pattern</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;">(</span><span style="color: #56B6C2;">!preg_match</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">&#39;/</span><span style="color: #C678DD;">^</span><span style="color: #56B6C2;">\+</span><span style="color: #E06C75;">?[0-9]{10,15}</span><span style="color: #C678DD;">$</span><span style="color: #E06C75;">/&#39;</span><span style="color: #ABB2BF;">,</span><span style="color: #61AFEF;"> </span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;">)) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E06C75;">$fail</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;Invalid phone number format.&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">        }</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">message</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;The :attribute must be a valid phone number.&#39;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
</li>
<li>
<p>Apply the custom rule in your validation:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Rules\</span><span style="color: #E5C07B;">ValidPhoneNumber</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;contacts.*.phone&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span><span style="color: #98C379;">&#39;required&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">ValidPhoneNumber</span><span style="color: #ABB2BF;">()],</span></div><div class='line'><span style="color: #ABB2BF;">]);</span></div></code></pre>
</li>
</ol>
<h2><a id="validating-nested-arrays" href="#validating-nested-arrays" class="" aria-hidden="true" title=""></a>Validating Nested Arrays</h2>
<p>You can validate deeply nested arrays by using the dot notation. For example:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;teams&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;required|array&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;teams.*.members&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;required|array&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;teams.*.members.*.name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;required|string&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;teams.*.members.*.role&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;required|string&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">]);</span></div></code></pre>
<p>Input Example:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">[</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;teams&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span></div><div class='line'><span style="color: #ABB2BF;">        [</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #98C379;">&#39;members&#39;</span><span style="color: #ABB2BF;"> =&gt; [</span></div><div class='line'><span style="color: #ABB2BF;">                [</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Alice&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;role&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Developer&#39;</span><span style="color: #ABB2BF;">],</span></div><div class='line'><span style="color: #ABB2BF;">                [</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Bob&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;role&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Designer&#39;</span><span style="color: #ABB2BF;">]</span></div><div class='line'><span style="color: #ABB2BF;">            ]</span></div><div class='line'><span style="color: #ABB2BF;">        ]</span></div><div class='line'><span style="color: #ABB2BF;">    ]</span></div><div class='line'><span style="color: #ABB2BF;">]</span></div></code></pre>
<h2><a id="tips-and-best-practices" href="#tips-and-best-practices" class="" aria-hidden="true" title=""></a>Tips and Best Practices</h2>
<ol>
<li><strong>Plan Your Validation Rules</strong>: Think through your data structure and validation requirements before writing the rules.</li>
<li><strong>Use Custom Messages</strong>: Customize error messages for better user experience.
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;items.*&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;string|max:50&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">], [</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #98C379;">&#39;items.*.max&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Each item must not exceed 50 characters.&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">]);</span></div></code></pre>
</li>
<li><strong>Leverage Custom Rules</strong>: For complex scenarios, create reusable custom rules to keep your code clean.</li>
<li><strong>Test Your Validation</strong>: Always test different scenarios to ensure your validation works as expected.</li>
</ol>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>Laravel’s array validation is a powerful feature that simplifies handling complex data structures. By understanding the basics and exploring advanced use cases, you can ensure your applications handle data validation effectively and provide a better user experience. Whether you’re working with simple lists or deeply nested arrays, Laravel’s validation tools have got you covered.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Fri, 20 Dec 2024 08:33:43 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[All Laravel and Livewire PHP Attributes]]></title>
                <link>https://nabilhassen.com/complete-guide-to-laravel-and-livewire-php-attributes-23-attributes</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#laravel-container-attributes">Laravel Container Attributes</a>
<ul>
<li><a href="#1-auth">1. #[Auth]</a></li>
<li><a href="#2-cache">2. #[Cache]</a></li>
<li><a href="#3-config">3. #[Config]</a></li>
<li><a href="#4-currentuser">4. #[CurrentUser]</a></li>
<li><a href="#5-db">5. #[DB]</a></li>
<li><a href="#6-log">6. #[Log]</a></li>
<li><a href="#7-routeparameter">7. #[RouteParameter]</a></li>
<li><a href="#8-storage">8. #[Storage]</a></li>
<li><a href="#9-tag">9. #[Tag]</a></li>
<li><a href="#10-authenticated">10. #[Authenticated]</a></li>
<li><a href="#11-bind">11. #[Bind]</a></li>
<li><a href="#12-context">12. #[Context]</a></li>
<li><a href="#13-database">13. #[Database]</a></li>
<li><a href="#14-give">14. #[Give]</a></li>
<li><a href="#15-scoped">15. #[Scoped]</a></li>
<li><a href="#16-singleton">16. #[Singleton]</a></li>
<li><a href="#17-boot">17. #[Boot]</a></li>
<li><a href="#18-initialize">18. #[Initialize]</a></li>
<li><a href="#19-scope">19. #[Scope]</a></li>
<li><a href="#20-scopedby">20. #[ScopedBy]</a></li>
<li><a href="#21-observedby">21. #[ObservedBy]</a></li>
<li><a href="#22-collectedby">22. #[CollectedBy]</a></li>
<li><a href="#23-usefactory">23. #[UseFactory]</a></li>
<li><a href="#24-useeloquentbuilder">24. #[UseEloquentBuilder]</a></li>
<li><a href="#25-usepolicy">25. #[UsePolicy]</a></li>
<li><a href="#26-useresource">26. #[UseResource]</a></li>
<li><a href="#27-useresourcecollection">27. #[UseResourceCollection]</a></li>
<li><a href="#28-deletewhenmissingmodels">28. #[DeleteWhenMissingModels]</a></li>
<li><a href="#29-withoutrelations">29. #[WithoutRelations]</a></li>
</ul>
</li>
<li><a href="#livewire-attributes">Livewire Attributes</a>
<ul>
<li><a href="#1-computed">1. Computed</a></li>
<li><a href="#2-isolate">2. Isolate</a></li>
<li><a href="#3-js">3. Js</a></li>
<li><a href="#4-layout">4. Layout</a></li>
<li><a href="#5-lazy">5. Lazy</a></li>
<li><a href="#6-locked">6. Locked</a></li>
<li><a href="#7-modelable">7. Modelable</a></li>
<li><a href="#8-on">8. On</a></li>
<li><a href="#9-reactive">9. Reactive</a></li>
<li><a href="#10-renderless">10. Renderless</a></li>
<li><a href="#11-rule">11. Rule</a></li>
<li><a href="#12-session">12. Session</a></li>
<li><a href="#13-title">13. Title</a></li>
<li><a href="#14-url">14. Url</a></li>
<li><a href="#15-async">15. Async</a></li>
<li><a href="#16-defer">16. Defer</a></li>
<li><a href="#17-json">17. Json</a></li>
<li><a href="#18-validate">18. Validate</a></li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<p>In modern PHP development, <strong>attributes</strong> provide a structured way to add metadata to classes, methods, and properties. Both Laravel and Livewire have embraced this feature, introducing several attributes to streamline common tasks. Let's explore the PHP attributes provided by Laravel's Container and Livewire, along with examples for each.</p>
<h2><a id="laravel-container-attributes" href="#laravel-container-attributes" class="" aria-hidden="true" title=""></a>Laravel Container Attributes</h2>
<p>Laravel's service container includes attributes that simplify dependency resolution and service injection:</p>
<h3><a id="1-auth" href="#1-auth" class="" aria-hidden="true" title=""></a>1. <code>#[Auth]</code></h3>
<p>Injects the authentication manager into a class.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Container\Attributes\</span><span style="color: #E5C07B;">Auth</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Contracts\Auth\</span><span style="color: #E5C07B;">Guard</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">PhotoController</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Controller</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">__construct</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">        #[Auth(</span><span style="color: #98C379;">&#39;web&#39;</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Guard</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$auth</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        ) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #7F848E;">//</span></div><div class='line'><span style="color: #ABB2BF;">        }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="2-cache" href="#2-cache" class="" aria-hidden="true" title=""></a>2. <code>#[Cache]</code></h3>
<p>Injects the cache manager into a class.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Container\Attributes\</span><span style="color: #E5C07B;">Cache</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Contracts\Cache\</span><span style="color: #E5C07B;">Repository</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">PhotoController</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Controller</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">__construct</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">        #[Cache(</span><span style="color: #98C379;">&#39;redis&#39;</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Repository</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$cache</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        ) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #7F848E;">//</span></div><div class='line'><span style="color: #ABB2BF;">        }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="3-config" href="#3-config" class="" aria-hidden="true" title=""></a>3. <code>#[Config]</code></h3>
<p>Injects configuration values directly into class dependencies.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Container\Attributes\</span><span style="color: #E5C07B;">Config</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">PhotoController</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Controller</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">__construct</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">        #[Config(</span><span style="color: #98C379;">&#39;app.timezone&#39;</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">string</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$timezone</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        ) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #7F848E;">//</span></div><div class='line'><span style="color: #ABB2BF;">        }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="4-currentuser" href="#4-currentuser" class="" aria-hidden="true" title=""></a>4. <code>#[CurrentUser]</code></h3>
<p>Injects the currently authenticated user.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Container\Attributes\</span><span style="color: #E5C07B;">CurrentUser</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Models\</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">PhotoController</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Controller</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">__construct</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">        #[CurrentUser]</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$currentUser</span></div><div class='line'><span style="color: #ABB2BF;">    ) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// $currentUser is the authenticated user instance</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="5-db" href="#5-db" class="" aria-hidden="true" title=""></a>5. <code>#[DB]</code></h3>
<p>Injects a specific database connection.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Container\Attributes\</span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\</span><span style="color: #E5C07B;">Connection</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">PhotoController</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Controller</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">__construct</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">        #[DB(</span><span style="color: #98C379;">&#39;mysql&#39;</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Connection</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$connection</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// $db is the &#39;mysql&#39; database connection</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="6-log" href="#6-log" class="" aria-hidden="true" title=""></a>6. <code>#[Log]</code></h3>
<p>Injects the logger instance into a class.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Container\Attributes\</span><span style="color: #E5C07B;">Log</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Psr\Log\</span><span style="color: #E5C07B;">LoggerInterface</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">PhotoController</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Controller</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">__construct</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">        #[Log(</span><span style="color: #98C379;">&#39;daily&#39;</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">LoggerInterface</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$log</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// $logger is the logger instance</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="7-routeparameter" href="#7-routeparameter" class="" aria-hidden="true" title=""></a>7. <code>#[RouteParameter]</code></h3>
<p>Injects a route parameter into a class.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Models\</span><span style="color: #E5C07B;">Photo</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Container\Attributes\</span><span style="color: #E5C07B;">RouteParameter</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">PhotoController</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Controller</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">__construct</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">        #[RouteParameter(</span><span style="color: #98C379;">&#39;photo&#39;</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Photo</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$photo</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #7F848E;">//</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="8-storage" href="#8-storage" class="" aria-hidden="true" title=""></a>8. <code>#[Storage]</code></h3>
<p>Injects the storage manager into a class.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Container\Attributes\</span><span style="color: #E5C07B;">Storage</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Contracts\Filesystem\</span><span style="color: #E5C07B;">Filesystem</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">PhotoController</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Controller</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">__construct</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">        #[Storage(</span><span style="color: #98C379;">&#39;local&#39;</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Filesystem</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$filesystem</span></div><div class='line'><span style="color: #ABB2BF;">    ) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">//</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="9-tag" href="#9-tag" class="" aria-hidden="true" title=""></a>9. <code>#[Tag]</code></h3>
<p>Tags a service for later retrieval.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Container\Attributes\</span><span style="color: #E5C07B;">Tag</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">PhotoController</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Controller</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">__construct</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">            #[Tag(</span><span style="color: #98C379;">&#39;reports&#39;</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">iterable</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$reports</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    )</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// ...</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="10-authenticated" href="#10-authenticated" class="" aria-hidden="true" title=""></a>10. <code>#[Authenticated]</code></h3>
<p>Injects the currently authenticated user (optionally for a given guard).</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Container\Attributes\</span><span style="color: #E5C07B;">Authenticated</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Contracts\Auth\</span><span style="color: #E5C07B;">Authenticatable</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">PhotoController</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Controller</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">__construct</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">        #[Authenticated(</span><span style="color: #98C379;">&#39;web&#39;</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> ?</span><span style="color: #E5C07B;">Authenticatable</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// $user is the authenticated user instance (or null)</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="11-bind" href="#11-bind" class="" aria-hidden="true" title=""></a>11. <code>#[Bind]</code></h3>
<p>Binds an abstract dependency to a concrete class.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Container\Attributes\</span><span style="color: #E5C07B;">Bind</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Contracts\</span><span style="color: #E5C07B;">PaymentGateway</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Services\</span><span style="color: #E5C07B;">StripeGateway</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">CheckoutController</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Controller</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">__construct</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">        #[Bind(</span><span style="color: #E5C07B;">StripeGateway</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">PaymentGateway</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$gateway</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">//</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="12-context" href="#12-context" class="" aria-hidden="true" title=""></a>12. <code>#[Context]</code></h3>
<p>Resolves a contextual value by key (supports a default).</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Container\Attributes\</span><span style="color: #E5C07B;">Context</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">PhotoController</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Controller</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">__construct</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">        #[Context(</span><span style="color: #98C379;">&#39;tenant.id&#39;</span><span style="color: #ABB2BF;">, default: </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> ?</span><span style="color: #E5C07B;">int</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$tenantId</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">//</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="13-database" href="#13-database" class="" aria-hidden="true" title=""></a>13. <code>#[Database]</code></h3>
<p>Injects a database connection (by name/enum).</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Container\Attributes\</span><span style="color: #E5C07B;">Database</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\</span><span style="color: #E5C07B;">Connection</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">PhotoController</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Controller</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">__construct</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">        #[Database(</span><span style="color: #98C379;">&#39;pgsql&#39;</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Connection</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$connection</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">//</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="14-give" href="#14-give" class="" aria-hidden="true" title=""></a>14. <code>#[Give]</code></h3>
<p>Provides a concrete class implementation (and params) for contextual dependency injection.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Container\Attributes\</span><span style="color: #E5C07B;">Give</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Contracts\</span><span style="color: #E5C07B;">ReportGenerator</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Services\</span><span style="color: #E5C07B;">PdfReportGenerator</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">ReportsController</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Controller</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">__construct</span><span style="color: #ABB2BF;">(</span></div><div class='line'><span style="color: #ABB2BF;">        #[Give(</span><span style="color: #E5C07B;">PdfReportGenerator</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">, [</span><span style="color: #98C379;">&#39;disk&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;local&#39;</span><span style="color: #ABB2BF;">])]</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">ReportGenerator</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$generator</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">    ) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">//</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="15-scoped" href="#15-scoped" class="" aria-hidden="true" title=""></a>15. <code>#[Scoped]</code></h3>
<p>Marks a class as scoped within the container.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Container\Attributes\</span><span style="color: #E5C07B;">Scoped</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">#[Scoped]</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">RequestCache</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">//</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="16-singleton" href="#16-singleton" class="" aria-hidden="true" title=""></a>16. <code>#[Singleton]</code></h3>
<p>Marks a class as a singleton within the container.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Container\Attributes\</span><span style="color: #E5C07B;">Singleton</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">#[Singleton]</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">AppWideRegistry</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">//</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="17-boot" href="#17-boot" class="" aria-hidden="true" title=""></a>17. <code>#[Boot]</code></h3>
<p>Marks a trait for Eloquent booting behavior.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\Attributes\</span><span style="color: #E5C07B;">Boot</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">#[Boot]</span></div><div class='line'><span style="color: #C678DD;">trait</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">HasSomethingToBoot</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// ...</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="18-initialize" href="#18-initialize" class="" aria-hidden="true" title=""></a>18. <code>#[Initialize]</code></h3>
<p>Marks a trait for Eloquent initialization behavior.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\Attributes\</span><span style="color: #E5C07B;">Initialize</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">#[Initialize]</span></div><div class='line'><span style="color: #C678DD;">trait</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">HasSomethingToInitialize</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// ...</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="19-scope" href="#19-scope" class="" aria-hidden="true" title=""></a>19. <code>#[Scope]</code></h3>
<p>Marks a method as a local scope.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\Attributes\</span><span style="color: #E5C07B;">Scope</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\</span><span style="color: #E5C07B;">Builder</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\</span><span style="color: #E5C07B;">Model</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Post</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Model</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    #[Scope]</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">published</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Builder</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$query</span><span style="color: #ABB2BF;">): </span><span style="color: #E5C07B;">Builder</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$query</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">where</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;published&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">true</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="20-scopedby" href="#20-scopedby" class="" aria-hidden="true" title=""></a>20. <code>#[ScopedBy]</code></h3>
<p>Applies one or more global scopes to a model.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\Attributes\</span><span style="color: #E5C07B;">ScopedBy</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\</span><span style="color: #E5C07B;">Model</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Models\Scopes\</span><span style="color: #E5C07B;">TenantScope</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">#[ScopedBy(</span><span style="color: #E5C07B;">TenantScope</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Post</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Model</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// ...</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="21-observedby" href="#21-observedby" class="" aria-hidden="true" title=""></a>21. <code>#[ObservedBy]</code></h3>
<p>Registers one or more observers for a model.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\Attributes\</span><span style="color: #E5C07B;">ObservedBy</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\</span><span style="color: #E5C07B;">Model</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Observers\</span><span style="color: #E5C07B;">PostObserver</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">#[ObservedBy(</span><span style="color: #E5C07B;">PostObserver</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Post</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Model</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// ...</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="22-collectedby" href="#22-collectedby" class="" aria-hidden="true" title=""></a>22. <code>#[CollectedBy]</code></h3>
<p>Associates a custom collection class with a model.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\Attributes\</span><span style="color: #E5C07B;">CollectedBy</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\</span><span style="color: #E5C07B;">Model</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Collections\</span><span style="color: #E5C07B;">PostCollection</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">#[CollectedBy(</span><span style="color: #E5C07B;">PostCollection</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Post</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Model</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// ...</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="23-usefactory" href="#23-usefactory" class="" aria-hidden="true" title=""></a>23. <code>#[UseFactory]</code></h3>
<p>Associates a factory class with a model.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\Attributes\</span><span style="color: #E5C07B;">UseFactory</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\</span><span style="color: #E5C07B;">Model</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Database\Factories\</span><span style="color: #E5C07B;">PostFactory</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">#[UseFactory(</span><span style="color: #E5C07B;">PostFactory</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Post</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Model</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// ...</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="24-useeloquentbuilder" href="#24-useeloquentbuilder" class="" aria-hidden="true" title=""></a>24. <code>#[UseEloquentBuilder]</code></h3>
<p>Uses a custom Eloquent builder class for a model.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\Attributes\</span><span style="color: #E5C07B;">UseEloquentBuilder</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\</span><span style="color: #E5C07B;">Model</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Database\</span><span style="color: #E5C07B;">PostBuilder</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">#[UseEloquentBuilder(</span><span style="color: #E5C07B;">PostBuilder</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Post</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Model</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// ...</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="25-usepolicy" href="#25-usepolicy" class="" aria-hidden="true" title=""></a>25. <code>#[UsePolicy]</code></h3>
<p>Associates a policy class with a model.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\Attributes\</span><span style="color: #E5C07B;">UsePolicy</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\</span><span style="color: #E5C07B;">Model</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Policies\</span><span style="color: #E5C07B;">PostPolicy</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">#[UsePolicy(</span><span style="color: #E5C07B;">PostPolicy</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Post</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Model</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// ...</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="26-useresource" href="#26-useresource" class="" aria-hidden="true" title=""></a>26. <code>#[UseResource]</code></h3>
<p>Associates an API resource class with a model.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\Attributes\</span><span style="color: #E5C07B;">UseResource</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\</span><span style="color: #E5C07B;">Model</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Http\Resources\</span><span style="color: #E5C07B;">PostResource</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">#[UseResource(</span><span style="color: #E5C07B;">PostResource</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Post</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Model</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// ...</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="27-useresourcecollection" href="#27-useresourcecollection" class="" aria-hidden="true" title=""></a>27. <code>#[UseResourceCollection]</code></h3>
<p>Associates an API resource collection class with a model.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\Attributes\</span><span style="color: #E5C07B;">UseResourceCollection</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\Eloquent\</span><span style="color: #E5C07B;">Model</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> App\Http\Resources\</span><span style="color: #E5C07B;">PostResourceCollection</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">#[UseResourceCollection(</span><span style="color: #E5C07B;">PostResourceCollection</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Post</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Model</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// ...</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="28-deletewhenmissingmodels" href="#28-deletewhenmissingmodels" class="" aria-hidden="true" title=""></a>28. <code>#[DeleteWhenMissingModels]</code></h3>
<p>Deletes a queued job if its related models can’t be found during deserialization.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Queue\Attributes\</span><span style="color: #E5C07B;">DeleteWhenMissingModels</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Contracts\Queue\</span><span style="color: #E5C07B;">ShouldQueue</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">#[DeleteWhenMissingModels]</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">ProcessOrder</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">implements</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">ShouldQueue</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// ...</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="29-withoutrelations" href="#29-withoutrelations" class="" aria-hidden="true" title=""></a>29. <code>#[WithoutRelations]</code></h3>
<p>Serializes Eloquent models on a job without relations.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Queue\Attributes\</span><span style="color: #E5C07B;">WithoutRelations</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Contracts\Queue\</span><span style="color: #E5C07B;">ShouldQueue</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">#[WithoutRelations]</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">SyncCustomer</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">implements</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">ShouldQueue</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// ...</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h2><a id="livewire-attributes" href="#livewire-attributes" class="" aria-hidden="true" title=""></a>Livewire Attributes</h2>
<p>Livewire introduces several attributes to enhance component functionality:</p>
<h3><a id="1-computed" href="#1-computed" class="" aria-hidden="true" title=""></a>1. <code>Computed</code></h3>
<p>The <code>#[Computed]</code> attribute is a way to create &quot;derived&quot; properties in Livewire. Like accessors on an Eloquent model, computed properties allow you to access values and cache them for future access during the request.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Livewire\Attributes\</span><span style="color: #E5C07B;">Computed</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">UserProfile</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Component</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$firstName</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$lastName</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    #[Computed]</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">getFullName</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;{</span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">firstName</span><span style="color: #98C379;">} {</span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">lastName</span><span style="color: #98C379;">}&quot;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>In this example, <code>getFullName</code> is a computed property that combines <code>firstName</code> and <code>lastName</code>.</p>
<h3><a id="2-isolate" href="#2-isolate" class="" aria-hidden="true" title=""></a>2. <code>Isolate</code></h3>
<p>By using Livewire's #[Isolate] class attribute, you can mark a component as &quot;isolated&quot;. This means that whenever that component makes a server roundtrip, it will attempt to isolate itself from other component requests.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Livewire\Attributes\</span><span style="color: #E5C07B;">Isolate</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">#[Isolate]</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">TodoList</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Component</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>This is useful if the update is expensive and you'd rather execute this component's update in parallel with others.</p>
<h3><a id="3-js" href="#3-js" class="" aria-hidden="true" title=""></a>3. <code>Js</code></h3>
<p>The <code>#[Js]</code> attribute is used to bind a JavaScript property directly to the component.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Livewire\Attributes\</span><span style="color: #E5C07B;">Js</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">NotificationComponent</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Component</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    #[Js]</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$isVisible</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">true</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>This property can now be used directly in the JavaScript side of the application to show or hide notifications.</p>
<h3><a id="4-layout" href="#4-layout" class="" aria-hidden="true" title=""></a>4. <code>Layout</code></h3>
<p>The <code>#[Layout]</code> attribute specifies the layout file that should be used by the component.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Livewire\Attributes\</span><span style="color: #E5C07B;">Layout</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">#[Layout(</span><span style="color: #98C379;">&#39;layouts.dashboard&#39;</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Dashboard</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Component</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>This would instruct Livewire to render the component within the <code>dashboard</code> layout.</p>
<h3><a id="5-lazy" href="#5-lazy" class="" aria-hidden="true" title=""></a>5. <code>Lazy</code></h3>
<p>Lazy-loaded components aren't full loaded until they enter the browser's viewport, for example when a user scrolls to one.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Livewire\Attributes\</span><span style="color: #E5C07B;">Lazy</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">#[Lazy]</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">UserProfile</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Component</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">//</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>In this case, the <code>$profileData</code> property will not be loaded until it's actually needed.</p>
<h3><a id="6-locked" href="#6-locked" class="" aria-hidden="true" title=""></a>6. <code>Locked</code></h3>
<p>The <code>#[Locked]</code> attribute prevents a property from being modified by the frontend.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Livewire\Attributes\</span><span style="color: #E5C07B;">Locked</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">UserSettings</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Component</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    #[Locked]</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$userId</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>In this example, the <code>$userId</code> property cannot be updated from the frontend.</p>
<h3><a id="7-modelable" href="#7-modelable" class="" aria-hidden="true" title=""></a>7. <code>Modelable</code></h3>
<p>The <code>#[Modelable]</code> attribute is used bind only one child component property from its parent component.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Livewire\Attributes\</span><span style="color: #E5C07B;">Modelable</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">PostForm</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Component</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    #[Modelable]</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$title</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="8-on" href="#8-on" class="" aria-hidden="true" title=""></a>8. <code>On</code></h3>
<p>The <code>#[On]</code> attribute binds an action or method to a specific event.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Livewire\Attributes\</span><span style="color: #E5C07B;">On</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">UserRegistered</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Component</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    #[On(</span><span style="color: #98C379;">&#39;userRegistered&#39;</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">handleNewUser</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// Handle the registration event</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>In this example, the method <code>handleNewUser</code> will be called when the <code>userRegistered</code> event is triggered.</p>
<h3><a id="9-reactive" href="#9-reactive" class="" aria-hidden="true" title=""></a>9. <code>Reactive</code></h3>
<p>The <code>#[Reactive]</code> attribute marks a property as reactive, meaning any child component properties will automatically update on the frontend when something in the parent component changes.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Livewire\Attributes\</span><span style="color: #E5C07B;">Reactive</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Counter</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Component</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    #[Reactive]</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$count</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">0</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">increment</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">count</span><span style="color: #ABB2BF;">++;</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="10-renderless" href="#10-renderless" class="" aria-hidden="true" title=""></a>10. <code>Renderless</code></h3>
<p>The <code>#[Renderless]</code> attribute is used to indicate that a component does not render any view, but it can be used for logic purposes.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Livewire\Attributes\</span><span style="color: #E5C07B;">Renderless</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">FormLogic</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Component</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    #[Renderless]</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">validateForm</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// Perform form validation logic</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>This class will not render any view but can handle the form validation logic.</p>
<h3><a id="11-rule" href="#11-rule" class="" aria-hidden="true" title=""></a>11. <code>Rule</code></h3>
<p>The <code>#[Rule]</code> attribute is used to define custom validation rules on component properties.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Livewire\Attributes\</span><span style="color: #E5C07B;">Rule</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">RegisterUser</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Component</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    #[Rule(</span><span style="color: #98C379;">&#39;required|string|max:255&#39;</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$username</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>This will enforce a validation rule on the <code>$username</code> property.</p>
<h3><a id="12-session" href="#12-session" class="" aria-hidden="true" title=""></a>12. <code>Session</code></h3>
<p>The <code>#[Session]</code> attribute binds a component property to the session.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Livewire\Attributes\</span><span style="color: #E5C07B;">Session</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">UserProfile</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Component</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    #[Session]</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$theme</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>This stores the <code>$theme</code> property in the session so it persists across requests.</p>
<h3><a id="13-title" href="#13-title" class="" aria-hidden="true" title=""></a>13. <code>Title</code></h3>
<p>The <code>#[Title]</code> attribute allows you to specify the title of the component’s view.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Livewire\Attributes\</span><span style="color: #E5C07B;">Title</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">#[Title(</span><span style="color: #98C379;">&#39;My Custom Page Title&#39;</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">PageTitle</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Component</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">render</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">view</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;page&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>This will set the page's title to &quot;My Custom Page Title&quot;.</p>
<h3><a id="14-url" href="#14-url" class="" aria-hidden="true" title=""></a>14. <code>Url</code></h3>
<p>The <code>#[Url]</code> attribute binds a property to the URL.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Livewire\Attributes\</span><span style="color: #E5C07B;">Url</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Navigation</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Component</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    #[Url]</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$currentUrl</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;&#39;</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>This makes the <code>$currentUrl</code> property automatically reflect the URL of the current page.</p>
<h3><a id="15-async" href="#15-async" class="" aria-hidden="true" title=""></a>15. <code>Async</code></h3>
<p>The <code>#[Async]</code> attribute allows an action method to run in parallel without blocking other requests.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Livewire\Attributes\</span><span style="color: #E5C07B;">Async</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">PostShow</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Component</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    #[Async]</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">logActivity</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// fire-and-forget side effect</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="16-defer" href="#16-defer" class="" aria-hidden="true" title=""></a>16. <code>Defer</code></h3>
<p>The <code>#[Defer]</code> attribute defers loading a component until right after the initial page load is complete.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Livewire\Attributes\</span><span style="color: #E5C07B;">Defer</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">#[Defer]</span></div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">RevenueWidget</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Component</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">//</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="17-json" href="#17-json" class="" aria-hidden="true" title=""></a>17. <code>Json</code></h3>
<p>The <code>#[Json]</code> attribute marks an action as a JSON endpoint so it can return data directly to JavaScript.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Livewire\Attributes\</span><span style="color: #E5C07B;">Json</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Search</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Component</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    #[Json]</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">search</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$query</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> []; </span><span style="color: #7F848E;">// return JSON directly to JS</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="18-validate" href="#18-validate" class="" aria-hidden="true" title=""></a>18. <code>Validate</code></h3>
<p>The <code>#[Validate]</code> attribute associates validation rules with component properties.</p>
<p><strong>Example</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Livewire\Attributes\</span><span style="color: #E5C07B;">Validate</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">PostCreate</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Component</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    #[Validate(</span><span style="color: #98C379;">&#39;required|min:3&#39;</span><span style="color: #ABB2BF;">)]</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$title</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;&#39;</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">save</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validate</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">//</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>With <strong>45+ PHP attributes</strong> in Laravel and Livewire, developers have a wide range of tools to simplify workflows, improve code clarity, and leverage modern PHP practices. These attributes reduce boilerplate and bring expressive, declarative coding to your applications.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Wed, 24 Dec 2025 21:00:44 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Add Logic To Laravel Requests Conditionally ]]></title>
                <link>https://nabilhassen.com/add-logic-to-laravel-requests-conditionally</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#introduction">Introduction</a></li>
<li><a href="#the-problem">The Problem</a></li>
<li><a href="#the-solution-when-method">The Solution: when() Method</a></li>
<li><a href="#how-it-works">How It Works</a>
<ul>
<li><a href="#method-signature">Method Signature:</a></li>
</ul>
</li>
<li><a href="#key-benefits">Key Benefits</a></li>
<li><a href="#real-world-example">Real-World Example</a>
<ul>
<li><a href="#before">Before:</a></li>
<li><a href="#after-laravel-11350">After (Laravel 11.35.0):</a></li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="introduction" href="#introduction" class="" aria-hidden="true" title=""></a>Introduction</h2>
<p>Laravel 11.35.0 introduces a powerful addition to the <code>Request</code> class — support for the <code>when()</code> method via the <code>Conditionable</code> trait. This feature, contributed by <a rel="nofollow noopener" target="_blank" href="https://twitter.com/ahmet_imamoglu">Ahmet İmrak</a>, allows developers to apply conditional logic seamlessly when working with incoming request data. This makes your code cleaner, more expressive, and aligns the <code>Request</code> class with other conditionable parts of the Laravel ecosystem like the Query Builder.</p>
<h2><a id="the-problem" href="#the-problem" class="" aria-hidden="true" title=""></a>The Problem</h2>
<p>Previously, conditional handling of incoming request data often required verbose <code>if</code> statements or repetitive inline checks. For example:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">input</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;account_id&#39;</span><span style="color: #ABB2BF;">)) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">merge</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;account_name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E5C07B;">Account</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">getName</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">input</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;account_id&#39;</span><span style="color: #ABB2BF;">))]);</span></div><div class='line'><span style="color: #ABB2BF;">} </span><span style="color: #C678DD;">else</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">merge</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;account_name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">]);</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">input</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;contact_id&#39;</span><span style="color: #ABB2BF;">)) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">merge</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;contact_name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E5C07B;">Contact</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">getName</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">input</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;contact_id&#39;</span><span style="color: #ABB2BF;">))]);</span></div><div class='line'><span style="color: #ABB2BF;">} </span><span style="color: #C678DD;">else</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">merge</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;contact_name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">]);</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Such conditional logic, though functional, is repetitive and harder to maintain as the number of conditions grows.</p>
<h2><a id="the-solution-when-method" href="#the-solution-when-method" class="" aria-hidden="true" title=""></a>The Solution: <code>when()</code> Method</h2>
<p>With Laravel 11.35.0, the <code>Request</code> class now uses the <code>Conditionable</code> trait, enabling the use of the <code>when()</code> method to streamline conditional operations. Here’s an example of how the same logic looks with the new method:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">prepareForValidation</span><span style="color: #ABB2BF;">(): </span><span style="color: #E5C07B;">void</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">when</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">input</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;account_id&#39;</span><span style="color: #ABB2BF;">),</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">fn</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$req</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">int</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$accountId</span><span style="color: #ABB2BF;">) =&gt; </span><span style="color: #E06C75;">$req</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">merge</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;account_name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E5C07B;">Account</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">getName</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$accountId</span><span style="color: #ABB2BF;">)]),</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">fn</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$req</span><span style="color: #ABB2BF;">) =&gt; </span><span style="color: #E06C75;">$req</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">merge</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;account_name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">])</span></div><div class='line'><span style="color: #ABB2BF;">    )-&gt;</span><span style="color: #61AFEF;">when</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">input</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;contact_id&#39;</span><span style="color: #ABB2BF;">),</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">fn</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$req</span><span style="color: #ABB2BF;">, </span><span style="color: #E5C07B;">int</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$contactId</span><span style="color: #ABB2BF;">) =&gt; </span><span style="color: #E06C75;">$req</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">merge</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;contact_name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E5C07B;">Contact</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">getName</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$contactId</span><span style="color: #ABB2BF;">)]),</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #C678DD;">fn</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$req</span><span style="color: #ABB2BF;">) =&gt; </span><span style="color: #E06C75;">$req</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">merge</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;contact_name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">])</span></div><div class='line'><span style="color: #ABB2BF;">    );</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h2><a id="how-it-works" href="#how-it-works" class="" aria-hidden="true" title=""></a>How It Works</h2>
<p>The <code>when()</code> method applies a callback when the given condition resolves to a truthy value. Additionally, you can pass a &quot;default&quot; callback to handle cases where the condition is falsy.</p>
<h3><a id="method-signature" href="#method-signature" class="" aria-hidden="true" title=""></a>Method Signature:</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">when</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$value</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">, ?</span><span style="color: #E5C07B;">callable</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$callback</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">, ?</span><span style="color: #E5C07B;">callable</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$default</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">null</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<ul>
<li><strong><code>$value</code>:</strong> The condition to evaluate (e.g., a request input value).</li>
<li><strong><code>$callback</code>:</strong> Executed if the condition is truthy.</li>
<li><strong><code>$default</code>:</strong> Executed if the condition is falsy.</li>
</ul>
<hr />
<h2><a id="key-benefits" href="#key-benefits" class="" aria-hidden="true" title=""></a>Key Benefits</h2>
<ol>
<li><strong>Cleaner Code:</strong> Removes repetitive <code>if</code> statements and simplifies conditional logic.</li>
<li><strong>Readability:</strong> Code becomes more expressive and easier to follow.</li>
<li><strong>Reusability:</strong> Aligns the <code>Request</code> class with other conditionable components like Collections and Query Builder.</li>
</ol>
<hr />
<h2><a id="real-world-example" href="#real-world-example" class="" aria-hidden="true" title=""></a>Real-World Example</h2>
<p>Imagine you’re preparing request data for validation. With the <code>when()</code> method, you can handle multiple conditionals concisely:</p>
<h3><a id="before" href="#before" class="" aria-hidden="true" title=""></a>Before:</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">if</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">input</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;is_admin&#39;</span><span style="color: #ABB2BF;">)) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">merge</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;role&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;admin&#39;</span><span style="color: #ABB2BF;">]);</span></div><div class='line'><span style="color: #ABB2BF;">} </span><span style="color: #C678DD;">else</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">merge</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;role&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;user&#39;</span><span style="color: #ABB2BF;">]);</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<h3><a id="after-laravel-11350" href="#after-laravel-11350" class="" aria-hidden="true" title=""></a>After (Laravel 11.35.0):</h3>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">when</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">$this</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">input</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;is_admin&#39;</span><span style="color: #ABB2BF;">),</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">fn</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$req</span><span style="color: #ABB2BF;">) =&gt; </span><span style="color: #E06C75;">$req</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">merge</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;role&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;admin&#39;</span><span style="color: #ABB2BF;">]),</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">fn</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$req</span><span style="color: #ABB2BF;">) =&gt; </span><span style="color: #E06C75;">$req</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">merge</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;role&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;user&#39;</span><span style="color: #ABB2BF;">])</span></div><div class='line'><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>This results in cleaner and more maintainable code.</p>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>The addition of the <code>when()</code> method to the <code>Request</code> class in Laravel 11.35.0 is a significant improvement for developers. Thanks to Ahmet İmrak's contribution, conditional logic in request data handling is now more elegant, readable, and aligned with Laravel’s fluent and expressive syntax.</p>
<p>Upgrade to Laravel 11.35.0 to take advantage of this feature and simplify your request processing logic.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 17 Dec 2024 14:23:56 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[6 Ways to Fix "could not find driver" error in Laravel]]></title>
                <link>https://nabilhassen.com/6-ways-to-fix-could-not-find-driver-error-in-laravel</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#what-is-the-laravel-could-not-find-driver-error">What is the Laravel &quot;could not find driver&quot; Error</a></li>
<li><a href="#common-causes-of-the-could-not-find-driver-error-in-laravel">Common Causes of the &quot;could not find driver&quot; error in Laravel</a></li>
<li><a href="#how-to-solve-could-not-find-driver-error-in-laravel">How to Solve &quot;could not find driver&quot; error in Laravel</a></li>
<li><a href="#best-practices-to-prevent-issues">Best Practices to Prevent Issues</a></li>
</ul>
<h2><a id="what-is-the-laravel-could-not-find-driver-error" href="#what-is-the-laravel-could-not-find-driver-error" class="" aria-hidden="true" title=""></a>What is the Laravel &quot;could not find driver&quot; Error</h2>
<p>The &quot;PDOException: could not find driver&quot; error in Laravel occurs when the application fails to locate the necessary PDO extension for database connections. This guide explains common causes, solutions for different environments, and best practices.</p>
<h2><a id="common-causes-of-the-could-not-find-driver-error-in-laravel" href="#common-causes-of-the-could-not-find-driver-error-in-laravel" class="" aria-hidden="true" title=""></a>Common Causes of the &quot;could not find driver&quot; error in Laravel</h2>
<ol>
<li><strong>Missing PDO Driver Extension:</strong> The required PDO extension (e.g., <code>pdo_mysql</code> or <code>pdo_pgsql</code>) is not installed or enabled.</li>
<li><strong>Incorrect PHP Configuration:</strong> Relevant extensions are not activated in the <code>php.ini</code> file.</li>
<li><strong>Server Environment Mismatch:</strong> The PHP version or server setup lacks compatibility with the required database drivers.</li>
<li><strong>Improper <code>.env</code> Configuration:</strong> Database credentials or connection settings in Laravel’s <code>.env</code> file are misconfigured.</li>
</ol>
<h2><a id="how-to-solve-could-not-find-driver-error-in-laravel" href="#how-to-solve-could-not-find-driver-error-in-laravel" class="" aria-hidden="true" title=""></a>How to Solve &quot;could not find driver&quot; error in Laravel</h2>
<ol>
<li>
<p><strong>General Fixes</strong></p>
<ul>
<li><strong>Install PDO Extensions</strong><br />
Ensure required PDO drivers are installed:</li>
</ul>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">sudo </span><span style="color: #98C379;">apt</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">install</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">php-mysql</span><span style="color: #ABB2BF;"> </span><span style="color: #7F848E;"># For MySQL</span></div><div class='line'><span style="color: #ABB2BF;">sudo </span><span style="color: #98C379;">apt</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">install</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">php-pgsql</span><span style="color: #ABB2BF;"> </span><span style="color: #7F848E;"># For PostgreSQL</span></div><div class='line'><span style="color: #ABB2BF;">sudo </span><span style="color: #98C379;">apt</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">install</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">php-sqlite3</span><span style="color: #ABB2BF;"> </span><span style="color: #7F848E;"># For SQLite</span></div></code></pre>
<p>Restart your web server:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">sudo </span><span style="color: #98C379;">service</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">apache2</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">restart</span></div></code></pre>
<ul>
<li><strong>Verify PHP Configuration</strong><br />
Check and enable extensions in the <code>php.ini</code> file:</li>
</ul>
<pre><code data-theme="one-dark-pro" data-lang="ini" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">extension</span><span style="color: #ABB2BF;">=</span><span style="color: #98C379;">pdo_mysql</span></div><div class='line'><span style="color: #C678DD;">extension</span><span style="color: #ABB2BF;">=</span><span style="color: #98C379;">pdo_pgsql</span></div><div class='line'><span style="color: #C678DD;">extension</span><span style="color: #ABB2BF;">=</span><span style="color: #98C379;">pdo_sqlite</span></div></code></pre>
<ul>
<li><strong>Clear Laravel Cache</strong><br />
After fixing configurations, clear Laravel caches to avoid old settings causing issues:</li>
</ul>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">config:clear</span></div><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">cache:clear</span></div><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">config:cache</span></div></code></pre>
</li>
<li>
<p><strong>Local Development Environment</strong></p>
<ul>
<li>For tools like Laravel Valet or Laragon, ensure PHP drivers are correctly installed as they manage PHP versions internally.</li>
</ul>
</li>
<li>
<p><strong>Shared Hosting</strong></p>
<ul>
<li>If you cannot modify <code>php.ini</code>, contact your hosting provider to enable required drivers.</li>
<li>Confirm the PHP version and database driver compatibility offered by the host.</li>
</ul>
</li>
<li>
<p><strong>Docker Environments</strong></p>
<ul>
<li>Add PDO extensions to your Dockerfile:</li>
</ul>
<pre><code data-theme="one-dark-pro" data-lang="dockerfile" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #61AFEF;">RUN</span><span style="color: #ABB2BF;"> docker-php-ext-install pdo pdo_mysql</span></div></code></pre>
<ul>
<li>Rebuild and restart your containers:</li>
</ul>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">docker-compose </span><span style="color: #98C379;">up</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--build</span></div></code></pre>
</li>
<li>
<p><strong>Production Servers</strong></p>
<ul>
<li>Verify the server has required drivers:</li>
</ul>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #D19A66;">-m</span><span style="color: #ABB2BF;"> | grep </span><span style="color: #98C379;">pdo</span></div></code></pre>
<ul>
<li>If missing, install them using package managers (<code>yum</code> or <code>apt</code>) based on your server's operating system.</li>
</ul>
</li>
<li>
<p><strong>Other Advanced Tips</strong></p>
<ul>
<li><strong>Update PHP:</strong> Outdated PHP versions might lack support for specific drivers. Ensure you are using a version compatible with your Laravel project.</li>
<li><strong>Cross-Check Database Configuration:</strong> Reconfirm <code>.env</code> settings:</li>
</ul>
<pre><code data-theme="one-dark-pro" data-lang="dotenv" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #abb2bf;">DB_CONNECTION=mysql</span></div><div class='line'><span style="color: #abb2bf;">DB_HOST=127.0.0.1</span></div><div class='line'><span style="color: #abb2bf;">DB_PORT=3306</span></div><div class='line'><span style="color: #abb2bf;">DB_DATABASE=your_database</span></div><div class='line'><span style="color: #abb2bf;">DB_USERNAME=your_username</span></div><div class='line'><span style="color: #abb2bf;">DB_PASSWORD=your_password</span></div></code></pre>
</li>
</ol>
<h2><a id="best-practices-to-prevent-issues" href="#best-practices-to-prevent-issues" class="" aria-hidden="true" title=""></a>Best Practices to Prevent Issues</h2>
<ol>
<li>Regularly update PHP, Laravel, and database drivers.</li>
<li>Use development tools like Laravel Sail, Valet, or Laragon for easier environment management.</li>
<li>When using Docker, maintain proper configuration for extensions in <code>docker-compose.yml</code> or Dockerfiles.</li>
<li>Always verify server settings during deployment and ensure compatibility between application and server configurations.</li>
</ol>
<p>By addressing these aspects, you can resolve and prevent the &quot;could not find driver&quot; error in Laravel effectively.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Mon, 16 Dec 2024 07:53:40 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Master Laravel Where Not Queries to Exclude Unwanted Data]]></title>
                <link>https://nabilhassen.com/master-laravel-where-not-queries-to-exclude-unwanted-data</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#understanding-wherenot-queries-in-laravel">Understanding whereNot Queries in Laravel</a></li>
<li><a href="#all-types-of-wherenot-queries-in-laravel">All Types of whereNot Queries in Laravel</a>
<ul>
<li><a href="#1-wherenot">1. whereNot</a></li>
<li><a href="#2-wherenotin">2. whereNotIn</a></li>
<li><a href="#3-wherenotnull">3. whereNotNull</a></li>
<li><a href="#4-wherenull">4. whereNull</a></li>
<li><a href="#5-wherenotbetween">5. whereNotBetween</a></li>
<li><a href="#6-wherenotexists">6. whereNotExists</a></li>
<li><a href="#7-wherenot-with-closures">7. whereNot with Closures</a></li>
</ul>
</li>
<li><a href="#combining-wherenot-with-other-conditions">Combining whereNot with Other Conditions</a></li>
<li><a href="#wrapping-up">Wrapping Up</a></li>
</ul>
<h2><a id="understanding-wherenot-queries-in-laravel" href="#understanding-wherenot-queries-in-laravel" class="" aria-hidden="true" title=""></a>Understanding <code>whereNot</code> Queries in Laravel</h2>
<p><code>whereNot</code> queries in Laravel are used to fetch records that do <strong>not</strong> meet a specific condition. For example, if you want to retrieve all users except those with the role of &quot;admin,&quot; you can use a <code>whereNot</code> query to achieve this.</p>
<p>These queries help you exclude data from your results, making it easy to focus only on the information you need.</p>
<h2><a id="all-types-of-wherenot-queries-in-laravel" href="#all-types-of-wherenot-queries-in-laravel" class="" aria-hidden="true" title=""></a>All Types of <code>whereNot</code> Queries in Laravel</h2>
<h3><a id="1-wherenot" href="#1-wherenot" class="" aria-hidden="true" title=""></a>1. <code>whereNot</code></h3>
<p>This method excludes results based on a single condition. For instance:</p>
<p><strong>Example: Exclude Users with a Specific Role</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// these are equivalent to the whereNot method</span></div><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">where</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;role&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;!=&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;admin&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">where</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;role&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;&lt;&gt;&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;admin&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereNot</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;role&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;admin&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>This query retrieves all users whose <code>role</code> column is <strong>not</strong> equal to &quot;admin.&quot;</p>
<h3><a id="2-wherenotin" href="#2-wherenotin" class="" aria-hidden="true" title=""></a>2. <code>whereNotIn</code></h3>
<p>If you need to exclude multiple values from your results, use <code>whereNotIn</code>.</p>
<p><strong>Example: Exclude Multiple Roles</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereNotIn</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;role&#39;</span><span style="color: #ABB2BF;">, [</span><span style="color: #98C379;">&#39;admin&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;editor&#39;</span><span style="color: #ABB2BF;">])-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>This query excludes users with roles of either &quot;admin&quot; or &quot;editor.&quot;</p>
<h3><a id="3-wherenotnull" href="#3-wherenotnull" class="" aria-hidden="true" title=""></a>3. <code>whereNotNull</code></h3>
<p>To exclude records where a column is null, you can use <code>whereNotNull</code>.</p>
<p><strong>Example: Fetch Users with Non-Empty Emails</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereNotNull</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;email&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>This query retrieves all users who have an email address.</p>
<h3><a id="4-wherenull" href="#4-wherenull" class="" aria-hidden="true" title=""></a>4. <code>whereNull</code></h3>
<p>Although not exactly a <code>whereNot</code> query, its complement <code>whereNull</code> can also be used effectively. For example:</p>
<p><strong>Example: Fetch Users without an Email Address</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereNull</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;email&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>This query retrieves all users whose <code>email</code> column is null.</p>
<h3><a id="5-wherenotbetween" href="#5-wherenotbetween" class="" aria-hidden="true" title=""></a>5. <code>whereNotBetween</code></h3>
<p>If you need to exclude records that fall within a specific range, use <code>whereNotBetween</code>.</p>
<p><strong>Example: Exclude Orders within a Date Range</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$orders</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Order</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereNotBetween</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;created_at&#39;</span><span style="color: #ABB2BF;">, [</span><span style="color: #98C379;">&#39;2024-01-01&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;2024-12-31&#39;</span><span style="color: #ABB2BF;">])-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>This query retrieves all orders outside the given date range.</p>
<h3><a id="6-wherenotexists" href="#6-wherenotexists" class="" aria-hidden="true" title=""></a>6. <code>whereNotExists</code></h3>
<p>To exclude results based on a related query, use <code>whereNotExists</code>.</p>
<p><strong>Example: Exclude Users Without Orders</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereNotExists</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$query</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$query</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">select</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">raw</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">1</span><span style="color: #ABB2BF;">))</span></div><div class='line'><span style="color: #ABB2BF;">          -&gt;</span><span style="color: #61AFEF;">from</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;orders&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">          -&gt;</span><span style="color: #61AFEF;">whereRaw</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;orders.user_id = users.id&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">})-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>This query retrieves users who do not have any orders in the <code>orders</code> table.</p>
<h3><a id="7-wherenot-with-closures" href="#7-wherenot-with-closures" class="" aria-hidden="true" title=""></a>7. <code>whereNot</code> with Closures</h3>
<p>For more complex logic, you can use a closure inside a <code>whereNot</code> query.</p>
<p><strong>Example: Exclude Users Based on Multiple Conditions</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereNot</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$query</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$query</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">where</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;role&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;admin&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">          -&gt;</span><span style="color: #61AFEF;">orWhere</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;is_active&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">false</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">})-&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>This query retrieves all users who are not admins and are also active.</p>
<p><em><strong>Note that all of the above where not methods could be used in an &quot;OR&quot; condition such as <code>orWhereNot</code>, <code>orWhereNotIn</code>, etc.</strong></em></p>
<h2><a id="combining-wherenot-with-other-conditions" href="#combining-wherenot-with-other-conditions" class="" aria-hidden="true" title=""></a>Combining <code>whereNot</code> with Other Conditions</h2>
<p>You can combine <code>whereNot</code> queries with other methods to refine your results. For instance:</p>
<p><strong>Example: Fetch Active Users Excluding Admins</strong></p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$users</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">whereNot</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;role&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;admin&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">where</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;is_active&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #D19A66;">true</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">get</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<p>This query retrieves all active users whose role is <strong>not</strong> &quot;admin.&quot;</p>
<h2><a id="wrapping-up" href="#wrapping-up" class="" aria-hidden="true" title=""></a>Wrapping Up</h2>
<p><code>whereNot</code> and its related methods (<code>whereNotIn</code>, <code>whereNotNull</code>, <code>whereNotBetween</code>, <code>whereNotExists</code>, and <code>whereNot</code> with closures) give you powerful tools to exclude unwanted data from your queries. Understanding and mastering these methods will help you write cleaner and more efficient Laravel code.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Thu, 12 Dec 2024 07:38:10 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Laravel 11.35.0: Introducing the URI Class]]></title>
                <link>https://nabilhassen.com/laravel-11350-introducing-the-uri-class</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#introducing-the-uri-class-in-laravel-11350">Introducing the Uri Class in Laravel 11.35.0</a></li>
<li><a href="#what-is-the-uri-class">What is the Uri Class?</a></li>
<li><a href="#usage-examples">Usage Examples</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="introducing-the-uri-class-in-laravel-11350" href="#introducing-the-uri-class-in-laravel-11350" class="" aria-hidden="true" title=""></a>Introducing the <code>Uri</code> Class in Laravel 11.35.0</h2>
<p>Laravel 11.35.0 introduces a fantastic new feature: the <code>Uri</code> class, contributed by <strong><a rel="nofollow noopener" target="_blank" href="https://x.com/taylorotwell">Taylor Otwell</a></strong>. This new addition makes working with URIs (Uniform Resource Identifiers) in Laravel applications easier and more expressive.</p>
<h2><a id="what-is-the-uri-class" href="#what-is-the-uri-class" class="" aria-hidden="true" title=""></a>What is the <code>Uri</code> Class?</h2>
<p>The <code>Uri</code> class provides methods for handling and manipulating URIs. It allows developers to extract components such as schemes, hosts, paths, queries, and ports more cleanly and conveniently.</p>
<p>Here’s how you can use it:</p>
<h2><a id="usage-examples" href="#usage-examples" class="" aria-hidden="true" title=""></a>Usage Examples</h2>
<ol>
<li><strong>Creating URI instances with <code>Uri::of</code></strong></li>
</ol>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$uri</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Uri</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">of</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;https://laravel.com&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">withQuery</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Taylor&#39;</span><span style="color: #ABB2BF;">])</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">withPath</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;/docs/installation&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">withFragment</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;hello-world&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// some of the available methods</span></div><div class='line'><span style="color: #E06C75;">$uri</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">scheme</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #E06C75;">$uri</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">host</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #E06C75;">$uri</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">user</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #E06C75;">$uri</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">password</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #E06C75;">$uri</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">path</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #E06C75;">$uri</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">port</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #E06C75;">$uri</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">query</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">all</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #E06C75;">$uri</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">query</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">has</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$uri</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">query</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">missing</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #E06C75;">$uri</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">query</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">decode</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">string</span><span style="color: #ABB2BF;">) </span><span style="color: #E06C75;">$uri</span><span style="color: #ABB2BF;">;</span></div></code></pre>
<ol start="2">
<li><strong>Retrieve URI instance from the current request</strong></li>
</ol>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$uri</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">uri</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<ol start="3">
<li><strong>Retrieve absolute URL for a path</strong></li>
</ol>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// will append &quot;/something&quot; to your app&#39;s base url and returns an absolute URL</span></div><div class='line'><span style="color: #E06C75;">$uri</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Uri</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">to</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;/something&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">withQuery</span><span style="color: #ABB2BF;">(...);</span></div></code></pre>
<ol start="4">
<li><strong>URI with named routes</strong></li>
</ol>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$uri</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Uri</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">route</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;named-route&#39;</span><span style="color: #ABB2BF;">, [</span><span style="color: #98C379;">&#39;user&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">]);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;">// generates a redirect to the location</span></div><div class='line'><span style="color: #C678DD;">return</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Uri</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">route</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;named-route&#39;</span><span style="color: #ABB2BF;">, [</span><span style="color: #98C379;">&#39;user&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">])-&gt;</span><span style="color: #61AFEF;">withQuery</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;Taylor&#39;</span><span style="color: #ABB2BF;">]);</span></div></code></pre>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>Before this release, developers often relied on PHP's native <code>parse_url</code> function, which could be cumbersome and error-prone. The new <code>Uri</code> class in Laravel provides an elegant and developer-friendly API for these tasks, ensuring better readability and maintainability. For more detail about this feature, check out <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/53731">pull request #53731</a>.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Wed, 11 Dec 2024 13:22:56 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Laravel Routing: Add Conditional Logic To Routes]]></title>
                <link>https://nabilhassen.com/laravel-routing-add-conditional-logic-to-routes</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#introduction">Introduction</a></li>
<li><a href="#the-problem-it-solves">The Problem It Solves</a></li>
<li><a href="#how-it-works">How It Works</a></li>
<li><a href="#supported-versions">Supported Versions</a></li>
</ul>
<h2><a id="introduction" href="#introduction" class="" aria-hidden="true" title=""></a>Introduction</h2>
<p>Laravel 11.34.0 introduces the famous <code>Conditionable</code> trait to the route management allowing to add conditional logic when defining routes with the <code>when()</code> method. This enhancement allows developers to add conditional logic when defining routes, bringing more flexibility and clarity to route definitions. This feature was introduced by <a rel="nofollow noopener" target="_blank" href="https://github.com/Boorinio">Boorinio</a> and merged as part of pull request <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/53654">#53654</a>.</p>
<h2><a id="the-problem-it-solves" href="#the-problem-it-solves" class="" aria-hidden="true" title=""></a>The Problem It Solves</h2>
<p>Previously, managing conditional logic for route definitions required more verbose or complex logic, often intertwined with other parts of your application. This new method simplifies the process, making route files cleaner and easier to understand.</p>
<h2><a id="how-it-works" href="#how-it-works" class="" aria-hidden="true" title=""></a>How It Works</h2>
<p>The <code>when()</code> method can be applied to define routes that load only when a given condition is true or to add any route related logic based on specified conditions. Here’s an example:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">Route</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">middleware</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;shop&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">domain</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;{shop}.domain.com&#39;</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">when</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">App</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">isProduction</span><span style="color: #ABB2BF;">(), </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E06C75;">$route</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$route</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">whereIn</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;shop&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #61AFEF;">app</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">ShopService</span><span style="color: #ABB2BF;">::</span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">getShopSlugs</span><span style="color: #ABB2BF;">());</span></div><div class='line'><span style="color: #ABB2BF;">    });</span></div></code></pre>
<p>This improvement not only enhances readability but also allows developers to control route availability dynamically based on various application states or configurations.</p>
<h2><a id="supported-versions" href="#supported-versions" class="" aria-hidden="true" title=""></a>Supported Versions</h2>
<p>The <code>when()</code> method is available on routes starting from Laravel 11.34.0.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Tue, 10 Dec 2024 10:14:51 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Laravel Migrations: Create Custom Column Types With rawColumn]]></title>
                <link>https://nabilhassen.com/laravel-migrations-create-custom-column-types-with-rawcolumn</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#introduction">Introduction</a></li>
<li><a href="#the-problem">The Problem</a></li>
<li><a href="#the-solution">The Solution</a></li>
<li><a href="#advantages">Advantages</a></li>
<li><a href="#considerations">Considerations</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="introduction" href="#introduction" class="" aria-hidden="true" title=""></a>Introduction</h2>
<p>Laravel's schema builder has a new feature released in v11.32.0: the <code>Blueprint::rawColumn()</code> method contributed by <a rel="nofollow noopener" target="_blank" href="https://github.com/Jacobs63">Jakub Potocký</a>. This addition simplifies the process of creating and updating custom column types that are not natively supported by Laravel grammers directly in migrations, addressing limitations with database-specific syntax.</p>
<h2><a id="the-problem" href="#the-problem" class="" aria-hidden="true" title=""></a>The Problem</h2>
<p>Previously, custom column definitions required raw SQL via <code>DB::statement</code>. This approach disrupted the logical flow of migrations because <code>DB::statement</code> cannot be used within table creation callbacks (i.e., <code>Schema::create</code>), as it executes immediately. The solution was to first define the <code>Schema::create</code>, then use <code>DB::statement</code> for definitions not natively supported, and finally, if needed, close with <code>Schema::table</code>.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">new</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Migration</span><span style="color: #ABB2BF;"> {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">up</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Schema</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">create</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;posts&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Blueprint</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$table</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E06C75;">$table</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">id</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">        });</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">DB</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">statement</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;alter table `posts` add `legacy_boolean` int(1) default 0 not null&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Schema</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">table</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;posts&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Blueprint</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$table</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E06C75;">$table</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">index</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;id&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;legacy_boolean&#39;</span><span style="color: #ABB2BF;">]);</span></div><div class='line'><span style="color: #ABB2BF;">        });</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">};</span></div></code></pre>
<h2><a id="the-solution" href="#the-solution" class="" aria-hidden="true" title=""></a>The Solution</h2>
<p><code>rawColumn()</code> allows you to specify custom SQL definitions inline during table creation. Example:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">Schema</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">create</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;posts&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> (</span><span style="color: #E5C07B;">Blueprint</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$table</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$table</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">id</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$table</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">rawColumn</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;legacy_boolean&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;int(1)&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">default</span><span style="color: #ABB2BF;">(</span><span style="color: #D19A66;">0</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$table</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">index</span><span style="color: #ABB2BF;">([</span><span style="color: #98C379;">&#39;id&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;legacy_boolean&#39;</span><span style="color: #ABB2BF;">]);</span></div><div class='line'><span style="color: #ABB2BF;">});</span></div></code></pre>
<h2><a id="advantages" href="#advantages" class="" aria-hidden="true" title=""></a>Advantages</h2>
<ol>
<li>Cleaner, more readable migrations.</li>
<li>Reduced reliance on separate raw SQL statements.</li>
<li>Enhanced consistency in table definition logic.</li>
</ol>
<h2><a id="considerations" href="#considerations" class="" aria-hidden="true" title=""></a>Considerations</h2>
<p>While <code>rawColumn()</code> simplifies syntax, it's database-specific. Ensure compatibility with your chosen database driver.</p>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>This new feature enhances Laravel's flexibility in handling non-standard column types. Developers can now write migrations that are both powerful and intuitive. Check out the <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/53496">PR #53496</a> for more details.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Thu, 05 Dec 2024 07:47:08 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[php artisan optimize:clear VS. cache:clear]]></title>
                <link>https://nabilhassen.com/php-artisan-cacheclear-what-it-does-and-what-it-does-not</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#tldr">TL;DR</a></li>
<li><a href="#the-story-behind-this-article">The Story Behind This Article</a></li>
<li><a href="#php-artisan-cacheclear-vs-optimize-vs-optimizeclear">php artisan cache:clear vs. optimize vs. optimize:clear</a>
<ul>
<li><a href="#what-does-php-artisan-optimizeclear-clear">What does php artisan optimize:clear clear?</a></li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="tldr" href="#tldr" class="" aria-hidden="true" title=""></a>TL;DR</h2>
<ul>
<li>
<p><code>php artisan optimize</code> caches config, routes, events, and views <strong>as files</strong> in <code>/storage/framework</code> and does <strong>not</strong> touch your cache driver.</p>
</li>
<li>
<p><code>php artisan cache:clear</code> flushes <strong>only</strong> your application cache driver (Redis, DB, etc.) and doesn’t remove optimize’s files.</p>
</li>
<li>
<p><code>php artisan optimize:clear</code> removes optimize’s files <strong>and</strong> clears cache driver data <strong>and</strong> compiled classes. Use <code>--except</code> or individual clear commands if you only want certain caches removed. Misunderstanding these differences can cause unnecessary or wrong operations during Laravel deployments.</p>
</li>
</ul>
<h2><a id="the-story-behind-this-article" href="#the-story-behind-this-article" class="" aria-hidden="true" title=""></a>The Story Behind This Article</h2>
<p>In one of my <a rel="nofollow noopener" target="_blank" href="https://nabilhassen.com/deploy-laravel-project-with-github-actions-cicd-workflow">blog posts</a>, there was some misunderstanding about what certain Laravel Artisan commands do behind the scenes. In that <a rel="nofollow noopener" target="_blank" href="https://nabilhassen.com/deploy-laravel-project-with-github-actions-cicd-workflow">blog post</a>, I shared an opinionated, custom Laravel deployment script that included the following two commands in this order:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;"># Optimize view, routes, events, configs</span></div><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">optimize</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;"># Clear caches</span></div><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">cache:clear</span></div></code></pre>
<p>This sparked a lot of criticism. Many believed that the commands above were being executed in the wrong order:</p>
<ol>
<li>The first command caches certain data.</li>
<li>The second command deletes what was cached by the first command.</li>
</ol>
<p>This, however, is a misunderstanding.</p>
<h2><a id="php-artisan-cacheclear-vs-optimize-vs-optimizeclear" href="#php-artisan-cacheclear-vs-optimize-vs-optimizeclear" class="" aria-hidden="true" title=""></a>php artisan cache:clear vs. optimize vs. optimize:clear</h2>
<p>Let’s first look at how Laravel defines these commands:</p>
<ul>
<li>
<p><code>php artisan cache:clear</code> - Flushes the application cache.</p>
</li>
<li>
<p><code>php artisan optimize</code> - When deploying your application to production, there are a variety of files that should be cached, including your configuration, events, routes, and views. Laravel provides a single, convenient <code>optimize</code> Artisan command that will cache all of these files.</p>
</li>
</ul>
<p>Both definitions use the word &quot;cache,&quot; but they refer to entirely different things. Let’s start with the <code>optimize</code> command.</p>
<p>The <code>optimize</code> command caches events, configurations, routes, and views <strong>in files</strong>. It does not interact with your actual cache driver (e.g., Redis, database, Memcached, etc.). All the cache files generated by <code>optimize</code> are stored in directories within the <code>/storage/framework</code> directory. This means that <code>php artisan optimize</code> and <code>php artisan cache:clear</code> have no relationship whatsoever.</p>
<p>If you’re wondering how to remove the cache files created by the <code>optimize</code> command, unfortunately, there isn’t a specific command to do only that.</p>
<p>The <code>php artisan cache:clear</code> command only flushes data from your cache drivers, it does not interact with the cache files created by the <code>optimize</code> command.</p>
<h3><a id="what-does-php-artisan-optimizeclear-clear" href="#what-does-php-artisan-optimizeclear-clear" class="" aria-hidden="true" title=""></a>What does <code>php artisan optimize:clear</code> clear?</h3>
<p>There’s also the <code>php artisan optimize:clear</code> command. However, this command does more than just remove the cache files created by <code>optimize</code>; it also removes compiled classes and flushes data from your actual cache driver.</p>
<p>As explained by Laravel:</p>
<blockquote>
<p>The <code>optimize:clear</code> method may be used to remove all of the cache
files generated by the <code>optimize</code> command as well as all keys in the
default cache driver.</p>
</blockquote>
<p>It removes all files created by the <code>optimize</code> command, flushes you application cache, and removes compiled classes.</p>
<p>This means that <code>optimize:clear</code> performs additional tasks that you might not want. If your goal is to remove only the cache files generated by <code>optimize</code>, you’ll need to run the relevant Artisan commands manually or use the <code>--except</code> flag with <code>optimize:clear</code> command:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">optimize:clear</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--except=cache,compiled</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;"># OR</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">view:clear</span></div><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">route:clear</span></div><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">event:clear</span></div><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">config:clear</span></div></code></pre>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>It’s important to understand the difference between <code>php artisan cache:clear</code>, <code>php artisan optimize</code>, and <code>php artisan optimize:clear</code> to avoid unnecessary confusion. While all these commands involve “cache,” they deal with completely different things. Misunderstanding their purpose can lead to unnecessary operations or even unintended issues during deployment. By knowing what each command does and doesn’t do, you can make better decisions for your Laravel projects. So next time you deploy, you’ll know exactly what’s happening behind the scenes.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Fri, 17 Oct 2025 18:58:05 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Laravel 11.34.0 - Access Laravel Request Data as an Object]]></title>
                <link>https://nabilhassen.com/laravel-11340-access-laravel-request-data-as-an-object</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#laravel-11340---requestfluent-method">Laravel 11.34.0 - Request::fluent Method</a></li>
<li><a href="#what-is-the-fluent-class">What is the Fluent class?</a></li>
<li><a href="#why-use-requestfluent">Why Use Request::fluent?</a></li>
<li><a href="#how-does-it-work">How Does It Work?</a></li>
<li><a href="#advantages-of-requestfluent">Advantages of Request::fluent</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h3><a id="laravel-11340---requestfluent-method" href="#laravel-11340---requestfluent-method" class="" aria-hidden="true" title=""></a>Laravel 11.34.0 - <code>Request::fluent</code> Method</h3>
<p>In Laravel 11.34.0, a new method, <code>Request::fluent</code>, was introduced by <a rel="nofollow noopener" target="_blank" href="https://twitter.com/ste_bau">Steve Bauman</a> to simplify handling request data. This method transforms the request into a Fluent instance, making it easier to access values dynamically. It offers a cleaner and more efficient way to interact with request input, improves null safety, and enhances code readability. By eliminating the need for traditional array-style access, it streamlines working with request data, especially in larger, more complex applications.</p>
<h3><a id="what-is-the-fluent-class" href="#what-is-the-fluent-class" class="" aria-hidden="true" title=""></a>What is the Fluent class?</h3>
<p>In Laravel, the <code>Fluent</code> class provides an easy way to interact with data by allowing dynamic property access. Instead of using traditional array or object notation, you can access request data as if it were an object. This enhances readability and reduces boilerplate code.</p>
<h3><a id="why-use-requestfluent" href="#why-use-requestfluent" class="" aria-hidden="true" title=""></a>Why Use <code>Request::fluent</code>?</h3>
<p>Before Laravel 11.34.0, accessing request data required using the <code>Request</code> facade with array-style access, like this:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">input</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;">);</span></div></code></pre>
<p>While this approach works, it has some limitations, especially when dealing with deeply nested or nullable data. The <code>Request::fluent</code> method simplifies these interactions and adds some extra benefits:</p>
<ol>
<li>
<p><strong>Null-Safety:</strong> It makes your code more resilient to missing or <code>null</code> values, which is especially useful when handling optional data.</p>
</li>
<li>
<p><strong>Readable Code:</strong> It allows accessing request data in a cleaner, more concise way.</p>
</li>
<li>
<p><strong>Improved Testing:</strong> Since it returns a <code>Fluent</code> instance, it's easier to test and mock request data in your tests.</p>
</li>
</ol>
<h3><a id="how-does-it-work" href="#how-does-it-work" class="" aria-hidden="true" title=""></a>How Does It Work?</h3>
<p>The new <code>fluent</code> method allows you to convert your request data into a <code>Fluent</code> instance, which provides a cleaner API for accessing values. Here's how you might use it:</p>
<h4><a id="example-usage" href="#example-usage" class="" aria-hidden="true" title=""></a>Example Usage:</h4>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Http\</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">store</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// Convert the request to a Fluent instance</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">fluent</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// Access data with dynamic properties</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$name</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">;  </span><span style="color: #7F848E;">// instead of $request-&gt;input(&#39;name&#39;)</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$email</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$data</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #E06C75;">email</span><span style="color: #ABB2BF;">;  </span><span style="color: #7F848E;">// instead of $request-&gt;input(&#39;email&#39;)</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>In the example above, <code>$data</code> is now a <code>Fluent</code> instance. You can access the data directly using properties (<code>$data-&gt;name</code>, <code>$data-&gt;email</code>), making the code easier to read and understand.</p>
<h3><a id="advantages-of-requestfluent" href="#advantages-of-requestfluent" class="" aria-hidden="true" title=""></a>Advantages of <code>Request::fluent</code></h3>
<ul>
<li>
<p><strong>Null-Safe Access:</strong> Instead of worrying about checking if a value exists in the request, the <code>Fluent</code> instance makes it easier to safely access data. If the value doesn’t exist, it won’t throw an error but return <code>null</code> instead.</p>
</li>
<li>
<p><strong>Cleaner Code:</strong> It reduces the verbosity of checking for values in request arrays or objects, making your code cleaner and less error-prone.</p>
</li>
<li>
<p><strong>Flexible and Convenient:</strong> Using dynamic properties to access request input is more intuitive and can be especially handy when working with complex request structures, such as nested data.</p>
</li>
</ul>
<h3><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h3>
<p>The <code>Request::fluent</code> method is a simple but powerful addition to Laravel. It enhances the way developers handle request data, making code more readable, safer, and easier to work with. If you're building applications with Laravel 11.34.0 or higher, try this new method to streamline your request handling and make your codebase cleaner and more maintainable.</p>
<p>For more information on check out the <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/53662">Pull Request #53662</a>.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Thu, 28 Nov 2024 13:16:27 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Deploy Laravel Project with GitHub Actions CI/CD Workflow]]></title>
                <link>https://nabilhassen.com/deploy-laravel-project-with-github-actions-cicd-workflow</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#introduction">Introduction</a></li>
<li><a href="#laravel-deploy-script">Laravel Deploy Script</a></li>
<li><a href="#github-actions-workflow-to-test--deploy-laravel">GitHub Actions Workflow to Test &amp; Deploy Laravel</a>
<ul>
<li><a href="#workflow-name-eg-mywebsitecom">Workflow Name: e.g. mywebsite.com</a></li>
<li><a href="#trigger-event">Trigger Event</a></li>
<li><a href="#job-eg-test-and-deploy">Job: e.g. test-and-deploy</a></li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="introduction" href="#introduction" class="" aria-hidden="true" title=""></a>Introduction</h2>
<p>In this guide, you’ll learn how to set up a deploy script for your Laravel project and integrate it seamlessly with a GitHub Actions workflow. We’ll walk through crafting a deployment script for your production server and explain each step of a GitHub Actions pipeline that tests and deploys your application whenever changes are pushed to the <code>main</code> branch. By the end, you’ll have a reliable and repeatable process to keep your Laravel application up to date with minimal manual effort.</p>
<h2><a id="laravel-deploy-script" href="#laravel-deploy-script" class="" aria-hidden="true" title=""></a>Laravel Deploy Script</h2>
<p>First we need to write a Laravel deploy script that will be triggered from our GitHub Actions workflow. Make sure to store this file in your production server. Nothing fancy here, those are all commands that we use while developing. Have a look:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;"># Change your Laravel project directory</span></div><div class='line'><span style="color: #56B6C2;">cd</span><span style="color: #ABB2BF;"> ~</span><span style="color: #98C379;">/mywebsite</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;"># Turn on maintenance mode</span></div><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">down</span><span style="color: #ABB2BF;"> || </span><span style="color: #56B6C2;">true</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;"># Pull the latest changes from the git repository</span></div><div class='line'><span style="color: #ABB2BF;">git </span><span style="color: #98C379;">pull</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">origin</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">main</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;"># Install composer dependecies</span></div><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">install</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--no-interaction</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--no-dev</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;"># Optimize view, routes, events, configs</span></div><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">optimize:clear</span></div><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">optimize</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;"># Clear expired password reset tokens</span></div><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">auth:clear-resets</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;"># Run database migrations</span></div><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">migrate</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--force</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #7F848E;"># Turn off maintenance mode</span></div><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">up</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #56B6C2;">exit</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">0</span></div></code></pre>
<h2><a id="github-actions-workflow-to-test--deploy-laravel" href="#github-actions-workflow-to-test--deploy-laravel" class="" aria-hidden="true" title=""></a>GitHub Actions Workflow to Test &amp; Deploy Laravel</h2>
<p>Next, we will write our GitHub Actions workflow that does two things in particular; <strong>Runs tests, and deploys to server</strong>. In the root directory of your Laravel project, create <code>.github</code> folder and inside <code>.github</code>, create <code>workflows</code> folder. You will end up with a <code>.github/workflows</code> structure. Create a YAML file <code>e.g. tests.yml</code> and save it in the workflows folder.</p>
<p>This workflow will be triggered when changes are pushed to the <code>main</code> branch. Let's see the workflow:</p>
<pre><code data-theme="one-dark-pro" data-lang="yaml" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">mywebsite.com</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #D19A66;">on</span><span style="color: #ABB2BF;">:</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #E06C75;">push</span><span style="color: #ABB2BF;">:</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">branches</span><span style="color: #ABB2BF;">: [</span><span style="color: #98C379;">&quot;main&quot;</span><span style="color: #ABB2BF;">]</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">jobs</span><span style="color: #ABB2BF;">:</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #E06C75;">test-and-deploy</span><span style="color: #ABB2BF;">:</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">runs-on</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">ubuntu-latest</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">steps</span><span style="color: #ABB2BF;">:</span></div><div class='line'><span style="color: #ABB2BF;">      - </span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">Checkout code</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">uses</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">actions/checkout@v4</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">      - </span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">Setup PHP</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">uses</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">shivammathur/setup-php@v2</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">with</span><span style="color: #ABB2BF;">:</span></div><div class='line'><span style="color: #ABB2BF;">          </span><span style="color: #E06C75;">php-version</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">&quot;8.3&quot;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">      - </span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">Set up Node.js</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">uses</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">actions/setup-node@v4</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">with</span><span style="color: #ABB2BF;">:</span></div><div class='line'><span style="color: #ABB2BF;">          </span><span style="color: #E06C75;">node-version</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">&quot;latest&quot;</span></div><div class='line'><span style="color: #ABB2BF;">          </span><span style="color: #E06C75;">cache</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">&quot;npm&quot;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">      - </span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">Copy .env</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">run</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">php -r &quot;file_exists(&#39;.env&#39;) || copy(&#39;.env.example&#39;, &#39;.env&#39;);&quot;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">      - </span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">Install PHP Dependencies</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">run</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">      - </span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">Generate key</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">run</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">php artisan key:generate</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">      - </span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">Install and Build Frontend Dependencies</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">run</span><span style="color: #ABB2BF;">: </span><span style="color: #C678DD;">|</span></div><div class='line'><span style="color: #98C379;">          npm ci</span></div><div class='line'><span style="color: #98C379;">          npm run build --if-present</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">      - </span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">Execute tests</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">run</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">composer test</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">      - </span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">Deploy to Server</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">uses</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">appleboy/ssh-action@v1.1.0</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">with</span><span style="color: #ABB2BF;">:</span></div><div class='line'><span style="color: #ABB2BF;">          </span><span style="color: #E06C75;">host</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">${{ secrets.SSH_HOST }}</span></div><div class='line'><span style="color: #ABB2BF;">          </span><span style="color: #E06C75;">username</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">${{ secrets.SSH_USER }}</span></div><div class='line'><span style="color: #ABB2BF;">          </span><span style="color: #E06C75;">key</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">${{ secrets.SSH_PRIVATE_KEY }}</span></div><div class='line'><span style="color: #ABB2BF;">          </span><span style="color: #E06C75;">script</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">cd scripts &amp;&amp; sh deploy_script.sh</span></div></code></pre>
<p>We will go through each step and understand what each step of the workflow does. Let's go.</p>
<h3><a id="workflow-name-eg-mywebsitecom" href="#workflow-name-eg-mywebsitecom" class="" aria-hidden="true" title=""></a>Workflow Name: <code>e.g. mywebsite.com</code></h3>
<p>The workflow is triggered on any <code>push</code> to the <code>main</code> branch. The workflow performs testing and deployment for a Laravel application (it could be your website or an API server or anything else).</p>
<h3><a id="trigger-event" href="#trigger-event" class="" aria-hidden="true" title=""></a>Trigger Event</h3>
<ul>
<li><strong><code>on: push</code></strong>:
<ul>
<li>Runs this workflow whenever changes are pushed to the <code>main</code> branch.</li>
</ul>
</li>
</ul>
<h3><a id="job-eg-test-and-deploy" href="#job-eg-test-and-deploy" class="" aria-hidden="true" title=""></a><strong>Job: <code>e.g. test-and-deploy</code></strong></h3>
<p>This job is executed on an <strong>Ubuntu</strong> environment (<code>ubuntu-latest</code>) and consists of multiple steps.</p>
<ol>
<li><strong>Checkout Code</strong></li>
</ol>
<pre><code data-theme="one-dark-pro" data-lang="yaml" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">- </span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">Checkout code</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #E06C75;">uses</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">actions/checkout@v4</span></div></code></pre>
<ul>
<li><strong>Action</strong>: Downloads the repository code to the runner.</li>
<li><strong>Purpose</strong>: Ensures the workflow has access to the latest application files.</li>
</ul>
<ol start="2">
<li><strong>Setup PHP</strong></li>
</ol>
<pre><code data-theme="one-dark-pro" data-lang="yaml" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">- </span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">Setup PHP</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #E06C75;">uses</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">shivammathur/setup-php@v2</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #E06C75;">with</span><span style="color: #ABB2BF;">:</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">php-version</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">&quot;8.3&quot;</span></div></code></pre>
<ul>
<li><strong>Action</strong>: Sets up PHP version 8.3 on the runner (i.e. Ubuntu).</li>
<li><strong>Purpose</strong>: Prepares the environment to execute PHP-based tasks such as running Laravel commands or installing dependencies.</li>
</ul>
<ol start="3">
<li><strong>Set up Node.js</strong></li>
</ol>
<pre><code data-theme="one-dark-pro" data-lang="yaml" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">- </span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">Set up Node.js</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #E06C75;">uses</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">actions/setup-node@v4</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #E06C75;">with</span><span style="color: #ABB2BF;">:</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">node-version</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">&quot;latest&quot;</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">cache</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">&quot;npm&quot;</span></div></code></pre>
<ul>
<li><strong>Action</strong>: Installs the latest Node.js version and enables caching for <code>npm</code>.</li>
<li><strong>Purpose</strong>: Provides the required Node.js environment to build and manage frontend assets.</li>
</ul>
<ol start="4">
<li><strong>Copy <code>.env</code> File</strong></li>
</ol>
<pre><code data-theme="one-dark-pro" data-lang="yaml" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">- </span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">Copy .env</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #E06C75;">run</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">php -r &quot;file_exists(&#39;.env&#39;) || copy(&#39;.env.example&#39;, &#39;.env&#39;);&quot;</span></div></code></pre>
<ul>
<li><strong>Action</strong>: Checks if a <code>.env</code> file exists; if not, it creates one by copying from <code>.env.example</code>.</li>
<li><strong>Purpose</strong>: Ensures that the application has the necessary environment configuration file.</li>
</ul>
<ol start="5">
<li><strong>Install PHP Dependencies</strong></li>
</ol>
<pre><code data-theme="one-dark-pro" data-lang="yaml" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">- </span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">Install PHP Dependencies</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #E06C75;">run</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist</span></div></code></pre>
<ul>
<li><strong>Action</strong>: Installs Laravel's PHP dependencies using Composer with optimized settings.</li>
<li><strong>Purpose</strong>: Prepares backend dependencies for the Laravel application.</li>
</ul>
<ol start="6">
<li><strong>Generate Application Key</strong></li>
</ol>
<pre><code data-theme="one-dark-pro" data-lang="yaml" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">- </span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">Generate key</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #E06C75;">run</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">php artisan key:generate</span></div></code></pre>
<ul>
<li><strong>Action</strong>: Runs the <code>key:generate</code> Artisan command to create an encryption key.</li>
<li><strong>Purpose</strong>: Ensures the Laravel application has a valid encryption key.</li>
</ul>
<ol start="7">
<li><strong>Install and Build Frontend Dependencies</strong></li>
</ol>
<pre><code data-theme="one-dark-pro" data-lang="yaml" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">- </span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">Install and Build Frontend Dependencies</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #E06C75;">run</span><span style="color: #ABB2BF;">: </span><span style="color: #C678DD;">|</span></div><div class='line'><span style="color: #98C379;">    npm ci</span></div><div class='line'><span style="color: #98C379;">    npm run build --if-present</span></div></code></pre>
<ul>
<li><strong>Action</strong>:
<ol>
<li>Installs frontend dependencies using <code>npm ci</code>.</li>
<li>Builds the frontend assets using <code>npm run build</code> if a build script is defined.</li>
</ol>
</li>
<li><strong>Purpose</strong>: Prepares and compiles the frontend assets.</li>
</ul>
<ol start="8">
<li><strong>Execute Tests</strong></li>
</ol>
<pre><code data-theme="one-dark-pro" data-lang="yaml" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">- </span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">Execute tests</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #E06C75;">run</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">composer test</span></div></code></pre>
<ul>
<li><strong>Action</strong>: Runs the PHP tests or any configured tests using a Composer command.</li>
<li><strong>Purpose</strong>: Validates the application's functionality by executing automated tests.</li>
</ul>
<ol start="9">
<li><strong>Deploy to Server</strong></li>
</ol>
<pre><code data-theme="one-dark-pro" data-lang="yaml" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">- </span><span style="color: #E06C75;">name</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">Deploy to Server</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #E06C75;">uses</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">appleboy/ssh-action@v1.1.0</span></div><div class='line'><span style="color: #ABB2BF;">  </span><span style="color: #E06C75;">with</span><span style="color: #ABB2BF;">:</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">host</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">${{ secrets.SSH_HOST }}</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">username</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">${{ secrets.SSH_USER }}</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">key</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">${{ secrets.SSH_PRIVATE_KEY }}</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">script</span><span style="color: #ABB2BF;">: </span><span style="color: #98C379;">cd scripts &amp;&amp; sh deploy_script.sh</span></div></code></pre>
<ul>
<li><strong>Action</strong>:
<ul>
<li>Connects to the deployment server via SSH using credentials stored as GitHub Secrets.</li>
<li>Executes the deployment script (<code>deploy_script.sh</code>) located in the <code>scripts</code> directory.</li>
</ul>
</li>
<li><strong>Purpose</strong>: Automates deployment to the production server.</li>
</ul>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>With the deploy script and GitHub Actions workflow in place, managing your Laravel application's deployment becomes significantly more efficient and less error-prone. You’ve set up an automated process that handles everything from testing your code to deploying it to the production server with just a push to the <code>main</code> branch. This approach not only saves time but also ensures consistent deployments, allowing you to focus on building features rather than worrying about manual setups. Whether you’re maintaining a website or an API server, this streamlined workflow is a game-changer for Laravel developers.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Fri, 15 Aug 2025 21:09:35 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Laravel 11: Introducing Schedule Grouping]]></title>
                <link>https://nabilhassen.com/laravel-11-introducing-schedule-grouping</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#introduction">Introduction</a></li>
<li><a href="#the-problem">The Problem</a></li>
<li><a href="#the-solution">The Solution</a></li>
<li><a href="#supported-laravel-versions">Supported Laravel Versions</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="introduction" href="#introduction" class="" aria-hidden="true" title=""></a>Introduction</h2>
<p>A recent addition in Laravel 11 authored by <a rel="nofollow noopener" target="_blank" href="https://github.com/istiak-tridip">Istiak Tridip</a> is <strong>Schedule Srouping</strong>. A powerful way to manage scheduled tasks in a more organized and intuitive manner.</p>
<h2><a id="the-problem" href="#the-problem" class="" aria-hidden="true" title=""></a>The Problem</h2>
<p>Before this feature, managing multiple scheduled tasks that shared common characteristics required repetitive configuration. For example, if several tasks needed to run every minute or in the background, developers had to specify these attributes for each task individually, leading to redundant and less maintainable code.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">command</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;command-one&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">everyMinute</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">runInBackground</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">withoutOverlapping</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">command</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;command-two&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">everyMinute</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">runInBackground</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">withoutOverlapping</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">command</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;command-three&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">everyMinute</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">runInBackground</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">withoutOverlapping</span><span style="color: #ABB2BF;">();</span></div></code></pre>
<h2><a id="the-solution" href="#the-solution" class="" aria-hidden="true" title=""></a>The Solution</h2>
<p>The new schedule grouping feature introduces a syntax similar to the <code>Route::group</code> method, allowing developers to group related tasks with shared configurations. Using a new <code>group</code> method, you can define common attributes like <code>-&gt;everyMinute()</code> or <code>-&gt;runInBackground()</code> once for a group, and apply them to all tasks within.</p>
<p>Here’s an example of how it works:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">group</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">everyMinute</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">runInBackground</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">withoutOverlapping</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">schedules</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> () {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">command</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;command-one&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">command</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;command-two&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">command</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;command-three&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    });</span></div></code></pre>
<p>You can even nest groups:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">group</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">runInBackground</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">withoutOverlapping</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">schedules</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> () {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">group</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">everyMinute</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">schedules</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> () {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">command</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;command-one&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">command</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;command-two&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">        });</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">group</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">everyTenMinutes</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">schedules</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> () {</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">command</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;command-three&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">command</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;command-four&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">        });</span></div><div class='line'><span style="color: #ABB2BF;">    });</span></div></code></pre>
<p>You can also override configurations for specific schedules as needed:</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">group</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">everyMinute</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">runInBackground</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">withoutOverlapping</span><span style="color: #ABB2BF;">()</span></div><div class='line'><span style="color: #ABB2BF;">    -&gt;</span><span style="color: #61AFEF;">schedules</span><span style="color: #ABB2BF;">(</span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> () {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">command</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;command-one&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">command</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;command-two&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">                </span><span style="color: #7F848E;">// Override the group&#39;s cron expression</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">command</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;command-three&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">everyTenMinutes</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">    });</span></div></code></pre>
<p>This approach drastically improves code readability and eliminates redundancy.</p>
<h2><a id="supported-laravel-versions" href="#supported-laravel-versions" class="" aria-hidden="true" title=""></a>Supported Laravel Versions</h2>
<p>This feature is officially supported starting from <strong>Laravel 11</strong>.</p>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>Schedule grouping is a game-changer for developers managing complex scheduling requirements. By reducing boilerplate code and improving readability, it exemplifies Laravel's commitment to developer-friendly features.</p>
<p>Explore this feature and more in Laravel 11 to streamline your application development.</p>
<p>For more details, check out the <a rel="nofollow noopener" target="_blank" href="https://github.com/laravel/framework/pull/53427">pull request</a>.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Thu, 21 Nov 2024 13:08:15 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Laravel Packages You Should Install in Every New Project]]></title>
                <link>https://nabilhassen.com/laravel-packages-you-should-install-in-every-new-project</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#introduction">Introduction</a></li>
<li><a href="#my-go-to-laravel-stack">My Go-to Laravel Stack</a></li>
<li><a href="#must-install-packages">Must-Install Packages</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="introduction" href="#introduction" class="" aria-hidden="true" title=""></a>Introduction</h2>
<p>In this blog post, I'll walk you through my preferred Laravel tech stack—a setup that has evolved over years of experimenting with various tools and frameworks. I'll share the frontend and backend technologies that now shape my go-to stack, from templating engines to frontend interactivity options. Additionally, I'll introduce you to the essential Laravel packages that I consistently use in almost every project to streamline development, improve functionality, and optimize performance. Whether you're a seasoned Laravel developer or just starting out, you'll find insights here that could shape your own stack.</p>
<h2><a id="my-go-to-laravel-stack" href="#my-go-to-laravel-stack" class="" aria-hidden="true" title=""></a>My Go-to Laravel Stack</h2>
<p>Over the years, I've experimented with various tech stacks to develop Laravel applications. In the early days of my Laravel journey, I used Laravel with the built-in templating engine, <strong>Blade</strong>, and sprinkled in some jQuery for frontend interactivity. Once I was introduced to <strong>Vue.js</strong>, I started building the frontend with it. I've built a few production-level projects using Vue.js, but ultimately, I moved on. Vue.js is great, but a better stack emerged—one that feels more &quot;PHP-ish&quot; and backend developer friendly: <strong>Livewire</strong>. With Livewire, I spend 70 to 80 percent of my time writing code in PHP for both the frontend and backend. Today, Livewire with Alpine.js (for frontend interactivity) is my go-to tech stack for developing Laravel applications. For CSS, I previously used Bootstrap and Bulma, but now I rely solely on Tailwind.</p>
<h2><a id="must-install-packages" href="#must-install-packages" class="" aria-hidden="true" title=""></a>Must-Install Packages</h2>
<p>I've realized that there are certain Laravel packages I install in nearly every project. I've even considered creating a repository with these packages pre-installed. Here are the packages:</p>
<ul>
<li>spatie/laravel-honeypot</li>
<li>spatie/laravel-sitemap</li>
<li>spatie/laravel-permission</li>
<li>spatie/laravel-backup</li>
<li>blade-ui-kit/blade-heroicons</li>
<li>filament/filament</li>
<li>larabug/larabug</li>
<li>barryvdh/laravel-debugbar</li>
</ul>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>To wrap up, my go-to Laravel stack combines the flexibility and ease of Livewire and Alpine.js for a PHP-centric approach with the clean styling power of Tailwind CSS. This setup has simplified my workflow and lets me focus more on backend logic while still achieving responsive, interactive frontends. Plus, the must-have packages listed make my projects more secure, feature-rich, and easier to debug. Hopefully, this breakdown gives you ideas on how to refine your Laravel projects and maybe even adopt some of these tools yourself.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Fri, 15 Nov 2024 07:56:00 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[How to Deploy Laravel on Shared Hosting]]></title>
                <link>https://nabilhassen.com/how-to-deploy-laravel-on-shared-hosting</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#introduction">Introduction</a></li>
<li><a href="#why-the-right-way-matters">Why the &quot;Right Way&quot; Matters</a></li>
<li><a href="#step-by-step-deployment-guideline">Step-by-step Deployment Guideline</a>
<ul>
<li><a href="#step-1-access-cpanel-and-check-requirements">Step 1: Access cPanel and Check Requirements</a></li>
<li><a href="#step-2-install-composer-optional">Step 2: Install Composer (Optional)</a></li>
<li><a href="#step-3-set-up-git">Step 3: Set Up Git</a></li>
<li><a href="#step-4-clone-the-repository-and-set-up-the-app">Step 4: Clone the Repository and Set Up the App</a></li>
<li><a href="#step-5-make-the-app-public">Step 5: Make the App Public</a></li>
<li><a href="#step-6-set-up-cron-jobs-optional">Step 6: Set Up Cron Jobs (Optional)</a></li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="introduction" href="#introduction" class="" aria-hidden="true" title=""></a>Introduction</h2>
<p>So, you're ready to deploy your Laravel app on a shared hosting in <strong>cPanel</strong>? While VPS hosting providers like DigitalOcean or AWS coupled with Laravel Forge might be the more common choice for Laravel projects, there are cases where you might have to <strong>deploy to a shared hosting</strong>.</p>
<p>Now, deploying Laravel in cPanel can be done, but you’ve got to do it <strong>the right way</strong> to avoid long-term headaches. In this tutorial, I’ll walk you through <strong>step-by-step</strong> on how to deploy your Laravel app smoothly in cPanel.</p>
<p>Let’s dive in!</p>
<h2><a id="why-the-right-way-matters" href="#why-the-right-way-matters" class="" aria-hidden="true" title=""></a>Why the &quot;Right Way&quot; Matters</h2>
<p>You’ve probably seen tutorials that suggest some risky deployment techniques, like uploading your <strong>vendor</strong> folder via FTP or moving files from <strong>Laravel's public</strong> folder to <strong>public_html</strong>. These shortcuts might work at first but can lead to a whole lot of issues down the road. <strong>Managing code changes, version upgrades, and database migrations</strong> becomes much harder if you take these approaches.</p>
<p>This guide will help you avoid those traps, so your Laravel app remains easy to maintain and upgrade.</p>
<p>Before we begin the step-by-step guide, make sure you build your frontend locally as it's cumbersome to build and bundle frontend on shared hosting:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">npm </span><span style="color: #98C379;">run</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">build</span></div></code></pre>
<h2><a id="step-by-step-deployment-guideline" href="#step-by-step-deployment-guideline" class="" aria-hidden="true" title=""></a>Step-by-step Deployment Guideline</h2>
<h3><a id="step-1-access-cpanel-and-check-requirements" href="#step-1-access-cpanel-and-check-requirements" class="" aria-hidden="true" title=""></a>Step 1: Access cPanel and Check Requirements</h3>
<ol>
<li>Log in to your cPanel: Navigate to <code>https://cpanel.yourdomain.com</code> or <code>https://yourdomain.com:2083</code> and log in with your credentials.</li>
<li>Check the <strong>Advanced</strong> section for the <strong>Terminal</strong> icon (if it's missing, request <strong>Shell Access</strong> from your hosting provider). We’ll use this terminal for most of the deployment tasks.</li>
</ol>
<p><img src="https://nabilhassen.com/storage/IpZEL0qQHePf9kCjhWKEctZnhL5CHuqBANZcADNS.webp" alt="terminal in cpanel advanced section" /></p>
<p>Once you're in, <strong>check your PHP version</strong> to ensure compatibility.</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #D19A66;">-v</span></div></code></pre>
<p>Make sure it is the right PHP version for you. If not, go to cPanel's homepage, look for <strong>Select PHP Version</strong> under the <strong>Software</strong> section and change the PHP version to your preferred version.</p>
<p><img src="https://nabilhassen.com/storage/IAvHMW0GTBHEQMcpa4TwETeddzdBYcnrYK4rNVNJ.png" alt="select php version in cpanel software section" /></p>
<p>Next, verify the <strong>PHP extensions</strong>:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #D19A66;">-m</span></div></code></pre>
<p>Ensure the following extensions are installed:</p>
<ul>
<li>ctype</li>
<li>curl</li>
<li>dom</li>
<li>fileinfo</li>
<li>filter</li>
<li>hash</li>
<li>mbstring</li>
<li>openssl</li>
<li>pcre</li>
<li>pdo</li>
<li>pdo_mysql</li>
<li>pdo_sqlite</li>
<li>session</li>
<li>sqlite3</li>
<li>tokenizer</li>
<li>xml</li>
</ul>
<p>and any other extension required by your application as well.</p>
<h3><a id="step-2-install-composer-optional" href="#step-2-install-composer-optional" class="" aria-hidden="true" title=""></a>Step 2: Install Composer <em>(Optional)</em></h3>
<p>Usually, composer is pre-installed by your hosting provider already. You can check by running:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #D19A66;">-V</span></div></code></pre>
<p>If not pre-installed, you can either ask your hosting provider to enable/install it or install it by yourself. Let's assume that you'll install it by yourself and start by adding an alias to your shell environment:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #56B6C2;">echo</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&#39;alias composer=&quot;php -d allow_url_fopen=On /home/username/composer.phar&quot;&#39;</span><span style="color: #ABB2BF;"> &gt;&gt; ~</span><span style="color: #98C379;">/.bashrc</span></div><div class='line'><span style="color: #56B6C2;">source</span><span style="color: #ABB2BF;"> ~</span><span style="color: #98C379;">/.bashrc</span></div></code></pre>
<p>Then, download and install Composer:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #56B6C2;">cd</span><span style="color: #ABB2BF;"> ~</span></div><div class='line'><span style="color: #ABB2BF;">curl </span><span style="color: #D19A66;">-k</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">-O</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">https://getcomposer.org/installer</span></div><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #D19A66;">-d</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">allow_url_fopen=On</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">installer</span></div></code></pre>
<p>Verify the installation:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #D19A66;">-V</span></div></code></pre>
<h3><a id="step-3-set-up-git" href="#step-3-set-up-git" class="" aria-hidden="true" title=""></a>Step 3: Set Up Git</h3>
<p>With Composer ready, let’s get <strong>Git</strong> set up. If Git isn’t pre-installed in your cPanel, ask your hosting provider to enable it.</p>
<p>Next, check if an <strong>SSH key</strong> exists:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">cat ~</span><span style="color: #98C379;">/.ssh/id_rsa.pub</span></div></code></pre>
<p>If not, generate one:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">ssh-keygen </span><span style="color: #D19A66;">-t</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">rsa</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">-b</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">4096</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">-C</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">&quot;your_cpanel_username&quot;</span></div></code></pre>
<p>Copy the public key:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">cat ~</span><span style="color: #98C379;">/.ssh/id_rsa.pub</span></div></code></pre>
<p>Add it to your GitHub repo under <strong>Settings -&gt; Deploy Keys</strong>.</p>
<blockquote>
<p><strong>RECOMMENDED</strong> — do not check the <strong>Allow write access</strong> checkbox.</p>
</blockquote>
<p><img src="https://nabilhassen.com/storage/5h4ZQxBsS3cfkDK8z1XI7nnrt7DxTADc8D5UmBcB.png" alt="deploy keys for a repo on github" /></p>
<h3><a id="step-4-clone-the-repository-and-set-up-the-app" href="#step-4-clone-the-repository-and-set-up-the-app" class="" aria-hidden="true" title=""></a>Step 4: Clone the Repository and Set Up the App</h3>
<p>Now, we’re ready to <strong>clone the app</strong>. Run the following command to clone the repository to a folder named &quot;app&quot; and then to navigate to the folder:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">git </span><span style="color: #98C379;">clone</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">git@github.com:username/repo.git</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">app</span><span style="color: #ABB2BF;"> &amp;&amp; </span><span style="color: #56B6C2;">cd</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">app</span></div></code></pre>
<p>Install the dependencies:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">install</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--no-dev</span></div></code></pre>
<p>While that’s running, create a new <strong>MySQL database</strong> in cPanel:</p>
<p><img src="https://nabilhassen.com/storage/5l5ucTBVppsMMOcsblHd5UWblclN6nntDN8pImt1.png" alt="mysql database wizard on cpanel" /></p>
<p>Then configure the <strong>.env</strong> file:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">cp </span><span style="color: #98C379;">.env.example</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">.env</span></div><div class='line'><span style="color: #ABB2BF;">nano </span><span style="color: #98C379;">.env</span></div></code></pre>
<p>Update your environment settings:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #E06C75;">APP_ENV</span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;">production</span></div><div class='line'><span style="color: #E06C75;">APP_DEBUG</span><span style="color: #56B6C2;">=</span><span style="color: #D19A66;">false</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #E06C75;">DB_HOST</span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;">localhost</span></div><div class='line'><span style="color: #E06C75;">DB_CONNECTION</span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;">mysql</span></div><div class='line'><span style="color: #E06C75;">DB_DATABASE</span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;">yourdbname</span></div><div class='line'><span style="color: #E06C75;">DB_USERNAME</span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;">youruser</span></div><div class='line'><span style="color: #E06C75;">DB_PASSWORD</span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;">yourpass</span></div></code></pre>
<p>Generate the application key:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">key:generate</span></div></code></pre>
<p>Run the migrations:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">migrate</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--force</span></div></code></pre>
<p>If you're using filament, optimize filament components and blade icons:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">filament:optimize</span></div></code></pre>
<p>Optimize views, routes, events, and configs:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">optimize</span></div></code></pre>
<p>Create the symbolic links configured for the application:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">storage:link</span></div></code></pre>
<h3><a id="step-5-make-the-app-public" href="#step-5-make-the-app-public" class="" aria-hidden="true" title=""></a>Step 5: Make the App Public</h3>
<p>Now, the app is still private. To make it accessible, we’ll create a <strong>symbolic link</strong> from the app's <code>public</code> folder to <code>public_html</code>. First, back up the existing <code>public_html</code> folder:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">mv </span><span style="color: #98C379;">public_html</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">public_html_old</span></div></code></pre>
<p>Then create the symlink:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">ln </span><span style="color: #D19A66;">-s</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">/home/yourusername/app/public</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">/home/yourusername/public_html</span></div></code></pre>
<p>Now, visit your site and it should be live!</p>
<h3><a id="step-6-set-up-cron-jobs-optional" href="#step-6-set-up-cron-jobs-optional" class="" aria-hidden="true" title=""></a>Step 6: Set Up Cron Jobs (Optional)</h3>
<p>If your app requires scheduled tasks, set up a <strong>Cron job</strong> in cPanel:</p>
<p><img src="https://nabilhassen.com/storage/upDOhqE9HjMGf2EwOwVahk7TMujsu7yjUuXHc8uP.webp" alt="cron jobs page on cpanel" /></p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">/usr/local/bin/php </span><span style="color: #98C379;">/home/yourusername/app/artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">schedule:run</span><span style="color: #ABB2BF;"> &gt;&gt; </span><span style="color: #98C379;">/dev/null</span><span style="color: #ABB2BF;"> 2&gt;&amp;1</span></div></code></pre>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>That’s it! You’ve successfully deployed your Laravel app to cPanel <strong>the right way</strong>. No shortcuts, no risky strategies—just a clean and maintainable setup. To deploy new changes, just <strong>push to your GitHub repo</strong> and run <code>git pull</code> from cPanel's terminal.</p>
<p>And if you want an even smoother deployment process, consider setting up a <strong>GitHub Actions</strong> workflow to test and automate deployments.</p>
<p>🎉☁️ <strong>Happy deploying!</strong></p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Mon, 21 Oct 2024 03:34:51 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Laravel Usage Limiter - Manage Rate and Usage Limits]]></title>
                <link>https://nabilhassen.com/laravel-usage-limiter-manage-rate-and-usage-limits</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#introduction">Introduction</a></li>
<li><a href="#requirement">Requirement</a></li>
<li><a href="#installation">Installation</a></li>
<li><a href="#example-usage">Example Usage</a></li>
<li><a href="#more-features">More Features</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="introduction" href="#introduction" class="" aria-hidden="true" title=""></a>Introduction</h2>
<p>Over the years, <strong>I've built many Laravel-powered SaaS applications</strong>. One of the <strong>core and common feature</strong> in almost any <strong>SaaS</strong> application is to <strong>manage usage consumption by users</strong>, accounts, or teams. The <strong>goal</strong> is to make sure <strong>users don’t overuse resources, whether it’s API calls</strong>, messaging limits, or anything else that requires control. Hence, I created a Laravel package that exactly does that --- <strong>Laravel Usage Limiter</strong>.</p>
<p><strong>Laravel Usage Limiter</strong> helps you track and restrict how often users can use or consume a specific feature in your app over a period of time (e.g., limit API calls to 100 per day). By defining your own limits, you can start managing things like API request limits, message sending limits, or any other controlled usage features.</p>
<p>In this tutorial, I’ll walk you through how to install and use this package in your Laravel app, and we’ll keep things super simple along the way. Let’s dive in!</p>
<h2><a id="requirement" href="#requirement" class="" aria-hidden="true" title=""></a>Requirement</h2>
<p>Laravel version 8.0 or higher.</p>
<h2><a id="installation" href="#installation" class="" aria-hidden="true" title=""></a>Installation</h2>
<p>Install Laravel Usage Limiter using the Composer package manager:</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">composer </span><span style="color: #98C379;">require</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">nabilhassen/laravel-usage-limiter</span></div></code></pre>
<p>Next, you should publish the Laravel Usage Limiter configuration and migration files using the vendor:publish Artisan command</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">vendor:publish</span><span style="color: #ABB2BF;"> </span><span style="color: #D19A66;">--provider=</span><span style="color: #98C379;">&quot;NabilHassen\LaravelUsageLimiter\ServiceProvider&quot;</span></div></code></pre>
<p>Finally, you should run the migrate command in order to create the tables needed</p>
<pre><code data-theme="one-dark-pro" data-lang="bash" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #ABB2BF;">php </span><span style="color: #98C379;">artisan</span><span style="color: #ABB2BF;"> </span><span style="color: #98C379;">migrate</span></div></code></pre>
<h2><a id="example-usage" href="#example-usage" class="" aria-hidden="true" title=""></a>Example Usage</h2>
<p>So, let's assume we working on a Laravel-powered e-commerce application where suppliers can list and sell their products. Our application has two plans; Pro and Premium. Each of these plans have their own limits as described below.</p>
<ul>
<li>Pro: 20 Products</li>
<li>Premium: 50 Products</li>
</ul>
<p>So the first step will be to use the <code>HasLimits</code> trait on the model that we would like to track which is likely the user model.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> NabilHassen\LaravelUsageLimiter\Traits\</span><span style="color: #E5C07B;">HasLimits</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Authenticatable</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">HasLimits</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Next, let's define our plans with their limits.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">namespace</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Database\Seeders</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> Illuminate\Database\</span><span style="color: #E5C07B;">Seeder</span><span style="color: #ABB2BF;">;</span></div><div class='line'><span style="color: #C678DD;">use</span><span style="color: #ABB2BF;"> NabilHassen\LaravelUsageLimiter\Models\</span><span style="color: #E5C07B;">Limit</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">PlanSeeder</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">extends</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">Seeder</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">/**</span></div><div class='line'><span style="color: #7F848E;">     * Run the database seeds.</span></div><div class='line'><span style="color: #7F848E;">     */</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">run</span><span style="color: #ABB2BF;">(): </span><span style="color: #E5C07B;">void</span></div><div class='line'><span style="color: #ABB2BF;">    {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// Pro plan can create 20 products</span></div><div class='line'><span style="color: #ABB2BF;">         </span><span style="color: #E5C07B;">Limit</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">create</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;products&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #98C379;">&#39;allowed_amount&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">20</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #98C379;">&#39;plan&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;pro&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #98C379;">&#39;reset_frequency&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;every month&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        ]);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #7F848E;">// Premium plan can create 50 products</span></div><div class='line'><span style="color: #ABB2BF;">         </span><span style="color: #E5C07B;">Limit</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">create</span><span style="color: #ABB2BF;">([</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #98C379;">&#39;name&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;products&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #98C379;">&#39;allowed_amount&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #D19A66;">50</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #98C379;">&#39;plan&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;premium&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">            </span><span style="color: #98C379;">&#39;reset_frequency&#39;</span><span style="color: #ABB2BF;"> =&gt; </span><span style="color: #98C379;">&#39;every month&#39;</span><span style="color: #ABB2BF;">,</span></div><div class='line'><span style="color: #ABB2BF;">        ]);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Once our seeder is ready, now we can run <code>php artisan db:seed PlanSeeder</code>. Great!</p>
<p>In your <code>User</code> creation logic, after a user is created, you should attach a limit to the user.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">namespace</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">App\Http\Controllers</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">UserController</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">store</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;"> </span><span style="color: #56B6C2;">=</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">create</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validated</span><span style="color: #ABB2BF;">());</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">setLimit</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;products&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;pro&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">destroy</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">User</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">unsetLimit</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;products&#39;</span><span style="color: #ABB2BF;">, </span><span style="color: #98C379;">&#39;pro&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$user</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">delete</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>Now in our <code>ProductController</code> class, whenever a supplier (i.e. the User) attempts to create a product, we can check their limits and decide if they're allowed to create more products or not meanwhile tracking their limits.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C678DD;">namespace</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">App\Http\Controllers</span><span style="color: #ABB2BF;">;</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #C678DD;">class</span><span style="color: #ABB2BF;"> </span><span style="color: #E5C07B;">ProductController</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">store</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Request</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #61AFEF;">abort_if</span><span style="color: #ABB2BF;">(</span><span style="color: #56B6C2;">!</span><span style="color: #61AFEF;"> auth</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">user</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">hasEnoughtLimit</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;products&#39;</span><span style="color: #ABB2BF;">),</span><span style="color: #61AFEF;"> </span><span style="color: #D19A66;">403</span><span style="color: #ABB2BF;">);</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E5C07B;">Product</span><span style="color: #ABB2BF;">::</span><span style="color: #61AFEF;">create</span><span style="color: #ABB2BF;">(</span><span style="color: #E06C75;">$request</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">validated</span><span style="color: #ABB2BF;">());</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #61AFEF;">auth</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">user</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">useLimit</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;products&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #C678DD;">public</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">destroy</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Product</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$product</span><span style="color: #ABB2BF;">) {</span></div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #E06C75;">$product</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">delete</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">        </span><span style="color: #61AFEF;">auth</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">user</span><span style="color: #ABB2BF;">()-&gt;</span><span style="color: #61AFEF;">unuseLimit</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;products&#39;</span><span style="color: #ABB2BF;">);</span></div><div class='line'><span style="color: #ABB2BF;">    }</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>✅ <strong>You're all set! Your application is now ready to track and manage resources and usage consumptions by your users.</strong></p>
<p>Let's go one step further. At the beginning of this tutorial, when we defined our plans and limits, we have also set reset frequency for each of our limits as <code>every month</code>.</p>
<p><strong><em>Laravel Usage Limiter</em></strong> comes with built-in command line tools. We will utilize one of the available commands to automatically reset users limits based on the reset frequency we've set earlier.</p>
<pre><code data-theme="one-dark-pro" data-lang="php" class='torchlight' style='background-color: #282c34; --theme-selection-background: #2c313a;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #7F848E;">// app/Console/Kernel.php</span></div><div class='line'><span style="color: #C678DD;">protected</span><span style="color: #ABB2BF;"> </span><span style="color: #C678DD;">function</span><span style="color: #ABB2BF;"> </span><span style="color: #61AFEF;">schedule</span><span style="color: #ABB2BF;">(</span><span style="color: #E5C07B;">Schedule</span><span style="color: #ABB2BF;"> </span><span style="color: #E06C75;">$schedule</span><span style="color: #ABB2BF;">)</span></div><div class='line'><span style="color: #ABB2BF;">{</span></div><div class='line'><span style="color: #ABB2BF;">    ...</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// Laravel &lt;= 11</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$schedule</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">command</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;limit:reset&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">everyMinute</span><span style="color: #ABB2BF;">();</span></div><div class='line'>&nbsp;</div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #7F848E;">// Laravel &gt;= 10</span></div><div class='line'><span style="color: #ABB2BF;">    </span><span style="color: #E06C75;">$schedule</span><span style="color: #ABB2BF;">-&gt;</span><span style="color: #61AFEF;">command</span><span style="color: #ABB2BF;">(</span><span style="color: #98C379;">&#39;limit:reset&#39;</span><span style="color: #ABB2BF;">)-&gt;</span><span style="color: #61AFEF;">everySecond</span><span style="color: #ABB2BF;">();</span></div><div class='line'><span style="color: #ABB2BF;">    ...</span></div><div class='line'><span style="color: #ABB2BF;">}</span></div></code></pre>
<p>👏👏 <strong>Your application is ready to manage, track, restrict, and automatically reset users limits.</strong></p>
<h2><a id="more-features" href="#more-features" class="" aria-hidden="true" title=""></a>More Features</h2>
<p>What we've implemented to this point the regular implementation of the <strong>Laravel Usage Limiter</strong> package. There are more features provided by the package which you can explore by visiting the <a rel="nofollow noopener" target="_blank" href="https://github.com/nabilhassen/laravel-usage-limiter">GitHub repo</a>.</p>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>In summary, the <strong>Laravel Usage Limiter</strong> package is a powerful tool for any Laravel developer looking to <strong>implement usage restrictions</strong> in their applications. Whether you're building a SaaS product or a simple feature, this package allows you to easily track and manage user consumption while providing flexibility to define your own limits. By following the steps outlined in this tutorial, you can quickly integrate usage tracking into your app and ensure that users stay within their designated boundaries.</p>
<p>Don't forget to explore the additional features offered by the package on its GitHub repository. With the right configuration, you'll be well on your way to delivering a robust application that keeps resource management in check.</p>
<p>💻 --- Happy coding!</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Mon, 21 Oct 2024 03:12:51 +0300</pubDate>
                            </item>
                    <item>
                <title><![CDATA[Why and How I Built a Personal Website]]></title>
                <link>https://nabilhassen.com/why-and-how-i-built-a-personal-website</link>
                <description><![CDATA[<ul class="table_of_contents">
<li><a href="#introduction">Introduction</a></li>
<li><a href="#why-i-decided-to-build-a-personal-website">Why I Decided to Build a Personal Website</a></li>
<li><a href="#what-i-used-to-build-my-personal-website">What I Used to Build My Personal Website</a></li>
<li><a href="#how-i-plan-to-attract--drive-traffic">How I Plan to Attract &amp; Drive Traffic</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2><a id="introduction" href="#introduction" class="" aria-hidden="true" title=""></a>Introduction</h2>
<p>In this post, I’ll walk you through why I decided to build my own personal website and the tools and technologies I used to make it happen. I’ll also share my plans for driving traffic to the site, including strategies for SEO and content promotion. Whether you’re curious about the tech stack or looking for tips on building your online presence, this post has something for you.</p>
<h2><a id="why-i-decided-to-build-a-personal-website" href="#why-i-decided-to-build-a-personal-website" class="" aria-hidden="true" title=""></a>Why I Decided to Build a Personal Website</h2>
<p>For most of my professional career, I worked as a full-time software developer. Looking ahead, I’m leaning more toward freelancing and/or an indie-hacking lifestyle. As a freelancer, I need a place to showcase my work and projects to potential clients. I’ve also been thinking about starting a blog for a long time. So, I came to a conclusion: <em><strong>I need to build a personal website</strong></em>. The idea is to have a space where I can display my work, highlight my skills, and enjoy blogging. Ultimately, the goal is to attract as many freelance leads as possible.</p>
<h2><a id="what-i-used-to-build-my-personal-website" href="#what-i-used-to-build-my-personal-website" class="" aria-hidden="true" title=""></a>What I Used to Build My Personal Website</h2>
<p>For all you nerds out there (myself included), this should be the fun part. I’ll share every tool I used to build this website. First things first, let’s categorize the tools and tech stack into the following:</p>
<ul>
<li>Frontend</li>
<li>Backend</li>
<li>DevOps</li>
<li>Analytics</li>
<li>Other Tools</li>
</ul>
<p>In general, I used my favorite tech stack, the <em><strong>TALL</strong></em> stack.
<em>TALL: Tailwind, Alpine.js, Livewire, Laravel</em></p>
<ol>
<li>
<p><strong>Frontend</strong></p>
<ul>
<li>DaisyUI</li>
<li>Tailwind</li>
<li>Alpine.js</li>
<li>Icons: devicon, heroicons, simpleicons</li>
</ul>
</li>
<li>
<p><strong>Backend</strong></p>
<ul>
<li>Laravel</li>
<li>Livewire</li>
<li>Filament</li>
<li>SQLite</li>
<li>PestPHP</li>
</ul>
</li>
<li>
<p><strong>DevOps</strong></p>
<ul>
<li>Hosting by <strong>Yegara</strong></li>
<li>CI/CD by <strong>GitHub Actions</strong></li>
<li>Control panel by <strong>cPanel</strong></li>
<li>DNS by <strong>Cloudflare</strong></li>
</ul>
</li>
<li>
<p><strong>Analytics &amp; SEO</strong></p>
<ul>
<li>Google Search Console</li>
<li>Google Analytics</li>
<li>Internal Tracking: I also track traffic internally with my backend</li>
<li>Semrush</li>
<li>Ahref</li>
</ul>
</li>
<li>
<p><strong>Other Tools</strong></p>
<ul>
<li>LaraBug</li>
<li>archtechx/laravel-seo</li>
<li>spatie/laravel-feed</li>
<li>spatie/laravel-honeypot</li>
<li>spatie/laravel-markdown</li>
<li>spatie/laravel-sitemap</li>
<li>smknstd/fakerphp-picsum-images</li>
</ul>
</li>
</ol>
<h2><a id="how-i-plan-to-attract--drive-traffic" href="#how-i-plan-to-attract--drive-traffic" class="" aria-hidden="true" title=""></a>How I Plan to Attract &amp; Drive Traffic</h2>
<p>For me, this is going to be the hardest task of all. Fortunately, all I need to do is observe what others are doing and replicate their efforts. Based on my observations, I’ve developed a plan to drive traffic to my site:</p>
<ul>
<li>Building backlinks</li>
<li>Creating content related to my website on X (formerly <em>Twitter</em>), Reddit, and LinkedIn</li>
<li>Writing blog posts and sharing them on X (formerly <em>Twitter</em>), Reddit, and LinkedIn</li>
</ul>
<p><em><strong>To summarize, I need to focus on link building and SEO.</strong></em></p>
<h2><a id="conclusion" href="#conclusion" class="" aria-hidden="true" title=""></a>Conclusion</h2>
<p>Building my personal website was just the beginning. Now, the real challenge lies in driving traffic to it. By focusing on SEO, link-building, and creating content across platforms like X, Reddit, and LinkedIn, I’m determined to make it a valuable tool in growing my freelancing career.</p>
]]></description>
                <author><![CDATA[Nabil Hassen]]></author>
                <pubDate>Mon, 21 Oct 2024 03:07:43 +0300</pubDate>
                            </item>
            </channel>
</rss>
