<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Cogway</title>
    <link>https://cogway.dev/</link>
    <description>Interactive explainers for Laravel and PHP. One concept at a time, turned into something you can step through, break, and run again.</description>
    <language>en</language>
    <atom:link href="https://cogway.dev/rss.xml" rel="self" type="application/rss+xml"/>
    <lastBuildDate>Tue, 15 Sep 2026 00:00:00 GMT</lastBuildDate>
    <item>
      <title>Why strlen and mb_strlen disagree about one string</title>
      <link>https://cogway.dev/explainers/bytes-vs-characters/</link>
      <guid isPermaLink="true">https://cogway.dev/explainers/bytes-vs-characters/</guid>
      <description>A PHP string is a row of bytes, not a row of characters. strlen counts bytes, mb_strlen counts code points, and grapheme_strlen counts what a reader can see. Cutting with the wrong one breaks the text in two different ways.</description>
      <pubDate>Tue, 15 Sep 2026 00:00:00 GMT</pubDate>
    </item>
    <item>
      <title>Why chunking can skip half your rows</title>
      <link>https://cogway.dev/explainers/chunk-skips-rows/</link>
      <guid isPermaLink="true">https://cogway.dev/explainers/chunk-skips-rows/</guid>
      <description>chunk() pages with LIMIT and OFFSET and re-runs the query each time. Write to the column you filtered on and rows shift out from under it, so the next offset starts past rows nobody ever visited.</description>
      <pubDate>Tue, 15 Sep 2026 00:00:00 GMT</pubDate>
    </item>
    <item>
      <title>Catastrophic backtracking: when one regex melts a CPU</title>
      <link>https://cogway.dev/explainers/catastrophic-backtracking/</link>
      <guid isPermaLink="true">https://cogway.dev/explainers/catastrophic-backtracking/</guid>
      <description>A nested quantifier makes the number of paths double with every letter, and it is the failing input that is slow. PHP gives up and returns false.</description>
      <pubDate>Wed, 05 Aug 2026 00:00:00 GMT</pubDate>
    </item>
    <item>
      <title>Magic methods: how $user-&gt;name works when there is no name</title>
      <link>https://cogway.dev/explainers/magic-methods/</link>
      <guid isPermaLink="true">https://cogway.dev/explainers/magic-methods/</guid>
      <description>Magic methods do not run first. A declared, accessible member always wins, and __get and __call are only the fallback when ordinary lookup finds nothing.</description>
      <pubDate>Wed, 05 Aug 2026 00:00:00 GMT</pubDate>
    </item>
    <item>
      <title>The middleware pipeline, and where the response comes back through</title>
      <link>https://cogway.dev/explainers/middleware-pipeline/</link>
      <guid isPermaLink="true">https://cogway.dev/explainers/middleware-pipeline/</guid>
      <description>Middleware is not a list of filters run once on the way in. Each one wraps the request and the response, so the after halves run in reverse.</description>
      <pubDate>Wed, 05 Aug 2026 00:00:00 GMT</pubDate>
    </item>
    <item>
      <title>Sanctum: a token or a cookie, depending on who is calling</title>
      <link>https://cogway.dev/explainers/sanctum-token-vs-session/</link>
      <guid isPermaLink="true">https://cogway.dev/explainers/sanctum-token-vs-session/</guid>
      <description>Sanctum authenticates two callers behind one guard: your own SPA by session cookie, a mobile client by bearer token. A token in your own SPA is the mistake.</description>
      <pubDate>Wed, 05 Aug 2026 00:00:00 GMT</pubDate>
    </item>
    <item>
      <title>How Eloquent casts raw database values into objects</title>
      <link>https://cogway.dev/explainers/attribute-casting/</link>
      <guid isPermaLink="true">https://cogway.dev/explainers/attribute-casting/</guid>
      <description>Model columns are not typed properties. They live in an array of raw values, and $casts converts them on read. isDirty compares them cast, not only raw.</description>
      <pubDate>Tue, 04 Aug 2026 00:00:00 GMT</pubDate>
    </item>
    <item>
      <title>The cache stampede, and what a lock prevents</title>
      <link>https://cogway.dev/explainers/cache-stampede/</link>
      <guid isPermaLink="true">https://cogway.dev/explainers/cache-stampede/</guid>
      <description>Cache::remember protects the database only while the value is warm. When a key expires, every concurrent request runs the callback. A lock collapses it to one.</description>
      <pubDate>Tue, 04 Aug 2026 00:00:00 GMT</pubDate>
    </item>
    <item>
      <title>When PHP copies a value, and when it shares it</title>
      <link>https://cogway.dev/explainers/references-memory/</link>
      <guid isPermaLink="true">https://cogway.dev/explainers/references-memory/</guid>
      <description>PHP assigns arrays by value, but defers the copy until a write. A reference is the opposite: two names, one slot. Copy-on-write and the foreach trap follow.</description>
      <pubDate>Sun, 02 Aug 2026 00:00:00 GMT</pubDate>
    </item>
    <item>
      <title>What a nested transaction actually rolls back</title>
      <link>https://cogway.dev/explainers/transaction-rollback/</link>
      <guid isPermaLink="true">https://cogway.dev/explainers/transaction-rollback/</guid>
      <description>A nested DB::transaction is a savepoint, not its own transaction. An inner commit runs no SQL, and nothing is durable until the outermost commit.</description>
      <pubDate>Sun, 02 Aug 2026 00:00:00 GMT</pubDate>
    </item>
    <item>
      <title>Why a projection is a view, not the source of truth</title>
      <link>https://cogway.dev/explainers/event-sourcing/</link>
      <guid isPermaLink="true">https://cogway.dev/explainers/event-sourcing/</guid>
      <description>A projection is one of many views folded from the event stream. Add a projector after the fact, replay it, and it rebuilds from events that already existed.</description>
      <pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate>
    </item>
    <item>
      <title>Why eager loading changes the number of queries</title>
      <link>https://cogway.dev/explainers/n-plus-one/</link>
      <guid isPermaLink="true">https://cogway.dev/explainers/n-plus-one/</guid>
      <description>with() is not an optimisation you sprinkle on. It changes when your queries happen. Drive the loop and watch the counter.</description>
      <pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate>
    </item>
    <item>
      <title>Why a failed job does not go straight to failed_jobs</title>
      <link>https://cogway.dev/explainers/queue-retries/</link>
      <guid isPermaLink="true">https://cogway.dev/explainers/queue-retries/</guid>
      <description>A thrown job is released and retried after a backoff. $tries counts total attempts, not retries. Killing the worker does not fail the job.</description>
      <pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate>
    </item>
    <item>
      <title>Why == and === are not the same comparison</title>
      <link>https://cogway.dev/explainers/type-juggling/</link>
      <guid isPermaLink="true">https://cogway.dev/explainers/type-juggling/</guid>
      <description>PHP&apos;s == does not compare values by eye. It coerces both sides to a common type first, following fixed rules, and one of those rules changed in PHP 8.</description>
      <pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate>
    </item>
  </channel>
</rss>
