<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/vendor/feed/atom.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US">
                        <id>https://freek.dev/feed/php</id>
                                <link href="https://freek.dev/feed/php" rel="self"></link>
                                <title><![CDATA[freek.dev - all PHP blogposts]]></title>
                    
                                <subtitle>All PHP blogposts on freek.dev</subtitle>
                                                    <updated>2026-09-04T14:30:28+02:00</updated>
                        <entry>
            <title><![CDATA[Digital Sovereignty Is Written in PHP]]></title>
            <link rel="alternate" href="https://freek.dev/3185-digital-sovereignty-is-written-in-php" />
            <id>https://freek.dev/3185</id>
            <author>
                <name><![CDATA[Freek Van der Herten]]></name>
                <email><![CDATA[freek@spatie.be]]></email>

            </author>
            <summary type="html">
                <![CDATA[<p>An interesting article on how PHP is used by the government.</p>


<a href='https://thephp.foundation/blog/2026/09/02/digital-sovereignty-is-written-in-php/'>Read more</a>]]>
            </summary>
                                    <updated>2026-09-04T14:30:28+02:00</updated>
        </entry>
            <entry>
            <title><![CDATA[Build Your Own AI-Powered Slack Bot with the Laravel AI SDK]]></title>
            <link rel="alternate" href="https://freek.dev/3184-build-your-own-ai-powered-slack-bot-with-the-laravel-ai-sdk" />
            <id>https://freek.dev/3184</id>
            <author>
                <name><![CDATA[Freek Van der Herten]]></name>
                <email><![CDATA[freek@spatie.be]]></email>

            </author>
            <summary type="html">
                <![CDATA[<p>In this article, we’ll build an AI-powered Slack bot with the Laravel AI SDK. Unlike tools such as Claude Tag, it can switch AI providers, answer questions, execute tasks, and retrieve information from a knowledge base you control.</p>


<a href='https://tighten.com/insights/build-your-own-ai-powered-slack-bot-with-the-laravel-ai-sdk/'>Read more</a>]]>
            </summary>
                                    <updated>2026-08-31T14:59:25+02:00</updated>
        </entry>
            <entry>
            <title><![CDATA[Immutability in PHP Beyond readonly]]></title>
            <link rel="alternate" href="https://freek.dev/3181-immutability-in-php-beyond-readonly" />
            <id>https://freek.dev/3181</id>
            <author>
                <name><![CDATA[Freek Van der Herten]]></name>
                <email><![CDATA[freek@spatie.be]]></email>

            </author>
            <summary type="html">
                <![CDATA[<p>A deep dive into immutability in PHP, from readonly properties and interior mutability to immutable value objects, collections, dates, cloning, boundaries, and testing.</p>


<a href='https://wendelladriel.com/blog/immutability-in-php-beyond-readonly'>Read more</a>]]>
            </summary>
                                    <updated>2026-08-17T14:12:30+02:00</updated>
        </entry>
            <entry>
            <title><![CDATA[`exit()` may silently break your parallel tests]]></title>
            <link rel="alternate" href="https://freek.dev/3177-exit-may-silently-break-your-parallel-tests" />
            <id>https://freek.dev/3177</id>
            <author>
                <name><![CDATA[Freek Van der Herten]]></name>
                <email><![CDATA[freek@spatie.be]]></email>

            </author>
            <summary type="html">
                <![CDATA[<p>Michael explains why exit() can make parallel test workers crash without useful diagnostics, and why verbose flags do not help when the process dies outside PHPUnit's control. The fix is simple: throw an exception instead, so the failure is reported normally with a stack trace.</p>


<a href='https://dyrynda.com.au/blog/exit-may-silently-break-your-parallel-tests'>Read more</a>]]>
            </summary>
                                    <updated>2026-08-12T12:30:31+02:00</updated>
        </entry>
            <entry>
            <title><![CDATA[sbx: Sandboxed Claude, complete with PHP and tools]]></title>
            <link rel="alternate" href="https://freek.dev/3175-sbx-sandboxed-claude-complete-with-php-and-tools" />
            <id>https://freek.dev/3175</id>
            <author>
                <name><![CDATA[Freek Van der Herten]]></name>
                <email><![CDATA[freek@spatie.be]]></email>

            </author>
            <summary type="html">
                <![CDATA[<p>A practical walkthrough for running Claude Code inside Docker's new sbx sandbox, with a custom PHP setup and extra tools for open source work. Benjamin also explains why sandboxing AI coding agents is the sensible default.</p>


<a href='https://www.beberlei.de/post/sbx-sandboxed-claude-complete-with-php-and-tools'>Read more</a>]]>
            </summary>
                                    <updated>2026-08-10T12:30:04+02:00</updated>
        </entry>
            <entry>
            <title><![CDATA[What's new in PHP 8.6]]></title>
            <link rel="alternate" href="https://freek.dev/3174-whats-new-in-php-86" />
            <id>https://freek.dev/3174</id>
            <author>
                <name><![CDATA[Freek Van der Herten]]></name>
                <email><![CDATA[freek@spatie.be]]></email>

            </author>
            <summary type="html">
                <![CDATA[<p>Brent surveys the most notable additions coming in PHP 8.6, including partial function application, the new polling API, readonly property defaults, and several smaller improvements and deprecations.</p>


<a href='https://stitcher.io/blog/new-in-php-86'>Read more</a>]]>
            </summary>
                                    <updated>2026-08-05T14:14:26+02:00</updated>
        </entry>
            <entry>
            <title><![CDATA[PHP version stats: July, 2026]]></title>
            <link rel="alternate" href="https://freek.dev/3171-php-version-stats-july-2026" />
            <id>https://freek.dev/3171</id>
            <author>
                <name><![CDATA[Freek Van der Herten]]></name>
                <email><![CDATA[freek@spatie.be]]></email>

            </author>
            <summary type="html">
                <![CDATA[<p>Brendt shares fresh Packagist-based PHP version stats for July 2026: PHP 8.4 is now the most-used version, while PHP 8.5 reached 16% adoption after six months. He also notes that package minimum requirements still lag behind, with relatively few popular packages requiring a version that still gets active bugfix support.</p>


<a href='https://stitcher.io/blog/php-version-stats-july-2026'>Read more</a>]]>
            </summary>
                                    <updated>2026-07-29T17:23:14+02:00</updated>
        </entry>
            <entry>
            <title><![CDATA[Building an order fulfilment workflow in Laravel]]></title>
            <link rel="alternate" href="https://freek.dev/3170-building-an-order-fulfilment-workflow-in-laravel" />
            <id>https://freek.dev/3170</id>
            <author>
                <name><![CDATA[Freek Van der Herten]]></name>
                <email><![CDATA[freek@spatie.be]]></email>

            </author>
            <summary type="html">
                <![CDATA[<p>Steve King builds a real order fulfilment flow to show how a workflow engine handles long-running processes in Laravel. The post covers steps, signals, retries, branching, human approval, compensation, and the surrounding tooling in one practical example.</p>


<a href='https://www.juststeveking.com/articles/building-an-order-fulfilment-workflow/'>Read more</a>]]>
            </summary>
                                    <updated>2026-07-25T14:30:28+02:00</updated>
        </entry>
            <entry>
            <title><![CDATA[Preventing SSRF in Laravel: Why Blocking Private IPs Fails]]></title>
            <link rel="alternate" href="https://freek.dev/3167-preventing-ssrf-in-laravel-why-blocking-private-ips-fails" />
            <id>https://freek.dev/3167</id>
            <author>
                <name><![CDATA[Freek Van der Herten]]></name>
                <email><![CDATA[freek@spatie.be]]></email>

            </author>
            <summary type="html">
                <![CDATA[<p>I found there wasn't any good SSRF prevention libraries for Laravel, so I built one. Very comprehensive tests based on this paper:
https://www.usenix.org/conference/usenixsecurity24/presentation/wessels</p>
<p>https://github.com/securized/laravel-ssrf</p>


<a href='https://securized.dev/laravel-ssrf-package'>Read more</a>]]>
            </summary>
                                    <updated>2026-07-22T15:24:24+02:00</updated>
        </entry>
            <entry>
            <title><![CDATA[PHP Attributes: What, Why, How and When]]></title>
            <link rel="alternate" href="https://freek.dev/3166-php-attributes-what-why-how-and-when" />
            <id>https://freek.dev/3166</id>
            <author>
                <name><![CDATA[Freek Van der Herten]]></name>
                <email><![CDATA[freek@spatie.be]]></email>

            </author>
            <summary type="html">
                <![CDATA[<p>A deep dive into PHP attributes, from metadata and Reflection to practical design patterns, Laravel examples, performance, testing, and the cases where explicit code is better.</p>


<a href='https://wendelladriel.com/blog/php-attributes-what-why-how-and-when'>Read more</a>]]>
            </summary>
                                    <updated>2026-07-21T14:43:26+02:00</updated>
        </entry>
            <entry>
            <title><![CDATA[Supercharge your PHP apps with Go-powered PHP extensions]]></title>
            <link rel="alternate" href="https://freek.dev/3164-supercharge-your-php-apps-with-go-powered-php-extensions" />
            <id>https://freek.dev/3164</id>
            <author>
                <name><![CDATA[Freek Van der Herten]]></name>
                <email><![CDATA[freek@spatie.be]]></email>

            </author>
            <summary type="html">
                <![CDATA[<p>A practical conference session on building PHP extensions with Go and FrankenPHP, then wiring them into Laravel and Symfony as native-feeling features. It uses an in-memory LRU cache as the example and offers a nice tour of framework flexibility and PHP internals.</p>


<a href='https://phpconference.nl/session/supercharge-your-php-apps-with-go-powered-php-extensions/'>Read more</a>]]>
            </summary>
                                    <updated>2026-07-17T14:30:31+02:00</updated>
        </entry>
            <entry>
            <title><![CDATA[New in PHP 8.6: Faster array_map with first-class callables]]></title>
            <link rel="alternate" href="https://freek.dev/3162-new-in-php-86-faster-array-map-with-first-class-callables" />
            <id>https://freek.dev/3162</id>
            <author>
                <name><![CDATA[Freek Van der Herten]]></name>
                <email><![CDATA[freek@spatie.be]]></email>

            </author>
            <summary type="html">
                <![CDATA[<p>In this video, Tideways shows how PHP 8.6 speeds up array_map when you use first-class callables.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/Bbc0fXNXB3U" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
]]>
            </summary>
                                    <updated>2026-07-15T14:30:27+02:00</updated>
        </entry>
            <entry>
            <title><![CDATA[The Laravel Scheduler Under the Hood]]></title>
            <link rel="alternate" href="https://freek.dev/3161-the-laravel-scheduler-under-the-hood" />
            <id>https://freek.dev/3161</id>
            <author>
                <name><![CDATA[Freek Van der Herten]]></name>
                <email><![CDATA[freek@spatie.be]]></email>

            </author>
            <summary type="html">
                <![CDATA[<p>A deep dive into the Laravel Scheduler, from event registration and cron evaluation to mutexes, background processes, sub-minute tasks, and production-safe scheduling.</p>


<a href='https://wendelladriel.com/blog/the-laravel-scheduler-under-the-hood'>Read more</a>]]>
            </summary>
                                    <updated>2026-07-14T14:02:25+02:00</updated>
        </entry>
            <entry>
            <title><![CDATA[Everything About the Context Facade]]></title>
            <link rel="alternate" href="https://freek.dev/3152-everything-about-the-context-facade" />
            <id>https://freek.dev/3152</id>
            <author>
                <name><![CDATA[Freek Van der Herten]]></name>
                <email><![CDATA[freek@spatie.be]]></email>

            </author>
            <summary type="html">
                <![CDATA[<p>A deep dive into Laravel Context, from request metadata and automatic log enrichment to hidden context, scoped values, queues, scheduled commands, and internals.</p>


<a href='https://wendelladriel.com/blog/everything-about-the-context-facade'>Read more</a>]]>
            </summary>
                                    <updated>2026-06-29T14:13:28+02:00</updated>
        </entry>
            <entry>
            <title><![CDATA[Improving Laravel Architecture With Expressive]]></title>
            <link rel="alternate" href="https://freek.dev/3134-improving-laravel-architecture-with-expressive" />
            <id>https://freek.dev/3134</id>
            <author>
                <name><![CDATA[Freek Van der Herten]]></name>
                <email><![CDATA[freek@spatie.be]]></email>

            </author>
            <summary type="html">
                <![CDATA[<p>Learn how Expressive can improve a Laravel application by keeping Eloquent as the database layer while moving business logic to fully typed objects.</p>


<a href='https://wendelladriel.com/blog/improving-laravel-architecture-with-expressive'>Read more</a>]]>
            </summary>
                                    <updated>2026-06-23T14:30:27+02:00</updated>
        </entry>
            <entry>
            <title><![CDATA[Eloquent Query Classes Pattern]]></title>
            <link rel="alternate" href="https://freek.dev/3146-eloquent-query-classes-pattern" />
            <id>https://freek.dev/3146</id>
            <author>
                <name><![CDATA[Freek Van der Herten]]></name>
                <email><![CDATA[freek@spatie.be]]></email>

            </author>
            <summary type="html">
                <![CDATA[<p>Learn how to use Eloquent Query Classes to organize important database logic in Laravel without adding a full repository layer.</p>


<a href='https://wendelladriel.com/blog/eloquent-query-classes-pattern'>Read more</a>]]>
            </summary>
                                    <updated>2026-06-22T14:30:28+02:00</updated>
        </entry>
            <entry>
            <title><![CDATA[Building RAG in Laravel: Four Ingestion Bugs That Silently Wreck Retrieval]]></title>
            <link rel="alternate" href="https://freek.dev/3144-building-rag-in-laravel-four-ingestion-bugs-that-silently-wreck-retrieval" />
            <id>https://freek.dev/3144</id>
            <author>
                <name><![CDATA[Freek Van der Herten]]></name>
                <email><![CDATA[freek@spatie.be]]></email>

            </author>
            <summary type="html">
                <![CDATA[<p>Every Laravel RAG tutorial builds the same ingestion pipeline (chunk, embed, store) and stops the moment the agent answers on screen. None of them check whether retrieval is any good. But retrieval quality is decided at ingestion, before the model runs once, and four decisions there fail with no error, no exception, no failed test:</p>
<ul>
<li><strong>Chunking</strong> that severs the answer mid-sentence, so <code>answer@1</code> falls while <code>source hit@1</code> still looks healthy.</li>
<li>An <strong>HNSW index</strong> built with <code>vector_l2_ops</code> while you query with cosine <code>&lt;=&gt;</code>. Postgres silently ignores the index and scans every row. Laravel 13's native <code>whereVectorSimilarTo()</code> hardcodes <code>&lt;=&gt;</code>, so it's easier to hit than ever. Shown with <code>EXPLAIN</code>.</li>
<li>The <strong>embedding dimension</strong> baked into the <code>vector(1536)</code> column type, so &quot;shrink it to save storage&quot; is a migration plus a full re-embed that quietly drops retrieval to 47%.</li>
<li><strong>Ingesting and querying with different models</strong>, which turns every distance into noise.</li>
</ul>
<p>Each bug is real code from a working repo, proven against an eval suite. It's the prequel to my earlier &quot;Evaluating RAG in Laravel&quot; post: build it, prove it, tune it. Every example verified against <code>laravel/ai</code> v0.7.2 and pgvector, with the full repo to clone.</p>


<a href='https://mujahidabbas.dev/blog/building-rag-laravel-pgvector/'>Read more</a>]]>
            </summary>
                                    <updated>2026-06-19T14:32:25+02:00</updated>
        </entry>
            <entry>
            <title><![CDATA[How PHP Attributes Changed the Way I Write Livewire]]></title>
            <link rel="alternate" href="https://freek.dev/3142-how-php-attributes-changed-the-way-i-write-livewire" />
            <id>https://freek.dev/3142</id>
            <author>
                <name><![CDATA[Freek Van der Herten]]></name>
                <email><![CDATA[freek@spatie.be]]></email>

            </author>
            <summary type="html">
                <![CDATA[<p>Bert De Swaef shows how PHP attributes made his Livewire components easier to read by attaching validation, URL sync, and event listeners directly to the properties and methods they belong to. Nice piece on how attributes reduce mental overhead, improve IDE support, and make components feel more self-documenting.</p>


<a href='https://bert.gent/articles/2026-05-24/how-php-attributes-changed-the-way-i-write-livewire'>Read more</a>]]>
            </summary>
                                    <updated>2026-06-17T12:30:28+02:00</updated>
        </entry>
            <entry>
            <title><![CDATA[Rust Tutorial For PHP and JavaScript Developers]]></title>
            <link rel="alternate" href="https://freek.dev/3141-rust-tutorial-for-php-and-javascript-developers" />
            <id>https://freek.dev/3141</id>
            <author>
                <name><![CDATA[Freek Van der Herten]]></name>
                <email><![CDATA[freek@spatie.be]]></email>

            </author>
            <summary type="html">
                <![CDATA[

<a href='https://youtu.be/lJdqrDFswns?si=xs8_bE4e1JwIsZHu'>Read more</a>]]>
            </summary>
                                    <updated>2026-06-16T14:55:29+02:00</updated>
        </entry>
            <entry>
            <title><![CDATA[#[RouteParameter] Does Not Bind Your Model]]></title>
            <link rel="alternate" href="https://freek.dev/3137-routeparameter-does-not-bind-your-model" />
            <id>https://freek.dev/3137</id>
            <author>
                <name><![CDATA[Freek Van der Herten]]></name>
                <email><![CDATA[freek@spatie.be]]></email>

            </author>
            <summary type="html">
                <![CDATA[<p>Michael Dyrynda explains a subtle Laravel gotcha: #[RouteParameter] only reads the current route parameter value, it does not perform implicit model binding. Good reminder that the controller signature still matters when you expect a bound model inside a form request.</p>


<a href='https://dyrynda.com.au/blog/route-parameters-can-hurt'>Read more</a>]]>
            </summary>
                                    <updated>2026-06-12T14:30:26+02:00</updated>
        </entry>
    </feed>
