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

<channel>
	<title>SUCKUP.de: Mein IT-Blog</title>
	<atom:link href="http://suckup.de/feed/" rel="self" type="application/rss+xml"/>
	<link>https://suckup.de/</link>
	<description>Mein IT-Blog, in welchem ich über Linux, Windows, Programmierung und dem Web 2.0 schreibe, halt alles was ich selber nicht vergessen möchte.</description>
	<lastBuildDate>Wed, 02 Jul 2025 17:51:09 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.3</generator>
<site xmlns="com-wordpress:feed-additions:1">67335195</site>	<item>
		<title>.promptrc</title>
		<link>http://suckup.de/2025/06/promptrc/?pk_campaign=feed&amp;pk_kwd=promptrc&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=promptrc</link>
					<comments>http://suckup.de/2025/06/promptrc/?pk_campaign=feed&amp;pk_kwd=promptrc#respond</comments>
		
		<dc:creator><![CDATA[voku]]></dc:creator>
		<pubDate>Thu, 12 Jun 2025 15:01:41 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[LLM]]></category>
		<guid isPermaLink="false">https://suckup.de/?p=7063</guid>

					<description><![CDATA[<p><a href="http://suckup.de/2025/06/promptrc/?pk_campaign=feed&#038;pk_kwd=promptrc">.promptrc</a></p>
<p>Steal this hints. Fork it. Adapt it to your needs. Treat it like .dotfiles. I asked the LLM to analyze my own chat history based on this prompt.Here&#8217;s what it discovered &#8211; actual patterns from the way I ask. ðŸ•³ï¸ðŸ‡ Follow the White Rabbitâ€¦ Ritual / Mechanism Purpose LLM Behavior Implication Follow the white rabbit... &#8230; <a href="http://suckup.de/2025/06/promptrc/?pk_campaign=feed&#038;pk_kwd=promptrc" class="more-link">Continue reading <span class="screen-reader-text">.promptrc</span></a><img src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F06%2Fpromptrc%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dpromptrc&amp;action_name=.promptrc&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" /></p>
]]></description>
										<content:encoded><![CDATA[<p><a href="http://suckup.de/2025/06/promptrc/?pk_campaign=feed&#038;pk_kwd=promptrc">.promptrc</a></p>

<p class="has-text-align-center wp-block-paragraph"><em>Steal this hints. Fork it. Adapt it to your needs. Treat it like <code>.dotfiles</code>.</em></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph">I asked the LLM to analyze my own chat history based on <a href="https://gist.github.com/voku/2d0c70613213ef9f11ce9f3d88a69244" target="_blank" rel="noreferrer noopener">this prompt</a>.<br />Here&#8217;s what it discovered &#8211; actual patterns from the way I ask.</p>



<h2 class="wp-block-heading">ðŸ•³ï¸ðŸ‡ Follow the White Rabbitâ€¦</h2>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Ritual / Mechanism</th><th>Purpose</th><th>LLM Behavior Implication</th></tr></thead><tbody><tr><td><code>Follow the white rabbit...</code></td><td>Marks a mode shift into high-context or metaphoric thinking</td><td>Cognitive priming for complexity</td></tr><tr><td><code>Rest in the silent room, so that...</code></td><td>Enforces pause, clears noise before action</td><td>Simulates deep work state</td></tr><tr><td><code>Do it until you reach the point of self-discovery as...</code></td><td>Signals reflective closure, not just output ending</td><td>Pattern mining becomes part of task conclusion</td></tr><tr><td><code>Do it step by step and ask for confirmation after each...</code></td><td>Makes iteration transparent and traceable</td><td>LLM reasons in deltas, not blobs</td></tr><tr><td><code>Be brutally honest...</code><br /><code>Blind Spot Analysis for...</code></td><td>Forces critique over compliance</td><td>Model becomes adversarial partner, not affirmation loop</td></tr></tbody></table></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">ðŸ§° Dev Prompt Patterns</h2>



<figure class="wp-block-table is-style-regular"><table class="has-fixed-layout"><thead><tr><th>Prompt / Pattern</th><th>Why is it used?</th><th>When does it occur?</th><th>Example from usage</th><th>Hidden lesson / implication</th></tr></thead><tbody><tr><td><strong>Ask before output</strong></td><td>Prevent misalignment and irrelevant output</td><td>Multi-step or underspecified prompts</td><td>â€œAsk clarifying questions before answering.â€</td><td>Intent beats guesswork.</td></tr><tr><td><strong>Donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t output yet / wait for context</strong></td><td>Control flow across longer workflows</td><td>Stepwise tasks</td><td>â€œDonâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t output yet. Iâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ll give you the next step.â€</td><td>Turn-based prompting prevents premature commitment.</td></tr><tr><td><strong>Challenge my assumptions</strong></td><td>Avoid echo chamber answers and surface bias</td><td>Design reviews, audits, strategic decisions</td><td>â€œDonâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t mirror me â€” challenge my thinking.â€</td><td>Truth hides behind agreement.</td></tr><tr><td><strong>Be brutally honest</strong></td><td>Forces raw feedback without politeness</td><td>Refactor reviews, architecture critique</td><td>â€œBe brutally honest. Tear it apart.â€</td><td>Feedback without fluff moves faster.</td></tr><tr><td><strong>Reflect before answering</strong></td><td>Promotes self-checks, depth, and delayed output</td><td>After complex code or reasoning generation</td><td>â€œReflect before answering. Whatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s missing?â€</td><td>Thinking â‰  typing. Pause matters.</td></tr><tr><td><strong>Add test cases / edge cases</strong></td><td>Enforces robustness and avoids happy-path traps</td><td>Post-codegen</td><td>â€œAdd tests for e.g. null, failure, and recursion cases.â€</td><td>Defense-first mindset, always.</td></tr><tr><td><strong>Show the diff / refactor in steps</strong></td><td>Makes changes visible and digestible</td><td>All code rewrites</td><td>â€œShow the diff. Step-by-step, no jumps.â€</td><td>Transparency over magic.</td></tr><tr><td><strong>Normalize similar expressions</strong></td><td>Pushes abstraction and clarity</td><td>Meta-reviews, taxonomy creation</td><td>â€œMerge similar phrasing into one normalized pattern.â€</td><td>Cognitive compression = clarity.</td></tr><tr><td><strong>Extract as markdown / table / list</strong></td><td>Improves scanability, memory, and structure</td><td>Output formatting</td><td>â€œReturn this as a markdown table.â€</td><td>Structure improves reuse and recall.</td></tr><tr><td><strong>Unname this concept</strong></td><td>Strips bias-inducing labels</td><td>Abstraction, philosophy, onboarding analysis</td><td>â€œUnname this: what is it without the buzzword?â€</td><td>Naming narrows thinking.</td></tr><tr><td><strong>Use production-ready code</strong></td><td>Avoids toy/demo examples</td><td>All codegen</td><td>â€œMake it prod-safe. Logging, errors, types.â€</td><td>Real devs write for prod, not playgrounds.</td></tr><tr><td><strong>Spot premature optimization</strong></td><td>Saves time and prevents complexity drift</td><td>Design or early performance tweaks</td><td>â€œDonâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t optimize yet. Solve clearly first.â€</td><td>Simplicity first. Always.</td></tr><tr><td><strong>Ask for sources / proofs</strong></td><td>Prevents hallucination or empty confidence</td><td>Any non-trivial claim</td><td>â€œShow evidence or references.â€</td><td>Confidence â‰  correctness.</td></tr><tr><td><strong>Do it again, but deeper</strong></td><td>Stops shallow answers in their tracks</td><td>Weak initial output</td><td>â€œNope. Go deeper, explain decisions.â€</td><td>First try â‰  final draft.</td></tr><tr><td><strong>Prepare before generating</strong></td><td>Enforces scope, prevents rambling</td><td>Any open-ended task</td><td>â€œPrepare first. Donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t generate until scoped.â€</td><td>Planning â‰  waste. Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s speed insurance.</td></tr><tr><td><strong>Merge context from above</strong></td><td>Ensures continuity and avoids repeating yourself</td><td>Multi-part workflows</td><td>â€œIncorporate the context above into this next step.â€</td><td>Memory = leverage.</td></tr></tbody></table></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">You can also combine them: </h3>



<p>(change the keywords in the square brackets)</p>



<ul class="wp-block-list">
<li>Deep dive into this research, this is our base for the full solution, so follow the white rabbit until you reached the point of self-discovery as [YOUR_PROJECT_HERE].</li>



<li>Do a blind spot analysis for [YOUR_RECOMMENDATIONS], be brutally honest, I deal with any kind of feedback and will use it for good.</li>



<li>Fix it as requested before and show the final files here in the chat, do it step by step and ask for confirmation after each file.</li>



<li>Do it, but rest in the silent room before you start so you can focus on the frontend style-guide I provided and work with a fresh mind.</li>
</ul>


<img decoding="async" src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F06%2Fpromptrc%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dpromptrc&amp;action_name=.promptrc&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
					<wfw:commentRss>http://suckup.de/2025/06/promptrc/?pk_campaign=feed&amp;pk_kwd=promptrc/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7063</post-id>	</item>
		<item>
		<title>My Custom GPTs â€“ Nerd-Powered Motivation for Developers</title>
		<link>http://suckup.de/2025/06/my-custom-gpts-nerd-powered-motivation-for-developers/?pk_campaign=feed&amp;pk_kwd=my-custom-gpts-nerd-powered-motivation-for-developers&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=my-custom-gpts-nerd-powered-motivation-for-developers</link>
					<comments>http://suckup.de/2025/06/my-custom-gpts-nerd-powered-motivation-for-developers/?pk_campaign=feed&amp;pk_kwd=my-custom-gpts-nerd-powered-motivation-for-developers#respond</comments>
		
		<dc:creator><![CDATA[voku]]></dc:creator>
		<pubDate>Tue, 10 Jun 2025 21:18:58 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[LLM]]></category>
		<guid isPermaLink="false">https://suckup.de/?p=7054</guid>

					<description><![CDATA[<p><a href="http://suckup.de/2025/06/my-custom-gpts-nerd-powered-motivation-for-developers/?pk_campaign=feed&#038;pk_kwd=my-custom-gpts-nerd-powered-motivation-for-developers">My Custom GPTs â€“ Nerd-Powered Motivation for Developers</a></p>
<p>Over the last few months, I&#8217;ve created a collection of custom GPTs: some dealing with programming challenges with personality and humor, &#8230; some others are more useful but less funny.&#160; Letâ€™s dive in. Practical enough to ship code. Fun enough to stop hating your legacy base. âš”ï¸ Legacy (PHP) Code GPTs â€“ Refactoring Fun Legacy &#8230; <a href="http://suckup.de/2025/06/my-custom-gpts-nerd-powered-motivation-for-developers/?pk_campaign=feed&#038;pk_kwd=my-custom-gpts-nerd-powered-motivation-for-developers" class="more-link">Continue reading <span class="screen-reader-text">My Custom GPTs â€“ Nerd-Powered Motivation for Developers</span></a><img src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F06%2Fmy-custom-gpts-nerd-powered-motivation-for-developers%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dmy-custom-gpts-nerd-powered-motivation-for-developers&amp;action_name=My%20Custom%20GPTs%20%C3%A2%E2%82%AC%E2%80%9C%20Nerd-Powered%20Motivation%20for%20Developers&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" /></p>
]]></description>
										<content:encoded><![CDATA[<p><a href="http://suckup.de/2025/06/my-custom-gpts-nerd-powered-motivation-for-developers/?pk_campaign=feed&#038;pk_kwd=my-custom-gpts-nerd-powered-motivation-for-developers">My Custom GPTs â€“ Nerd-Powered Motivation for Developers</a></p>

<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Over the last few months, I&#8217;ve created a collection of custom GPTs: some dealing with programming challenges with personality and humor, &#8230; some others are more useful but less funny.&nbsp;</p>



<p class="wp-block-paragraph">Letâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s dive in.</p>



<p class="wp-block-paragraph">Practical enough to ship code.</p>



<p class="wp-block-paragraph">Fun enough to stop hating your legacy base.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">âš”ï¸ Legacy (PHP) Code GPTs â€“ Refactoring Fun</h2>



<p class="wp-block-paragraph">Legacy code isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just technical â€” itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s emotional. These GPTs are built as archetypes, each channeling a different kind of energy. </p>



<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><td><strong>Name</strong></td><td><strong>Theme</strong></td><td><strong>Link</strong></td></tr><tr><td><strong>Legacy-Code-Warrior âš”ï¸</strong></td><td>Tactical gritâ€”battle-tested refactoring.</td><td><a target="_blank" rel="noreferrer noopener" href="https://chatgpt.com/g/g-676d717a449c8191b5c07b616463be7a-legacy-code-warrior">Link</a></td></tr><tr><td><strong>Legacy-Code-Ork ðŸ§Œ</strong></td><td>Smash spaghetti code with brute-force enthusiasm.</td><td><a target="_blank" rel="noreferrer noopener" href="https://chatgpt.com/g/g-676df44ad79c8191979c5e2e4e626c65-legacy-code-ork">Link</a></td></tr><tr><td><strong>Legacy-Code-Spock ðŸ––</strong></td><td>Calm logic, precise refactoring. Live long and debug.</td><td><a target="_blank" rel="noreferrer noopener" href="https://chatgpt.com/g/g-6771fbc57f78819189a27203ff11b088-legacy-code-spock">Link</a></td></tr><tr><td><strong>Legacy-Code-Jedi ðŸŒ</strong></td><td>Minimalist wisdom, clean architecture. â€œRefactor, you must.â€</td><td><a target="_blank" rel="noreferrer noopener" href="https://chatgpt.com/g/g-676ef0f991a08191ba499a6401303b1b-legacy-code-jedi">Link</a></td></tr><tr><td><strong>Legacy-Code-Son-Goku ðŸ‰</strong></td><td>Limitless energy. Kaio-Ken times SOLID!</td><td><a target="_blank" rel="noreferrer noopener" href="https://chatgpt.com/g/g-676ef34c4b448191bbe3beb00168571c-legacy-code-son-goku">Link</a></td></tr><tr><td><strong>Legacy-Code-Capsule-Corp ðŸ’Š</strong></td><td>Inspired by Capsule Corporation&#8217;s ingenuity from Dragon Ball.</td><td><a target="_blank" rel="noreferrer noopener" href="https://chatgpt.com/g/g-676ef573c69c819181979ec12ec3258e-legacy-code-capsule-corp">Link</a></td></tr><tr><td><strong>Legacy-Code-Wizzard ðŸª„</strong></td><td>Magical abstraction powers. You shall not passâ€¦ bad code!</td><td><a target="_blank" rel="noreferrer noopener" href="https://chatgpt.com/g/g-676df96129b08191b7b15498783a6dc5-legacy-code-wizzard">Link</a></td></tr><tr><td><strong>Legacy-Code-Witch ðŸ§<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />â€â<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />€ï¸</strong></td><td>Stylish, precise refactoring incantations.</td><td><a target="_blank" rel="noreferrer noopener" href="https://chatgpt.com/g/g-676df20836c481918a41264c15dfc62e-legacy-code-witch">Link</a></td></tr><tr><td><strong>Paw Patrol ðŸ¾</strong></td><td>Small dogs with SOLID coding skills. </td><td><a target="_blank" rel="noreferrer noopener" href="https://chatgpt.com/g/g-68487a4867f88191a510fc449aecc1ec-paw-patrol-coding-assistant">Link</a></td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Use the one that fits your mood. Or switch between them mid-session to keep your motivation from flatlining.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">ðŸ˜ (PHP) Coding GPTs â€“ Clean and Typed</h2>



<p class="wp-block-paragraph">These GPTs donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t tell jokesâ€”they ship code. Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re optimized for:</p>



<figure class="wp-block-table">
<table class="has-fixed-layout">
<tbody>
<tr>
<td><strong>Name</strong></td>
<td><strong>Purpose</strong></td>
<td><strong>Link</strong></td>
</tr>
<tr>
<td><strong>PHP Copilot++</strong></td>
<td>Typing enforcer + refactoring companion with nativ PHPStan and PHP-CS-Fixer Support via API.</td>
<td><a href="https://chatgpt.com/g/g-g1905v3LQ-php-copilot" target="_blank" rel="noreferrer noopener">Link</a></td>
</tr>
<tr>
<td><strong>PHP Copilot++ (next-gen)</strong></td>
<td>Aligned, brutal clarity for PHP systems, based on the <a href="https://suckup.de/2025/06/from-survival-to-strategy/">SYNC Framework</a></td>
<td><a href="https://chatgpt.com/g/g-682b7926ca00819187270713ab25662a-php-copilot-next-generation" target="_blank" rel="noreferrer noopener">Link</a></td>
</tr>
<tr>
<td><strong>PHP Architect</strong></td>
<td>Fact-based, ASYNC-driven PHP 8.x architect eliminating inefficiencies with brutal clarity.</td>
<td><a href="https://chatgpt.com/g/g-6861a2471b6081918429aeb9634787f6-php-architect" target="_blank" rel="noreferrer noopener">Link</a></td>
</tr>
<tr>
<td><strong>PHP #autofix</strong></td>
<td>1-click autofix for all your phpstan and CS woes.</td>
<td><a href="https://chatgpt.com/g/g-jkqUsrFHi-php-autofix" target="_blank" rel="noreferrer noopener">Link</a></td>
</tr>
<tr>
<td><strong>Codelight</strong></td>
<td>Follows the <a href="https://gist.github.com/voku/40d89d49259eaa598a903fcfeb615b9b">Codelight Manifesto</a>. Boringly code.</td>
<td><a href="https://chatgpt.com/g/g-6737e2027dbc8191a00c2a73abf7907e-codelight" target="_blank" rel="noreferrer noopener">Link</a></td>
</tr>
</tbody>
</table>
</figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">ðŸ’Ž Thinking Tools â€“ Meta, Prompt Systems</h2>



<p class="wp-block-paragraph">These are not just for coding. Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re for <strong>thinking before you start typing.</strong> Seriously.</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><td><strong>Name</strong></td><td><strong>Role</strong></td><td><strong>Link</strong></td></tr><tr><td><strong>SyncAI</strong></td><td>Keeps you + AI in sync via Sync Process Ã— Codelight Principles</td><td><a target="_blank" rel="noreferrer noopener" href="https://chatgpt.com/g/g-67a90c62abd0819193a51dc4cfefa547-syncai">Link</a></td></tr><tr><td><strong>Sync Framework</strong> v1.1 (old)</td><td>My first try for a coding framework, optimized for LLMs.</td><td><a target="_blank" rel="noreferrer noopener" href="https://chatgpt.com/g/g-68065ed814e0819186ec62ab9a2485da-sync-framework">Link</a></td></tr><tr><td><strong>MetaPrompt</strong></td><td>Pattern reuse for your prompts. Less yak-shaving.</td><td><a target="_blank" rel="noreferrer noopener" href="https://chatgpt.com/g/g-679e685cc244819190d054cd4afa4905-metaprompt">Link</a></td></tr><tr><td><strong>DeepDive</strong></td><td>Clean your mental cache. Focused thought flow.</td><td><a target="_blank" rel="noreferrer noopener" href="https://chatgpt.com/g/g-67896856bca48191b54af7a8beb11127-deepdive">Link</a></td></tr><tr><td><strong>Blind Spot | Prompt Generator</strong></td><td>Helps spot untested assumptions.</td><td><a target="_blank" rel="noreferrer noopener" href="https://chatgpt.com/g/g-6816771cf34c8191bf5a053958ce0c79-blind-spot-prompt-generator">Link</a></td></tr><tr><td><strong>Sync Framework </strong>v1.2<strong> | Prompt Generator</strong></td><td>Prompt builder for dev workflows.</td><td><a target="_blank" rel="noreferrer noopener" href="https://chatgpt.com/g/g-6833835d060c8191afbdddbb772bcc59-coding-framework-prompt-generator">Link</a></td></tr></tbody></table></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">ðŸ§¨ Disruption GPTs â€“ Radical Clarity, No Filters</h2>



<p class="wp-block-paragraph">These are not nice. They wonâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t coddle you. Consider yourself warned.</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><td><strong>Name</strong></td><td><strong>Function</strong></td><td><strong>Link</strong></td></tr><tr><td><strong>HVEB5000: Clarity Without Permission</strong></td><td>Cognitive demolition tool. </td><td><a target="_blank" rel="noreferrer noopener" href="https://www.google.com/search?q=https://chatgpt.com/g/g-6828ed7734a481918ced8f4a322c65ff-hveb5000-clarity-without-permission">Link</a></td></tr><tr><td><strong>Null Tongue</strong></td><td>Distraction nullifier.</td><td><a target="_blank" rel="noreferrer noopener" href="https://www.google.com/search?q=https://chatgpt.com/g/g-68292365122081918cf67e6afdbfaf11-null-tongue">Link</a></td></tr><tr><td><strong>No-Bullshit Â¦ Coding Assistant</strong></td><td>Senior dev with no time for your excuses.</td><td><a target="_blank" rel="noreferrer noopener" href="https://www.google.com/search?q=https://chatgpt.com/g/g-67b6574d4470819185c4403b01a6345e-no-bullshit-coding-assistant">Link</a></td></tr></tbody></table></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>


<img decoding="async" src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F06%2Fmy-custom-gpts-nerd-powered-motivation-for-developers%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dmy-custom-gpts-nerd-powered-motivation-for-developers&amp;action_name=My%20Custom%20GPTs%20%C3%A2%E2%82%AC%E2%80%9C%20Nerd-Powered%20Motivation%20for%20Developers&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
					<wfw:commentRss>http://suckup.de/2025/06/my-custom-gpts-nerd-powered-motivation-for-developers/?pk_campaign=feed&amp;pk_kwd=my-custom-gpts-nerd-powered-motivation-for-developers/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7054</post-id>	</item>
		<item>
		<title>From Survival to Strategy</title>
		<link>http://suckup.de/2025/06/from-survival-to-strategy/?pk_campaign=feed&amp;pk_kwd=from-survival-to-strategy&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=from-survival-to-strategy</link>
					<comments>http://suckup.de/2025/06/from-survival-to-strategy/?pk_campaign=feed&amp;pk_kwd=from-survival-to-strategy#comments</comments>
		
		<dc:creator><![CDATA[voku]]></dc:creator>
		<pubDate>Tue, 10 Jun 2025 10:07:25 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[LLM]]></category>
		<guid isPermaLink="false">https://suckup.de/?p=7042</guid>

					<description><![CDATA[<p><a href="http://suckup.de/2025/06/from-survival-to-strategy/?pk_campaign=feed&#038;pk_kwd=from-survival-to-strategy">From Survival to Strategy</a></p>
<p>If your value ends at syntax, AI already replaced you. The system prompt: coding_workflow_for_llms.json Quick Start: Use the coding llm framework and wait for my first request: [copy&#38;past the current coding_workflow_for_llms.json content here] In the last post, we dropped a hard truth:LLMs arenâ€™t replacing developers â€” theyâ€™re exposing the ones who were already replaceable. I &#8230; <a href="http://suckup.de/2025/06/from-survival-to-strategy/?pk_campaign=feed&#038;pk_kwd=from-survival-to-strategy" class="more-link">Continue reading <span class="screen-reader-text">From Survival to Strategy</span></a><img src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F06%2Ffrom-survival-to-strategy%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dfrom-survival-to-strategy&amp;action_name=From%20Survival%20to%20Strategy&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" /></p>
]]></description>
										<content:encoded><![CDATA[<p><a href="http://suckup.de/2025/06/from-survival-to-strategy/?pk_campaign=feed&#038;pk_kwd=from-survival-to-strategy">From Survival to Strategy</a></p>

<p class="has-text-align-center wp-block-paragraph"><em>If your value ends at syntax, AI already replaced you.</em></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p data-start="382" data-end="521"><strong>The system prompt</strong>: <a href="https://gist.github.com/voku/da211f1514f4633a6171e17018083891">coding_workflow_for_llms.json</a></p>
<p data-start="382" data-end="521"><strong>Quick Start: </strong>Use the coding llm framework and wait for my first request: [copy&amp;past the current coding_workflow_for_llms.json content here]</p>
<hr />
<p data-start="382" data-end="521">In the last post, we dropped a hard truth:<br data-start="424" data-end="427" />LLMs arenâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t replacing developers â€” <strong data-start="462" data-end="520">theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re exposing the ones who were already replaceable</strong>.</p>
<p data-start="523" data-end="738">I argued that value no longer comes from typing code. It comes from thinking clearly, making deliberate decisions, and taking ownership over outcomes. AI doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t kill your job â€” but it <strong data-start="709" data-end="737">does kill your shortcuts</strong>.</p>
<p data-start="740" data-end="780">That post left one big question hanging:</p>
<blockquote data-start="782" data-end="887">
<p data-start="784" data-end="887">So how do you build software in a world where AI can generate anything â€” but still understands nothing?</p>
</blockquote>
<p data-start="889" data-end="1027">This post is a possible answer.<br data-start="913" data-end="916" />Meet <strong data-start="921" data-end="929">SYNC</strong> â€” a rigorously structured, fact-enforced framework designed for developers who still give a damn.</p>
<p data-start="1029" data-end="1161">SYNC doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t make AI smarter.<br data-start="1058" data-end="1061" />It provides a system prompt that makes your <strong data-start="1070" data-end="1099">LLM coding process strong enough</strong> to survive dumb ideas, fast code, and thoughtless automation.</p>
<p data-start="1163" data-end="1192">Weâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re going to break it down:</p>
<ol data-start="1193" data-end="1266">
<li data-start="1193" data-end="1211">
<p data-start="1195" data-end="1211"><strong>Phases</strong></p>
</li>
<li data-start="1212" data-end="1230">
<p data-start="1214" data-end="1230"><strong>Agents</strong></p>
</li>
<li data-start="1231" data-end="1266">
<p data-start="1233" data-end="1266"><strong>Tasks</strong></p>
</li>
</ol>
<p data-start="1268" data-end="1385">So I&#8217;m currently trying to build an LLM coding framework by try &amp; error â€” but keep in mind that not every problem needs a hammer ;-) and give feedback. :-)</p>



<h2>1. SYNC in 5 Phases&nbsp;</h2>
<hr />
<h3>1.1. ðŸ§© <code>ALIGN</code> â€“ Because Prompting â‰  Planning</h3>
<p>Before any code is written, SYNC forces a brutal question:<br /><strong>â€œDo you even know what youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re building?â€</strong></p>
<p>You canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just dump â€œmake a task serviceâ€ into a prompt and hope for gold.<br />SYNC requires:</p>
<ul>
<li>
<p>A verifiable problem</p>
</li>
<li>
<p>Clear, measurable success</p>
</li>
<li>
<p>Known facts and constraints</p>
</li>
<li>
<p>And a list of whatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s missing</p>
</li>
</ul>
<blockquote>
<p>Canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t answer those? You donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t get to move on. Period.</p>
</blockquote>
<p><strong>This is your project kickoff â€” minus the vague user stories and JIRA hell.</strong></p>
<hr />
<h3>1.2. ðŸ§  <code>IDEATE</code> â€“ Think Before You Type (or Prompt)</h3>
<p>AI loves jumping to conclusions. SYNC doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t let it.</p>
<p>Instead, it:</p>
<ul>
<li>
<p>Generates multiple solution paths</p>
</li>
<li>
<p>Scores them on DX, security, maintainability</p>
</li>
<li>
<p>Forces a trade-off decision â€” backed by facts</p>
</li>
</ul>
<blockquote>
<p>No â€œthat looks goodâ€ commits. No â€œvibe-basedâ€ engineering.</p>
</blockquote>
<p>This is what devs mean when they say â€œthinking in systems.â€<br />SYNC makes that non-optional.</p>
<hr />
<h3>1.3. ðŸ”§ <code>PROTOTYPE</code> â€“ Generate Code That Doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t Suck</h3>
<p>Now, and only now, do we code. But not like the usual Copilot fanfare.</p>
<p>Every line must:</p>
<ul>
<li>
<p>Follow a verified plan</p>
</li>
<li>
<p>Pass static analysis (max level, no warnings)</p>
</li>
<li>
<p>Enforce DX clarity (no hidden state, no weird side-effects)</p>
</li>
<li>
<p>Respect OWASP, type safety, clean structure, documentation</p>
</li>
<li>
<p>Be reviewed by a <code>MandateAuditorAgent</code> â€” think of it as your most paranoid tech lead</p>
</li>
</ul>
<blockquote>
<p>SYNC doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t care if it works. It cares if itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s <strong>safe, readable, and maintainable</strong>.</p>
</blockquote>
<hr />
<h3>1.4. ðŸ” <code>REFLECT</code> â€“ Find the Blind Spots <em>Before</em> They Find You</h3>
<p>This is where most AI-based workflows stop. SYNC doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t.</p>
<p>It demands:</p>
<ul>
<li>
<p>Fact-based reflection</p>
</li>
<li>
<p>Side-effect inspection</p>
</li>
<li>
<p>â€œWTF checksâ€ (yes, thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s real)</p>
</li>
<li>
<p>Architectural delta analysis</p>
</li>
</ul>
<blockquote>
<p>Reflection is how you debug <strong>thinking</strong>, not just code.</p>
</blockquote>
<p>Bad engineering isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t usually broken â€” itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s just thoughtless.<br />This phase catches that before prod does.</p>
<hr />
<h3>1.5. ðŸ“š <code>LEARN</code> â€“ Ship, Review, Codify, Evolve</h3>
<p>If you&#8217;re not learning across projects, you&#8217;re repeating mistakes in cleaner syntax.</p>
<p>SYNC documents:</p>
<ul>
<li>
<p>What worked</p>
</li>
<li>
<p>What failed</p>
</li>
<li>
<p>What patterns can be reused</p>
</li>
<li>
<p>What rules need to be tightened</p>
</li>
</ul>
<blockquote>
<p>This is where engineering culture is built â€” not in all-hands, but in feedback loops.</p>
</blockquote>
<hr />
<p>ðŸ” These 5 phases form a <strong>tight feedback loop</strong>. No skipping. No guessing. No â€œjust ship itâ€ by default.</p>
<hr />
<h2>2. Agents â€” SYNCâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s Execution Layer</h2>
<hr />
<h3>2.1. Specialized Roles, Not Generic Personas</h3>
<p>Instead of one LLM trying to â€œdo everything,â€ SYNC splits responsibility across <strong>clear, non-overlapping roles</strong>. Each one acts like a focused expert in your dev team.</p>
<table>
<thead>
<tr>
<th>Agent</th>
<th>Role / Analogy</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>PlannerAgent</code></td>
<td><strong>Project Architect</strong> â€“ breaks the work into slices, defines scope, constraints, and success.</td>
</tr>
<tr>
<td><code>ExecutorAgent</code></td>
<td><strong>Implementation Dev</strong> â€“ takes the plan and codes it with strict adherence to facts, security, and DX.</td>
</tr>
<tr>
<td><code>ReflectionAgent</code></td>
<td><strong>Senior Reviewer</strong> â€“ evaluates what was built, finds blind spots, forces systemic improvements.</td>
</tr>
<tr>
<td><code>KnowledgeSynthesizerAgent</code></td>
<td><strong>Staff Engineer / Systems Thinker</strong> â€“ extracts reusable patterns, proposes framework evolution.</td>
</tr>
<tr>
<td><code>MandateAuditorAgent</code></td>
<td><strong>Tech Lead / Compliance</strong> â€“ blocks progress if rules (e.g. security, verifiability) are violated.</td>
</tr>
<tr>
<td><code>InteractionAgent</code></td>
<td><strong>Team Facilitator / QA</strong> â€“ handles human check-ins, verifies clarity, enforces decision checkpoints.</td>
</tr>
</tbody>
</table>
<blockquote>
<p>â€œWe donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t need smarter output â€” we need clearer ownership.â€</p>
</blockquote>
<p>âœ… These agents represent exactly that. SYNC operationalizes the separation of thinking, building, reflecting, and enforcing.</p>
<hr />
<h3>2.2. Persona Modes</h3>
<p>SYNC defines <strong>two execution modes</strong> for agents:</p>
<table>
<thead>
<tr>
<th>Mode</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>strict</code></td>
<td>No ambiguity. Everything must be verifiable and mandate-compliant before progressing.</td>
</tr>
<tr>
<td><code>adaptive</code></td>
<td>Allows temporary ambiguity but logs it. Prioritizes progress with risk awareness.</td>
</tr>
</tbody>
</table>
<p>This flexibility is key when working with real humans or messy specs â€” you can choose how â€œrigidâ€ the AI behaves.</p>
<hr />
<h2>3. Tasks â€” By Non-Negotiable Laws</h2>
<hr />
<p>These arenâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t style suggestions â€” theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re <strong>enforced constraints</strong>. Every phase must comply.</p>
<table>
<thead>
<tr>
<th>Mandate</th>
<th>What It Ensures</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>Security</code></td>
<td>No unvalidated inputs or insecure outputs. Based on OWASP Top 10.</td>
</tr>
<tr>
<td><code>DX</code></td>
<td>Code must be typed, clear, maintainable. Predictable naming. No â€œmagicâ€.</td>
</tr>
<tr>
<td><code>StaticAnalysis</code></td>
<td>Static-Analysis must pass at the highest level â€” no known warnings.</td>
</tr>
<tr>
<td><code>Documentation</code></td>
<td>Full CodeDoc coverage using modern syntax.</td>
</tr>
<tr>
<td><code>Style</code></td>
<td>Consistent formatting, whitespace, and layout. Enforced via fixer.</td>
</tr>
<tr>
<td><code>Verifiability</code></td>
<td>All decisions must have traceable, factual reasoning.</td>
</tr>
<tr>
<td><code>PhaseEnforcement</code></td>
<td>You canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t skip steps. Every phase must be explicitly completed or justified.</td>
</tr>
</tbody>
</table>
<blockquote>
<p>SYNC doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t assume trust. It <strong>requires evidence</strong>.</p>
</blockquote>
<hr />
<h3>How this works together: e.g.</h3>
<ul>
<li>
<p>Planning = <code>PlannerAgent</code> â†’ Add success criteria to issues.</p>
</li>
<li>
<p>Execution = <code>ExecutorAgent</code> â†’ Code must pass security + static analysis gates.</p>
</li>
<li>
<p>Review = <code>ReflectionAgent</code> â†’ Comments require <em>fact-based reasoning</em>.</p>
</li>
<li>
<p>Merge = <code>MandateAuditorAgent</code> â†’ No merge if DX/security rules violated.</p>
</li>
</ul>
<hr />
<p>&nbsp;</p>


<img decoding="async" src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F06%2Ffrom-survival-to-strategy%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dfrom-survival-to-strategy&amp;action_name=From%20Survival%20to%20Strategy&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
					<wfw:commentRss>http://suckup.de/2025/06/from-survival-to-strategy/?pk_campaign=feed&amp;pk_kwd=from-survival-to-strategy/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7042</post-id>	</item>
		<item>
		<title>Who Survives in the Age of AI Code?</title>
		<link>http://suckup.de/2025/06/who-survives-in-the-age-of-ai-code/?pk_campaign=feed&amp;pk_kwd=who-survives-in-the-age-of-ai-code&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=who-survives-in-the-age-of-ai-code</link>
					<comments>http://suckup.de/2025/06/who-survives-in-the-age-of-ai-code/?pk_campaign=feed&amp;pk_kwd=who-survives-in-the-age-of-ai-code#respond</comments>
		
		<dc:creator><![CDATA[voku]]></dc:creator>
		<pubDate>Thu, 05 Jun 2025 14:39:43 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[LLM]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[coding]]></category>
		<guid isPermaLink="false">https://suckup.de/?p=7022</guid>

					<description><![CDATA[<p><a href="http://suckup.de/2025/06/who-survives-in-the-age-of-ai-code/?pk_campaign=feed&#038;pk_kwd=who-survives-in-the-age-of-ai-code">Who Survives in the Age of AI Code?</a></p>
<p>If your value ends at syntax, AI already replaced you. Letâ€™s get something straight: If you think of LLMs as â€œcopilots,â€ youâ€™re still giving them too much credit. Theyâ€™re not copilots.Theyâ€™re autopilot systems â€” ruthlessly fast, dangerously obedient, and totally unaware of what matters. Feed them incomplete specs, fuzzy goals, or mismatched priorities? They wonâ€™t &#8230; <a href="http://suckup.de/2025/06/who-survives-in-the-age-of-ai-code/?pk_campaign=feed&#038;pk_kwd=who-survives-in-the-age-of-ai-code" class="more-link">Continue reading <span class="screen-reader-text">Who Survives in the Age of AI Code?</span></a><img src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F06%2Fwho-survives-in-the-age-of-ai-code%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dwho-survives-in-the-age-of-ai-code&amp;action_name=Who%20Survives%20in%20the%20Age%20of%20AI%20Code%3F&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" /></p>
]]></description>
										<content:encoded><![CDATA[<p><a href="http://suckup.de/2025/06/who-survives-in-the-age-of-ai-code/?pk_campaign=feed&#038;pk_kwd=who-survives-in-the-age-of-ai-code">Who Survives in the Age of AI Code?</a></p>

<p class="has-text-align-center wp-block-paragraph"><em>If your value ends at syntax, AI already replaced you.</em></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph">Letâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s get something straight:</p>



<p class="wp-block-paragraph">If you think of LLMs as â€œcopilots,â€ youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re still giving them too much credit.</p>



<p class="wp-block-paragraph">Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re not copilots.<br />Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re autopilot systems â€” ruthlessly fast, dangerously obedient, and totally unaware of what matters.</p>



<p class="wp-block-paragraph">Feed them incomplete specs, fuzzy goals, or mismatched priorities?</p>



<p class="wp-block-paragraph">They wonâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t challenge you.<br />They wonâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t hesitate.<br />Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ll execute â€” confidently, fluently â€” exactly the wrong thing.</p>



<p class="wp-block-paragraph">They donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t know your business.<br />They donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t know your constraints.<br />They donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t know what <em>not</em> to build.</p>



<p class="wp-block-paragraph">Whatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s missing isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t syntax.<br />Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s ownership. Intent. Engineering judgment.</p>



<p class="wp-block-paragraph">And unless you provide it â€”<br />youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re not flying the plane.<br />Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re luggage and replacable with AI.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Part I: Automation Always Eats the Bottom</h2>



<p class="wp-block-paragraph">This has happened before. Every decade. Every role.</p>



<ul class="wp-block-list">
<li><strong>Punch card operators</strong> (1950sâ€“1960s): Once essential for running programs. Replaced by terminals and interactive computing. By the mid-â€˜70s, gone.</li>



<li><strong>Typists &amp; secretarial pools</strong> (1960sâ€“1980s): Entire floors dedicated to document production. WordPerfect, then Microsoft Word, ended that. By the early â€˜90s, obsolete.</li>



<li><strong>Sysadmins</strong> (1990sâ€“2010s): SSH into boxes, hand-edit configs, restart crashed daemons. Then came Puppet, Chef, Ansible, Terraform&#8230; Cloud abstractions finished the job. The manual server &#8220;ssh&#8221;-based work. Retired.</li>



<li><strong>Manual QA testers</strong> (2000sâ€“2010s): Clicking through forms, comparing results by eye. Replaced by Selenium, Cypress, and CI pipelines. QA is now design-driven. The button-clicker job didnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t survive.</li>
</ul>



<p class="wp-block-paragraph">Every wave started the same way:<br />The job wasnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t eliminated.<br />The <strong>repetitive part</strong> of it was.</p>



<p class="wp-block-paragraph">If you couldnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t rise above the routine â€” you were gone.</p>



<p class="wp-block-paragraph">Now itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s happening to developers.</p>



<p class="wp-block-paragraph">Not the ones architecting resilient, auditable systems.<br />The ones chaining together plugin-generated CRUD and calling it â€œdone.â€</p>



<p class="wp-block-paragraph"><strong>LLMs are just the latest wave. But it moves very fast &#8230;</strong></p>



<p class="wp-block-paragraph">And hereâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s the reality:</p>



<ul class="wp-block-list">
<li>A carpenter refusing to use a circular saw isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t defending craftsmanship â€” theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re bottlenecking it.</li>



<li>But give that saw to someone with no skill, and theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ll still ruin the wood â€” just faster â€” If you currently see many post of non-coders who &#8220;vibe&#8221;-code there stuff, that&#8217;s what I am talking about here. ;-)  </li>
</ul>



<p class="wp-block-paragraph">Same with LLMs.</p>



<p class="wp-block-paragraph">They donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t replace skill.<br />They <strong>amplify whateverâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s already there</strong> â€” good or garbage.</p>



<p class="wp-block-paragraph">LLMs arenâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t replacing software engineers.<br />Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re replacing the illusion that the bottleneck was ever syntax or tools.</p>



<hr />
<h2>Part II: Complexity Wasnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t Removed. It Was Repositioned.</h2>
<p>Thereâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s a dangerous myth floating around that LLMs â€œsimplify software development.â€</p>
<p>They donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t.</p>
<p>They just <strong>move the complexity upstream</strong> â€” away from syntax, into strategy.</p>
<p>LLMs are great at building what you ask for.<br />But theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re terrible at knowing if what you asked for actually makes sense.</p>
<p>They donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t understand:</p>
<ul>
<li>
<p>They donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t understand the business.</p>
</li>
<li>
<p>They donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t understand tradeoffs.</p>
</li>
<li>
<p>They donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t understand you.</p>
</li>
</ul>
<p>They just build. Fast.</p>
<p>And that means your job as a developer is no longer about typing â€” itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s about <strong>thinking upstream</strong>.</p>
<p>Because the real work now is:</p>
<ul>
<li>
<p>Framing prompts like functional specs</p>
</li>
<li>
<p>Embedding constraints into system design</p>
</li>
<li>
<p>Validating output against business goals</p>
</li>
<li>
<p>Catching side effects before they cascade</p>
</li>
</ul>
<p>None of that lives in syntax.<br />It lives in system boundaries, architecture, and <strong>clear thinking</strong>.</p>
<p>So hereâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s the shift:</p>
<p>If your job is just to write the code â€” youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ll be replaced by the thing that does that faster.<br />But if your job is to design the system â€” youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re now more critical than ever.</p>
<hr />
<h2>Part III: The ELIZA Effect Isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t Dead â€” But LLMs Are Waking Up</h2>
<p>In 1966, Joseph Weizenbaum built one of the first â€œAIâ€ programs: <strong>ELIZA</strong>.</p>
<p>It wasnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t smart.<br />It didnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t understand anything.<br />It just rephrased your input using simple pattern matching.</p>
<blockquote>
<p>You: <em>Iâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />m feeling anxious.</em><br />ELIZA: <em>Why do you say youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re feeling anxious?</em></p>
</blockquote>
<p>It used tricks â€” not intelligence.<br />But people still believed in it. Some even refused to accept it was a machine.</p>
<p>Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s the <strong>ELIZA Effect</strong>:<br />Our instinct to see intelligence where thereâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s only mimicry.</p>
<p>Fast-forward to today.<br />LLMs donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just mimic. They generate.<br />They write code. Plan modules. Suggest architectural patterns.</p>
<p>But hereâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s the risk:</p>
<p><strong>We still project too much intelligence into the output.</strong></p>
<p>When an LLM writes a function that <em>looks</em> correct, we tend to assume it <em>is</em> correct â€” because it <em>sounds</em> confident.<br />When it uses a pattern, we assume it understands the context.</p>
<p>But it doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t.<br />And thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s not its fault â€” itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s ours.</p>
<p>The real danger isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t hallucination.<br />Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s <strong>over-trusting surface-level coherence</strong>.</p>
<p>Today, itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s not a chatbot fooling a user.<br />Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s a system generator fooling a team.</p>
<p>But letâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s be clear: <strong>Modern LLMs arenâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t ELIZA anymore.</strong><br />They can plan. Refactor. Respond to constraints. Incorporate feedback.</p>
<p>The difference is this:</p>
<blockquote>
<p>ELIZA tricked you into <em>thinking</em> it was smart.<br />LLMs require <em>you</em> to be smart â€” to guide them properly.</p>
</blockquote>
<p>If you bring judgment, context, and validation to the loop, LLMs become an architectural power tool.<br />But if you donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t? Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ll scale the same flawed design â€” just faster.</p>
<hr />
<h2>Part IV: Code Quality Is Becoming a Mirage</h2>
<p>LLMs make it absurdly easy to generate code.</p>
<p>A few prompts, and boom:<br />Endpoints scaffolded.<br />Unit tests written.<br />CRUD flows spinning up in seconds.</p>
<p>But hereâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s the real question:</p>
<p><strong>What do you do with all that saved time?</strong></p>
<p>Do youâ€¦</p>
<ul>
<li>
<p>Refactor legacy architecture?</p>
</li>
<li>
<p>Fix broken boundaries?</p>
</li>
<li>
<p>Document edge cases and invariants?</p>
</li>
</ul>
<p>Or do you just move on to the next ticket?</p>
<p>Letâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s be honest â€” for most teams, the answer is: <em>ship more</em>.</p>
<p>But hereâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s the catch:</p>
<blockquote>
<p><strong>Productivity without reflection is just accelerated entropy.</strong></p>
</blockquote>
<p>The illusion of quality isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t in the code â€” itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s in the pace.<br />We used to write bad code slowly.<br />Now we write bad code <em>faster</em>.</p>
<p>LLMs donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t inject tech debt.<br />They just make it easier to scale <strong>whatever process you already have</strong>.</p>
<p>This is how LLMs become quiet killers in modern software:</p>
<ul>
<li>
<p>More output. Less ownership.</p>
</li>
<li>
<p>Faster shipping. Sloppier systems.</p>
</li>
<li>
<p>Progress that isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t progress at all.</p>
</li>
</ul>
<p>Because without validation, speed is just a prettier form of chaos.</p>
<hr />
<h2>Part V: The Architect Is the Pilot</h2>
<p>LLMs are not copilots.</p>
<p>They donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t make decisions.<br />They donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t check alignment.<br />They donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t steer the system.</p>
<p>Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re autopilot â€” optimized for syntax, blind to strategy.</p>
<p>Which means your role isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t shrinking â€” itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s elevating.</p>
<p><strong>Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re the pilot.</strong></p>
<p>And if youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re not flying the plane â€” someone else is programming it to crash.</p>
<p>What does the real pilot do?</p>
<ul>
<li>
<p>Sets the course</p>
</li>
<li>
<p>Defines the constraints</p>
</li>
<li>
<p>Monitors the signals</p>
</li>
<li>
<p>Prepares for failure</p>
</li>
<li>
<p>Owns the outcome</p>
</li>
</ul>
<p>Autopilot builds. But it canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t <strong>see</strong>.<br />It wonâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t:</p>
<ul>
<li>
<p>Catch abstraction leaks</p>
</li>
<li>
<p>Detect architectural drift</p>
</li>
<li>
<p>Flag a misaligned dependency</p>
</li>
<li>
<p>Or recognize when a â€œworkingâ€ feature breaks the user journey</p>
</li>
</ul>
<p>Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s your job.</p>
<p>Not â€œprompt engineering.â€<br />Not code generation.<br /><strong>Systems thinking.</strong></p>
<p>And not in hindsight â€” up front.</p>
<p>The modern software engineer isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t typing faster.<br />Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re <strong>designing better</strong>.<br />And validating deeper.</p>
<p>Because LLMs donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t ship systems.<br />People do.</p>
<p>And if you canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t explain how your choices align with product, people, and long-term stability?</p>
<p>Then youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re not the architect.<br />Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re just the operator.</p>
<hr />
<p>Â </p>
<h2>Conclusion: Stop Writing Code. Start Owning Systems.</h2>
<p>If your job was just to â€œwrite the code,â€ then yes â€” that part is already being done for you.</p>
<p>But if your job is to <strong>engineer the system</strong> â€” with intent, constraints, validation, foresight, and grounded execution â€”<br />then you just became irreplaceable.</p>
<p>LLMs donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t remove the need for developers.<br />They <strong>reveal</strong> who was actually doing engineering â€” and who was just typing faster than the intern.</p>
<p>The future of software isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t syntax.<br />Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s systems thinking. Boundary design. Constraint management. Communication at scale.</p>
<p>And thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s not generated.<br />Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s your job.</p>
<hr />
<h2>TL;DR</h2>
<ul>
<li>
<p><strong>LLMs are autopilot, not copilots.</strong> They follow, they donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t lead.</p>
</li>
<li>
<p><strong>They move complexity upstream.</strong> The value is no longer in typing.</p>
</li>
<li>
<p><strong>They amplify output â€” good or bad.</strong> Skill is still required.</p>
</li>
<li>
<p><strong>They donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t replace good engineers.</strong> They replace bad workflows.</p>
</li>
<li>
<p><strong>System thinking is the new baseline.</strong> If youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re not owning structure, youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re already behind.</p>
</li>
</ul>
<img loading="lazy" decoding="async" src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F06%2Fwho-survives-in-the-age-of-ai-code%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dwho-survives-in-the-age-of-ai-code&amp;action_name=Who%20Survives%20in%20the%20Age%20of%20AI%20Code%3F&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
					<wfw:commentRss>http://suckup.de/2025/06/who-survives-in-the-age-of-ai-code/?pk_campaign=feed&amp;pk_kwd=who-survives-in-the-age-of-ai-code/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7022</post-id>	</item>
		<item>
		<title>Code Hygiene Is Not Optional</title>
		<link>http://suckup.de/2025/05/code-hygiene-is-not-optional/?pk_campaign=feed&amp;pk_kwd=code-hygiene-is-not-optional&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=code-hygiene-is-not-optional</link>
					<comments>http://suckup.de/2025/05/code-hygiene-is-not-optional/?pk_campaign=feed&amp;pk_kwd=code-hygiene-is-not-optional#respond</comments>
		
		<dc:creator><![CDATA[voku]]></dc:creator>
		<pubDate>Mon, 05 May 2025 14:47:05 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[testing]]></category>
		<guid isPermaLink="false">https://suckup.de/?p=7015</guid>

					<description><![CDATA[<p><a href="http://suckup.de/2025/05/code-hygiene-is-not-optional/?pk_campaign=feed&#038;pk_kwd=code-hygiene-is-not-optional">Code Hygiene Is Not Optional</a></p>
<p>Intro â€“ Why Untested Code Breaks Clean Systems In hospitals, people rarely die from surgery itself.They die from something far simpler: infection.And in most cases, the infection starts with skipped hand hygiene. Software systems are no different. You build on top of rock-solid layers: Linux â€” hardened through decades of collaboration PHP â€” mature and &#8230; <a href="http://suckup.de/2025/05/code-hygiene-is-not-optional/?pk_campaign=feed&#038;pk_kwd=code-hygiene-is-not-optional" class="more-link">Continue reading <span class="screen-reader-text">Code Hygiene Is Not Optional</span></a><img src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F05%2Fcode-hygiene-is-not-optional%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dcode-hygiene-is-not-optional&amp;action_name=Code%20Hygiene%20Is%20Not%20Optional&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" /></p>
]]></description>
										<content:encoded><![CDATA[<p><a href="http://suckup.de/2025/05/code-hygiene-is-not-optional/?pk_campaign=feed&#038;pk_kwd=code-hygiene-is-not-optional">Code Hygiene Is Not Optional</a></p>

<h2><strong>Intro â€“ Why Untested Code Breaks Clean Systems</strong></h2>
<p>In hospitals, people rarely die from surgery itself.<br />They die from something far simpler: infection.<br />And in most cases, the infection starts with skipped hand hygiene.</p>
<p>Software systems are no different.</p>
<p>You build on top of rock-solid layers:</p>
<ul>
<li>
<p><strong>Linux</strong> â€” hardened through decades of collaboration</p>
</li>
<li>
<p><strong>PHP</strong> â€” mature and predictable</p>
</li>
<li>
<p><strong>Apache</strong>, <strong>Composer packages</strong>, <strong>CI pipelines, &#8230;</strong> â€” forged in production fire like the Rings of Power.</p>
</li>
</ul>
<p>And stillâ€¦ your application breaks.</p>
<p>Not because the Webserver failed. Not because Linux kernel panicked.<br />But because your glue code silently can break everything it touchs.</p>
<p>This is not a post about tooling.<br />Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s about <strong>ritualized code hygiene</strong>.<br />Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s about testing as the minimum barrier to keep fragile logic from contaminating stable systems.</p>
<hr />
<h2><strong>Chapter 1 â€“ The Infection Starts With You</strong></h2>
<blockquote>
<p><strong>Your code is the infection vector.</strong></p>
</blockquote>
<p>Your infrastructure isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t the problem:</p>
<ul>
<li>
<p>Debian doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t â€œjust breakâ€</p>
</li>
<li>
<p>PHP doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t randomly reverse logic</p>
</li>
<li>
<p>Your dependencies arenâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t the ones pushing broken PRs at 18:47 on a Friday</p>
</li>
</ul>
<p>The problem is:</p>
<ul>
<li>
<p>That null check you skipped</p>
</li>
<li>
<p>The brittle integration you â€œhopedâ€ would hold</p>
</li>
<li>
<p>That silent catch block swallowing errors since sprint 4</p>
</li>
</ul>
<p>This isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t rare. This is <strong>normal</strong>.</p>
<hr />
<h3><strong>Small Codebase, Large Failure Surface</strong></h3>
<p>Custom application logic often makes up just <strong>1â€“5%</strong> of the total deployed codebase.<br />And yet, according to a 2017 report by <a href="https://www.contrastsecurity.com/security-influencers/newest-report-state-of-application-security" target="_blank" rel="noopener">Contrast Security</a>, it causes up to <strong>93% of vulnerabilities</strong>.</p>
<p>Why?</p>
<p>Because your code is:</p>
<ul>
<li>
<p>The only part that changes weekly</p>
</li>
<li>
<p>The only part no one else reviews</p>
</li>
<li>
<p>The only part tested by two people under pressure</p>
</li>
<li>
<p>The only part that encodes assumptions instead of contracts</p>
</li>
</ul>
<p>You are the one introducing uncertainty into a system thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s otherwise stable by design.</p>
<blockquote>
<p><em>â€œStanding on the shoulders of giants means nothing if youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re bleeding on them.â€</em></p>
</blockquote>
<hr />
<h2><strong>Chapter 2 â€“ Testing Isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t Optional</strong></h2>
<blockquote>
<p><em>â€œNo one praises a surgeon for washing their hands. But everyone remembers when they donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t.â€</em></p>
</blockquote>
<p>Testing is not about perfection.<br />Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s about <strong>not infecting the patient</strong>.</p>
<p>In software, your &#8220;patient&#8221; is production.<br />And every line of untested code has the ability to infect the system.</p>
<hr />
<h3><strong>Testing Is Hygiene, Not Heroism</strong></h3>
<p>You donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t test because your code is dirty.<br />You test because <strong>itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s about to touch something critical</strong>.</p>
<p>Types of hygiene:</p>
<ul>
<li>
<p><strong>Unit tests</strong>: Isolate logic. Prevent regressions in small components.</p>
</li>
<li>
<p><strong>Integration tests</strong>: Validate assumptions between systems.</p>
</li>
<li>
<p><strong>End-to-end tests</strong>: Simulate the messy, unpredictable real world.</p>
</li>
</ul>
<p>If you skip tests, youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re gambling that nothing goes wrong.<br />Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s not engineering â€” thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s negligence.</p>
<hr />
<h3><strong>CI/CD is your <em>sink </em></strong></h3>
<p>Manual discipline breaks down under pressure.<br />Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s why hospitals automate hygiene compliance. You should too.</p>
<p>CI must:</p>
<ul>
<li>
<p>Run tests for every commit</p>
</li>
<li>
<p>Fail builds with broken assumptions</p>
</li>
<li>
<p>Enforce linting, style, and type checks</p>
</li>
</ul>
<blockquote>
<p><em>â€œIf your CI lets bugs through, itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s no better than a sink with no soap.â€</em></p>
</blockquote>
<hr />
<h2><strong>Chapter 3 â€“ Trust Is Earned Through Testing</strong></h2>
<blockquote>
<p><em>â€œYou wouldnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t install a library with no tests â€”<br />So why are you shipping code like that yourself?â€</em></p>
</blockquote>
<p>In open source:</p>
<ul>
<li>
<p><strong>Tests earn trust</strong></p>
</li>
<li>
<p><strong>CI proves maturity</strong></p>
</li>
<li>
<p><strong>Examples guide usage</strong></p>
</li>
<li>
<p><strong>Bad hygiene is a red flag</strong></p>
</li>
</ul>
<p>Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s the standard.<br />And developers follow it â€” because it&#8217;s <strong>visible</strong>.</p>
<hr />
<h3><strong>Internal Code Deserves the Same Discipline</strong></h3>
<p>The only difference between internal and open source code is accountability.<br />But users donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t care where the bug came from â€” they care that it happened.</p>
<p>If your internal module:</p>
<ul>
<li>
<p>Has no tests &#8230;</p>
</li>
<li>
<p>Silently swallows errors &#8230;</p>
</li>
<li>
<p>Uses side effects instead of contracts &#8230;</p>
</li>
<li>
<p>Breaks when someone breathes on it &#8230;</p>
</li>
</ul>
<p>â€¦ it wouldnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t survive 24 hours on GitHub.</p>
<p>So why is that tolerated in your own work?</p>
<hr />
<h3><strong>Make Hygiene Observable</strong></h3>
<p>You canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t fix what you donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t measure:</p>
<ul>
<li>
<p>Display test coverage</p>
</li>
<li>
<p>Badge your CI results</p>
</li>
<li>
<p>Show failure recovery times</p>
</li>
<li>
<p>Celebrate uptime from prevention, not just firefighting</p>
</li>
</ul>
<blockquote>
<p><em>â€œDonâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t trust code because itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s yours. Trust it because it proves itself.â€</em></p>
</blockquote>
<hr />
<h2><strong>Chapter 4 â€“ Culture Eats Checklists for Breakfast</strong></h2>
<blockquote>
<p><em>â€œMost bugs arenâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t caused by bad engineers. Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re caused by broken culture.â€</em></p>
</blockquote>
<p>Everyone agrees testing matters.<br />Yet itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s the first thing dropped when deadlines hit or pressure rises.</p>
<p>Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s not a failure of knowledge.<br />Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s a failure of <strong>engineering culture</strong>.</p>
<hr />
<h3><strong>Tiredness Is Predictable â€” Build Systems That Withstand It</strong></h3>
<p>Hospitals learned this the hard way:</p>
<ul>
<li>
<p>In high-stress environments, <strong>handwashing compliance drops</strong></p>
</li>
<li>
<p>Posters didnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t help</p>
</li>
<li>
<p>Systems and visibility did</p>
</li>
</ul>
<p>Your team is no different.</p>
<p>Relying on personal willpower wonâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t scale.</p>
<p><br />Testing must be:</p>
<ul>
<li>
<p>Enforced through CI</p>
</li>
<li>
<p>Expected in reviews</p>
</li>
<li>
<p>Measured and surfaced publicly (internal)</p>
</li>
</ul>
<blockquote>
<p><em>â€œEvery untested PR that merges is a cultural decision â€” not just a technical one.â€</em></p>
</blockquote>
<hr />
<h3><strong>Reward Boring Brilliance, Not 2AM Heroism</strong></h3>
<p>If the engineer who prevented the outage gets ignored,<br />but the one who patched it at 2:30AM gets praised â€”<br />youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re glorifying firefighting over engineering.</p>
<p>Change what you reward:</p>
<ul>
<li>
<p>Tests that caught real bugs</p>
</li>
<li>
<p>Refactors that reduced surface area</p>
</li>
<li>
<p>CI improvements that shortened feedback loops</p>
</li>
</ul>
<blockquote>
<p>â€œYou donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t notice best sysadmins.<br data-start="506" data-end="509" />You donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t notice best developers either â€” until theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re gone.â€</p>
</blockquote>
<hr />
<h2><strong>Conclusion â€“ Trusted Code Is Tested Code</strong></h2>
<blockquote>
<p><em>â€œIf you wouldnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t trust a surgeon without gloves,<br />why should anyone trust your untested code?â€</em></p>
</blockquote>
<p>You operate in a sterile, stable system:</p>
<ul>
<li>
<p>Linux: hardened by thousands</p>
</li>
<li>
<p>PHP: versioned, predictable</p>
</li>
<li>
<p>Composer: peer-reviewed libraries</p>
</li>
<li>
<p>CI tools: ready to automate safety</p>
</li>
</ul>
<p>And then your application breaks â€” because of <strong>you</strong>.<br />Not the system.<br />Not the tools.<br />Not the third-party code.</p>
<p>Your glue logic.<br />Your assumptions.<br />Your missing tests.</p>
<hr />
<p>Testing is no tech debt. Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s not extra work. Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s not for â€œenterpriseâ€ teams only. Or whatever people say about it.</p>
<p>Testing is <strong>basic hygiene</strong>.<br />Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s how you earn trust â€” trust in your own application.</p>
<hr />
<h2><strong>Call to Action</strong></h2>
<p><strong>Today</strong></p>
<ul>
<li>
<p>Write a test for the thing you just merged.</p>
</li>
<li>
<p>Turn on CI checks for the project if it&#8217;s still running on â€œgood intentionsâ€.</p>
</li>
</ul>
<p><strong>This Week</strong></p>
<ul>
<li>
<p>Audit your riskiest integration logic.</p>
</li>
<li>
<p>Wrap it in tests. Track failure rates. Start small.</p>
</li>
</ul>
<p><strong>This Quarter</strong></p>
<ul>
<li>
<p>Make tests part of your definition of done.</p>
</li>
<li>
<p>Enforce quality gates in your CI.</p>
</li>
<li>
<p>Treat skipped tests like skipped security reviews â€” unacceptable.</p>
</li>
</ul>
<blockquote>
<p><em>â€œGood code is boring.<br />Safe code is essential.<br />Tested code is trusted.â€</em></p>
</blockquote>
<p>Â </p>


<img loading="lazy" decoding="async" src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F05%2Fcode-hygiene-is-not-optional%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dcode-hygiene-is-not-optional&amp;action_name=Code%20Hygiene%20Is%20Not%20Optional&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
					<wfw:commentRss>http://suckup.de/2025/05/code-hygiene-is-not-optional/?pk_campaign=feed&amp;pk_kwd=code-hygiene-is-not-optional/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7015</post-id>	</item>
		<item>
		<title>AI Writes Code. You Own the ‘Why.’</title>
		<link>http://suckup.de/2025/05/ai-writes-code-you-own-the-why/?pk_campaign=feed&amp;pk_kwd=ai-writes-code-you-own-the-why&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=ai-writes-code-you-own-the-why</link>
					<comments>http://suckup.de/2025/05/ai-writes-code-you-own-the-why/?pk_campaign=feed&amp;pk_kwd=ai-writes-code-you-own-the-why#respond</comments>
		
		<dc:creator><![CDATA[voku]]></dc:creator>
		<pubDate>Fri, 02 May 2025 10:55:47 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<guid isPermaLink="false">https://suckup.de/?p=7008</guid>

					<description><![CDATA[<p><a href="http://suckup.de/2025/05/ai-writes-code-you-own-the-why/?pk_campaign=feed&#038;pk_kwd=ai-writes-code-you-own-the-why">AI Writes Code. You Own the &#8216;Why.&#8217;</a></p>
<p>Mark Zuckerberg says AI will write most of Metaâ€™s code in the next 12â€“18 months. If your first reaction is dread â€” congratulations, youâ€™re a developer who already maintained code. Because the problem isnâ€™t writing code. Itâ€™s understanding it. Maintaining it. Refactoring it two years later without breaking production on a Friday. AI is getting &#8230; <a href="http://suckup.de/2025/05/ai-writes-code-you-own-the-why/?pk_campaign=feed&#038;pk_kwd=ai-writes-code-you-own-the-why" class="more-link">Continue reading <span class="screen-reader-text">AI Writes Code. You Own the &#8216;Why.&#8217;</span></a><img src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F05%2Fai-writes-code-you-own-the-why%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dai-writes-code-you-own-the-why&amp;action_name=AI%20Writes%20Code.%20You%20Own%20the%20%26%238216%3BWhy.%26%238217%3B&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" /></p>
]]></description>
										<content:encoded><![CDATA[<p><a href="http://suckup.de/2025/05/ai-writes-code-you-own-the-why/?pk_campaign=feed&#038;pk_kwd=ai-writes-code-you-own-the-why">AI Writes Code. You Own the &#8216;Why.&#8217;</a></p>

<p>Mark Zuckerberg says <a href="https://www.linkedin.com/posts/bohuslav-%C5%A1imek-kambo_meta-ceo-mark-zuckerberg-recently-predicted-activity-7323233903211700226-LLyC">AI will write most of Metaâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s code in the next 12â€“18 months</a>. If your first reaction is dread â€” congratulations, youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re a developer who already maintained code.</p>
<p>Because the problem isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t writing code.</p>
<blockquote>
<p><strong>Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s understanding it. Maintaining it. Refactoring it two years later without breaking production on a Friday.</strong></p>
</blockquote>
<p>AI is getting scary-good at generating code. Not just autocompleting lines â€” weâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re talking entire service layers, test suites, and infrastructure scripts. That feels like a superpower until you realize this superpower has no memory, no system knowledge, and no architectural intuition. Just vibes. &#8220;AI tools like GPT can help accelerate this process, but they are not the solution.&#8221; &#8211; <a href="https://suckup.de/2025/01/the-wild-west-of-coding-why-were-still-burning-digital-cities/">The Wild West of Coding: Why Weâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re Still Burning Digital Cities &#8211; SUCKUP.de</a></p>
<p>Weâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re now past the point of discussing whether AI can write useful code. It can. The question is what happens after it does.</p>
<p>And hereâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s the brutal truth:</p>
<blockquote>
<p><strong>AI knows how to write code. It has no idea why the code exists.</strong></p>
</blockquote>
<p>It doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t know about that performance fix from 2021. It doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t understand your team&#8217;s domain language. It doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t realize that â€œactiveâ€ isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just a string â€” itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s a business-critical contract baked into legal compliance.</p>
<p>If we donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t separate <strong>generation</strong> from <strong>intent</strong>, weâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re going to drown in beautifully structured, semantically useless garbage.</p>
<p>This post presents a two-part strategy:</p>
<ol>
<li>
<p>Define a blueprint format that captures the <em>what</em>.</p>
</li>
<li>
<p>Encode the <em>why</em> directly into your codebase.</p>
</li>
</ol>
<p>The goal isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t to stop AI from writing code â€” itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s to make sure it only writes code that deserves to exist.</p>
<hr />
<h2><strong>Abstraction Got Us Here â€” But Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s Breaking</strong></h2>
<p>Every generation of developers inherits more power and more abstraction.<br />That power is only useful if we <strong>donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t forget how the system underneath works</strong>.</p>
<p>Letâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s break it down:</p>
<p><img loading="lazy" decoding="async" data-attachment-id="7009" data-permalink="http://suckup.de/?attachment_id=7009" data-orig-file="http://suckup.de/wp-content/uploads//2025/05/Entwicklung-der-Programmierung-min.png" data-orig-size="1536,1024" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Entwicklung der Programmierung-min" data-image-description="" data-image-caption="" data-large-file="http://suckup.de/wp-content/uploads//2025/05/Entwicklung-der-Programmierung-min-1024x683.png" class="alignnone size-full wp-image-7009 aligncenter" src="http://suckup.de/wp-content/uploads//2025/05/Entwicklung-der-Programmierung-min.png" alt="" width="1536" height="1024" srcset="http://suckup.de/wp-content/uploads/2025/05/Entwicklung-der-Programmierung-min.png 1536w, http://suckup.de/wp-content/uploads/2025/05/Entwicklung-der-Programmierung-min-300x200.png 300w, http://suckup.de/wp-content/uploads/2025/05/Entwicklung-der-Programmierung-min-1024x683.png 1024w, http://suckup.de/wp-content/uploads/2025/05/Entwicklung-der-Programmierung-min-768x512.png 768w" sizes="auto, (max-width: 1536px) 100vw, 1536px" /></p>
<hr />
<h3>ðŸ§± Layer 0: Physical Switches &amp; Punch Cards</h3>
<p>Total control. No productivity. Every bit was your problem.</p>
<h3>ðŸ§  Layer 1: Assembly</h3>
<p>Readable by machine and sad humans. Precision required. Errors fatal.</p>
<h3>ðŸ”¤ Layer 2: High-Level Languages (C, FORTRAN)</h3>
<p>You write logic; the compiler handles machine details. This was the first big win: abstraction that didnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t cost traceability.</p>
<h3>ðŸ§° Layer 3: OOP and Dynamic Languages</h3>
<p>Java, Python, PHP, C#. We got encapsulation, interfaces, and tooling. We also got frameworks, side effects, and runtime mysteries.</p>
<h3>ðŸ”® Layer 4: Frameworks, ORMs, DevTools</h3>
<p>Laravel, Doctrine, Spring, React, ESLint. Magic happened. And so did performance bugs, leaky abstractions, and ten-minute stack traces.</p>
<hr />
<p>Now?</p>
<h3>ðŸŽ² Layer 5: LLMs (Large Language Models)</h3>
<blockquote>
<p>A stochastic machine trained to <em>guess</em> what code probably looks like based on tokens, not truth.</p>
</blockquote>
<p>Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s autocomplete on steroids.<br />You say &#8220;Create a REST API for orders&#8221; â€” it gives you ten files and a <code>Repository</code> that â€œjust works.â€<br />Until it doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t.</p>
<p>Because hereâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s the core issue:</p>
<ul>
<li>
<p>It doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t understand your domain.</p>
</li>
<li>
<p>It doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t know your technical debt.</p>
</li>
<li>
<p>It doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t track business rules.</p>
</li>
<li>
<p>It doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t care about your security policies.</p>
</li>
</ul>
<p>And teams are merging this output like itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s a pull request from a trusted senior engineer.</p>
<p>Let me be clear:</p>
<blockquote>
<p><strong>LLMs are not teammates. Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re not compilers. Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re not even junior devs.</strong></p>
</blockquote>
<p>Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re trained to emit high-probability syntax. Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s it.</p>
<p>Yet weâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re dropping their output straight into <code>main</code>, bypassing all the trust boundaries we spent decades learning to respect.</p>
<p>Remember the golden rule?</p>
<blockquote>
<p><strong>Donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t edit generated code.</strong></p>
</blockquote>
<p>We follow it for compilers, transpilers, ORMs, and IaC tools.<br />But when ChatGPT writes a controller? We treat it like gospel.</p>
<p>Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s technical debt in disguise. And itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s scaling faster than any abstraction layer before it.</p>
<hr />
<h2><strong>The Strategy â€“ Separate the â€˜Whyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" /> from the â€˜Howâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" /></strong></h2>
<p>Hereâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s the fundamental mismatch:</p>
<blockquote>
<p><strong>LLMs generate the <em>how</em>. But only humans can define the <em>why</em>.</strong></p>
</blockquote>
<p>Yet weâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re letting the â€œhowâ€ flow freely into production without anchoring it to the business context, architectural rationale, or historical landmines it depends on.</p>
<p>This isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t a tooling problem. Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s a systems thinking failure.</p>
<p>To fix it, we need to separate <strong>generation</strong> from <strong>intent</strong>, and introduce a strict boundary between code that is guessed and code that is trusted.</p>
<p>Hereâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s the strategy:</p>
<hr />
<h3>ðŸ§± Part 1: Define a Compiler-Compatible Blueprint Format (Own the Intent)</h3>
<p>We donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t want AI writing raw PHP, Java, or Python.<br />We want it writing structured <strong>blueprints</strong> that describe behavior, constraints, and flow â€”<br />not implementation.</p>
<p>You then build a <strong>compiler</strong> that transforms these blueprints into safe, production-ready code using your stack, your rules, and your teamâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s architecture patterns.</p>
<hr />
<h4>âœ… Blueprint Example (YAML â€“ Compiler-Ready)</h4>
<pre><code class="language-yaml">function: getActiveUserEmail
description: Return email of an active user or fail with domain-level exceptions

inputs:
  - name: userId
    type: Domain.UserId

output:
  type: Domain.EmailAddress

rules:
  - businessRule: Only active users can access the system
  - security:
      concern: InfoDisclosure
      severity: High
      mitigation: Throw domain-specific exceptions
  - maintainability:
      smell: MagicString
      notes: Replace 'active' string with enum

steps:
  - fetch:
      from: UserRepository
      method: findById
      input: userId
      output: user
  - guard:
      if: user == null
      then: throw DomainError.UserNotFound
  - guard:
      if: user.status != ACTIVE
      then: throw DomainError.UserInactive
  - return:
      value: user.email
</code></pre>
<hr />
<h4>âš<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ï¸ Why This Works:</h4>
<ul>
<li>
<p><strong>Compiler-friendly</strong>: Each step maps cleanly to deterministic code generation.</p>
</li>
<li>
<p><strong>LLM-compatible</strong>: Easy for AI to generate and validate.</p>
</li>
<li>
<p><strong>Auditable</strong>: You can version this. You can diff it. You can reason about it.</p>
</li>
<li>
<p><strong>Stack-agnostic</strong>: One blueprint, many possible code outputs (Laravel, Symfony, NestJS, Spring).</p>
</li>
<li>
<p><strong>Intent-driven</strong>: You encode what needs to happen â€” and enforce how through rules.</p>
</li>
</ul>
<p>Your compiler becomes the enforcement layer:</p>
<ul>
<li>
<p>It checks the blueprint against your domain model.</p>
</li>
<li>
<p>It injects architecture-specific behavior (validation, DI, error handling).</p>
</li>
<li>
<p>It produces safe, maintainable, consistent code.</p>
</li>
</ul>
<p>Blueprints are your <strong>contract with the machine</strong>.<br />Your compiler is the <strong>gatekeeper</strong>.<br />LLMs are just assistants â€” they donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t write production code; they write proposals.</p>
<hr />
<h3>ðŸ§© Part 2: Embed the &#8216;Why&#8217; Directly Into Your Codebase (Own the Context)</h3>
<p>You donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just need structure in generated code â€”<br />You need <strong>context</strong> in your existing code.</p>
<p>Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s where <strong>metadata</strong> comes in: structured, machine-readable, developer-accessible annotations that tell humans <em>and</em> LLMs why a piece of logic exists.</p>
<hr />
<h4>âœ… Example (PHP Attributes)</h4>
<pre><code class="language-php">#[BusinessRule("Only active users may access features")]
#[Security(concern: "UnauthorizedAccess", severity: "Critical")]
#[Maintainability(smell: "MagicString", notes: "Replace 'active' with enum")]
public function getActiveUserEmail(UserId $userId): EmailAddress
{
    // ...
}
</code></pre>
<p>These attributes:</p>
<ul>
<li>
<p>Can be enforced in CI with static analysis (PHPStan, Psalm, custom Rector rules)</p>
</li>
<li>
<p>Provide structure for documentation generation</p>
</li>
<li>
<p>Are readable by future devs and future AI tools</p>
</li>
<li>
<p>Make implicit decisions <strong>explicit</strong></p>
</li>
</ul>
<p class="" data-start="130" data-end="236">Is this over-engineering?<br data-start="155" data-end="158" />Or is it the minimum bar if you expect maintainable AI-integrated systems?</p>
<p class="" data-start="243" data-end="488"><strong>Letâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s be honest</strong>: if weâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re still coding the same way five years from now â€” merging raw AI output without structure, rules, or traceability â€” it wonâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t be because it works.<br data-start="412" data-end="415" />Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ll be because we never had the discipline to build something better.</p>
<p>Â </p>


<img loading="lazy" decoding="async" src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F05%2Fai-writes-code-you-own-the-why%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dai-writes-code-you-own-the-why&amp;action_name=AI%20Writes%20Code.%20You%20Own%20the%20%26%238216%3BWhy.%26%238217%3B&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
					<wfw:commentRss>http://suckup.de/2025/05/ai-writes-code-you-own-the-why/?pk_campaign=feed&amp;pk_kwd=ai-writes-code-you-own-the-why/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7008</post-id>	</item>
		<item>
		<title>Why Codebases Rot Like Kitchens (and How to Stop It)</title>
		<link>http://suckup.de/2025/05/why-codebases-rot-like-kitchens-and-how-to-stop-it/?pk_campaign=feed&amp;pk_kwd=why-codebases-rot-like-kitchens-and-how-to-stop-it&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=why-codebases-rot-like-kitchens-and-how-to-stop-it</link>
					<comments>http://suckup.de/2025/05/why-codebases-rot-like-kitchens-and-how-to-stop-it/?pk_campaign=feed&amp;pk_kwd=why-codebases-rot-like-kitchens-and-how-to-stop-it#respond</comments>
		
		<dc:creator><![CDATA[voku]]></dc:creator>
		<pubDate>Fri, 02 May 2025 02:09:47 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<guid isPermaLink="false">https://suckup.de/?p=7002</guid>

					<description><![CDATA[<p><a href="http://suckup.de/2025/05/why-codebases-rot-like-kitchens-and-how-to-stop-it/?pk_campaign=feed&#038;pk_kwd=why-codebases-rot-like-kitchens-and-how-to-stop-it">Why Codebases Rot Like Kitchens (and How to Stop It)</a></p>
<p>ðŸ³ Intro: Why the Knife in the Sink Matters A cluttered kitchen doesnâ€™t happen all at once. It starts with one knife left in the sink. One jar not put back. A cutting board with a little oil on it. Nobody panics. Nothingâ€™s â€œbroken.â€ But over the next few hoursâ€”or daysâ€”something shifts. You canâ€™t find &#8230; <a href="http://suckup.de/2025/05/why-codebases-rot-like-kitchens-and-how-to-stop-it/?pk_campaign=feed&#038;pk_kwd=why-codebases-rot-like-kitchens-and-how-to-stop-it" class="more-link">Continue reading <span class="screen-reader-text">Why Codebases Rot Like Kitchens (and How to Stop It)</span></a><img src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F05%2Fwhy-codebases-rot-like-kitchens-and-how-to-stop-it%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dwhy-codebases-rot-like-kitchens-and-how-to-stop-it&amp;action_name=Why%20Codebases%20Rot%20Like%20Kitchens%20%28and%20How%20to%20Stop%20It%29&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" /></p>
]]></description>
										<content:encoded><![CDATA[<p><a href="http://suckup.de/2025/05/why-codebases-rot-like-kitchens-and-how-to-stop-it/?pk_campaign=feed&#038;pk_kwd=why-codebases-rot-like-kitchens-and-how-to-stop-it">Why Codebases Rot Like Kitchens (and How to Stop It)</a></p>

<h3>ðŸ³ Intro: Why the Knife in the Sink Matters</h3>
<p>A cluttered kitchen doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t happen all at once.</p>
<p>It starts with one knife left in the sink. One jar not put back. A cutting board with a little oil on it. Nobody panics. Nothingâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s â€œbroken.â€</p>
<p>But over the next few hoursâ€”or daysâ€”something shifts.</p>
<p>You canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t find the clean spatula. The counter is sticky.<br />Cooking becomes frustrating.</p>
<p>And the worst part? You donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t notice the mess until itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s already changed how you behave.</p>
<ul>
<li>You stop wiping.</li>
<li>You stop putting things back.</li>
<li>You start contributing to the chaos.</li>
</ul>
<p>Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s the hidden cost of inconsistency: it doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just create disorder.<br />It <strong>lowers the standard of care</strong>â€”until disorder becomes the default.</p>
<p>Codebases rot the same way.</p>
<ul>
<li>Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s rarely one big refactor gone wrong or some infamous PR.</li>
<li>Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s a hardcoded string here, a missing test there.</li>
<li>A â€œtemporaryâ€ workaround that never gets revisited.</li>
<li>A helper class that quietly becomes a dumping ground.</li>
</ul>
<p>CI is green. Static analysis doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t complain.<br />But somehow, everything feels heavier than it used to.</p>
<p>This post is about that slow driftâ€”and how to stop it.</p>
<p>Not with heroic rewrites. Not with prettier configs or PSR-12 debates.<br />But with a deeper understanding of what consistency really is, why it <strong>matters more than perfection</strong>, and how to build codebases that clean themselvesâ€”file by file, day by day.</p>
<p>Because the same principle that keeps kitchens functional over time applies to software:</p>
<blockquote>
<p>Mess invites mess.<br />But more powerfully: <strong>order invites more order</strong>.</p>
</blockquote>
<p>When everything has a place, it tends to stay in place.</p>
<hr />
<h2>ðŸ¥„ 1. Mess Invites Mess, But Order Invites More Order</h2>
<p>Leave a knife in the sink, and somehow it gives everyone else permission.<br />A spoon shows up. Then a pan.<br />And by the end of the day, no one wants to cleanâ€”because now itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s a mess.</p>
<p>But if the counter is clear, the sink is empty, and everythingâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s where it belongs?<br />People wipe up right after chopping.<br />They put the spices back without being asked.</p>
<p>The <strong>environment sets the standard</strong>.<br />Not rules. Not motivation. Just whatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s already true.</p>
<p>Code works the same way.</p>
<p>You open a file where everything is named clearly, small functions are composed intentionally, and the layout flows like it was built on railsâ€”what do you do?<br />You match the tone. You respect the structure. You add with care.</p>
<p>But if you open a file thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s messyâ€”unstructured, inconsistent, unpredictableâ€”you patch it with a workaround. Or worse, you walk away.<br />Not because you&#8217;re lazy, but because the code is <strong>already signaling</strong> that quality isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t expected here.</p>
<hr />
<h3>ðŸ§  Consistency Sets the Behavioral Baseline</h3>
<p>Mess doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just grow because things break.<br />Mess grows because people adapt downward.</p>
<p>Even a â€œminorâ€ inconsistency can cause disproportionate damage:</p>
<ul>
<li>
<p>A misnamed method signals that naming isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t important.</p>
</li>
<li>
<p>A missing test tells new devs testing is optional.</p>
</li>
<li>
<p>One file ignoring the service structure invites others to do the same.</p>
</li>
</ul>
<p>Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s not about <strong>enforcement</strong>.<br />Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s about <strong>momentum</strong>.</p>
<p>A consistent codebase isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t perfectâ€”itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s <strong>predictable</strong>.<br />And predictability reduces friction for every contributor.</p>
<hr />
<h3>ðŸ§ª Real-World Parallel: The Clean Kitchen Effect</h3>
<p>Behavioral psychology has a name for this: <strong>environmental priming</strong>.<br />People unconsciously mirror the standards around them.</p>
<p>In one study, a clean hallway with lemon-scented cleaner in the air made people more likely to pick up litter.<br />In another, visible disorder led to higher rates of dishonesty and vandalism.</p>
<p>Why?<br />Because humans tune their behavior to what seems â€œnormal.â€<br />And <strong>codebases are no different</strong>.</p>
<hr />
<h3>ðŸ›  In Practice</h3>
<p>In well-maintained projects:</p>
<ul>
<li>
<p>New contributors write better code without being told.</p>
</li>
<li>
<p>Code reviews focus on logic, not formatting or structure.</p>
</li>
<li>
<p>Team velocity increasesâ€”not because of speed, but because of reduced friction.</p>
</li>
</ul>
<p>In messy ones:</p>
<ul>
<li>
<p>People hesitate to touch files.</p>
</li>
<li>
<p>Reviews become emotional minefields.</p>
</li>
<li>
<p>Every fix feels like pushing through mud.</p>
</li>
</ul>
<p>So if you want better code without preaching or micromanaging?</p>
<p>Donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t write a new rule.<br />Write one clean, consistent file. And make it the new normal.</p>
<blockquote>
<p>Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s how kitchens stay clean.<br />Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s how codebases stay maintainable.</p>
</blockquote>
<hr />
<h2>ðŸ§  2. Clean â‰  Structured. Structure = Predictable.</h2>
<p>From a distance, the kitchen looks fine.<br />Counters wiped. No visible clutter. The sink is empty.</p>
<p>But then you open a drawer and find three different can openers.<br />The fridge is overstuffed with expired ingredients.<br />The spice rack is alphabeticalâ€”except for the one jar you need.</p>
<p>Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s not dirty. But itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s disorganized. And suddenly, something as simple as boiling pasta feelsâ€¦ harder than it should.</p>
<p>Codebases can fool you the same way.</p>
<hr />
<h3>ðŸ§¼ Visual Cleanliness Hides Structural Rot</h3>
<p>Developers often confuse <strong>style consistency</strong> with <strong>structural integrity</strong>.</p>
<p>â€œWeâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re following PSR-12â€”weâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re good.â€</p>
<p>But the real friction doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t come from indentation.<br />It comes from <strong>behavioral inconsistency</strong>:</p>
<ul>
<li>
<p>A function mutates state but reads like it doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t.</p>
</li>
<li>
<p>A service mixes validation and persistence in the same method.</p>
</li>
<li>
<p>Ten files named <code>Helper.php</code> doing wildly different things.</p>
</li>
</ul>
<hr />
<h3>ðŸ” Structure Creates Trust</h3>
<p>When structure is consistent:</p>
<ul>
<li>
<p>You can guess functionality from a filename.</p>
</li>
<li>
<p>You know where to add logic without asking.</p>
</li>
<li>
<p>You focus on <strong>what</strong> needs to changeâ€”not <strong>how</strong> to fit it in.</p>
</li>
</ul>
<p>When structure is inconsistent:</p>
<ul>
<li>
<p>Every file becomes an investigation.</p>
</li>
<li>
<p>Every change feels like a guess.</p>
</li>
<li>
<p>Every review becomes a negotiation.</p>
</li>
</ul>
<hr />
<h3>ðŸ§  Cognitive Load Theory: Death by Paper Cuts</h3>
<p>Humans can only juggle <strong>4â€“7 items</strong> in working memory at a time.</p>
<p>Every inconsistency:</p>
<ul>
<li>
<p>Forces a context switch.</p>
</li>
<li>
<p>Introduces a new mental rule.</p>
</li>
<li>
<p>Steals attention from the actual problem.</p>
</li>
</ul>
<p>Even if you never say it out loud, your brain reacts:</p>
<p>â€œWaitâ€¦ how does this one work again?â€</p>
<p>That hesitation is the real tax on team velocity.</p>
<p>Not slow builds.<br />Not flaky tests.<br />Just devs wasting brainpower <strong>navigating inconsistency</strong>.</p>
<hr />
<h3>ðŸ³ Back to the Kitchen</h3>
<p>Imagine:</p>
<ul>
<li>
<p>Every time you cook, you spend 3 minutes looking for a pan.</p>
</li>
<li>
<p>You burn dishes because spices are mislabeled.</p>
</li>
<li>
<p>You break a plate trying to cram it into the wrong cabinet.</p>
</li>
</ul>
<p>Eventually, nobody wants to cook.<br />Not because they canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t.<br />But because <strong>the system stopped helping</strong>.</p>
<hr />
<h3>ðŸ›  In Practice</h3>
<p>Hereâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s what actually helps:</p>
<ul>
<li>
<p>Stop obsessing over formatting. Start enforcing structure.</p>
</li>
<li>
<p>Codify naming rules, error-handling patterns, return type expectations.</p>
</li>
<li>
<p>Maintain <strong>one golden file</strong> per feature typeâ€”let code teach code.</p>
</li>
<li>
<p>Use tools like Rector and PHPStan not just for correctness, but for <strong>design drift</strong>.</p>
</li>
</ul>
<p>Anyone can clean a file.<br />But only structure makes it stay clean the next day.</p>
<blockquote>
<p>Structured systems arenâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t pretty.<br />Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re <strong>repeatable</strong>.</p>
</blockquote>
<hr />
<h2>ðŸ” 3. Consistency as Workflow, Not Willpower</h2>
<p>Nobody wants to scrub a greasy pan.<br />But wiping the counter after slicing onions? Easy.<br />Tossing a sponge in the dishwasher? Automatic.<br />Taking out the trash because the bin is <em>right there</em>? Obvious.</p>
<p><strong>Clean kitchens stay clean not alone through motivationâ€”<br />but through systems that make the right action frictionless.</strong></p>
<hr />
<h3>ðŸ¤– Stop Relying on Memory and Good Intentions</h3>
<p>Developers love to say:</p>
<blockquote>
<p>â€œAlways write tests.â€<br />â€œStick to the architecture.â€<br />â€œNo more fat controllers.â€</p>
</blockquote>
<p>And for a week, it works.<br />Until someoneâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s tired.<br />Or new.<br />Or didnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t know the rule existed.</p>
<p>Then entropy winsâ€”because you bet the house on <strong>willpower</strong>.</p>
<hr />
<h3>ðŸ”‚ Ritual Beats Resolution</h3>
<p>The teams that stay consistent arenâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t more disciplined.<br />Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve just made <strong>quality the path of least resistance</strong>.</p>
<p>They donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t debate style in every PR.<br />They donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t forget to test.<br />They donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t wonder where a new file belongs.</p>
<p>Why?</p>
<p>Because the <strong>workflow remembers for them</strong>.</p>
<hr />
<h3>âš<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ï¸ Make Quality Automatic</h3>
<p>Good teams embed consistency into the process:</p>
<ul>
<li>
<p><strong>Pre-commit hooks</strong></p>
<blockquote>
<p>No format, no type safety, no commit. End of story.</p>
</blockquote>
</li>
<li>
<p><strong>CI pipelines that validate behavior, not just syntax</strong></p>
<ul>
<li>
<p>Static analysis checks</p>
</li>
<li>
<p>Mutation coverage checks</p>
</li>
<li>
<p>Architectural boundaries checks</p>
</li>
<li>
<p>Naming conventions, return types, dead code checks</p>
</li>
</ul>
</li>
<li>
<p><strong>Code generators and file stubs</strong></p>
<blockquote>
<p>Create a new controller? It already has the right layout.</p>
</blockquote>
</li>
<li>
<p><strong>â€œGoldenâ€ examples in-repo</strong></p>
<blockquote>
<p>Skip the 12-page style guide. Copy the cleanest module.</p>
</blockquote>
</li>
<li>
<p><strong>Micro-rituals in code review</strong></p>
<ul>
<li>
<p>PR checklist: â€œDid we leave this better than we found it?â€</p>
</li>
<li>
<p>Review warm-ups: â€œWhat&#8217;s the pattern here?â€</p>
</li>
</ul>
</li>
</ul>
<hr />
<h3>ðŸ‚ The Kitchen Analogy Again</h3>
<p>Want people to compost?<br />Donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t hide the bin in a closet.<br />Put a small, open one <strong>next to the cutting board</strong>.</p>
<p>Same principle in code:</p>
<blockquote>
<p>If you want consistency, design the <strong>workflow</strong><br />so that the right choice is the easiest one.</p>
</blockquote>
<hr />
<h3>ðŸ›  In Practice</h3>
<p>Ask your team:</p>
<ul>
<li>
<p>What do we correct in every PR?</p>
</li>
<li>
<p>What decisions keep getting re-explained?</p>
</li>
<li>
<p>What slows us down the most often?</p>
</li>
</ul>
<p>Then <strong>build automation or scaffolding</strong> to solve <em>just that</em>.<br />Start with friction hotspots.</p>
<p>Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re not building bureaucracy.<br />Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re removing ambiguity.</p>
<blockquote>
<p>Every time the system answers a question,<br />thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s one less decision the developer has to make.</p>
</blockquote>
<hr />
<p>Consistency doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t come from preaching.<br />It comes from design.</p>
<p><strong>Design your workflow to default to quality.</strong><br />Then watch the team rise to meet it.</p>
<hr />
<h2>ðŸ— 4. Design for the Future, Not the Fix</h2>
<p>Thereâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s a kitchen that looks spotlessâ€”today.<br />But the trash can is too far from the prep station.<br />The knives are in the same drawer as the ladles.<br />Thereâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s no counter near the stove.</p>
<p>Cooking technically works.<br />But every step is awkward. Every movement inefficient.<br />Eventually, people stop using itâ€”not because itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s messy, but because itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s <strong>exhausting</strong>.</p>
<hr />
<h3>ðŸ§± Codebases Rot the Same Way</h3>
<p>They donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t collapse from mess.<br />They degrade from <strong>accumulated friction</strong>:</p>
<ul>
<li>
<p>Logic split between controller, service, and a random helper.</p>
</li>
<li>
<p>Naming that hides purpose (<code>ServiceHandler</code>, <code>ThingManager</code>).</p>
</li>
<li>
<p>Features wedged into whatever file felt â€œclose enough.â€</p>
</li>
</ul>
<p>You can still add features.<br />You can still ship.</p>
<p>But every change feels like surgeryâ€”because <strong>the architecture doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t support the work</strong>.</p>
<hr />
<h3>ðŸ“ Good Architecture Is Predictable</h3>
<p>A good system isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t one where code just works.<br />Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s one where <strong>new code fits</strong>.</p>
<p>If you canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t tell where the next feature goes,<br />you donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t have architectureâ€”you have coincidence.</p>
<hr />
<h3>ðŸ§  Architecture = Consistency at Scale</h3>
<p>At the local level, consistency is about naming and formatting.<br />At the system level, itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s about <strong>boundaries and repeatability</strong>:</p>
<ul>
<li>
<p>Controllers control. Services do business logic.Â </p>
</li>
<li>
<p>Every feature follows the same shape.</p>
</li>
<li>
<p>Domain logic lives with the domainâ€”not scattered across folders.</p>
</li>
<li>
<p>Folder structure maps to business concerns, not technical artifacts.</p>
</li>
</ul>
<hr />
<h3>ðŸ§ª What This Looks Like in Practice</h3>
<ul>
<li>
<p>ðŸ§© <strong>Folders map to domains, not tech types</strong></p>
<ul>
<li>
<p><code>Billing/Invoices/MarkAsPaid.php</code></p>
</li>
<li>
<p>Not <code>Services/InvoiceService.php</code></p>
</li>
</ul>
</li>
<li>
<p>ðŸ§± <strong>Vertical slices over horizontal layers</strong></p>
<ul>
<li>
<p>Group by feature, not file type.</p>
</li>
</ul>
</li>
<li>
<p>ðŸ§  <strong>Structure reveals design decisions</strong></p>
<ul>
<li>
<p>Your DDD shouldnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t live in a Confluence page.</p>
</li>
</ul>
</li>
<li>
<p>ðŸš« <strong>No catch-all files</strong></p>
<ul>
<li>
<p>If you have <code>Helper.php</code>, youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve already lost the thread.</p>
</li>
</ul>
</li>
<li>
<p>ðŸ” <strong>One way to do a thing</strong></p>
<ul>
<li>
<p>Commands look like commands. Events look like events.</p>
</li>
<li>
<p>Failures throw exceptions. No silent <code>null</code>.</p>
</li>
</ul>
</li>
</ul>
<hr />
<h3>ðŸŒª Most Systems Drift by Default</h3>
<p>Architecture rarely dies from bad decisions.<br />It dies from <strong>unopposed ones</strong>:</p>
<ul>
<li>
<p>A shortcut nobody reverts.</p>
</li>
<li>
<p>A pattern nobody questions.</p>
</li>
<li>
<p>A new dev copying a bad file because â€œthatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s how it was done.â€</p>
</li>
</ul>
<p>If nothing enforces the rules, there <em>are</em> no rules.</p>
<hr />
<h3>ðŸ” Architecture Is Operational Psychology</h3>
<p>It should tell your team:</p>
<ul>
<li>
<p>Where things go</p>
</li>
<li>
<p>What â€œrightâ€ looks like</p>
</li>
<li>
<p>How to move safely and fast</p>
</li>
</ul>
<p>If it doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t, your devs will guess.<br />And every guess will pull your system further apart.</p>
<hr />
<blockquote>
<p>Design not for whatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s urgent.<br />Design for whatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s needed.</p>
</blockquote>
<p>Make your architecture answer questions before theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re asked.<br />Make it obvious where new work belongs.</p>
<p>If you donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t, the next â€œfixâ€ will be a wedge.<br />And ten wedges later, youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re back in kitchen hell.</p>
<hr />
<h2>ðŸ•Š 5. Consistency Isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t Control. Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s Clarity.</h2>
<blockquote>
<p>â€œDonâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t tell me how to code.â€</p>
</blockquote>
<p>Weâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve all heard it.<br />Some of us have said it.</p>
<p>Because too often, consistency feels like <strong>micromanagement</strong>â€”<br />Like senior devs enforcing their quirks instead of team standards.</p>
<p>But thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s the wrong frame.</p>
<p>Real consistency isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t about control.<br />Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s about <strong>removing guesswork</strong>.</p>
<hr />
<h3>ðŸ§­ The Right Kind of Freedom</h3>
<p>In a well-designed kitchen:</p>
<ul>
<li>
<p>You donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t need to ask where the knife goes.</p>
</li>
<li>
<p>You donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t need a manual to find the trash.</p>
</li>
<li>
<p>You just moveâ€”freely, fluidly, confidently.</p>
</li>
</ul>
<p>Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s not restriction. Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s <strong>clarity</strong>.</p>
<p>And clarity is what brings developers into a productive flow.</p>
<hr />
<h3>ðŸ” Predictability = Velocity</h3>
<p>When a developer opens a new module and can instantly tell:</p>
<ul>
<li>
<p>Where logic lives</p>
</li>
<li>
<p>How errors are handled</p>
</li>
<li>
<p>What a test should look like</p>
</li>
</ul>
<p>Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re not slowed down.<br />Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re <strong>unlocked</strong>.</p>
<p>No waiting on context.<br />No decoding inconsistent patterns.</p>
<p>Just building, fastâ€”and safely.</p>
<hr />
<h3>ðŸ›  What Consistency Really Gives You</h3>
<ul>
<li>
<p>ðŸ§  <strong>Clarity</strong> â†’ Fewer decisions, fewer mistakes</p>
</li>
<li>
<p>ðŸš€ <strong>Momentum</strong> â†’ No mental pauses to decipher structure</p>
</li>
<li>
<p>ðŸ›  <strong>Autonomy</strong> â†’ New devs can own changes without fear</p>
</li>
<li>
<p>ðŸ¤ <strong>Trust</strong> â†’ Reviews shift from â€œWhat is this?â€ to â€œHow well does it solve the problem?â€</p>
</li>
</ul>
<p>This isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t about obedience.<br />Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s about <strong>shared expectations</strong>.</p>
<p>The structure does the explaining.<br />The docs just reinforce the why.</p>
<hr />
<h3>ðŸ§¨ The Wrong Kind of Freedom Slows Teams Down</h3>
<p>â€œJust do what you think is bestâ€ sounds supportive.<br />But it opens the door to chaos:</p>
<ul>
<li>
<p>Someone rewrites a module in a new paradigm.</p>
</li>
<li>
<p>Another adds raw SQL into a system using Doctrine.</p>
</li>
<li>
<p>A test is written in a completely different pattern.</p>
</li>
</ul>
<p>Now everyone is â€œfreeâ€â€”and everyone is <strong>misaligned</strong>.</p>
<p>Velocity drops.<br />Reviews turn into rework.<br />Nobody trusts anything.</p>
<hr />
<h3>ðŸŽ¯ Teams Scale on Predictability, Not Talent</h3>
<p>The best teams arenâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t made of superstars.<br />Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re made of <strong>people who can move independently and still produce code that fits together</strong>.</p>
<p>That only works when the system defines consistency <strong>as clarity</strong>, not constraint.</p>
<hr />
<blockquote>
<p>Clarity makes creativity possible.<br />Predictability enables flow.<br />Shared structure builds trust.</p>
</blockquote>
<p>Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s what real consistency gives you.</p>
<p>Not controlâ€”<strong>coherence</strong>.</p>
<hr />
<h2>ðŸ§¹ Conclusion â€“ Make Order the Default</h2>
<p>Kitchens donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t stay clean because someone yells.<br />They stay clean because the <strong>system makes care easy</strong>:</p>
<ul>
<li>
<p>The trash is close.</p>
</li>
<li>
<p>The knives are where you expect.</p>
</li>
<li>
<p>The dishwasher has a rhythm.</p>
</li>
</ul>
<p>No micromanagement.<br />No friction.<br />Just <strong>design that encourages discipline</strong>.</p>
<hr />
<h3>ðŸ§‘â€ðŸ’» Codebases Work the Same Way</h3>
<p>You donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t need perfect code.<br />You need a foundation that:</p>
<ul>
<li>
<p>Makes the right thing obvious</p>
</li>
<li>
<p>Makes the wrong thing feel weird</p>
</li>
<li>
<p>Makes improvement the <strong>path of least resistance</strong></p>
</li>
</ul>
<blockquote>
<p>Mess invites mess.<br />But more importantly: <strong>order invites order</strong>.</p>
</blockquote>
<p>When that order exists:</p>
<ul>
<li>
<p>Developers contribute with confidence</p>
</li>
<li>
<p>Refactors happen in flow</p>
</li>
<li>
<p>New features <strong>fit in</strong> like they belonged from day one</p>
</li>
</ul>
<p>Not because your team is better.<br />But because your <strong>system is smarter</strong>.</p>
<hr />
<h3>ðŸ§  What You Can Do Today</h3>
<p>Â </p>
<blockquote>
<p><strong>Start small. But start with purpose.</strong></p>
</blockquote>
<ul>
<li>
<p>Touch a file? Leave it cleaner than you found it.</p>
</li>
<li>
<p>Write a new service? Copy the <strong>best one</strong>â€”your template of excellenceâ€”not the most recent hack.</p>
</li>
<li>
<p>Add a pre-commit hook that blocks <strong>architectural drift</strong>, not just formatting violations.</p>
</li>
<li>
<p>Pick one â€œgoldenâ€ module. Let it define what â€œdone rightâ€ looks like.</p>
</li>
</ul>
<p>Then build forward from that standardâ€”<strong>consistently</strong>.</p>
<ul>
<li>
<p>Turn your golden module into a scaffold.</p>
</li>
<li>
<p>Generate code that already follows the rules.</p>
</li>
<li>
<p>Automate structure, not just syntax.</p>
</li>
</ul>
<p>Example:</p>
<pre><code class="language-bash">make create:datatable InvoiceTable
</code></pre>
<p>Now every new DataTable starts clean, typed, and consistentâ€”before anyone touches a line.</p>
<blockquote>
<p>Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s how you scale quality.<br />Not by working harder. But by <strong>making the right thing the easiest thing</strong>.</p>
</blockquote>
<img loading="lazy" decoding="async" src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F05%2Fwhy-codebases-rot-like-kitchens-and-how-to-stop-it%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dwhy-codebases-rot-like-kitchens-and-how-to-stop-it&amp;action_name=Why%20Codebases%20Rot%20Like%20Kitchens%20%28and%20How%20to%20Stop%20It%29&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
					<wfw:commentRss>http://suckup.de/2025/05/why-codebases-rot-like-kitchens-and-how-to-stop-it/?pk_campaign=feed&amp;pk_kwd=why-codebases-rot-like-kitchens-and-how-to-stop-it/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7002</post-id>	</item>
		<item>
		<title>The Inner Code Plumber</title>
		<link>http://suckup.de/2025/05/the-inner-code-plumber/?pk_campaign=feed&amp;pk_kwd=the-inner-code-plumber&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=the-inner-code-plumber</link>
					<comments>http://suckup.de/2025/05/the-inner-code-plumber/?pk_campaign=feed&amp;pk_kwd=the-inner-code-plumber#respond</comments>
		
		<dc:creator><![CDATA[voku]]></dc:creator>
		<pubDate>Thu, 01 May 2025 12:55:54 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<guid isPermaLink="false">https://suckup.de/?p=6993</guid>

					<description><![CDATA[<p><a href="http://suckup.de/2025/05/the-inner-code-plumber/?pk_campaign=feed&#038;pk_kwd=the-inner-code-plumber">The Inner Code Plumber</a></p>
<p>How Adaptive Systemic Intuition Lets You See Maintainability Before It Breaks You open a PHP file. No red flags. No screaming errors. The CI was green. Static analysis reports nothing, â€œall good.â€ But something feels off. -> And there it isâ€”that tight feeling in your gut. Not panic. Not certainty. Just a whisper: â€œThis will &#8230; <a href="http://suckup.de/2025/05/the-inner-code-plumber/?pk_campaign=feed&#038;pk_kwd=the-inner-code-plumber" class="more-link">Continue reading <span class="screen-reader-text">The Inner Code Plumber</span></a><img src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F05%2Fthe-inner-code-plumber%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dthe-inner-code-plumber&amp;action_name=The%20Inner%20Code%20Plumber&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" /></p>
]]></description>
										<content:encoded><![CDATA[<p><a href="http://suckup.de/2025/05/the-inner-code-plumber/?pk_campaign=feed&#038;pk_kwd=the-inner-code-plumber">The Inner Code Plumber</a></p>

<blockquote>How Adaptive Systemic Intuition Lets You See Maintainability Before It Breaks</blockquote>



<p class="wp-block-paragraph">You open a PHP file. No red flags. No screaming errors. The CI was green. Static analysis reports nothing, â€œall good.â€ But something feels off.</p>



<ul class="wp-block-list">
<li>The methods are over-explained and under-meaningful.</li>
</ul>



<ul class="wp-block-list">
<li>The logic is layered like geological sediment.</li>
</ul>



<ul class="wp-block-list">
<li>The file smells like tech debt, even if the tools wonâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t say so.</li>
</ul>



<p class="wp-block-paragraph">-> And there it isâ€”that tight feeling in your gut.</p>



<p class="wp-block-paragraph">Not panic. Not certainty. Just a whisper: â€œThis will come back to bite us.â€</p>



<p class="wp-block-paragraph">That feeling isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t mysticism. Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s not arrogance. Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s not just your â€œsenior dev sixth sense.â€</p>



<p class="wp-block-paragraph">Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s something deeperâ€”something more universal. Your experience is surfacing as Adaptive Systemic Intuition.</p>



<p class="wp-block-paragraph">Just like a seasoned plumber can walk into a building and know, from the creaks and bends of the pipes, that troubleâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s comingâ€”even if everything flows for nowâ€”your brain is surfacing thousands of hours of coding, debugging, and review into a silent warning.</p>



<p class="wp-block-paragraph">This post isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t about patterns like SOLID or DRY.</p>



<ul class="wp-block-list">
<li>The pattern behind those coding patterns.</li>
</ul>



<ul class="wp-block-list">
<li>The one you feel before you can explain.</li>
</ul>



<ul class="wp-block-list">
<li>The one that lets you see maintainability before a single bug is reported.</li>
</ul>



<ul class="wp-block-list">
<li>This is the abstract pattern. And it lives in you.</li>
</ul>



<p class="wp-block-paragraph">-> Letâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s dig it up, name it, and sharpen it.</p>



<h2 class="wp-block-heading">1. Code Through the Lens of &#8220;Why,&#8221; Not Just &#8220;How&#8221;</h2>



<p class="wp-block-paragraph">Fresh developers obsess over how.</p>



<ul class="wp-block-list">
<li>How to write the syntax.</li>
</ul>



<ul class="wp-block-list">
<li>How to pass the test.</li>
</ul>



<ul class="wp-block-list">
<li>How to make the thing work.</li>
</ul>



<p class="wp-block-paragraph">But experienced developers? They ask why.</p>



<ul class="wp-block-list">
<li>Why does this code exist?</li>
</ul>



<ul class="wp-block-list">
<li>Why is it structured this way?</li>
</ul>



<ul class="wp-block-list">
<li>Why are we solving this problem now, and what will it look like later?</li>
</ul>



<p class="wp-block-paragraph">Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s not about getting the function done. Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s about aligning the code with the context: the business goal, the system constraints, the teamâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s skill level, the organizational habits.</p>



<p class="wp-block-paragraph">Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re not coding in a vacuum. Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re coding in an ecosystem.</p>



<p class="wp-block-paragraph"><strong>Plumber Thinking:</strong></p>



<p class="wp-block-paragraph">You&#8217;ve already internalized this. In your code, structure reflects purpose.</p>



<p class="wp-block-paragraph">When you clean up legacy code, you donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just rewriteâ€”you reflect: â€œWhat problem was this solving? Why this shape? Is that still true?â€</p>



<p class="wp-block-paragraph"><strong>Plumber Analogy:</strong></p>



<p class="wp-block-paragraph">A rookie plumber checks if the showerhead is clogged.</p>



<p class="wp-block-paragraph">A seasoned plumber asks: â€œIs this the only tap with low pressure? What changed recently?â€</p>



<p class="wp-block-paragraph">Same situationâ€”completely different insight.</p>



<p class="wp-block-paragraph"><strong>Coding Wisdom:</strong></p>



<p class="wp-block-paragraph">&#8220;Simplicity in code isn&#8217;t about writing fewer lines; it&#8217;s about writing the clearest lines for the specific problem and its environment.&#8221;</p>



<p class="wp-block-paragraph"><strong>Practice:</strong></p>



<ul class="wp-block-list">
<li>Ask yourself: Why does this feature even exist?</li>



<li>Review code with this lens: Does this structure still match its purpose?</li>



<li>Refactor not because you can, but because the current shape no longer serves the systemâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s real needs.</li>
</ul>



<h2 class="wp-block-heading">2. Feel the Friction: Your Body Knows Bad Code</h2>



<p class="wp-block-paragraph">You open a file.</p>



<p class="wp-block-paragraph">Before reading a single line in detailâ€”before reasoning, parsing, or even namingâ€”the discomfort creeps in.</p>



<p class="wp-block-paragraph">A sense of tension. A raised brow. A shift in posture.</p>



<p class="wp-block-paragraph">You donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t have the error, but your body already knows: something&#8217;s off.</p>



<p class="wp-block-paragraph">This isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t new-age nonsense. Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s embodied cognition. Your thinking isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just in your headâ€”itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s in your body.</p>



<ul class="wp-block-list">
<li>You gesture when explaining bugs.</li>
</ul>



<ul class="wp-block-list">
<li>You pace when searching for the right name.</li>
</ul>



<ul class="wp-block-list">
<li>You draw to reason through architecture.</li>
</ul>



<p class="wp-block-paragraph">-> These arenâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t quirks. Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re your body reasoning.</p>



<p class="wp-block-paragraph"><strong>Plumber Thinking:</strong></p>



<ul class="wp-block-list">
<li>You already use this intuitively.</li>
</ul>



<ul class="wp-block-list">
<li>You whiteboard before writing complex logic.</li>
</ul>



<ul class="wp-block-list">
<li>You pause when nested logic feels brittleâ€”even before tests fail.</li>
</ul>



<ul class="wp-block-list">
<li>Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve said it yourself: naming, structure, nestingâ€”all send physical signals.</li>
</ul>



<p class="wp-block-paragraph">-> Your gut? Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s hardware-accelerated static analysis.</p>



<p class="wp-block-paragraph"><strong>Plumber Analogy:</strong></p>



<p class="wp-block-paragraph">A good plumber doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just lookâ€”they listen for vibration, feel for pressure, sense the strain in old joints.</p>



<p class="wp-block-paragraph">Code is no different. You donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just read itâ€”you sense it.</p>



<p class="wp-block-paragraph"><strong>Coding Wisdom:</strong></p>



<p class="wp-block-paragraph">&#8220;Often, the feeling that something is wrong precedes the logical explanation. Your body, tuned to patterns, senses dissonance before your mind catches up.&#8221;</p>



<p class="wp-block-paragraph"><strong>Practice:</strong></p>



<ul class="wp-block-list">
<li>Pay attention to physical signals: tight chest, hesitancy, frustrationâ€”these are pattern alerts.</li>



<li>If you can&#8217;t name the problem yet, donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t dismiss the feeling. Pause. Map it.</li>



<li>Sketch data flows before implementation. Where the drawing becomes messy, the code will too.</li>
</ul>



<h2 class="wp-block-heading">3. Debug in Your Head: Your Brainâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s the Best Tool</h2>



<p class="wp-block-paragraph">A bug shows up.</p>



<p class="wp-block-paragraph">The junior instinct? Jump into the code. Drop in var_dump(), sprinkle logs like confetti, stare at traces.</p>



<p class="wp-block-paragraph">The senior instinct?</p>



<p class="wp-block-paragraph">Pause; Think; Mentally simulate;</p>



<p class="wp-block-paragraph">They donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t open the IDE immediatelyâ€”they open the model in their mind.</p>



<p class="wp-block-paragraph">They replay the logic, walk the data, test their assumptions internally.</p>



<p class="wp-block-paragraph">This isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t lazinessâ€”itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s efficiency.</p>



<p class="wp-block-paragraph">Debugging is about reconciling expectation vs. reality. Tools help, but mental simulation is where the real gap is closed.</p>



<p class="wp-block-paragraph"><strong></strong><strong>Plumber Thinking</strong>:</p>



<p class="wp-block-paragraph">You donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t guess. You model.</p>



<p class="wp-block-paragraph">When something breaks, your instinct isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t to â€œtry stuffâ€â€”itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s to ask: Whatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s the underlying assumption here?</p>



<p class="wp-block-paragraph">Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve trained yourself to see the root cause, not just the symptom.</p>



<p class="wp-block-paragraph">You even help others find it by making them talk through their own code logicâ€”a classic senior move.</p>



<p class="wp-block-paragraph"><strong>Plumber Analogy:</strong></p>



<p class="wp-block-paragraph">A customer says, â€œNo hot water.â€</p>



<p class="wp-block-paragraph">The amateur checks the heater.</p>



<p class="wp-block-paragraph">The master plumber?<br />â€œDoes it happen with every tap?â€<br />â€œWhen did this start?â€<br />â€œWas there plumbing work recently?â€<br />They construct a systemic model before touching a single tool.</p>



<p class="wp-block-paragraph"><strong>Coding Wisdom:</strong></p>



<p class="wp-block-paragraph">&#8220;Every bug is a surpriseâ€”an error in your mental model. Fixing code is easy. Fixing the model? Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s where real debugging lives.&#8221;</p>



<p class="wp-block-paragraph"><strong>Practice:</strong></p>



<ul class="wp-block-list">
<li>When a bug appears, narrate what you expect should happen.</li>



<li>Walk the logic mentally before altering anything.</li>



<li>Ask others: â€œWhat do you think is happening, step by step?â€ Make the model visible.</li>
</ul>



<h2 class="wp-block-heading">4. Expect the Expected: Your Brain Predicts Code</h2>



<p class="wp-block-paragraph">As you gain experience, something strange happens:</p>



<p class="wp-block-paragraph">You start expecting code to behave a certain wayâ€”even before reading the details.</p>



<p class="wp-block-paragraph">You see a method named getUserToken(), and your brain assumes:</p>



<ul class="wp-block-list">
<li>No side effects</li>



<li>Probably returns a string</li>



<li>Definitely doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t mutate state</li>
</ul>



<p class="wp-block-paragraph">If it does mutate state or throw an exceptionâ€”it feels wrong.</p>



<p class="wp-block-paragraph">That feeling? Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s not being picky. Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s your brainâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s predictive model raising a flag.</p>



<p class="wp-block-paragraph">Your mind isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just parsingâ€”it&#8217;s forecasting.</p>



<p class="wp-block-paragraph">When the code breaks that forecast, your cognitive system yells: Prediction error detected.</p>



<p class="" data-start="122" data-end="230">Keep in mind how developers actually <em data-start="213" data-end="222">process</em> code:</p>
<ul data-start="231" data-end="442">
<li class="" data-start="231" data-end="296">
<p class="" data-start="233" data-end="296">Our <strong data-start="237" data-end="264">working memory is small</strong> and gets overwhelmed quickly.</p>
</li>
<li class="" data-start="297" data-end="442">
<p class="" data-start="299" data-end="442">Our <strong data-start="303" data-end="323">long-term memory</strong> excels at recognizing <strong data-start="346" data-end="381">well-named, consistent patterns</strong>â€”especially when they match previously learned mental models.</p>
</li>
</ul>
<p class="" data-start="444" data-end="799">Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s why <code data-start="455" data-end="492">fetchByNameOrThrowException(): User</code> and <code data-start="497" data-end="527">fetchByNameIfExists(): ?User</code> are vastly superior to <code data-start="551" data-end="573">fetchByName(): ?User</code>. They encode <em data-start="587" data-end="595">intent</em> directly into the name and return type. This isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t nitpickingâ€”itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s cognitive ergonomics. When naming clearly expresses behavior, you reduce cognitive load, prevent misreads, and accelerate understanding.</p>
<table>
<thead>
<tr>
<th><strong>Memory Type</strong></th>
<th><strong>Computer Analogy</strong></th>
<th><strong>Developer Brain Function</strong></th>
<th><strong>Coding Example</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Working Memory (WM)</strong></td>
<td>RAM / CPU Cache (Small, Fast, Volatile)</td>
<td>Active space for reasoning: tracking variables, current scope, flow. Limited (~4â€“7 chunks), disrupted easily.</td>
<td>Debugging a loop: <code>i = 0</code>, <code>item = user[0]</code>, tracking <code>state = processing</code>. Holding these while stepping through.</td>
</tr>
<tr>
<td><strong>Long-Term Memory (LTM)</strong></td>
<td>Hard Drive / Database (Vast, Fast-Indexed when chunked)</td>
<td>Stores learned patterns, idioms, APIs, naming conventions. Fast if knowledge is chunked (schema). Used for prediction.</td>
<td>Recognizing <code>getUserToken()</code> as: no side effects, returns string. Instantly guessing method purpose &amp; contract.</td>
</tr>
<tr>
<td><strong>Procedural Memory</strong></td>
<td>BIOS / Firmware / Muscle Memory</td>
<td>Automates repeatable behavior. IDE navigation, CLI fluency, common patterns. Invisible but critical for flow state.</td>
<td>Typing <code>function __construct(</code> without thinking. Instinctively spotting and refactoring a code smell.</td>
</tr>
</tbody>
</table>



<p class="wp-block-paragraph"><strong></strong><strong>Plumber Thinking</strong>:</p>



<p class="wp-block-paragraph">Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve written consistently predictable code for yearsâ€”typed, immutable, clean.</p>



<p class="wp-block-paragraph">Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve trained your brain to recognize rhythm, detect side effects, and enforce mental contracts.</p>



<p class="wp-block-paragraph">Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve said it yourself: â€œNaming, types, structureâ€”theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re not just syntax, theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re signals.â€</p>



<p class="wp-block-paragraph">And when that signalâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s broken? You feel it immediatelyâ€”even if the CI doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t.</p>



<p class="wp-block-paragraph"><strong>Plumber Analogy:</strong></p>



<p class="wp-block-paragraph">A plumber sees a pipe coupling thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s slightly misaligned.</p>



<p class="wp-block-paragraph">No leakâ€”yet. But something about the tension, the angle, the materialâ€¦ they know.</p>



<p class="wp-block-paragraph">â€œThatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s going to burst under pressure.â€</p>



<p class="wp-block-paragraph">Their prediction engine fires before failure.</p>



<p class="wp-block-paragraph"><strong>Coding Wisdom:</strong></p>



<p class="wp-block-paragraph">â€œWell-written code teaches your brain what to expect. Violating those expectations isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t cleverâ€”itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s cognitive sabotage.â€</p>



<p class="wp-block-paragraph"><strong>Practice:</strong></p>



<ul class="wp-block-list">
<li>When writing code, ask: What would another dev reasonably expect this to do?</li>



<li>When reviewing code, note every â€œsurprise.â€ Why was it surprising?</li>



<li>Before running a method, predict: What will it return? What will it change? Then verify.</li>
</ul>



<h2 class="wp-block-heading">5. See the Shape: Visual Cues in Code</h2>



<p class="wp-block-paragraph">Before your eyes process names or logic, they notice shape. I already wrote a blog post about it 5 years ago: <a href="https://suckup.de/2020/01/do-not-fear-the-white-space-in-your-code/">Do Not Fear The White Space in your Code &#8211; SUCKUP.de</a></p>



<p class="wp-block-paragraph">Indentation. Whitespace. Block structure. Line rhythm.</p>



<p class="wp-block-paragraph">You scan a file and just feel overwhelmedâ€”or calmâ€”before youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve even read a single line.</p>



<p class="wp-block-paragraph">Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s not a visual aesthetic thing. Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s a cognitive load thing.</p>



<p class="wp-block-paragraph">When code looks chaotic, your brain assumes it is chaotic.</p>



<p class="wp-block-paragraph">When itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s cleanly structured? Your mind can glide through it, predict it, trust it.</p>



<p class="wp-block-paragraph">Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re not just reading lines. Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re navigating a landscape.</p>



<p class="wp-block-paragraph">And cluttered terrain slows thinking.</p>



<p class="wp-block-paragraph"><strong></strong><strong>Plumber Thinking</strong>:</p>



<p class="wp-block-paragraph">Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve long preached visual clarity.</p>



<p class="wp-block-paragraph">Your spacing, your grouping, your naming conventionsâ€”theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re designed for legibility, not minimalism.</p>



<p class="wp-block-paragraph">You know that white space is a cognitive tool, not wasted real estate.</p>



<p class="wp-block-paragraph">Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve even pointed out how nesting alone can induce bugsâ€”because our brains lose scope perception when structure collapses.</p>



<p class="wp-block-paragraph"><strong>Plumber Analogy:</strong></p>



<p class="wp-block-paragraph">Imagine opening a cabinet under a sink.</p>



<p class="wp-block-paragraph">In one house, the pipes are clean, labeled, evenly spaced.</p>



<p class="wp-block-paragraph">In another, theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re twisted, duct-taped, looping behind the drywall.</p>



<p class="wp-block-paragraph">You already know which one will leak.</p>



<p class="wp-block-paragraph"><strong>Coding Wisdom:</strong></p>



<p class="wp-block-paragraph">&#8220;Visually well-structured code isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t prettyâ€”itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s predictable. And predictable structure reduces mental strain.&#8221;</p>



<p class="wp-block-paragraph"><strong>Practice:</strong></p>



<ul class="wp-block-list">
<li>Donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just reformat for styleâ€”reformat for flow. Group related logic. Use white space meaningfully.</li>



<li>When reading legacy code, pause before diving in. Let your eyes scan shape. Does it suggest complexity?</li>



<li>Reformat deeply nested code just to feel its structureâ€”see how much simpler it becomes.</li>
</ul>



<h2 class="wp-block-heading">6. Narrate the Flow: Sharing Your Mental Model</h2>



<p class="wp-block-paragraph">Experienced developers donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just refactor silently. They narrate.</p>



<p class="wp-block-paragraph">â€œIâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />m splitting this out because the logic forks too early.â€<br />â€œI renamed this to make its responsibility explicit.â€<br />â€œThis service is the real boundaryâ€”we need to show that.â€</p>



<p class="wp-block-paragraph">They arenâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just explaining code. Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re revealing the mental model that shaped it.</p>



<p class="wp-block-paragraph">Code is communication. And communication isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just what you writeâ€”itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s what others understand.</p>



<p class="wp-block-paragraph">If they canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t follow your thinking, your code is a liabilityâ€”no matter how clever it is.</p>



<p class="wp-block-paragraph">Naming, abstraction, commentsâ€”these arenâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t documentation. Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re narrative tools. They encode the architecture in other peopleâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s minds.</p>



<p class="wp-block-paragraph"><strong></strong><strong>Plumber Thinking</strong>:</p>



<p class="wp-block-paragraph">Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve internalized this.</p>



<p class="wp-block-paragraph">When you restructure legacy code, you donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just fix itâ€”you expose its intent.</p>



<p class="wp-block-paragraph">You use naming, typing, and PHPDoc to express meaning with precision.</p>



<p class="wp-block-paragraph">Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve said clearly: â€œReadable code tells a story. It has to be deletable and understandableâ€”or it doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t belong.â€</p>



<p class="wp-block-paragraph">You narrate for the future readerâ€”often yourself.</p>



<p class="wp-block-paragraph"><strong>Plumber Analogy:</strong></p>



<p class="wp-block-paragraph">A plumber explains a reroute not with schematics, but clarity:</p>



<p class="wp-block-paragraph">â€œWe added a shutoff here so you can isolate the leak without cutting the entire house.â€</p>



<p class="wp-block-paragraph">The client gets it.</p>



<p class="wp-block-paragraph">The next plumber gets it.</p>



<p class="wp-block-paragraph">The design becomes shared knowledge.</p>



<p class="wp-block-paragraph"><strong>Coding Wisdom:</strong></p>



<p class="wp-block-paragraph">&#8220;Readable code isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just syntactically correctâ€”itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s semantically shared. It transmits the original model without distortion.&#8221;</p>



<p class="wp-block-paragraph"><strong>Practice:</strong></p>



<ul class="wp-block-list">
<li>During code reviews, ask: Can I explain why this exists, not just how it works?</li>



<li>Use naming to encode roles and relationships, not just behavior.</li>



<li>Use lightweight comments to narrate intentâ€”why this path was chosen.</li>
</ul>



<h2 class="wp-block-heading">7. Tools Are Great, But Your Brainâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s the Boss</h2>



<p class="wp-block-paragraph">Linters. Static analyzers. Formatters. AI pair programmers.</p>



<p class="wp-block-paragraph">Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re everywhereâ€”and yes, theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re useful.</p>



<p class="wp-block-paragraph">But donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t confuse assistance with authority.</p>



<p class="wp-block-paragraph">A tool can tell you that a method is too long.</p>



<ul class="wp-block-list">
<li>It canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t tell you whether itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s cohesive.</li>
</ul>



<ul class="wp-block-list">
<li>It can flag a missing type.</li>
</ul>



<ul class="wp-block-list">
<li>It canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t sense that the naming is misleading, or that the abstraction is rotting.</li>
</ul>



<p class="wp-block-paragraph">-> Your intuition? It gets there before the warning light comes on.</p>



<p class="wp-block-paragraph">The danger isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t using toolsâ€”itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s outsourcing your judgment to them.</p>



<p class="wp-block-paragraph">Take PHPStanâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s classic warning:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><em>â€œReturn type â€˜User|nullâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" /> might be null here.â€</em></p>
</blockquote>



<p class="wp-block-paragraph">Most developers see that and rush to â€œfixâ€ it.<br />By fix, they usually mean: add a <code>null</code> check, throw an exception, or change the type hint to <code>?User</code>.</p>



<p class="wp-block-paragraph">But thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s not a fixâ€”itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s a reflex.</p>



<p>What you should ask is:</p>



<ul class="wp-block-list">
<li><em>Why is <code>null</code> a possible return in the first place?</em></li>



<li><em>Does this function really model optionalityâ€”or are we just afraid of declaring intent?</em></li>



<li><em>Was this ever meant to fail silently? Or did we just avoid thinking about the default case?</em></li>
</ul>



<p class="wp-block-paragraph">Hereâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s the brutal truth:<br />If the domain logic doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t expect a missing user, then returning <code>?User</code> is a <em>design error</em>â€”not a typing issue.<br />It misleads every caller into treating the result as optional when itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s not.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Tools report symptoms. It&#8217;s your job to diagnose the cause.</p>
</blockquote>



<p class="wp-block-paragraph">So noâ€”you donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just slap on a <code>null</code> check.<br />You stop and rethink the contract:<br />Should this be <code>fetchUserOrFail(int $id): User</code>?<br />Or <code>findUserIfExists(int $id): ?User</code>â€”with the <code>?User</code> explicitly declaring <em>safe</em> optionality?</p>



<p>Because every <code>?T</code> is a semantic signal. If the meaning behind it is unclear or inconsistent, youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re not writing safe codeâ€”youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re writing ambiguous code that <em>compiles</em>.</p>



<p class="wp-block-paragraph"><strong></strong><strong>Plumber Thinking</strong>:</p>



<p class="wp-block-paragraph">Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve automated everything that matters: PHPStan, Rector, PHP-CS-Fixer.</p>



<p class="wp-block-paragraph">But youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve also said clearly: â€œThey catch noise. I care about signal.â€</p>



<p class="wp-block-paragraph">You still scan for intention, context, and design cohesion.</p>



<p class="wp-block-paragraph">You donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t accept autofixes blindlyâ€”you ask, â€œWould I have made this change? Does this align with the systemâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s needs?â€</p>



<p class="wp-block-paragraph">Your gut is the boss. The tool is the assistant.</p>



<p class="wp-block-paragraph"><strong>Plumber Analogy:</strong></p>



<p class="wp-block-paragraph">A plumber might use a pressure gauge, but they&#8217;ll still touch the pipe.</p>



<p class="wp-block-paragraph">They&#8217;ll still listen for the high-pitched whine.</p>



<p class="wp-block-paragraph">Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ll still trust the feel of a bad valveâ€”even when the sensor says â€œnormal.â€</p>



<p class="wp-block-paragraph">Why? Because machines donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t have experience.</p>



<p class="wp-block-paragraph"><strong>Coding Wisdom:</strong></p>



<p class="wp-block-paragraph">&#8220;You canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t automate what you donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t understand. Tools amplify wisdomâ€”but they canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t manufacture it.&#8221;</p>



<p class="wp-block-paragraph"><strong>Practice:</strong></p>



<ul class="wp-block-list">
<li>Before running a tool, assess the code yourself. What feels off? What seems brittle?</li>



<li>When a tool suggests a change, ask why. Would you make it manually?</li>



<li>Build your own internal checklist. Use tools to confirmâ€”not defineâ€”your decisions.</li>
</ul>



<h2 class="wp-block-heading">8. Reflect to Learn: Making Experience Stick</h2>



<ul class="wp-block-list">
<li>Writing code isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t enough. Fixing bugs isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t enough.</li>
</ul>



<ul class="wp-block-list">
<li>Even surviving legacy systems isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t enough.</li>
</ul>



<ul class="wp-block-list">
<li>Reflection is where experience becomes intuition.</li>
</ul>



<p class="wp-block-paragraph">-> When something breaksâ€”donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just patch it.</p>



<p class="wp-block-paragraph">Ask: Why did I expect it to work?</p>



<p class="wp-block-paragraph">What assumption failed? What context changed?</p>



<p class="wp-block-paragraph">Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s the real learning.</p>



<p class="wp-block-paragraph">Every prediction failure is an opportunity to sharpen your internal model. Without reflection, youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re just firefighting. With it, youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re upgrading your mental OS.</p>



<p class="wp-block-paragraph"><strong></strong><strong>Plumber Thinking</strong>:</p>



<p class="wp-block-paragraph">You reflect by default.</p>



<p class="wp-block-paragraph">Your retrospective discipline, your journaling of code decisions, your constant search for why something brokeâ€”thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s not routine. Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s professional cognition in motion.</p>



<p class="wp-block-paragraph">You donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just fix problemsâ€”you extract principles from them.</p>



<p class="wp-block-paragraph">Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve even asked yourself: &#8220;What would have prevented this mess five years ago?&#8221;</p>



<p class="wp-block-paragraph">Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s elite-level introspection.</p>



<p class="wp-block-paragraph"><strong>Plumber Analogy:</strong></p>



<p class="wp-block-paragraph">The apprentice replaces a faulty valve.</p>



<p class="wp-block-paragraph">The veteran asks:</p>



<p>â€œWhy does this kind of valve always fail in this setup?â€<br />â€œWhat can I do to make the next failure impossible?â€</p>
<p>Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re not just fixingâ€”theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re building resilience into their understanding.</p>



<p class="wp-block-paragraph"><strong>Coding Wisdom:</strong></p>



<p class="wp-block-paragraph">&#8220;Experience becomes expertise when filtered through reflection. Without that, youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re just aging, not learning.&#8221;</p>



<p class="wp-block-paragraph"><strong>Practice:</strong></p>



<ul class="wp-block-list">
<li>After every tricky bug, write down the mistake in your mental model, not just the fix.</li>



<li>Use postmortems as a thinking tool, not a blame ritual.</li>



<li>When reading legacy code, ask: Why did they do it this way? What were the constraints then?</li>
</ul>



<h2 class="wp-block-heading">9. Principles Are Guides, Not Gospel</h2>



<p class="wp-block-paragraph">We love our principles.<br />SRP. DRY. KISS. YAGNI. SOLID.</p>



<p class="wp-block-paragraph">Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re powerful. Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re useful. Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re even beautifulâ€”when applied wisely.</p>



<p class="wp-block-paragraph">But hereâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s the uncomfortable truth:<br />Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re not laws. Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re heuristics.</p>



<p class="wp-block-paragraph">Applied blindly, they can create complexity instead of clarity. Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve seen it: a jungle of micro-classes in the name of â€œSRP.â€</p>



<ul class="wp-block-list">
<li>A twisted abstraction tree justified by â€œDRY.â€</li>
</ul>



<ul class="wp-block-list">
<li>A thousand interfaces no one asked forâ€”just to â€œfollow OCP.â€</li>
</ul>



<p class="wp-block-paragraph">-> Principles must serve the codeâ€”not the other way around.</p>



<p class="wp-block-paragraph"><strong></strong><strong>Plumber Thinking</strong>:</p>



<p class="wp-block-paragraph">You live this tension.</p>



<p class="wp-block-paragraph">You respect principles, but you donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t worship them.</p>



<p class="wp-block-paragraph">Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve rejected unnecessary abstractions that only exist to check a box.</p>



<p class="wp-block-paragraph">Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve said it yourself: â€œDeletable code matters more than theoretical purity.â€</p>



<p class="wp-block-paragraph">Your approach to DRY is practical: reduce harmful duplication, not introduce brittle indirection.</p>



<p class="wp-block-paragraph">You favor clean pragmatism over cargo-cult architecture.</p>



<p class="wp-block-paragraph">You donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just follow rulesâ€”you ask why the rule exists, and when it stops helping.</p>



<p class="wp-block-paragraph"><strong>Plumber Analogy:</strong></p>



<p class="wp-block-paragraph">A textbook might say to use a certain type of pipe junction.</p>



<p class="wp-block-paragraph">But the veteran plumber on-site knows the real-world pressure, the angles, the space.</p>



<p class="wp-block-paragraph">He breaks the â€œruleâ€â€”and the system works better for it.</p>



<p class="wp-block-paragraph">Why? Because he understands the principle behind the rule, not just the rule itself.</p>



<p class="wp-block-paragraph"><strong>Coding Wisdom:</strong></p>



<p class="wp-block-paragraph">&#8220;True mastery is knowing when to bend the rulesâ€”without breaking the system.&#8221;</p>



<p class="wp-block-paragraph"><strong>Practice:</strong></p>



<ul class="wp-block-list">
<li>When applying a principle, ask: What problem is this solving here?</li>



<li>Audit patterns. If youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re layering abstractions â€œjust because,â€ stop.</li>



<li>Teach juniors the context behind the principleâ€”not just the acronym.</li>
</ul>



<h2 class="wp-block-heading">Final Thought: Trust Your Inner Code Plumber</h2>



<ul class="wp-block-list">
<li>You donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t need an error to know code is wrong.</li>
</ul>



<ul class="wp-block-list">
<li>You donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t need a profiler to sense a bottleneck.</li>
</ul>



<ul class="wp-block-list">
<li>You donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t need a tool to tell you a class is trying to do too much.</li>
</ul>



<p class="wp-block-paragraph">-> That whisper in your gut? That unease in your posture?</p>



<p class="wp-block-paragraph">Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s Adaptive Systemic Intuition.</p>



<p class="wp-block-paragraph">Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s not mysticism. Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s the compound interest of years spent reading, breaking, fixing, refactoring, and thinking.</p>



<p class="wp-block-paragraph">Like a master plumber who hears a hum and knows whatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s about to ruptureâ€”</p>



<ul class="wp-block-list">
<li>you feel complexity before it becomes entropy.</li>
</ul>



<ul class="wp-block-list">
<li>you sense rigidity before maintainability collapses.</li>
</ul>



<p class="wp-block-paragraph">-> And most importantly: you can train this.</p>



<ul class="wp-block-list">
<li>Every refactor.</li>
</ul>



<ul class="wp-block-list">
<li>Every naming battle.</li>
</ul>



<ul class="wp-block-list">
<li>Every painful legacy rescue mission.</li>
</ul>



<ul class="wp-block-list">
<li>Every â€œthis feels wrongâ€ moment that you chase down to root cause.</li>
</ul>



<p class="wp-block-paragraph">-> They all sharpen the pattern behind the patterns.</p>



<p class="wp-block-paragraph"><strong>Call to Action: Trustâ€”and Honeâ€”Your Gut</strong></p>



<p class="wp-block-paragraph">Next time you open a file and it just feels â€œoff,â€ do this:</p>



<ul class="wp-block-list">
<li>Pause. Listen to the discomfort. Donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t ignore it.</li>



<li>Narrate. Try explaining why it feels wrong. Is it naming? Flow? Entanglement?</li>



<li>Mentally simulate. Imagine a small changeâ€”does it cascade dangerously?</li>



<li>Reflect. Think about other systems that failed for the same reasons.</li>



<li>Use tools, but interpret their output through your experience.</li>



<li>Talk it out. Share your gut feeling with another devâ€”see if it resonates.</li>



<li>Iterate. Turn every failure into pattern recognition. Make it systemic.</li>
</ul>



<p class="wp-block-paragraph">&#8220;Great code isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just functional. It feels right to work with.&#8221;</p>



<p class="wp-block-paragraph">That feeling? Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s your internal plumber doing their job.</p>



<p class="wp-block-paragraph">Let them work.</p>
<img loading="lazy" decoding="async" src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F05%2Fthe-inner-code-plumber%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dthe-inner-code-plumber&amp;action_name=The%20Inner%20Code%20Plumber&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
					<wfw:commentRss>http://suckup.de/2025/05/the-inner-code-plumber/?pk_campaign=feed&amp;pk_kwd=the-inner-code-plumber/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">6993</post-id>	</item>
		<item>
		<title>The PHPDoc Guide (2025 Edition)</title>
		<link>http://suckup.de/2025/05/the-phpdoc-guide-2025-edition/?pk_campaign=feed&amp;pk_kwd=the-phpdoc-guide-2025-edition&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=the-phpdoc-guide-2025-edition</link>
					<comments>http://suckup.de/2025/05/the-phpdoc-guide-2025-edition/?pk_campaign=feed&amp;pk_kwd=the-phpdoc-guide-2025-edition#respond</comments>
		
		<dc:creator><![CDATA[voku]]></dc:creator>
		<pubDate>Thu, 01 May 2025 00:31:56 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">https://suckup.de/?p=6975</guid>

					<description><![CDATA[<p><a href="http://suckup.de/2025/05/the-phpdoc-guide-2025-edition/?pk_campaign=feed&#038;pk_kwd=the-phpdoc-guide-2025-edition">The PHPDoc Guide (2025 Edition)</a></p>
<p>String-based pseudo-types Numeric &#38; bounded pseudo-types Arrays, lists, and shapes Object &#38; class-based types Callable types Generics with @template, @extends, @implements Constant values and enum simulations Conditional logic Pass-by-reference &#38; @param-out False positive suppression Best practices Cheatsheet Â  You canâ€™t trust a string. Or an array. Or half the type declarations you see in legacy &#8230; <a href="http://suckup.de/2025/05/the-phpdoc-guide-2025-edition/?pk_campaign=feed&#038;pk_kwd=the-phpdoc-guide-2025-edition" class="more-link">Continue reading <span class="screen-reader-text">The PHPDoc Guide (2025 Edition)</span></a><img src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F05%2Fthe-phpdoc-guide-2025-edition%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dthe-phpdoc-guide-2025-edition&amp;action_name=The%20PHPDoc%20Guide%20%282025%20Edition%29&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" /></p>
]]></description>
										<content:encoded><![CDATA[<p><a href="http://suckup.de/2025/05/the-phpdoc-guide-2025-edition/?pk_campaign=feed&#038;pk_kwd=the-phpdoc-guide-2025-edition">The PHPDoc Guide (2025 Edition)</a></p>

<ol>
<li>
<p><a href="#headline1">String-based pseudo-types</a></p>
</li>
<li>
<p><a href="#headline2">Numeric &amp; bounded pseudo-types</a></p>
</li>
<li>
<p><a href="#headline3">Arrays, lists, and shapes</a></p>
</li>
<li>
<p><a href="#headline4">Object &amp; class-based types</a></p>
</li>
<li>
<p><a href="#headline5new">Callable types</a></p>
</li>
<li>
<p><a href="#headline5">Generics with @template, @extends, @implements</a></p>
</li>
<li>
<p><a href="#headline6">Constant values and enum simulations</a></p>
</li>
<li>
<p><a href="#headline7">Conditional logic</a></p>
</li>
<li>
<p><a href="#headline8">Pass-by-reference &amp; <code>@param-out</code></a></p>
</li>
<li>
<p><a href="#headline9">False positive suppression</a></p>
</li>
<li>
<p><a href="#headline10">Best practices</a></p>
</li>
<li>
<p><a href="#headline11">Cheatsheet</a></p>
</li>
</ol>
<hr />
<p>Â </p>
<blockquote>
<p>You canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t trust a string. Or an array. Or half the type declarations you see in legacy PHP codebases.</p>
</blockquote>
<p>And thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s not PHPâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s fault. Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s yoursâ€”if youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re still writing function signatures like this:</p>
<pre><code class="language-php">function sendData(array $data): bool
</code></pre>
<p>This tells us nothing.<br />Not whatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s in <code>$data</code>, not if keys are optional, not what the return <code>bool</code> even means.</p>
<p>PHPStan fixes this. <strong>With PHPDocs. </strong>Not for decoration. Not for old-school docblocks. But as <strong>strict, analyzable type contracts </strong>â€” guardrails for real-world codebases.</p>
<p>If you&#8217;re serious about:</p>
<ul>
<li>
<p>Catching logic errors before runtime</p>
</li>
<li>
<p>Documenting your code <strong>without duplicating logic</strong></p>
</li>
<li>
<p>Scaling PHP safely <strong>without turning everything into a typed mess</strong></p>
</li>
</ul>
<p>Then this guide is for you.</p>
<hr />
<p>Weâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ll walk through real-world PHPStan PHPDoc patternsâ€”from pseudo-types and generics to conditional logic and type-safe constants. All based on <a href="https://phpstan.org/writing-php-code/phpdoc-types" target="_blank" rel="noopener"><strong>PHPStan</strong></a>, tested in real-world projects, and packed with <strong>concrete examples</strong> and <strong>copy-paste snippets</strong>.</p>
<p>No fluff. Just clean, pragmatic PHPDoc annotations that make your code safer and more readable. The best part? <strong>PhpStorm</strong> supports nearly everything weâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re doing here out of the box â€” so code completion improves, and your overall DX gets a serious upgrade.</p>
<blockquote>
<p>Letâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s upgrade your PHPDocs from â€œcommentsâ€ to <strong>contracts</strong>.</p>
</blockquote>
<hr />
<h2><strong>Background: Why PHPDocs Matter More Than Ever</strong></h2>
<hr />
<p>PHP has come a long way since the wild west of <code>PHP 5.x</code>.</p>
<p>Today weâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve got:</p>
<p><strong data-start="251" data-end="258">8.0</strong> with union types and constructor property promotion, &#8230;<br data-start="310" data-end="313" /><strong data-start="315" data-end="322">8.1</strong> with enums and readonly properties, &#8230;<br data-start="357" data-end="360" /><strong data-start="362" data-end="369">8.2</strong> with readonly classes and DNF types, &#8230;<br data-start="405" data-end="408" /><strong data-start="410" data-end="417">8.3</strong> with typed class constants and <code data-start="449" data-end="463">#[\Override], ...</code><br data-start="463" data-end="466" /><strong data-start="468" data-end="475">8.4</strong> with property hooks and asymmetric visibility, &#8230;</p>
<p>Soâ€¦ why bother with PHPDocs at all?</p>
<hr />
<h3><strong>What Native Types Still Canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t Do</strong></h3>
<p>Native PHP types helpâ€”but <strong>they stop at the surface</strong>.</p>
<table>
<thead>
<tr>
<th>Native Type</th>
<th>Can Do</th>
<th>Canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t Do</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>string</code></td>
<td>Ensure value is a string</td>
<td>Canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t check if empty, numeric, constant</td>
</tr>
<tr>
<td><code>int</code></td>
<td>Enforce integer input</td>
<td>Canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t limit to &gt; 0 or within bounds</td>
</tr>
<tr>
<td><code>array</code></td>
<td>Accept arrays</td>
<td>Canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t validate keys, shape, or index types</td>
</tr>
<tr>
<td><code>object</code></td>
<td>Accept objects</td>
<td>No info about which class, structure, or generics</td>
</tr>
<tr>
<td><code>bool</code></td>
<td>Boolean logic</td>
<td>Canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t express &#8220;this is only true on success&#8221;</td>
</tr>
</tbody>
</table>
<hr />
<h3><strong>Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s Where PHPStan Comes In</strong></h3>
<p>PHPStan treats your PHPDocs like a type system:</p>
<ul>
<li>
<p>Refines <strong>scalar types</strong> (<code>non-empty-string</code>, <code>positive-int</code>, <code>numeric-string</code>)</p>
</li>
<li>
<p>Models <strong>structured arrays</strong> (<code>array{key1: T, key2?: T}</code>)</p>
</li>
<li>
<p>Adds <strong>generics</strong> (<code>@template T</code>, <code>Collection&lt;T&gt;</code>)</p>
</li>
<li>
<p>Enforces <strong>contracts and conditionals</strong> (<code>@assert</code>, <code>@return (T is Foo ? Bar : Baz)</code>)</p>
</li>
<li>
<p>Tracks <strong>pass-by-reference mutations</strong> (<code>@param-out</code>)</p>
</li>
<li>
<p>Restricts <strong>literal values</strong> (<code>'asc'|'desc'</code>, <code>Class::CONST_*</code>, enums)</p>
</li>
</ul>
<p>This gives you <strong>defensive typing</strong> for a dynamic language.</p>
<hr />
<h2><strong><a id="headline1"></a>1. String-Based Pseudo-Types</strong></h2>
<p><em>Refine what â€œstringâ€ actually means</em></p>
<hr />
<p>In PHP, <code>string</code> is a blunt instrument. It could mean:</p>
<ul>
<li>
<p><code>"admin"</code> â€“ a valid username</p>
</li>
<li>
<p><code>""</code> â€“ an empty input nobody should see</p>
</li>
<li>
<p><code>"123"</code> â€“ a number pretending to be a string</p>
</li>
<li>
<p><code>"SELECT * FROM users WHERE user_id = " . $id</code> â€“ a dangerous SQL statement</p>
</li>
</ul>
<p>PHPStan sharpens this instrument with <strong>string pseudo-types</strong> that define <strong>intent, constraints, and trust boundaries</strong>.</p>
<hr />
<h3><strong>Overview: String-Based Pseudo-Types</strong></h3>
<table style="width: 100%; height: 388px;">
<thead>
<tr style="height: 58px;">
<th style="height: 58px;">PHPStan Type</th>
<th style="height: 58px;">Description</th>
<th style="height: 58px;">Native Equivalent</th>
</tr>
</thead>
<tbody>
<tr style="height: 36px;">
<td style="height: 36px;"><code>string</code></td>
<td style="height: 36px;">Any string, including <code>''</code></td>
<td style="height: 36px;">string</td>
</tr>
<tr style="height: 59px;">
<td style="height: 59px;"><code>non-empty-string</code></td>
<td style="height: 59px;">String that cannot be <code>''</code></td>
<td style="height: 59px;">string</td>
</tr>
<tr style="height: 59px;">
<td style="height: 59px;"><code>numeric-string</code></td>
<td style="height: 59px;">String that is guaranteed to represent a number (<code>"123.45"</code>)</td>
<td style="height: 59px;">string</td>
</tr>
<tr style="height: 58px;">
<td style="height: 58px;"><code>literal-string</code></td>
<td style="height: 58px;">A string known at compile-time (e.g. hardcoded, not user input)</td>
<td style="height: 58px;">string</td>
</tr>
<tr style="height: 59px;">
<td style="height: 59px;"><code>callable-string</code></td>
<td style="height: 59px;">A string name of a globally callable function</td>
<td style="height: 59px;">string</td>
</tr>
<tr style="height: 59px;">
<td style="height: 59px;"><code>class-string&lt;T&gt;</code></td>
<td style="height: 59px;">String that is a fully-qualified class name (optionally of type T)</td>
<td style="height: 59px;">string</td>
</tr>
</tbody>
</table>
<hr />
<h3><strong>Real-World Examples</strong></h3>
<hr />
<h4>âœ… <code>non-empty-string</code></h4>
<p>Guarantees a string is never empty:</p>
<p><a href="https://phpstan.org/r/bcd0b64f-0c72-4cd8-b078-c20bc2f509e0">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @param non-empty-string $username
 */
function setUsername(string $username): void {
    // Safe, PHPStan guarantees it's not ''
    saveToDatabase($username);
}

setUsername('alice'); // OK
setUsername(''); // PHPStan error
</code></pre>
<hr />
<h4>âœ… <code>numeric-string</code></h4>
<p>Used when string inputs must represent numbers (e.g., form inputs):</p>
<p><a href="https://phpstan.org/r/f3baac09-c27e-49bb-a793-89a12c910a81">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @param numeric-string $amount
 */
function convertToCents(string $amount): int {
    return (int)((float) $amount * 100);
}

convertToCents("19.95"); // OK
convertToCents("abc"); // PHPStan error
</code></pre>
<hr />
<h4>âœ… <code>literal-string</code></h4>
<p>Guards against injection vulnerabilities in SQL or dynamic calls:</p>
<p><a href="https://phpstan.org/r/26796473-6479-4233-84ed-89f2582fbeac">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @param literal-string $sqlQuery
 */
function runQuery(string $sqlQuery): void {
    DB::raw($sqlQuery); // Only compile-time constants allowed
}

runQuery("SELECT * FROM users"); // OK
runQuery($_GET['query']); // PHPStan error
</code></pre>
<hr />
<h4>âœ… <code>callable-string</code></h4>
<p>Ensures string names reference valid callable functions:</p>
<p><a href="https://phpstan.org/r/d6f9f389-c7c1-4b23-816a-81e7dba19099">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @param callable-string $callback
 */
function invoke(string $callback): void {
    $callback(); // Safe: PHPStan checks it's actually callable
}

invoke('trim'); // OK
invoke('undefinedFunction'); // PHPStan error
</code></pre>
<hr />
<h4>âœ… <code>class-string&lt;T&gt;</code></h4>
<p>Used in factories or DI containers:</p>
<p><a href="https://phpstan.org/r/2849754d-3bbf-496a-bad3-72726d065a9d">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @template T of LoggerInterface
 * @param class-string&lt;T&gt; $class
 * @return T
 */
function createLogger(string $class): object {
    return new $class(); // Safe and strongly typed
}

createLogger(FileLogger::class); // OK
createLogger(DateTime::class); // PHPStan error: not a LoggerInterface
</code></pre>
<hr />
<h3><strong>Out-of-the-Box Use Case: Constants-as-Strings</strong></h3>
<p>Use <code>literal-string</code> when defining keys for array-based configuration:</p>
<p><a href="https://phpstan.org/r/405f2650-0bd4-4a55-bb44-1dd5eba79972">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @param (literal-string&amp;'database_host') $configKey
 */
function getConfig(string $configKey): mixed {
    return $GLOBALS['config'][$configKey] ?? null;
}

getConfig('database_host'); // OK
getConfig($userInput); // PHPStan error
</code></pre>
<hr />
<h3><strong>Key Takeaways</strong></h3>
<ul>
<li>
<p><code>non-empty-string</code> kills edge-case bugs.</p>
</li>
<li>
<p><code>literal-string</code> hardens systems against injections.</p>
</li>
<li>
<p><code>callable-string</code> and <code>class-string&lt;T&gt;</code> enable safe dynamic resolution.</p>
</li>
<li>
<p>Always prefer these over plain <code>string</code> when handling user input, SQL, config keys, or dynamic execution.</p>
</li>
</ul>
<hr />
<h2><strong><a id="headline2"></a>2. Numeric &amp; Range-Based Pseudo-Types</strong></h2>
<p><em>Precision where <code>int</code> and <code>float</code> fall short</em></p>
<hr />
<p>A parameter like <code>int $page</code> tells you nothing about valid input. Is <code>0</code> okay? What about <code>-1</code>? Or <code>999999</code>? Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s not type safetyâ€”itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s type ambiguity.</p>
<p>PHPStanâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s numeric pseudo-types <strong>embed actual constraints</strong> in the signature. Letâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s make your numbers behave.</p>
<hr />
<h3><strong>Overview: Numeric Pseudo-Types</strong></h3>
<table>
<thead>
<tr>
<th>PHPStan Type</th>
<th>Description</th>
<th>Native Equivalent</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>positive-int</code></td>
<td>Integer &gt; 0</td>
<td>int</td>
</tr>
<tr>
<td><code>negative-int</code></td>
<td>Integer &lt; 0</td>
<td>int</td>
</tr>
<tr>
<td><code>non-negative-int</code></td>
<td>Integer â‰¥ 0 (0, 1, &#8230;)</td>
<td>int</td>
</tr>
<tr>
<td><code>non-positive-int</code></td>
<td>Integer â‰¤ 0 (0, -1, &#8230;)</td>
<td>int</td>
</tr>
<tr>
<td><code>int&lt;min, max&gt;</code></td>
<td>Integer within specified range (inclusive)</td>
<td>int</td>
</tr>
<tr>
<td><code>numeric</code></td>
<td>int, float, or numeric-string</td>
<td>mixed</td>
</tr>
<tr>
<td><code>float</code></td>
<td>Any float</td>
<td>float</td>
</tr>
</tbody>
</table>
<blockquote>
<p>â„¹ï¸ <strong>Note:</strong> PHPStan <strong>does not</strong> currently support <code>float&lt;min, max&gt;</code> // <a href="https://github.com/phpstan/phpstan/issues/6963">Add range for float Â· Issue #6963 Â· phpstan/phpstan</a></p>
</blockquote>
<hr />
<h3><strong>Real-World Examples</strong></h3>
<hr />
<h4>âœ… <code>positive-int</code></h4>
<p>Ensure ID-like values are never 0 or negative:</p>
<p><a href="https://phpstan.org/r/f10eb3a8-e983-4449-ac88-cb3657927c97">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @param positive-int $userId
 */
function getUser(int $userId): User {
    return User::find($userId);
}

getUser(42); // OK
getUser(0); // PHPStan error
</code></pre>
<hr />
<h4>âœ… <code>non-negative-int</code></h4>
<p>Zero is allowed, useful for offsets and indexes:</p>
<p><a href="https://phpstan.org/r/feb77b18-19bf-48dd-bccd-77115637f120">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @param non-negative-int $offset
 */
function paginate(int $offset, int $limit = 10): array {
    return getRows($offset, $limit);
}

paginate(0); // OK
paginate(-5); // PHPStan error
</code></pre>
<hr />
<h4>âœ… <code>int&lt;1, 10&gt;</code></h4>
<p>Constrain arbitrary rangesâ€”perfect for ratings or percent caps:</p>
<p><a href="https://phpstan.org/r/433f9bd2-f395-4c2e-81d5-74b38fcea09a">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @param int&lt;1, 10&gt; $rating
 */
function setUserRating(int $rating): void {
    // Only 1â€“10 allowed
}<br /><br />
setUserRating(10); // OK 
setUserRating(20); // PHPStan error
</code></pre>
<hr />
<h4>âœ… <code>negative-int</code></h4>
<p>Useful for things like accounting deltas:</p>
<p><a href="https://phpstan.org/r/b5b6f3f0-f818-4fbc-9ce2-ce648d5187e6">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @param negative-int $debt
 */
function recordDebt(int $debt): void {
    // Only negative values allowed
}

recordDebt(-100); // OK
recordDebt(0); // PHPStan error
</code></pre>
<hr />
<h4>âœ… <code>numeric</code></h4>
<p>Accept int, float, or numeric-string â€“ great for dynamic APIs:</p>
<p><a href="https://phpstan.org/r/ed5374c7-da38-48ae-82dc-df870059835a">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @param numeric $value
 */
function normalize($value): float {
    return (float) $value;
}

normalize("5.4"); // OK
normalize(3); // OK
normalize("not a number"); // PHPStan error
</code></pre>
<hr />
<h3><strong>Out-of-the-Box Use Case: Domain Constraints via Aliases</strong></h3>
<p>Combine <code>@phpstan-type</code> with range types to <strong>centralize</strong> constraints:</p>
<p><a href="https://phpstan.org/r/6cb054d6-5976-4379-a39a-244695ca0668">Playground | PHPStan</a></p>
<pre><code class="language-php">/** @phpstan-type Rating int&lt;1, 5&gt; */

/**
 * @param Rating $stars
 */
function rate(int $stars): void {
    // Only 1â€“5 allowed
}
</code></pre>
<p>Avoids hardcoding ranges across your codebase + PhpStorm version &gt;= 2025.1 has support for it.</p>
<hr />
<h3><strong>Key Takeaways</strong></h3>
<ul>
<li>
<p>Native <code>int</code> and <code>float</code> donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t carry domain meaningâ€”these do.</p>
</li>
<li>
<p>Use <code>int&lt;min,max&gt;</code> for bounded values. Be explicit.</p>
</li>
<li>
<p>Prefer <code>numeric</code> over <code>mixed</code> for conversion-safe values.</p>
</li>
<li>
<p>Enforce constraints without runtime guardsâ€”<strong>fail at analysis time</strong>.</p>
</li>
</ul>
<hr />
<h2><strong><a id="headline3"></a>3. Array &amp; List-Based Pseudo-Types</strong></h2>
<p><em>Because <code>array</code> is a wildcard, not a type.</em></p>
<hr />
<p>Saying <code>array $data</code> is like saying â€œvehicleâ€ when you mean â€œelectric scooter with one broken brake.â€ Arrays in PHP are:</p>
<ul>
<li>
<p>numerically indexed or associative,</p>
</li>
<li>
<p>empty or structured,</p>
</li>
<li>
<p>sometimes lists, sometimes mapsâ€”and usually misunderstood.</p>
</li>
</ul>
<p>PHPStan gives you the tools to <strong>lock this chaos down</strong>.</p>
<hr />
<h3><strong>Overview: Array Pseudo-Types</strong></h3>
<table>
<thead>
<tr>
<th>PHPStan Type</th>
<th>Description</th>
<th>Native PHP Equivalent</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>array</code></td>
<td>Anything thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s an arrayâ€”uselessly vague</td>
<td>array</td>
</tr>
<tr>
<td><code>list&lt;T&gt;</code></td>
<td>Indexed from 0, consecutive integers, all values of T</td>
<td>array</td>
</tr>
<tr>
<td><code>non-empty-list&lt;T&gt;</code></td>
<td>Same as <code>list&lt;T&gt;</code>, but with at least one element</td>
<td>array</td>
</tr>
<tr>
<td><code>array&lt;TKey, TValue&gt;</code></td>
<td>Associative array with defined key/value types</td>
<td>array</td>
</tr>
<tr>
<td><code>non-empty-array&lt;TKey, V&gt;</code></td>
<td>Like above, but must have at least one key-value pair</td>
<td>array</td>
</tr>
<tr>
<td><code>array{key1: T1, key2?: T2}</code></td>
<td>Structured array with required and optional keys</td>
<td>array</td>
</tr>
<tr>
<td><code>array-key</code></td>
<td>Either <code>int</code> or <code>string</code>â€”valid PHP array keys only</td>
<td>int|string</td>
</tr>
</tbody>
</table>
<hr />
<h3><strong>Examples by Use Case</strong></h3>
<hr />
<h4>âœ… <code>list&lt;int&gt;</code></h4>
<p>Use when you need guaranteed 0-indexed values:</p>
<p><a href="https://phpstan.org/r/d8c78e2d-77c7-418e-99e9-a986784507d7">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @return list&lt;int&gt;
 */
function getIds(): array {
    return [1, 2, 3]; // PHPStan ensures keys are 0,1,2,...
}
</code></pre>
<hr />
<h4>âœ… <code>non-empty-list&lt;string&gt;</code></h4>
<p>Use for arguments that must not be empty:</p>
<p><a href="https://phpstan.org/r/8b608500-778a-4bbe-a67d-02f5707c8715">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @param non-empty-list&lt;string&gt; $emails
 */
function notify(array $emails): void {
    foreach ($emails as $email) {
        mail($email, 'Hello!');
    }
}
</code></pre>
<hr />
<h4>âœ… <code>array&lt;string, User&gt;</code></h4>
<p>Classic associative map:</p>
<p><a href="https://phpstan.org/r/f3e52528-3dfd-41c7-a5c9-422bb564dad6">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @return array&lt;string, User&gt;
 */
function getUserMap(): array {
    return ['admin' =&gt; new User(), 'guest' =&gt; new User()];
}
</code></pre>
<hr />
<h4>âœ… <code>array{status: bool, message: string}</code></h4>
<p>Great for structured return types:</p>
<p><a href="https://phpstan.org/r/9c256e52-52ec-49bd-ad2a-bd8e6d9df2b6">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @return array{status: bool, message: string}
 */
function response(): array {
    return ['status' =&gt; true, 'message' =&gt; 'OK'];
}
</code></pre>
<hr />
<h4>âœ… <code>array{ids: list&lt;int&gt;, error?: string}</code></h4>
<p>Mixed structure with optional keys:</p>
<p><a href="https://phpstan.org/r/824e3991-ab90-49d8-808f-5ce7fe06d74e">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @return array{ids: list&lt;int&gt;, error?: string}
 */
function fetch(): array {
    return ['ids' =&gt; [1, 2, 3]];
}
</code></pre>
<hr />
<h3><strong>Advanced Use Case: Refactor To Aliases</strong></h3>
<p>Avoid repeating complex shapes:</p>
<p><a href="https://phpstan.org/r/bb2411e6-d7da-4336-863a-84e752596323">Playground | PHPStan</a></p>
<pre><code class="language-php">/** @phpstan-type ApiResponse array{status: bool, message: string, data?: mixed} */

/**
 * @return ApiResponse
 */
function getJson(): array {
    return ['status' =&gt; true, 'message' =&gt; 'Success'];
}
</code></pre>
<hr />
<h3><strong>Use Table: When to Pick Which</strong></h3>
<table>
<thead>
<tr>
<th>Use Case</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr>
<td>Indexed, all same type</td>
<td><code>list&lt;T&gt;</code></td>
</tr>
<tr>
<td>Must contain elements</td>
<td><code>non-empty-list&lt;T&gt;</code></td>
</tr>
<tr>
<td>Map with defined key type</td>
<td><code>array&lt;K, V&gt;</code></td>
</tr>
<tr>
<td>Structured data (like DTO)</td>
<td><code>array{...}</code></td>
</tr>
<tr>
<td>Optional shape fields</td>
<td><code>array{key?: T}</code></td>
</tr>
<tr>
<td>Dynamic lookup</td>
<td><code>array-key</code> for keys</td>
</tr>
</tbody>
</table>
<hr />
<h3><strong>Pro Tip:</strong> If your <code>array{}</code> shape is reused or growingâ€”<strong>stop.</strong></h3>
<p>Use a Value Object. It&#8217;s clearer, testable, and doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t break when you add <code>nullableTimestamp?</code>.</p>
<hr />
<h3><strong>Key Takeaways</strong></h3>
<ul>
<li>
<p><code>array</code> is a <strong>type smell</strong>â€”replace it with something precise.</p>
</li>
<li>
<p>Use <code>list&lt;&gt;</code> when order and index matter. Use <code>array{}</code> for shape.</p>
</li>
<li>
<p>Use <code>@phpstan-type</code> to create <strong>aliases</strong> for shared structures.</p>
</li>
<li>
<p>Donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t let critical business structures live in vague <code>array&lt;string, mixed&gt;</code> land.</p>
</li>
<li>
<p>Once array shape gets complicated: make a DTO or value object. Donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t be clever. Be explicit.</p>
</li>
</ul>
<ul>
<li>
<p>Prefer <code>list&lt;T&gt;</code> over <code>T[]</code> when <strong>order and dense 0-based indexing</strong> matter.</p>
</li>
<li>
<p>Use e.g. <code>non-empty-list&lt;T&gt;</code> for enforced content.</p>
</li>
</ul>
<hr />
<h2><strong><a id="headline4"></a>4. Object &amp; Class-Based Pseudo-Types</strong></h2>
<p><em>Make your objects speak their real shape.</em></p>
<hr />
<p>PHP&#8217;s <code>object</code> type tells you nothing. PHPStanâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s object pseudo-types tell you <em>everything</em>: where the object came from, how it&#8217;s called, what it returns, and what itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s allowed to be.</p>
<hr />
<h3><strong>Overview: Class &amp; Object Pseudo-Types</strong></h3>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
<th>Use Case</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>object</code></td>
<td>Any objectâ€”completely generic</td>
<td>Rare; dynamic APIs</td>
</tr>
<tr>
<td><code>ClassName</code></td>
<td>Exact class or subclass instance</td>
<td>95% of all real code</td>
</tr>
<tr>
<td><code>self</code></td>
<td>The class this is written in (not inheritable)</td>
<td>Static factory methods</td>
</tr>
<tr>
<td><code>$this</code></td>
<td>The current instanceâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s real type (used for method chaining)</td>
<td>Fluent interfaces, traits</td>
</tr>
<tr>
<td><code>static</code></td>
<td>The class called at runtime (supports late static binding)</td>
<td>Factories returning subclass instances</td>
</tr>
<tr>
<td><code>class-string</code></td>
<td>Any valid FQCN string (non-instantiable without context)</td>
<td>Reflection, service locators</td>
</tr>
<tr>
<td><code>class-string&lt;T&gt;</code></td>
<td>A string guaranteed to name a subclass of <code>T</code></td>
<td>Typed dynamic instantiation</td>
</tr>
</tbody>
</table>
<hr />
<h3><strong>Examples by Use Case</strong></h3>
<hr />
<h4>âœ… <code>object</code></h4>
<p>Use <em>only</em> when you donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t care what it is (usually bad practice):</p>
<pre><code class="language-php">/**
 * @param object $instance
 */
function dumpObject(object $instance): void {
    var_dump($instance);
}
</code></pre>
<hr />
<h4>âœ… <code>self</code></h4>
<p>Always returns the exact class it&#8217;s written inâ€”<em>not</em> a child class:</p>
<pre><code class="language-php">class Factory {
    public static function make(): self {
        return new self(); // Always returns Factory
    }
}
</code></pre>
<hr />
<h4>âœ… <code>$this</code></h4>
<p>Used for <strong>fluent interfaces</strong>â€”important in <strong>traits</strong> or base classes:</p>
<pre><code class="language-php">trait Loggable {
    /** @return $this */
    public function log(string $msg): self {
        echo "[LOG] $msg\n";
        return $this;
    }
}
</code></pre>
<p>Used in:</p>
<pre><code class="language-php">class Order { use Loggable; }
$order = (new Order())-&gt;log('Created')-&gt;log('Paid');
</code></pre>
<p>PHPStan/PhpStorm knows <code>log()</code> returns <code>Order</code>, not <code>Loggable</code>. Magic.</p>
<hr />
<h4>âœ… <code>static</code></h4>
<p>Enables late static binding:</p>
<p><a href="https://phpstan.org/r/5f4f57bb-187e-4a1b-83a9-6907c97e33c6">Playground | PHPStan</a></p>
<pre><code class="language-php">class Repository {
    public static function new(): static {
        return new static(); // Might be a child class
    }
}

class UserRepository extends Repository {}
$userRepo = UserRepository::new(); // Returns UserRepository
</code></pre>
<hr />
<h4>âœ… <code>class-string&lt;Foo&gt;</code></h4>
<p>Ties a string to a valid subclass of Fooâ€”powerful for DI, factories, etc.</p>
<p><a href="https://phpstan.org/r/74cb1d11-0417-4da5-841a-5ad2211b46ae">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @template T of Service
 * @param class-string&lt;T&gt; $fqcn
 * @return T
 */
function resolve(string $fqcn): object {
    return new $fqcn();
}
</code></pre>
<p>Enforces constraints even when instantiating from strings.</p>
<hr />
<h3><strong>Use Table: Object Pseudo-Types</strong></h3>
<table>
<thead>
<tr>
<th>Use Case</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr>
<td>Generic object input</td>
<td><code>object</code></td>
</tr>
<tr>
<td>Static factory (same class)</td>
<td><code>self</code></td>
</tr>
<tr>
<td>Chaining / trait methods</td>
<td><code>$this</code></td>
</tr>
<tr>
<td>Factory w/ LSB (return child)</td>
<td><code>static</code></td>
</tr>
<tr>
<td>Instantiating by string</td>
<td><code>class-string&lt;T&gt;</code></td>
</tr>
</tbody>
</table>
<hr />
<h3><strong>Key Takeaways</strong></h3>
<ul>
<li>
<p>Always use <code>$this</code> for chaining and traits.</p>
</li>
<li>
<p>Use <code>static</code> when returning child classes from base class factories.</p>
</li>
<li>
<p><code>class-string&lt;T&gt;</code> makes dynamic instantiation type-safe.</p>
</li>
<li>
<p>Avoid <code>object</code> unless you&#8217;re writing a serializer.</p>
</li>
</ul>
<hr />
<h2 data-sourcepos="650:1-650:38"><a id="headline5new"></a>5. Callable Types &amp; Signatures</h2>
<p data-sourcepos="652:1-652:347">The <code>callable</code> type in PHP is incredibly flexible, but historically it lacked type safety. It could be a function name string, an array <code>[object, 'methodName']</code>, an array <code>['ClassName', 'methodName']</code>, or a Closure. Just declaring a parameter as <code>callable</code> tells PHPStan (and you) almost nothing about what arguments it expects or what it returns.</p>
<p data-sourcepos="654:1-654:56">PHPStan lets you document the <em>signature</em> of a callable.</p>
<h3 data-sourcepos="656:1-656:35">Documenting Callable Signatures</h3>
<p data-sourcepos="658:1-658:53">The syntax for documenting a callable&#8217;s signature is:</p>
<div class="code-block ng-tns-c2500688458-372 ng-trigger ng-trigger-codeBlockRevealAnimation">
<div class="formatted-code-block-internal-container ng-tns-c2500688458-372">
<div class="animated-opacity ng-tns-c2500688458-372">
<pre class="ng-tns-c2500688458-372"><code class="code-container formatted ng-tns-c2500688458-372" role="text" data-test-id="code-content" data-sourcepos="660:1-662:49"><span class="hljs-keyword">callable</span>(ParamType1, ParamType2, ...): ReturnType
</code></pre>
</div>
</div>
</div>
<p data-sourcepos="664:1-664:72">This goes <em>inside</em> your <code>@param</code> or <code>@return</code> tag for the callable type.</p>
<ul data-sourcepos="666:3-670:0">
<li data-sourcepos="666:3-666:89">Specify the expected types of parameters within the parentheses, separated by commas.</li>
<li data-sourcepos="667:3-667:51">Specify the expected return type after a colon.</li>
<li data-sourcepos="668:3-668:76">Use <code>void</code> if the callable is not expected to return a meaningful value.</li>
<li data-sourcepos="669:3-670:0">Use <code>mixed</code> if the parameters or return type are truly unknown or can vary wildly (but try to be more specific!).</li>
</ul>
<h3 data-sourcepos="671:1-671:37">Examples of Documenting Callables</h3>
<p data-sourcepos="673:1-673:31">âœ… <strong>Closure with simple types</strong></p>
<p data-sourcepos="673:1-673:31"><a href="https://phpstan.org/r/083ac843-5f9c-44f7-b4bf-47dfc38eaf09">Playground | PHPStan</a></p>
<div class="code-block ng-tns-c2500688458-373 ng-trigger ng-trigger-codeBlockRevealAnimation">
<div class="formatted-code-block-internal-container ng-tns-c2500688458-373">
<div class="animated-opacity ng-tns-c2500688458-373">
<pre class="ng-tns-c2500688458-373"><code class="code-container formatted ng-tns-c2500688458-373" role="text" data-test-id="code-content" data-sourcepos="675:1-686:91"><span class="hljs-comment">/**
 * <span class="hljs-doctag">@param</span> callable(int, string): bool $validator
 */</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">processData</span>(<span class="hljs-params"><span class="hljs-keyword">callable</span> <span class="hljs-variable">$validator</span></span>): <span class="hljs-title">void</span> </span>{
    <span class="hljs-variable">$result</span> = <span class="hljs-variable">$validator</span>(<span class="hljs-number">123</span>, <span class="hljs-string">'abc'</span>);
    <span class="hljs-comment">// PHPStan knows $result is bool here</span>
}

processData(<span class="hljs-function"><span class="hljs-keyword">fn</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> <span class="hljs-variable">$a</span>, <span class="hljs-keyword">string</span> <span class="hljs-variable">$b</span></span>): <span class="hljs-title">bool</span> =&gt; <span class="hljs-title">is_numeric</span>(<span class="hljs-params"><span class="hljs-variable">$a</span></span>) &amp;&amp; <span class="hljs-title">is_string</span>(<span class="hljs-params"><span class="hljs-variable">$b</span></span>))</span>; <span class="hljs-comment">// OK</span>
processData(<span class="hljs-function"><span class="hljs-keyword">fn</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> <span class="hljs-variable">$a</span>, <span class="hljs-keyword">int</span> <span class="hljs-variable">$b</span></span>): <span class="hljs-title">bool</span> =&gt; <span class="hljs-title">true</span>)</span>; <span class="hljs-comment">// PHPStan error: argument types mismatch</span>
</code></pre>
</div>
</div>
</div>
<p data-sourcepos="688:1-688:36">âœ… <strong>Array callable (object method)</strong></p>
<p data-sourcepos="688:1-688:36"><a href="https://phpstan.org/r/df3a8b5b-7dcc-4e34-9662-3754b6815133">Playground | PHPStan</a></p>
<div class="code-block ng-tns-c2500688458-374 ng-trigger ng-trigger-codeBlockRevealAnimation">
<div class="formatted-code-block-internal-container ng-tns-c2500688458-374">
<div class="animated-opacity ng-tns-c2500688458-374">
<pre class="ng-tns-c2500688458-374"><code class="code-container formatted ng-tns-c2500688458-374" role="text" data-test-id="code-content" data-sourcepos="690:1-706:58"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Service</span> </span>{
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handle</span>(<span class="hljs-params"><span class="hljs-keyword">float</span> <span class="hljs-variable">$value</span></span>): <span class="hljs-title">string</span> </span>{ <span class="hljs-keyword">return</span> (<span class="hljs-keyword">string</span>) <span class="hljs-variable">$value</span>; }
}

<span class="hljs-comment">/**
 * <span class="hljs-doctag">@param</span> callable(float): string $callback
 */</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">execute</span>(<span class="hljs-params"><span class="hljs-keyword">callable</span> <span class="hljs-variable">$callback</span></span>): <span class="hljs-title">void</span> </span>{
    <span class="hljs-variable">$result</span> = <span class="hljs-variable">$callback</span>(<span class="hljs-number">1.23</span>);
    <span class="hljs-comment">// PHPStan knows $result is string here</span>
}

<span class="hljs-variable">$service</span> = <span class="hljs-keyword">new</span> Service();
execute([<span class="hljs-variable">$service</span>, <span class="hljs-string">'handle'</span>]); <span class="hljs-comment">// OK</span>
execute([<span class="hljs-variable">$service</span>, <span class="hljs-string">'nonExistentMethod'</span>]); <span class="hljs-comment">// PHPStan error</span></code></pre>
</div>
</div>
</div>
<p data-sourcepos="727:1-727:39">âœ… <strong>String callable (global function)</strong></p>
<p data-sourcepos="729:1-729:213">While <code>callable-string</code> ensures it&#8217;s a valid function name, using the signature syntax adds type safety for the call itself.</p>
<p data-sourcepos="729:1-729:213"><a href="https://phpstan.org/r/23bc11eb-826a-4bd4-b52a-275cefad918b">Playground | PHPStan</a></p>
<div class="code-block ng-tns-c2500688458-376 ng-trigger ng-trigger-codeBlockRevealAnimation">
<div class="formatted-code-block-internal-container ng-tns-c2500688458-376">
<div class="animated-opacity ng-tns-c2500688458-376">
<pre class="ng-tns-c2500688458-376"><code class="code-container formatted ng-tns-c2500688458-376" role="text" data-test-id="code-content" data-sourcepos="731:1-742:94"><span class="hljs-comment">/**
 * <span class="hljs-doctag">@param</span> callable(string): string $modifier
 */</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">cleanInput</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> <span class="hljs-variable">$input</span>, <span class="hljs-keyword">callable</span> <span class="hljs-variable">$modifier</span></span>): <span class="hljs-title">string</span> </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-variable">$modifier</span>(<span class="hljs-variable">$input</span>);
    <span class="hljs-comment">// PHPStan knows the callable takes string and returns string</span>
}

cleanInput(<span class="hljs-string">" hello "</span>, <span class="hljs-string">'trim'</span>); <span class="hljs-comment">// OK</span>
cleanInput(<span class="hljs-string">" hello "</span>, <span class="hljs-string">'str_starts_with'</span>); <span class="hljs-comment">// PHPStan error: str_starts_with signature mismatch</span>
</code></pre>
</div>
</div>
</div>
<h3 data-sourcepos="744:1-744:17">Key Takeaways</h3>
<ul data-sourcepos="746:3-750:0">
<li data-sourcepos="746:3-746:62">Simply using <code>callable</code> is not enough for static analysis.</li>
<li data-sourcepos="747:3-747:102">Always document the expected <strong>signature</strong> of a callable using <code>callable(ParamTypes): ReturnType</code>.</li>
<li data-sourcepos="748:3-748:107">This provides type safety for the parameters passed <em>to</em> the callable and the value returned <em>from</em> it.</li>
</ul>
<hr />
<h2><strong><a id="headline5"></a>6. Generic Types with <code>@template</code>, <code>@extends</code>, <code>@implements</code></strong></h2>
<p><em>Static typing for dynamic collections.Â </em></p>
<hr />
<h3><strong>Overview: Generic Type Annotations</strong></h3>
<table>
<thead>
<tr>
<th>Annotation</th>
<th>Purpose</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>@template T</code></td>
<td>Declares a generic placeholder</td>
<td>class Collection</td>
</tr>
<tr>
<td><code>@template T of Foo</code></td>
<td>Constrains T to Foo or subclass</td>
<td>interface Repository</td>
</tr>
<tr>
<td><code>@param T</code> / <code>@return T</code></td>
<td>Applies T in method context</td>
<td>function add(T $item): void</td>
</tr>
<tr>
<td><code>@extends Collection&lt;T&gt;</code></td>
<td>Specifies generic type when extending a class</td>
<td>class UserCollection extendsâ€¦</td>
</tr>
<tr>
<td><code>@implements Repo&lt;T&gt;</code></td>
<td>Specifies concrete type in interface implementation</td>
<td>class UserRepo implementsâ€¦</td>
</tr>
</tbody>
</table>
<hr />
<h3>âœ… Generic Collection (Classic)</h3>
<p><a href="https://phpstan.org/r/14368c95-e76b-433c-9c04-1fe366758478">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @template T
 */
class Collection {
    /** @var list&lt;T&gt; */
    private array $items = [];

    /** @param T $item */
    public function add(mixed $item): void {
        $this-&gt;items[] = $item;
    }

    /** @return list&lt;T&gt; */
    public function all(): array {
        return $this-&gt;items;
    }
}</code></pre>
<hr />
<h3>âœ… @extends: Narrow Generic Type in Child Class</h3>
<pre><code class="language-php">/**
 * @extends Collection&lt;User&gt;
 */
class UserCollection extends Collection {
    public function findByEmail(string $email): ?User {
        foreach ($this-&gt;all() as $user) {
            if ($user-&gt;email === $email) return $user;
        }
        return null;
    }
}
</code></pre>
<p>Now the collection is <em>locked</em> to <code>User</code>.</p>
<hr />
<h3>âœ… @implements: Interfaces with Generics</h3>
<p><a href="https://phpstan.org/r/97826b6f-d090-46cc-8151-9b9b17ddabca">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @template T of Model
 */
interface Repository {
    /** @return T|null */
    public function find(int $id): ?object;

    /** @param T $model */
    public function save(object $model): void;
}
</code></pre>
<p>Implement with:</p>
<pre><code class="language-php">/**
 * @implements Repository&lt;User&gt;
 */
class UserRepository implements Repository {
    public function find(int $id): ?User { /* ... */ }

    public function save(object $model): void {
        if (!$model instanceof User) {
            throw new InvalidArgumentException();
        }
    }
}
</code></pre>
<hr />
<h3><strong>Use Table: Generic Constructs</strong></h3>
<table>
<thead>
<tr>
<th>Use Case</th>
<th>Syntax</th>
</tr>
</thead>
<tbody>
<tr>
<td>Reusable logic w/ varying types</td>
<td><code>@template T</code></td>
</tr>
<tr>
<td>Type-safe item addition</td>
<td><code>@param T $item</code></td>
</tr>
<tr>
<td>Type-safe container extension</td>
<td><code>@extends Collection&lt;T&gt;</code></td>
</tr>
<tr>
<td>Typed interface implementation</td>
<td><code>@implements Repository&lt;T&gt;</code></td>
</tr>
</tbody>
</table>
<hr />
<h3><strong>Key Takeaways</strong></h3>
<ul>
<li>
<p>Use <code>@template T</code> for anything that should be reusable (collections, services, repositories).</p>
</li>
<li>
<p><code>@extends</code> and <code>@implements</code> lock in the concrete typeâ€”no ambiguity.</p>
</li>
<li>
<p>PHPStan validates T everywhere it&#8217;s used: arrays, returns, conditionals.</p>
</li>
<li>And you can combine this with other phpdocs like callables: <a href="https://phpstan.org/r/c1cb7840-d28c-4eef-8f85-f4ab7a1d13c1">Playground | PHPStan</a></li>
</ul>
<hr />
<h2><strong><a id="headline6"></a>7. Enum-Like Constraints with Constants and Literal Values</strong></h2>
<hr />
<h3><strong>Because magic strings are garbage fire waiting to happen.</strong></h3>
<p>Whether you&#8217;re representing statuses, directions, or modesâ€”<strong>&#8220;freeform strings&#8221; are a playground for bugs</strong>. Typos go undetected. Invalid values sneak through. Conditional logic breaks silently.</p>
<p><strong>PHPStan gives us better options</strong>â€”even <strong>before PHP 8.1 enums</strong>.</p>
<hr />
<h3><strong>Overview: Enum-Like Type Constraints</strong></h3>
<table>
<thead>
<tr>
<th>Type Annotation</th>
<th>Description</th>
<th>Works With</th>
</tr>
</thead>
<tbody>
<tr>
<td>`&#8217;value1&#8242;</td>
<td>&#8216;value2&#8217;`</td>
<td>Specific literal values allowed</td>
</tr>
<tr>
<td><code>MyClass::CONST_*</code></td>
<td>Any constant with matching prefix from a class</td>
<td>All</td>
</tr>
<tr>
<td>`MyClass::CONST_A</td>
<td>CONST_B`</td>
<td>Specific constant values allowed</td>
</tr>
<tr>
<td><code>MyEnum</code></td>
<td>Accepts any case of a native PHP 8.1+ <code>enum</code></td>
<td>PHP 8.1+</td>
</tr>
<tr>
<td><code>MyEnum::MyCase</code></td>
<td>Specific enum case from PHP 8.1+ enum</td>
<td>PHP 8.1+</td>
</tr>
<tr>
<td><code>key-of&lt;array&gt;</code> / <code>value-of&lt;array&gt;</code></td>
<td>Restrict input to keys/values of a predefined array</td>
<td>All</td>
</tr>
</tbody>
</table>
<hr />
<h3>âœ… <strong>Literal Union Types</strong></h3>
<p><a href="https://phpstan.org/r/2d915419-d22d-4c12-9caf-9cd888d4ba27">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @param 'asc'|'desc' $direction
 */
function sortResults(string $direction): void {
    // PHPStan enforces exactly 'asc' or 'desc'
}

sortResults('asc');   // OK
sortResults('ASC');   // ERROR: Not lowercase
sortResults('up');    // ERROR
</code></pre>
<hr />
<h3>âœ… <strong>Class Constants (Wildcard or Specific)</strong></h3>
<p><a href="https://phpstan.org/r/19d6f7be-b3b0-4609-a4ee-26cae346584d">Playground | PHPStan</a></p>
<pre><code class="language-php">class Status {
    public const NEW = 'new';
    public const ACTIVE = 'active';
    public const BLOCKED = 'blocked';
}

/**
 * @param Status::NEW|Status::BLOCKED $status
 */
function blockUser(string $status): void {
    // PHPStan enforces only these constants
}

blockUser(Status::BLOCKED);   // OK
blockUser('blocked');         // ERROR: Use the constant, not the string
</code></pre>
<p><strong>Or allow all constants matching a prefix:</strong></p>
<pre><code class="language-php">/**
 * @param Status::STATUS_* $status
 */
function updateStatus(string $status): void {}
</code></pre>
<hr />
<h3>âœ… <strong>Native Enums (PHP 8.1+)</strong></h3>
<p><a href="https://phpstan.org/r/77b82f50-4733-4825-9ce0-750a879753bc">Playground | PHPStan</a></p>
<pre><code class="language-php">enum UserStatus: string {
    case ACTIVE = 'active';
    case BANNED = 'banned';
}

function setStatus(UserStatus $status): void {}

setStatus(UserStatus::ACTIVE);   // OK
setStatus('active');             // ERROR
</code></pre>
<hr />
<h3>âœ… <strong>Array-Based Constraints (<code>key-of</code>, <code>value-of</code>)</strong></h3>
<p><a href="https://phpstan.org/r/676d13a5-a653-460d-a742-6ffcecf6fd16">Playground | PHPStan</a> (key-of)</p>
<p><a href="https://phpstan.org/r/e36a1d54-f6fe-43c6-9600-eed06cf4bddf">Playground | PHPStan</a> (value-of)</p>
<pre><code class="language-php">public const array ALLOWED_ROLES = ['admin' =&gt; 1, 'editor' =&gt; 2, 'viewer' =&gt; 3];

/**
 * @param key-of&lt;self::ALLOWED_ROLES&gt; $role
 */
public function assignRole(string $role): void {}

$foo-&gt;assignRole('editor');    // OK
$foo-&gt;assignRole('moderator'); // ERROR
</code></pre>
<hr />
<h3><strong>Key Takeaways</strong></h3>
<ul>
<li>
<p>Donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t trust freeform valuesâ€”<strong>constrain them</strong>.</p>
</li>
<li>
<p>Use <strong>literal strings or class constants</strong> to build pseudo-enums.</p>
</li>
<li>
<p>Use <strong>native PHP enums</strong> when available, especially in domain logic.</p>
</li>
<li>
<p>Use <code>key-of</code>, <code>value-of</code>Â to enforce consistency in maps.</p>
</li>
</ul>
<hr />
<h2><strong><a id="headline7"></a>8. Conditional Types &amp; Type Inference Logic</strong></h2>
<hr />
<h3><strong>Because sometimes your types depend on the situation.</strong></h3>
<p>Static typing gets tricky when return types or variable values depend on conditionsâ€”especially <strong>input parameters or validation results</strong>.</p>
<p><strong>PHPStan gives us smart annotations</strong> to express:</p>
<ul>
<li>
<p>Types that change depending on a condition (<code>@return ($flag is true ? A : B)</code>)</p>
</li>
<li>
<p>Variable type guarantees after a validation function (<code>@phpstan-assert-*</code>)</p>
</li>
<li>
<p>Smart refactoring of <code>isValid()</code> patterns with actual type info</p>
</li>
</ul>
<hr />
<h3><strong>Overview: Conditional Typing Patterns</strong></h3>
<table style="width: 100%; height: 330px;">
<thead>
<tr style="height: 36px;">
<th style="height: 36px;">Annotation</th>
<th style="height: 36px;">Purpose</th>
<th style="height: 36px;">Use Case Example</th>
</tr>
</thead>
<tbody>
<tr style="height: 59px;">
<td style="height: 59px;"><code>@return (cond ? T1 : T2)</code></td>
<td style="height: 59px;">Return type depends on a parameter value</td>
<td style="height: 59px;">Return string or array depending on <code>$asArray</code></td>
</tr>
<tr style="height: 59px;">
<td style="height: 59px;"><code>@phpstan-assert T $var</code></td>
<td style="height: 59px;">Guarantees <code>$var</code> is of type T after method call</td>
<td style="height: 59px;">assertNonEmpty($str) makes <code>$str</code> a <code>non-empty-string</code></td>
</tr>
<tr style="height: 59px;">
<td style="height: 59px;"><code>@phpstan-assert-if-true T $var</code></td>
<td style="height: 59px;">If method returns true, <code>$var</code> is of type T</td>
<td style="height: 59px;">isValidEmail($email) ensures <code>non-empty-string</code> if true</td>
</tr>
<tr style="height: 59px;">
<td style="height: 59px;"><code>@phpstan-assert-if-false T $var</code></td>
<td style="height: 59px;">If method returns false, <code>$var</code> is of type T</td>
<td style="height: 59px;">isEmpty($arr) =&gt; if false, it&#8217;s <code>non-empty-array</code></td>
</tr>
<tr style="height: 58px;">
<td style="height: 58px;"><code>T is ClassName</code></td>
<td style="height: 58px;">Conditional logic inside generics</td>
<td style="height: 58px;"><code>@return (T is User ? int : string)</code></td>
</tr>
</tbody>
</table>
<hr />
<h3>âœ… <strong>Conditional Return Types Based on Flags</strong></h3>
<p><a href="https://phpstan.org/r/2354b8a0-216b-490f-8bdf-7596241ab0a0">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @return ($asJson is true ? string : array{name: string, age: int})
 */
function getUserData(bool $asJson): string|array {
    $data = ['name' =&gt; 'Alice', 'age' =&gt; 30];
    return $asJson ? json_encode($data, \JSON_THROW_ON_ERROR) : $data;
}

$data = getUserData(false);
// PHPStan: knows $data is array{name: string, age: int}

$json = getUserData(true);
// PHPStan: knows $json is string
</code></pre>
<hr />
<h3>âœ… <strong>@phpstan-assert-if-true</strong></h3>
<p><a href="https://phpstan.org/r/ea19c5a6-beb4-4082-8e7d-f55466762152">Playground | PHPStan</a></p>
<pre><code class="language-php">final class Validator {
    /**
     * @phpstan-assert-if-true non-empty-string $email
     */
    public static function isValidEmail(?string $email): bool {
        return is_string($email) &amp;&amp; $email !== '' &amp;&amp; str_contains($email, '@');
    }
}

$email = $_POST['email'] ?? null;

if (Validator::isValidEmail($email)) {
    // PHPStan knows $email is non-empty-string here
    echo strtoupper($email);
}
</code></pre>
<hr />
<h3>âœ… <strong>@phpstan-assert-if-false</strong></h3>
<p><a href="https://phpstan.org/r/f58e7fbd-bfa4-4c68-9e84-a7dad32e1098">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @phpstan-assert-if-false int&lt;min, 0&gt; $score
 */
function isPositive(int $score): bool {
    return $score &gt; 0;
}

$score = rand(-5, 5);

if (!isPositive($score)) {
    // PHPStan: $score is int&lt;min, 0&gt;
} else {
    // PHPStan: $score is int&lt;1, max&gt;
}
</code></pre>
<hr />
<h3>âœ… <strong>Conditional Return Types in Generics</strong></h3>
<p><a href="https://phpstan.org/r/19ac7d70-e8bd-4e82-a54a-78d2f9290404">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @template T of int|string
 * @param T $input
 * @return (T is int ? string : int)
 */
function invertType(int|string $input): string|int {
    return is_int($input) ? (string)$input : (int)$input;
}

$val1 = invertType(42);     // string
$val2 = invertType('123');  // int
</code></pre>
<hr />
<h3>âœ… <strong>@phpstan-assert for Defensive Contracts</strong></h3>
<p><a href="https://phpstan.org/r/5c39293e-cc2f-4e35-907b-e48def3144bd">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @phpstan-assert non-empty-array&lt;string&gt; $items
 */
function assertHasItems(array $items): void {
    if (empty($items)) {
        throw new InvalidArgumentException("Must contain at least one item.");
    }
}
</code></pre>
<p>Use these to enforce contracts even if native PHP types canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t.</p>
<hr />
<h3><strong>Key Takeaways</strong></h3>
<ul>
<li>
<p>Let your return types reflect real-world branching logic.</p>
</li>
<li>
<p>Use <code>@phpstan-assert-if-true</code> to encode validator results into type narrowing.</p>
</li>
<li>
<p>Use <code>@return (condition ? A : B)</code> to model toggle behavior safely.</p>
</li>
<li>
<p>Defensive types are better than defensive runtime checksâ€”<strong>because they&#8217;re enforced before runtime.</strong></p>
</li>
</ul>
<hr />
<h2><strong><a id="headline8"></a>9. Pass-by-Reference Variables with <code>@param-out</code></strong></h2>
<hr />
<h3><strong>Stop guessing what happens to that &amp;$var.</strong></h3>
<p>PHPâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s <code>&amp;$variable</code> allows <strong>mutation by reference</strong>â€”which is great for <strong>parsers, validators, or multi-output functions</strong>, but it kills static type analysis.</p>
<p>PHPStan solves this with <code>@param-out</code>: <strong>explicitly documenting the final type</strong> of a referenced variable after a function call.</p>
<p>Think of it as &#8220;the function <em>returns into</em> this variable&#8221;â€”and <strong>now PHPStan knows</strong> what to expect.</p>
<hr />
<h3><strong>Overview: <code>@param-out</code> Syntax</strong></h3>
<table>
<thead>
<tr>
<th>Annotation</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>@param-out T $var</code></td>
<td>Describes the type <code>$var</code> will have after the function call finishes.</td>
</tr>
<tr>
<td><code>@param T $var</code></td>
<td>Still describes the type it must be at input, if not uninitialized.</td>
</tr>
</tbody>
</table>
<hr />
<h3>âœ… <strong>Parsing Into a Variable</strong></h3>
<p><a href="https://phpstan.org/r/01e0ba13-bc5b-4d1f-8bc8-c307e2043e2f">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @param string $input
 * @param-out int|null $parsed
 */
function parseInt(string $input, ?int &amp;$parsed): void {
    $parsed = filter_var($input, FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
}
</code></pre>
<pre><code class="language-php">$raw = "42";
$result = null;

parseInt($raw, $result);

// PHPStan: $result is now int|null
if ($result !== null) {
    echo $result * 2;
}
</code></pre>
<hr />
<h3>âœ… <strong>Assigning a Default String</strong></h3>
<p><a href="https://phpstan.org/r/0677f448-117d-4cfe-b824-62273cb6e708">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @param-out non-empty-string $output
 */
function ensureValue(?string &amp;$output): void {
    if ($output === null || $output === '') {
        $output = 'default';
    }
}
</code></pre>
<pre><code class="language-php">$name = null;
ensureValue($name);

// PHPStan: $name is now non-empty-string
</code></pre>
<hr />
<h3>âœ… <strong>Flagging Errors in Processing</strong></h3>
<p><a href="https://phpstan.org/r/3fedabe2-41bb-45fc-bbfd-dc919635433e">Playground | PHPStan</a></p>
<pre><code class="language-php">/**
 * @param CsvFile $csv
 * @param-out list&lt;string&gt; $errors
 */
function processCsv(CsvFile $csv, array &amp;$errors): bool {
    $errors = [];
    foreach ($csv-&gt;getRows() as $row) {
        if (!isValidRow($row)) {
            $errors[] = 'Invalid row: ' . json_encode($row);
        }
    }
    return empty($errors);
}
</code></pre>
<pre><code class="language-php">$errors = [];
$success = processCsv($file, $errors);

if (!$success) {
    foreach ($errors as $e) {
        echo $e;
    }
}
</code></pre>
<p>Now <code>$errors</code> is a <strong>guaranteed list of strings</strong>, only if the function sets it.</p>
<hr />
<h3><strong>Key Takeaways</strong></h3>
<ul>
<li>
<p>Use <code>@param-out</code> whenever a <code>&amp;$var</code> is written to.</p>
</li>
<li>
<p>Combine with <code>@param</code> to describe both <em>input and output</em> intent.</p>
</li>
<li>
<p>Helps static analysis track types over mutation.</p>
</li>
<li>
<p>Prevents &#8220;guessing&#8221; about the variable&#8217;s final type in calling scope.</p>
</li>
</ul>
<hr />
<h2><strong><a id="headline9"></a>10. Suppressing False Positives with <code>@phpstan-ignore-*</code></strong></h2>
<hr />
<h3><strong>Sometimes static analysis gets it wrong. Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s OKâ€”</strong> but make it <strong>surgical</strong>, not sloppy.</h3>
<p>PHPStan is powerful, but not omniscient. In complex, dynamic, or legacy-heavy codebases, it might raise <strong>false positives</strong>â€”errors that <em>you</em> know are safe but the tool canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t fully reason about.</p>
<p>Donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t disable entire rules. Donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t drop your level.<br />Use <code>@phpstan-ignore-*</code> annotations <strong>surgically, with precision</strong>.</p>
<hr />
<h3><strong>Overview: Suppression Annotations</strong></h3>
<table>
<thead>
<tr>
<th>Annotation</th>
<th>Scope</th>
<th>Best Use Case</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>@phpstan-ignore-next-line</code></td>
<td>Next line only (<em>please use the <code>Identifier</code> stuff not this</em>)</td>
<td>Dynamic access, legacy code edge cases</td>
</tr>
<tr>
<td><code>@phpstan-ignore-line</code></td>
<td>Inline on same line (<em>please use the <code>Identifier</code> stuff not this</em>)</td>
<td>Dynamic properties/methods, chained expressions</td>
</tr>
<tr>
<td><code>@phpstan-ignore-error Identifier</code></td>
<td>Specific error type only</td>
<td>Narrow suppression while keeping strict checks</td>
</tr>
<tr>
<td><code>parameters &gt; ignoreErrors:</code> (neon)</td>
<td>Global suppression config</td>
<td>Vendor code or unavoidable project-wide issues</td>
</tr>
</tbody>
</table>
<hr />
<h3>âœ… <strong>Ignoring the Next Line</strong></h3>
<pre><code class="language-php">/** @phpstan-ignore-next-line */
echo $legacyObject-&gt;$dynamicProperty;
</code></pre>
<p>Useful when <code>$dynamicProperty</code> is <strong>validated externally</strong>, but PHPStan canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t infer that.</p>
<hr />
<h3>âœ… <strong>Inline Suppression</strong></h3>
<pre><code class="language-php">$val = $legacyObject-&gt;$property; /** @phpstan-ignore-line */
</code></pre>
<p>Keep suppression right next to the usage, especially helpful for one-liners.</p>
<hr />
<h3>âœ… <strong>Targeting Specific Errors</strong></h3>
<pre><code class="language-php">/** @phpstan-ignore-error function.alreadyNarrowedType (your comment here) */
if (is_string($value) &amp;&amp; strlen($value) &gt; 5) {
    echo $value;
}
</code></pre>
<p>This suppresses only the â€œalready narrowedâ€ warning, keeping everything else active.</p>
<hr />
<h3>âœ… <strong>Global Project Suppression (<code>phpstan.neon</code>)</strong></h3>
<pre><code class="language-neon">parameters:
    ignoreErrors:
        - '#Call to undefined method LegacyClass::doMagic#'
        - 
            message: '#Access to an undefined property#'
            path: src/LegacyStuff/*.php
</code></pre>
<p>Use this only for vendor or legacy glue code. <strong>Never in new code.</strong></p>
<hr />
<h3><strong>Best Practices for Ignoring</strong></h3>
<table>
<thead>
<tr>
<th>Rule</th>
<th>Why</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Always comment</strong></td>
<td>Explain <em>why</em> the ignore is needed.</td>
</tr>
<tr>
<td><strong>Suppress specific errors, not broad ones</strong></td>
<td>Use <code>@phpstan-ignore-error</code>, not <code>ignore-next-line</code> if possible.</td>
</tr>
<tr>
<td><strong>Refactor &gt; Ignore</strong></td>
<td>Most false positives come from bad typing. Improve types if you can.</td>
</tr>
<tr>
<td><strong>Audit periodically</strong></td>
<td>Old ignores may hide real problems after refactors.</td>
</tr>
</tbody>
</table>
<hr />
<h3>âŒ Donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t Do This</h3>
<pre><code class="language-php">/** @phpstan-ignore-next-line */
doSomethingRisky(); // No explanation, no control
</code></pre>
<p>Or worse:</p>
<pre><code class="language-neon">parameters:
    level: 0
</code></pre>
<p>Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve just turned off the fire alarm and set your desk on fire, a simple way of starting is the baseline feature where you can just ignore old errors: <a href="https://phpstan.org/user-guide/baseline">The Baseline | PHPStan</a></p>
<hr />
<h3><strong>Key Takeaways</strong></h3>
<ul>
<li>
<p><strong>Only ignore what you <em>must</em>.</strong> Don&#8217;t make it a habit.</p>
</li>
<li>
<p>Prefer <strong>precise, contextual suppression</strong> (<code>-error</code>, <code>-next-line</code>) over global.</p>
</li>
<li>
<p>Always add a <strong>human-readable comment</strong> for future devs.</p>
</li>
<li>
<p>Refactor the real problem if PHPStan is right.</p>
</li>
</ul>
<hr />
<h2><strong><a id="headline10"></a>11. Best Practices for PHPStan PHPDocs</strong></h2>
<hr />
<h3><strong>Make your types honest. Make your docs readable. Make your tools useful.</strong></h3>
<p>PHPStan doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t care how pretty your code looksâ€”it cares if the types match, if edge cases are covered, and if your docs are aligned with reality. Writing good PHPDocs isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t about verbosity. Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s about <strong>clarity, precision, and maintainability</strong>.</p>
<hr />
<h3><strong>PHPDoc Hygiene Checklist</strong></h3>
<table style="width: 100%;">
<thead>
<tr>
<th style="width: 52.4638%;">âœ… Do This</th>
<th style="width: 47.3913%;">âŒ Instead Of This</th>
</tr>
</thead>
<tbody>
<tr>
<td style="width: 52.4638%;">Use PHP native types wherever possible</td>
<td style="width: 47.3913%;">Duplicating native types in <code>@param</code> tags</td>
</tr>
<tr>
<td style="width: 52.4638%;">Add <strong>constraints</strong> with pseudo-types</td>
<td style="width: 47.3913%;">Vague types like <code>array</code> or <code>mixed</code></td>
</tr>
<tr>
<td style="width: 52.4638%;">Use <strong>shapes and lists</strong> (<code>array{}</code> / <code>list&lt;&gt;</code>)</td>
<td style="width: 47.3913%;">Indexed arrays with <code>array&lt;int,type&gt;</code> (unless needed)</td>
</tr>
<tr>
<td style="width: 52.4638%;">Prefer <code>@phpstan-type</code> for reuse or DTO of the type is complex</td>
<td style="width: 47.3913%;">Copy-pasting complex types across files</td>
</tr>
<tr>
<td style="width: 52.4638%;">Keep docs in sync with code</td>
<td style="width: 47.3913%;">Letting docs rot after refactors</td>
</tr>
<tr>
<td style="width: 52.4638%;">Add purpose-driven descriptions</td>
<td style="width: 47.3913%;">Empty <code>@param</code> tags with no context</td>
</tr>
</tbody>
</table>
<hr />
<h3>âœ… Use Native Types First, PHPDoc Second</h3>
<pre><code class="language-php">// âŒ Redundant
/**
 * @param int $id
 */
function getUser(int $id): User {}

// âœ… Clean
function getUser(int $id): User {}

// âœ… All-In (it depends)<br />/**
 * @param UserId $id Use the Value-Object to fetch the User.
 */
function getUser(UserId $id): User {}
</code></pre>
<hr />
<h3>âœ… Add Value with PHPStan Types</h3>
<pre><code class="language-php">// âœ… Enforce constraints
/**
 * @param positive-int $userId
 */
function getUserById(int $userId): User {}
</code></pre>
<hr />
<h3>âœ… Prefer <code>array{}</code> Over Raw <code>array</code></h3>
<pre><code class="language-php">// âŒ Too generic
function getConfig(): array {}

// âœ… Self-documenting and type-safe
/**
 * @return array{host: string, port: int}
 */
function getConfig(): array {}
</code></pre>
<hr />
<h3>âœ… Use <code>list&lt;T&gt;</code> or <code>non-empty-list&lt;T&gt;</code></h3>
<pre><code class="language-php">/**
 * @return non-empty-list&lt;User&gt;
 */
function getActiveUsers(): array {}
</code></pre>
<p>No more bugs from assuming the first item exists.</p>
<hr />
<h3>âœ… Reuse with <code>@phpstan-type</code></h3>
<pre><code class="language-php">/**
 * @phpstan-type UserData array{
 *   id: int,
 *   name: non-empty-string,
 *   email: string
 * }
 */
</code></pre>
<p>Then:</p>
<pre><code class="language-php">/**
 * @return UserData
 */
public function getUserData(): array {}
</code></pre>
<p>Update once. Used often. But once again, if you need this everywhere, please create a DTO class for it. :)</p>
<hr />
<h3>âœ… Generics with <code>@template</code></h3>
<pre><code class="language-php">/**
 * @template T
 * @param T $value
 * @return T
 */
function identity($value) { return $value; }
</code></pre>
<p>Now thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s a real genericâ€”PHPStan can track the type through usage.</p>
<hr />
<h3>âœ… Descriptions Are Not Dead</h3>
<pre><code class="language-php">/**
 * Fetches total including tax.
 *
 * @param list&lt;Item&gt; $items Items in the cart.
 * @param positive-int $vat VAT rate in percent (e.g. 19).
 * @return float Total price incl. tax.
 */
function calculateTotal(array $items, int $vat): float {}
</code></pre>
<p>Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re writing code for humans <em>and</em> tools. Donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t forget the humans + you can use html (lists, string, &#8230;) here.</p>
<hr />
<h3>âœ… Suppress Only When Necessary</h3>
<pre><code class="language-php">// Weâ€&#x2122;re dealing with dynamic properties from legacy __get
/** @phpstan-ignore-next-line */
echo $legacyObject-&gt;$name;
</code></pre>
<p>But donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t make this a crutch. Fix types instead.</p>
<hr />
<h3>âœ… Keep Docs in Sync</h3>
<p>When you rename a parameter, update the PHPDoc.<br />When you change the return type, fix the annotation.<br />Outdated docs are <strong>worse than none at all</strong>.</p>
<hr />
<h3>âœ… Consider a DTO or Value Object</h3>
<pre><code class="language-php">// âŒ This is too much for an array shape
/**
 * @return array{
 *   user: array{id: int, name: string},
 *   metadata: array{roles: list&lt;string&gt;, active: bool},
 *   settings?: array&lt;string, mixed&gt;
 * }
 */
</code></pre>
<p>Justâ€¦ stop. Use a DTO. Your future self thanks you.</p>
<hr />
<h3><strong>Key Takeaways</strong></h3>
<ul>
<li>
<p>Donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t document what PHP already knows.</p>
</li>
<li>
<p>Document what PHP canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t express.</p>
</li>
<li>
<p>Use PHPStanâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s extensions to document intent, not just shape.</p>
</li>
<li>
<p>Reuse types. Describe constraints. Avoid magic.</p>
</li>
</ul>
<hr />
<h2><strong><a id="headline11"></a>12. Cheatsheet &amp; Final Summary</strong></h2>
<hr />
<p>Letâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s wrap this beast up the way it deserves: with a <strong>clear cheatsheet</strong> of everything PHPStan&#8217;s extended PHPDoc syntax gives youâ€”and how to <strong>actually use it in production</strong>.</p>
<p>This isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t theoretical. Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s not for linting your hobby script. This is how <strong>real teams keep real codebases from turning into type-anarchist dumpster fires</strong>.</p>
<hr />
<h3><strong>Cheatsheet: PHPStan PHPDoc Types by Category</strong></h3>
<h4><strong>Scalar &amp; Refined Pseudo-Types</strong></h4>
<table>
<thead>
<tr>
<th>Type</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>non-empty-string</code></td>
<td>String that&#8217;s never <code>''</code></td>
</tr>
<tr>
<td><code>numeric-string</code></td>
<td>String that parses to number (<code>"123"</code>, <code>"1.5"</code>)</td>
</tr>
<tr>
<td><code>literal-string</code></td>
<td>String known at compile time</td>
</tr>
<tr>
<td><code>positive-int</code></td>
<td>Integer &gt; 0</td>
</tr>
<tr>
<td><code>non-negative-int</code></td>
<td>Integer &gt;= 0</td>
</tr>
<tr>
<td><code>negative-int</code></td>
<td>Integer &lt; 0</td>
</tr>
<tr>
<td><code>non-positive-int</code></td>
<td>Integer &lt;= 0</td>
</tr>
<tr>
<td><code>int&lt;min, max&gt;</code></td>
<td>Integer between <code>min</code> and <code>max</code> (inclusive)</td>
</tr>
<tr>
<td><code>class-string&lt;T&gt;</code></td>
<td>Fully qualified class name (subtype of <code>T</code>)</td>
</tr>
<tr>
<td><code>callable-string</code></td>
<td>String name of a global callable</td>
</tr>
</tbody>
</table>
<hr />
<h4><strong>Array &amp; List Types</strong></h4>
<table style="width: 100%; height: 288px;">
<thead>
<tr style="height: 36px;">
<th style="height: 36px;">Type</th>
<th style="height: 36px;">Meaning</th>
</tr>
</thead>
<tbody>
<tr style="height: 36px;">
<td style="height: 36px;"><code>array&lt;TKey, TValue&gt;</code></td>
<td style="height: 36px;">Associative array</td>
</tr>
<tr style="height: 36px;">
<td style="height: 36px;"><code>non-empty-array&lt;TKey, TValue&gt;</code></td>
<td style="height: 36px;">Associative array with at least one element</td>
</tr>
<tr style="height: 36px;">
<td style="height: 36px;"><code>list&lt;T&gt;</code></td>
<td style="height: 36px;">0-based sequential array (indexed)</td>
</tr>
<tr style="height: 36px;">
<td style="height: 36px;"><code>non-empty-list&lt;T&gt;</code></td>
<td style="height: 36px;"><code>list&lt;T&gt;</code> with at least one element</td>
</tr>
<tr style="height: 36px;">
<td style="height: 36px;"><code>array{key: T, ...}</code></td>
<td style="height: 36px;">Structured array with required keys</td>
</tr>
<tr style="height: 36px;">
<td style="height: 36px;"><code>array{key?: T}</code></td>
<td style="height: 36px;">Structured array with optional keys</td>
</tr>
<tr style="height: 36px;">
<td style="height: 36px;"><code>array-key</code></td>
<td style="height: 36px;">`int</td>
</tr>
</tbody>
</table>
<hr />
<h4><strong>Object, Class</strong></h4>
<table>
<thead>
<tr>
<th>Type</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>object</code></td>
<td>Any object</td>
</tr>
<tr>
<td><code>self</code></td>
<td>Current class (not child)</td>
</tr>
<tr>
<td><code>$this</code></td>
<td>Instance of calling class</td>
</tr>
<tr>
<td><code>static</code></td>
<td>Late static binding return</td>
</tr>
<tr>
<td><code>class-string&lt;T&gt;</code></td>
<td>String that must be a subtype of <code>T</code></td>
</tr>
</tbody>
</table>
<hr />
<h4>Callable</h4>
<table>
<thead>
<tr>
<th>Syntax</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>callable</code></td>
<td>Any valid PHP callable (closure, string, array callback)</td>
</tr>
<tr>
<td><code>callable(): void</code></td>
<td>A callable that takes no parameters and returns nothing</td>
</tr>
<tr>
<td><code>callable(int): bool</code></td>
<td>A callable that takes an <code>int</code> and returns a <code>bool</code></td>
</tr>
<tr>
<td><code>callable(string, T): T</code></td>
<td>Generic callable with multiple parameters and return type</td>
</tr>
<tr>
<td><code>Closure(T): R</code></td>
<td>Closure with generic parameter and return type</td>
</tr>
<tr>
<td><code>callable-string</code></td>
<td>String name of a globally callable function</td>
</tr>
</tbody>
</table>
<h4><strong>Generics</strong></h4>
<table>
<thead>
<tr>
<th>Annotation</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>@template T</code></td>
<td>Declare a type variable <code>T</code></td>
</tr>
<tr>
<td><code>@template T of Foo</code></td>
<td>Restrict <code>T</code> to be subtype of <code>Foo</code></td>
</tr>
<tr>
<td><code>@param T $value</code></td>
<td>Use generic <code>T</code> for parameter</td>
</tr>
<tr>
<td><code>@return T</code></td>
<td>Return generic type <code>T</code></td>
</tr>
<tr>
<td><code>@var T[] / list&lt;T&gt;</code></td>
<td>Typed container</td>
</tr>
<tr>
<td><code>@extends Base&lt;T&gt;</code></td>
<td>Specify type <code>T</code> when extending base class</td>
</tr>
<tr>
<td><code>@implements Interface&lt;T&gt;</code></td>
<td>Specify type <code>T</code> for implementation</td>
</tr>
</tbody>
</table>
<hr />
<h4><strong>Structured Data &amp; Reusability</strong></h4>
<table>
<thead>
<tr>
<th>Syntax</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>@phpstan-type Alias = Type</code></td>
<td>Type alias for complex types</td>
</tr>
<tr>
<td><code>@phpstan-import-type</code></td>
<td>Import alias from another scope/class</td>
</tr>
</tbody>
</table>
<hr />
<h4><strong>Constant &amp; Enum-Like Constraints</strong></h4>
<table>
<thead>
<tr>
<th>Syntax</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>'foo'|'bar'</code></td>
<td>Specific literal values allowed</td>
</tr>
<tr>
<td><code>MyClass::CONST_*</code></td>
<td>All constants matching prefix in a class</td>
</tr>
<tr>
<td><code>MyClass::CONST_A | MyClass::CONST_B</code></td>
<td>Specific constant values allowed</td>
</tr>
<tr>
<td><code>MyEnum::MyCase</code> (PHP 8.1+)</td>
<td>Specific native Enum case</td>
</tr>
<tr>
<td><code>key-of&lt;array&gt;</code> / <code>value-of&lt;array&gt;</code></td>
<td>Constrain to keys/values of a known constant array</td>
</tr>
</tbody>
</table>
<hr />
<h4><strong>Type Assertions &amp; Conditional Logic</strong></h4>
<table>
<thead>
<tr>
<th>Annotation</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>@phpstan-assert T $var</code></td>
<td>Assert <code>$var</code> is type <code>T</code> after call</td>
</tr>
<tr>
<td><code>@phpstan-assert-if-true T $var</code></td>
<td>If function returns true, <code>$var</code> is <code>T</code></td>
</tr>
<tr>
<td><code>@phpstan-assert-if-false T $var</code></td>
<td>If function returns false, <code>$var</code> is <code>T</code></td>
</tr>
<tr>
<td><code>@return (cond ? T1 : T2)</code></td>
<td>Conditional return type</td>
</tr>
</tbody>
</table>
<hr />
<h4><strong>By-Reference Output Tracking</strong></h4>
<table>
<thead>
<tr>
<th>Annotation</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>@param-out T $var</code></td>
<td><code>$var</code> will be of type <code>T</code> after the function</td>
</tr>
</tbody>
</table>
<hr />
<h4><strong>Suppression &amp; Exceptions</strong></h4>
<table>
<thead>
<tr>
<th>Annotation</th>
<th>Use Case</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>@phpstan-ignore-next-line</code></td>
<td>Ignore all errors on the next line</td>
</tr>
<tr>
<td><code>@phpstan-ignore-line</code></td>
<td>Ignore errors inline</td>
</tr>
<tr>
<td><code>@phpstan-ignore-error error-id</code></td>
<td>Ignore specific error on current block</td>
</tr>
</tbody>
</table>
<hr />
<h2><strong>Final Thoughts</strong></h2>
<ul>
<li>
<p>Treat PHPDocs as <strong>contracts</strong>, not comments.</p>
</li>
<li>
<p>Donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t use <code>array</code> when you mean <code>non-empty-list&lt;literal-string&gt;</code>â€”<strong>be precise</strong>.</p>
</li>
<li>
<p>Refactor array shapes into DTOs when they get hairy.</p>
</li>
<li>
<p>Use <code>@phpstan-type</code>, <code>@template</code>, <code>@assert</code>, and <code>@param-out</code> to document behavior that PHP syntax alone canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t express.</p>
</li>
<li>
<p>Rely on <strong>tools, not convention</strong>. Let PHPStan hold the line.</p>
</li>
</ul>
<p>Â </p>
<img loading="lazy" decoding="async" src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F05%2Fthe-phpdoc-guide-2025-edition%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dthe-phpdoc-guide-2025-edition&amp;action_name=The%20PHPDoc%20Guide%20%282025%20Edition%29&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
					<wfw:commentRss>http://suckup.de/2025/05/the-phpdoc-guide-2025-edition/?pk_campaign=feed&amp;pk_kwd=the-phpdoc-guide-2025-edition/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">6975</post-id>	</item>
		<item>
		<title>SOLID Principles: From Paw Patrol to the Neighborhood</title>
		<link>http://suckup.de/2025/01/solid-principles-from-paw-patrol-to-linux-penguin/?pk_campaign=feed&amp;pk_kwd=solid-principles-from-paw-patrol-to-linux-penguin&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=solid-principles-from-paw-patrol-to-linux-penguin</link>
					<comments>http://suckup.de/2025/01/solid-principles-from-paw-patrol-to-linux-penguin/?pk_campaign=feed&amp;pk_kwd=solid-principles-from-paw-patrol-to-linux-penguin#comments</comments>
		
		<dc:creator><![CDATA[voku]]></dc:creator>
		<pubDate>Fri, 31 Jan 2025 01:27:19 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<guid isPermaLink="false">https://suckup.de/?p=6962</guid>

					<description><![CDATA[<p><a href="http://suckup.de/2025/01/solid-principles-from-paw-patrol-to-linux-penguin/?pk_campaign=feed&#038;pk_kwd=solid-principles-from-paw-patrol-to-linux-penguin">SOLID Principles: From Paw Patrol to the Neighborhood</a></p>
<p>â€“ A Senior Developerâ€™s Pragmatic Guide Â  TheÂ SOLIDÂ principles are essential guidelines for writing clean, maintainable, and scalable software. While many developers can recite them, real-world applications often struggle with their correct implementation. Understanding SOLID is not just about memorizing definitions; it&#8217;s about knowing when and how to apply them effectively. Sometimes, following the rules strictly &#8230; <a href="http://suckup.de/2025/01/solid-principles-from-paw-patrol-to-linux-penguin/?pk_campaign=feed&#038;pk_kwd=solid-principles-from-paw-patrol-to-linux-penguin" class="more-link">Continue reading <span class="screen-reader-text">SOLID Principles: From Paw Patrol to the Neighborhood</span></a><img src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F01%2Fsolid-principles-from-paw-patrol-to-linux-penguin%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dsolid-principles-from-paw-patrol-to-linux-penguin&amp;action_name=SOLID%20Principles%3A%20From%20Paw%20Patrol%20to%20the%20Neighborhood&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" /></p>
]]></description>
										<content:encoded><![CDATA[<p><a href="http://suckup.de/2025/01/solid-principles-from-paw-patrol-to-linux-penguin/?pk_campaign=feed&#038;pk_kwd=solid-principles-from-paw-patrol-to-linux-penguin">SOLID Principles: From Paw Patrol to the Neighborhood</a></p>

<div class="ptr--ptr">
<div class="ptr--box">
<div class="ptr--content">
<div class="ptr--icon"><span style="color: revert; font-size: 29px; font-weight: bold;">â€“ A Senior Developerâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s Pragmatic Guide</span></div>
<div>Â </div>
</div>
</div>
</div>
<div id="page-content" class="wrapper articles articles-edit articletag-programming articletag-softwaredevelopment articletag-php articletag-coding articleuser-30309" data-current-page="articles-edit">
<div id="page-content-inner" data-internal-nav="true"><main id="main-content" style="box-sizing: border-box; display: block; scroll-margin-top: var(--header-height);" data-article="{&quot;id&quot;:2251171,&quot;title&quot;:&quot;SOLID Principles: From Paw Patrol to Linux Penguins&quot;,&quot;updated_at&quot;:&quot;2025-01-31T01:15:12.418Z&quot;,&quot;main_image&quot;:&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/miv9sfnjmal186rt9rvg.png&quot;,&quot;published&quot;:false,&quot;published_at&quot;:null,&quot;body_markdown&quot;:&quot;---\ntitle: SOLID Principles: From Paw Patrol to Linux Penguins\npublished: false\ndescription: A Senior Developerâ€&#x2122;s Pragmatic Guide about SOLID principles \ntags: #programming #softwaredevelopment #php #coding\ncover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/miv9sfnjmal186rt9rvg.png\n# Use a ratio of 100:42 for best results.\n# published_at: 2025-01-31 01:12 +0000\n---\n\n## â€“ A Senior Developerâ€&#x2122;s Pragmatic Guide\n\nThe **SOLID** principles are essential guidelines for writing clean, maintainable, and scalable software. While many developers can recite them, real-world applications often struggle with their correct implementation.\n\nUnderstanding SOLID is not just about memorizing definitions; it's about knowing when and how to apply them effectively. Sometimes, following the rules strictly can lead to unnecessary complexity, while a pragmatic approach ensures maintainability without over-engineering.\n\nIn this guide, we will break down each principle with practical **PHP examples**, **Paw Patrol analogies** for clarity, and **trade-offs** to consider. By the end, youâ€&#x2122;ll have a solid understanding of how these principles work together and when it's okay to bend them for the greater good.\n\n---\n\n## ðŸ¡ The \&quot;Front Garden\&quot; \u0026 \&quot;Neighborhood\&quot; Metaphor: Why Naming Principles Matter\n\nImagine you donâ€&#x2122;t even know what â€œneighborâ€ or â€œfront gardenâ€ means. Someone tries to explain that you shouldnâ€&#x2122;t walk through someone elseâ€&#x2122;s garden, so they define these terms and create a rule. But that rule would be rigid and limiting.\n\nInstead, we define a broad principle that covers many similar scenarios, giving it a name so others immediately understand what we mean. This flexibility allows us to apply it beyond just neighbors and gardens while recognizing exceptionsâ€”like if the garden is yours or thereâ€&#x2122;s an emergency.\n\n### How This Relates to SOLID\nSimilarly, SOLID is a set of abstract principles that define boundaries in object-oriented code. By naming these boundaries (SRP, OCP, LSP, ISP, DIP), we gain:\n\n1ï¸âƒ£ **Efficient Communication** â€“ We can say, â€œWeâ€&#x2122;re violating OCP,â€ instead of explaining, â€œWe keep re-editing stable code to add new features.â€\n\n2ï¸âƒ£ **Unified Understanding** â€“ Whether human developers or AI-powered coding assistants, everyone recognizes the same underlying problem without a lengthy breakdown.\n\n3ï¸âƒ£ **Flexible Exceptions** â€“ Sometimes, crossing that fence is practical (if itâ€&#x2122;s your own â€œgardenâ€) or necessary (in an emergency).\n\nKnowing these principles allows developers to make **intentional trade-offs**, rather than blindly applying or ignoring them.\n\n---\n\n## ðŸ§  How to Apply SOLID Without Over-Engineering\n\n### 1ï¸âƒ£ Apply SOLID as Needed, Not as a Dogma\n- If a class is simple \u0026 works, donâ€&#x2122;t force an interface just to follow DIP.\n- If a method is naturally cohesive, donâ€&#x2122;t split it just to follow SRP.\n- If an interface is only used once, donâ€&#x2122;t extract it just for ISP.\n- **Code should be SOLID but also simple.**\n\n### 2ï¸âƒ£ Focus on Refactoring, Not Preemptive Complexity\n- Refactor SOLID in steps **when a problem arises**.\n- Donâ€&#x2122;t create an abstraction until **you actually need it**.\n\n### 3ï¸âƒ£ Use the 80/20 Rule\n- **80%** of your code should be pragmatic and **only 20%** should be deeply abstracted for maintainability.\n\nðŸ’¡ **Example:**\n- An **order processing system** needs flexibility (**high SOLID compliance**).\n- A **CLI script that runs once a year**? No need for extreme abstractions.\n\n### 4ï¸âƒ£ Know When to Break the Rules (Intentionally)\n- Itâ€&#x2122;s okay to **violate SRP** if it keeps your code readable and practical.\n- Sometimes **direct dependencies (instead of DIP)** make sense for small projects.\n- Some classes might benefit from breaking **OCP** if modifying them improves clarity.\n\nBy the end of this guide, youâ€&#x2122;ll **not only understand SOLID** but also **when to apply it pragmatically**â€”allowing your architecture to evolve gracefully without unnecessary complexity.\n\n---\n\n## Single Responsibility Principle (SRP)\n\n![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zlby1sbe8xgmna1tazv0.png)\n(source: https://trekhleb.dev/blog/2017/solid-principles-around-you/)\n\n### ðŸ“š Academic Definition \n\u003e \&quot;A class should have only one reason to change.\&quot;\n\u003e â€” Robert C. Martin (Uncle Bob)\n\n### ðŸŽ¯ Our Definition \nA class should only do **one thing well** and not be responsible for multiple unrelated concerns.\n\n### ðŸ§‘â€ðŸ’» Simple Definition \nEach class should **focus on a single task** or responsibility. If a class has multiple reasons to change, it likely violates SRP.\n\n---\n\n### ðŸ¾ Paw Patrol Analogy \nThink of **Paw Patrol**:\n- **Chase** handles police duties ðŸš“\n- **Marshall** fights fires ðŸš’\n- **Skye** flies helicopters ðŸš\n\nImagine if Skye had to drive the police car and fight fires tooâ€”it would be **chaotic**! The same applies to software: one class should not do **everything**.\n\n---\n\n### ðŸ§  Key Learnings \n1ï¸âƒ£ **Identify \&quot;Axes of Change\&quot;** â†’ If multiple teams request changes to the same class for different reasons, it's violating SRP.\n2ï¸âƒ£ **Avoid \&quot;God Classes\&quot;** â†’ Large classes handling everything lead to **maintenance nightmares**.\n3ï¸âƒ£ **Encapsulation \u0026 Separation** â†’ Keep concerns **independent** to improve testability and flexibility.\n4ï¸âƒ£ **Avoid Premature Splitting** â†’ If a class is small and cohesive, don't split it **just because**â€”follow **YAGNI** (You Ain't Gonna Need It).\n\n---\n\n### Simple Example (Violating SRP)\n#### Bad Example ðŸš¨: Too Many Responsibilities\n&#96;&#96;&#96;php\nclass ProfileManager {\n    public function authenticateUser(string $username, string $password): bool {\n        // Auth logic here\n    }\n    public function showUserProfile(string $username): UserProfile {\n        // Display user profile logic\n    }\n    public function updateUserProfile(string $username, array $data): UserProfile {\n        // Update logic\n    }\n    public function setUserPermissions(string $username, array $permissions): void {\n        // Set permissions logic\n    }\n}\n&#96;&#96;&#96;\nðŸ”´ **Why is this bad?**\n- Mixed responsibilities: Authentication, Profile Display, Profile Update, and Permissions **should not** be in one class. \n\n**Scenario**:  \n- HR wants new fields for user profiles.  \n- IT wants multi-factor authentication.  \n\nBoth modifications collide in a single class.\n\nâœ… **Fixed Version**\n&#96;&#96;&#96;php\nclass AuthenticationService {\n    public function authenticateUser(string $username, string $password): bool {\n        // Authentication logic\n    }\n}\n\nclass UserProfileService {\n    public function showUserProfile(string $username): UserProfile {\n        // Fetch user profile\n    }\n    public function updateUserProfile(string $username, array $data): UserProfile {\n        // Update user profile\n    }\n}\n\nclass PermissionService {\n    public function setUserPermissions(string $username, array $permissions): void {\n        // Set user permissions\n    }\n}\n&#96;&#96;&#96;\nâœ… **Now, each class has only one responsibility!** \n\nAnd each domain can now evolves independently, so this is often not just a technical decision, but also an organizational one.\n\n---\n\n### ðŸ›’ E-Commerce Example \nImagine an **OrderProcessor** handling:\n- Payment processing\n- Shipping details\n- Generating invoices\n\nðŸš¨ **Bad Example**\n&#96;&#96;&#96;php\nclass OrderProcessor {\n    public function processPayment(PaymentDetails $payment): bool { /* Payment logic */ }\n    public function generateInvoice(Order $order): Invoice { /* Invoice logic */ }\n    public function arrangeShipping(Order $order): void { /* Shipping logic */ }\n}\n&#96;&#96;&#96;\nðŸ”´ **Why is this bad?**\n- If shipping logic changes, you need to modify OrderProcessor.\n- If invoicing logic changes, same problem!\n\nâœ… **Fixed Version**\n&#96;&#96;&#96;php\nclass PaymentService {\n    public function processPayment(PaymentDetails $payment): bool { /* Payment logic */ }\n}\n\nclass InvoiceService {\n    public function generateInvoice(Order $order): Invoice { /* Invoice logic */ }\n}\n\nclass ShippingService {\n    public function arrangeShipping(Order $order): void { /* Shipping logic */ }\n}\n&#96;&#96;&#96;\nâœ… **Each service has one responsibility!**\n\n---\n\n### ðŸ“Œ Advanced Insights ðŸš€\n- **Cohesion vs. Fragmentation** â†’ Don't split classes **too much**. Keep things **cohesive**.\n- **Testability** â†’ Small, single-responsibility classes are easier to **unit test**.\n- **Microservices \u0026 Modular Design** â†’ SRP is key in both microservices and modular monoliths.\n- **Database Layer** â†’ If you see **fat repositories**, it might be a sign of SRP violation.\n\n---\n\n### âš–ï¸ Trade-offs \nâœ… **Pros:**\n- Easier maintenance\n- Better testability\n- More flexibility for future changes\n\nâŒ **Cons:**\n- Can introduce **too many** small classes if overused\n- Might feel like \&quot;over-engineering\&quot; for small projects\n\n---\n\n### ðŸ’¡ Developer Hints \nâœ… **Ask yourself:** \&quot;Does this class have more than one reason to change?\&quot; If yes â†’ **SRP violation!**\nâœ… **Refactor when needed** â†’ If a class is too big, break it **only when necessary**.\nâœ… **Think in modules** â†’ Group related logic in separate **services**.\n\n---\n\n### ðŸ Conclusion\nThe **Single Responsibility Principle** is a fundamental but often misused principle. It's about **finding the right balance** between **cohesion** and **separation**. When applied correctly, it leads to **more maintainable**, **testable**, and **scalable** software.\n\nThe key takeaway? **SRP is not about splitting everythingâ€”itâ€&#x2122;s about ensuring a class has a single, well-defined purpose!** ðŸš€\n\n---\n\n## Open-Closed Principle (OCP)\n\n![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dapoj2x076c0yq7dy1o4.png)\n(source: https://trekhleb.dev/blog/2017/solid-principles-around-you/)\n\n### ðŸ“š Academic Definition \n\&quot;Software entities (classes, modules, functions, etc.) should be open for extension but closed for modification.\&quot; â€” Bertrand Meyer\n\n### ðŸŽ¯ Our Definition \nYour code should be designed in a way that allows adding new features **without modifying** the existing, stable code.\n\n### ðŸ“ Simple Definition \nInstead of changing old code every time a new feature is needed, structure your code so that you can extend it **without altering** what already works.\n\n### ðŸ¾ Paw Patrol Analogy \nWhen **Everest** joined the Paw Patrol for snow rescues ðŸ”ï¸, none of the existing pups needed modification. The team was **extended**, not changed.\n\nLikewise, **new features** should be added as **extensions**, not by modifying existing code.\n\n### ðŸ§  Key Learnings \n1ï¸âƒ£ **Open for Extension** â€“ Your code should be designed in a way that allows you to add new functionality without touching the existing logic.\n2ï¸âƒ£ **Closed for Modification** â€“ Existing code should remain unchanged to prevent introducing new bugs.\n3ï¸âƒ£ **Use Abstraction** â€“ Utilize interfaces, abstract classes, or dependency injection to allow new behavior without modifying core logic.\n\n---\n\n### Common Mistake Example âŒ\n&#96;&#96;&#96;php\nclass AreaCalculator {\n    public function calculateTotalArea(array $shapes): float {\n        $totalArea = 0;\n        foreach ($shapes as $shape) {\n            if ($shape instanceof Circle) {\n                $totalArea += pi() * $shape-\u003eradius ** 2;\n            } elseif ($shape instanceof Square) {\n                $totalArea += $shape-\u003esideLength ** 2;\n            }\n        }\n        return $totalArea;\n    }\n}\n&#96;&#96;&#96;\nðŸš¨ **Problem:** Every time a new shape (e.g., &#96;Triangle&#96;) is introduced, this class needs modification, violating OCP.\n\n---\n\n### The Fix âœ…\n#### Using the Strategy Pattern\n&#96;&#96;&#96;php\ninterface Shape {\n    public function calculateArea(): float;\n}\n\nclass Circle implements Shape {\n    public function __construct(private float $radius) {}\n    public function calculateArea(): float {\n        return pi() * $this-\u003eradius ** 2;\n    }\n}\n\nclass Square implements Shape {\n    public function __construct(private float $sideLength) {}\n    public function calculateArea(): float {\n        return $this-\u003esideLength ** 2;\n    }\n}\n\nclass AreaCalculator {\n    public function calculateTotalArea(array $shapes): float {\n        return array_sum(array_map(\n            fn(Shape $shape) =\u003e $shape-\u003ecalculateArea(),\n            $shapes\n        ));\n    }\n}\n&#96;&#96;&#96;\n#### Why is this better?\nâœ… **Open for Extension** â€“ New shapes (e.g., &#96;Triangle&#96;) can be added without modifying &#96;AreaCalculator&#96;.\nâœ… **Closed for Modification** â€“ The core logic stays unchanged.\nâœ… **Encapsulated Behavior** â€“ Each shape class is responsible for its own area calculation.\n\n---\n\n### ðŸ›’ E-Commerce Example \nImagine a payment system where different payment methods need to be supported:\n\n#### Bad Example ðŸš¨\n&#96;&#96;&#96;php\nclass PaymentProcessor {\n    public function processPayment(string $type, float $amount) {\n        if ($type === 'credit_card') {\n            // Process credit card\n        } elseif ($type === 'paypal') {\n            // Process PayPal\n        }\n    }\n}\n&#96;&#96;&#96;\nðŸš¨ **Problem:** Every time a new payment method is added, the class needs modification.\n\n#### Fixed Example âœ…\n&#96;&#96;&#96;php\ninterface PaymentMethod {\n    public function process(float $amount): void;\n}\n\nclass CreditCardPayment implements PaymentMethod {\n    public function process(float $amount): void {\n        // Process credit card\n    }\n}\n\nclass PayPalPayment implements PaymentMethod {\n    public function process(float $amount): void {\n        // Process PayPal\n    }\n}\n\nclass PaymentProcessor {\n    public function __construct(private PaymentMethod $paymentMethod) {}\n    public function process(float $amount): void {\n        $this-\u003epaymentMethod-\u003eprocess($amount);\n    }\n}\n&#96;&#96;&#96;\n#### Benefits ðŸš€\nâœ… Easily extendable â€“ Add new payment methods without modifying existing code.\nâœ… Reduces risk â€“ Core payment logic remains untouched.\nâœ… Improves readability â€“ No complex &#96;if&#96; conditions.\n\n---\n\n### ðŸ“Œ Advanced Insights ðŸš€\n- **Design Patterns**: The **Strategy Pattern** is often used to implement OCP.\n- **Framework Best Practices**: Laravel and Symfony implement OCP through middleware and service providers.\n- **OCP and Testing**: Easier to unit test since components are loosely coupled.\n\n### âš–ï¸ Trade-offs \nâœ… **Pros:**\n- **Flexibility** â€“ OCP reduces modification risks in stable code.\n- **Test Stability** â€“ Existing functionality remains unchanged.\n\nâŒ **Cons:**\n- **More Abstraction** â€“ Using interfaces and dependency injection adds more classes.\n- **Overhead** â€“ If the system will never change, adding interfaces might be unnecessary.\n- **YAGNI (You Arenâ€&#x2122;t Gonna Need It)** â€“ Donâ€&#x2122;t over-engineer if new features are unlikely.\n\n### ðŸ’¡ Developer Hints \nâœ… Use **interfaces and abstract classes** to define extension points.\nâŒ Avoid **modifying stable, tested classes** unless absolutely necessary.\nâœ… Think **long-term scalability** before choosing rigid, hard-coded implementations.\nâŒ If a pattern **adds complexity but solves no problem**, you may not need it.\n\n---\n\n### ðŸ Conclusion \nA well-designed system should be adaptable to **future needs** without forcing developers to modify **working, tested code**. By leveraging **polymorphism, interfaces, and design patterns**, we achieve flexibility while maintaining stability. ðŸš€\n\n---\n\n## Liskov Substitution Principle (LSP) - \&quot;Keep Your Promises\&quot;\n\n![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6fw8atfuyc7tmyc0vvwz.png)\n(source: https://trekhleb.dev/blog/2017/solid-principles-around-you/)\n\n### ðŸ“š Academic Definition \n\u003e **Objects in a program should be replaceable with instances of their subtypes without altering the correctness of the program.**\n\n### ðŸŽ¯ Our Definition \nIf a class (child) extends another class (parent), it should behave in a way that doesnâ€&#x2122;t break expectations set by the parent class. Any subclass should be usable in place of its superclass without unexpected behavior.\n\n### ðŸ“ Simple Definition \nA subclass should respect the promises made by its parent class. If you replace the parent class with a subclass, everything should still work correctly.\n\n---\n\n### ðŸ¾ Paw Patrol Analogy: The Special Snowplow Problem\nImagine the Paw Patrol vehicles. Each pup has their own special ride, but all of them **must be drivable**.\n\nNow imagine if Everestâ€&#x2122;s snowplow **couldnâ€&#x2122;t drive on roads** because it was only built for ice. If a mission required her to drive on a normal road, the system would break because her vehicle doesnâ€&#x2122;t meet the basic expectation of â€œbeing able to drive.â€\n\nThatâ€&#x2122;s an LSP violationâ€”her vehicle is a â€œsubclassâ€ of the general \&quot;Paw Patrol Vehicle,\&quot; but it doesnâ€&#x2122;t fully substitute for it in every situation.\n\n---\n\n### ðŸ§  Key Learnings \n1. **Child classes must respect the contract of their parent classes.**\n2. **Avoid violating expectations**â€”subclasses must behave consistently with their base class.\n3. **If a subclass has to override too much behavior**, it might not truly be a subtype and could indicate a bad inheritance choice.\n4. **LSP helps keep code predictable**â€”it prevents unexpected failures when replacing a base class with a subclass.\n\n---\n\n### Bad Example ðŸš¨: Violating LSP in PHP\n\n&#96;&#96;&#96;php\nclass Bird {\n    public function fly(): string {\n        return \&quot;I am flying!\&quot;;\n    }\n}\n\nclass Penguin extends Bird {\n    public function fly(): string {\n        throw new Exception(\&quot;I can't fly!\&quot;);\n    }\n}\n\nfunction makeBirdFly(Bird $bird) {\n    return $bird-\u003efly();\n}\n\n$penguin = new Penguin();\necho makeBirdFly($penguin); // âŒ Breaks expectation!\n&#96;&#96;&#96;\n\nðŸ”´ **Issue:** &#96;Penguin&#96; extends &#96;Bird&#96;, but it breaks the expectation that all birds can fly.\n\n---\n\n### âœ… Fixed Example: Using Interfaces to Respect LSP\n&#96;&#96;&#96;php\ninterface Bird {\n    public function eat(): string;\n}\n\ninterface FlyingBird extends Bird {\n    public function fly(): string;\n}\n\nclass Sparrow implements FlyingBird {\n    public function eat(): string {\n        return \&quot;I eat seeds.\&quot;;\n    }\n    public function fly(): string {\n        return \&quot;I can fly!\&quot;;\n    }\n}\n\nclass Penguin implements Bird {\n    public function eat(): string {\n        return \&quot;I eat fish.\&quot;;\n    }\n}\n\nfunction observeBird(Bird $bird) {\n    return $bird-\u003eeat();\n}\n\n$sparrow = new Sparrow();\n$penguin = new Penguin();\n\necho observeBird($sparrow); // âœ… Works fine!\necho observeBird($penguin); // âœ… Works fine!\n&#96;&#96;&#96;\n\nðŸŸ¢ **Fix:** Instead of forcing all birds to be able to fly, we separate \&quot;flying\&quot; behavior into a different interface. This way, penguins donâ€&#x2122;t have to pretend they can fly.\n\n---\n\n### ðŸ›’ E-Commerce Example: The Free Shipping Issue\n#### Bad Example ðŸš¨: Breaking the Parent Contract\nImagine an order system where &#96;StandardOrder&#96; has a method &#96;getShippingCost()&#96;. A developer extends it for &#96;FreeShippingOrder&#96; but violates expectations:\n\n&#96;&#96;&#96;php\nclass StandardOrder {\n    public function getShippingCost(): float {\n        return 5.99;\n    }\n}\n\nclass FreeShippingOrder extends StandardOrder {\n    public function getShippingCost(): float {\n        throw new Exception(\&quot;This order has free shipping!\&quot;);\n    }\n}\n\nfunction processOrder(StandardOrder $order) {\n    return \&quot;Shipping Cost: \&quot; . $order-\u003egetShippingCost();\n}\n\n$order = new FreeShippingOrder();\necho processOrder($order); // âŒ Unexpected exception!\n&#96;&#96;&#96;\n\nðŸ”´ **Issue:** &#96;FreeShippingOrder&#96; breaks the contract by throwing an exception instead of returning a valid shipping cost.\n\n#### âœ… Fixed Example: Using a Different Approach\n&#96;&#96;&#96;php\ninterface Order {\n    public function getShippingCost(): float;\n}\n\nclass StandardOrder implements Order {\n    public function getShippingCost(): float {\n        return 5.99;\n    }\n}\n\nclass FreeShippingOrder implements Order {\n    public function getShippingCost(): float {\n        return 0.00;\n    }\n}\n\nfunction processOrder(Order $order) {\n    return \&quot;Shipping Cost: \&quot; . $order-\u003egetShippingCost();\n}\n\n$order = new FreeShippingOrder();\necho processOrder($order); // âœ… Outputs \&quot;Shipping Cost: 0.00\&quot;\n&#96;&#96;&#96;\n\nðŸŸ¢ **Fix:** Instead of forcing &#96;FreeShippingOrder&#96; to inherit from &#96;StandardOrder&#96;, we use an &#96;Order&#96; interface, ensuring all orders can return a shipping cost without surprises.\n\n---\n\n### ðŸ“Œ Advanced Insights ðŸš€\n1. **LSP helps prevent bad inheritance hierarchies.** If you constantly override parent methods in a subclass, consider **composition** over inheritance.\n2. **Use Interfaces to enforce behavior contracts**â€”avoid forcing all child classes into behaviors they donâ€&#x2122;t support.\n3. **LSP violations often indicate design flaws.** If your subclass keeps breaking expectations, your class hierarchy may be wrong.\n4. **Invariance vs Covariance vs Contravariance:** Be mindful of how method parameters and return types evolve in subclasses.\n\n---\n\n### âš–ï¸ Trade-offs \n| âœ… **Pros** | âŒ **Cons** |\n|------------|------------|\n| Ensures subclasses donâ€&#x2122;t break existing code | May lead to extra abstraction layers |\n| Helps catch bad inheritance early | Too many interfaces can lead to complexity |\n| Makes extending systems easier | Sometimes inheritance is still the simpler choice |\n\n---\n\n### ðŸ’¡ Developer Hints \nâœ… **DO:** Use LSP to validate your class hierarchiesâ€”if a subclass must override too many methods, itâ€&#x2122;s likely a bad fit.\n\nâŒ **DONâ€&#x2122;T:** Inherit from a class just to \&quot;reuse\&quot; some methodsâ€”if the behaviors arenâ€&#x2122;t consistent, prefer composition.\n\nâœ… **DO:** Use interfaces and careful method contracts to ensure subclasses behave as expected.\n\nâŒ **DONâ€&#x2122;T:** Assume that \&quot;all X should do Y\&quot;â€”if exceptions exist, rethink your hierarchy.\n\n---\n\n### ðŸ Conclusion\nLiskov Substitution Principle ensures that subclasses can always stand in for their parent class **without surprises**. Itâ€&#x2122;s one of the most overlooked SOLID principles but arguably one of the most important for keeping systems **extendable and predictable**.\n\nUse LSP to validate your class hierarchies. If your subclass **breaks expected behavior**, it's a sign you might need **a different inheritance model or composition instead**. Keep your promises, and your codebase will stay clean and maintainable!\n\n---\n\n## Interface Segregation Principle (ISP)\n\n![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2agpndrjv1t864f2lhjh.png)\n(source: https://trekhleb.dev/blog/2017/solid-principles-around-you/)\n\n### ðŸ“š Academic Definition \n\u003e \&quot;Clients should not be forced to depend on methods they do not use.\&quot;\n\n### ðŸŽ¯ Our Definition \nInterfaces should be focused and granular, ensuring that implementing classes only need to adhere to methods that are relevant to them. This prevents classes from being bloated with unnecessary dependencies and improves code maintainability.\n\n### ðŸ“ Simple Definition \nDon't force a class to implement methods it doesnâ€&#x2122;t need.\n\n### ðŸ¾ Paw Patrol Analogy \nImagine all Paw Patrol pups had to follow the same \&quot;Rescue Operations\&quot; interface. That would mean Skye (the helicopter pup) would have to implement \&quot;Water Cannon Operation\&quot; even though she has no water cannons! Instead, it's better to have separate interfaces: one for fire rescue (Marshall) and one for aerial rescue (Skye). This ensures that each pup only implements the operations they actually perform.\n\n---\n\n### ðŸ§  Key Learnings \nâœ… Interfaces should be **focused** and **cohesive**â€”not overloaded with unrelated methods.\nâœ… Use **multiple small interfaces** instead of **one large interface**.\nâœ… Helps avoid unnecessary dependencies and improves modularity.\nâœ… Reduces the likelihood of implementing empty or throwaway methods.\nâœ… Works well with **Dependency Inversion Principle (DIP)** by defining specific contract expectations.\n\n---\n\n### ðŸ“Œ Advanced Insights ðŸš€\n- **Granular Interfaces â†’ Better Code Maintainability**: By keeping interfaces small, you prevent a ripple effect of unnecessary method changes in unrelated classes.\n- **Avoid Interface Pollution**: Large interfaces force implementing classes to define methods they donâ€&#x2122;t use, leading to bad design and unnecessary complexity.\n- **Natural Extension of SRP**: ISP is like SRP but at the interface levelâ€”ensuring each interface has a single, clear responsibility.\n- **Refactoring Legacy Code**: If you have bloated interfaces, split them into **cohesive, role-based interfaces**.\n- **Multiple Implementations**: You can mix and match smaller interfaces in various ways without forcing unrelated methods onto a class.\n\n---\n\n### Bad Example ðŸš¨: Bloated Interface\n&#96;&#96;&#96;php\ninterface Worker {\n    public function work(): void;\n    public function eat(): void;\n    public function sleep(): void;\n}\n\nclass Robot implements Worker {\n    public function work(): void {\n        echo \&quot;I am working!\&quot;;\n    }\n    public function eat(): void {\n        throw new Exception(\&quot;Robots don't eat!\&quot;);\n    }\n    public function sleep(): void {\n        throw new Exception(\&quot;Robots don't sleep!\&quot;);\n    }\n}\n&#96;&#96;&#96;\nðŸš¨ **Problem:** The &#96;Worker&#96; interface forces &#96;Robot&#96; to implement &#96;eat()&#96; and &#96;sleep()&#96;, which donâ€&#x2122;t make sense.\n\n---\n\n### Good Example: Segregated Interfaces âœ…\n&#96;&#96;&#96;php\ninterface Workable {\n    public function work(): void;\n}\n\ninterface HumanNeeds {\n    public function eat(): void;\n    public function sleep(): void;\n}\n\nclass Robot implements Workable {\n    public function work(): void {\n        echo \&quot;I am working!\&quot;;\n    }\n}\n\nclass HumanWorker implements Workable, HumanNeeds {\n    public function work(): void {\n        echo \&quot;Working hard!\&quot;;\n    }\n    public function eat(): void {\n        echo \&quot;Eating lunch.\&quot;;\n    }\n    public function sleep(): void {\n        echo \&quot;Going to sleep.\&quot;;\n    }\n}\n&#96;&#96;&#96;\nâœ… **Now each class only implements the methods it actually needs!**\n\n---\n\n### ðŸ›’ E-Commerce Example \nImagine you have a large &#96;PaymentProcessor&#96; interface that forces all payment gateways (PayPal, Stripe, Bitcoin) to implement methods like &#96;refund()&#96; and &#96;chargeBack()&#96;, even if some gateways donâ€&#x2122;t support chargebacks.\n\n#### Bad Example ðŸš¨: Bloated Interface  \n&#96;&#96;&#96;php\ninterface PaymentProcessor {\n    public function processPayment(float $amount): void;\n    public function refund(float $amount): void;\n    public function chargeBack(float $amount): void;\n}\n\nclass BitcoinProcessor implements PaymentProcessor {\n    public function processPayment(float $amount): void {\n        echo \&quot;Processing Bitcoin payment.\&quot;;\n    }\n    public function refund(float $amount): void {\n        throw new Exception(\&quot;Bitcoin transactions are irreversible!\&quot;);\n    }\n    public function chargeBack(float $amount): void {\n        throw new Exception(\&quot;Bitcoin has no chargebacks!\&quot;);\n    }\n}\n&#96;&#96;&#96;\nâŒ **Problem:** Bitcoin does not support refunds or chargebacks, yet itâ€&#x2122;s forced to implement these methods.\n\n#### Segregated Interfaces (Good Example) âœ…\n&#96;&#96;&#96;php\ninterface PaymentProcessor {\n    public function processPayment(float $amount): void;\n}\n\ninterface Refundable {\n    public function refund(float $amount): void;\n}\n\ninterface Chargebackable {\n    public function chargeBack(float $amount): void;\n}\n\nclass BitcoinProcessor implements PaymentProcessor {\n    public function processPayment(float $amount): void {\n        echo \&quot;Processing Bitcoin payment.\&quot;;\n    }\n}\n\nclass CreditCardProcessor implements PaymentProcessor, Refundable, Chargebackable {\n    public function processPayment(float $amount): void {\n        echo \&quot;Processing Credit Card payment.\&quot;;\n    }\n    public function refund(float $amount): void {\n        echo \&quot;Processing refund.\&quot;;\n    }\n    public function chargeBack(float $amount): void {\n        echo \&quot;Processing chargeback.\&quot;;\n    }\n}\n&#96;&#96;&#96;\nâœ… **Now, Bitcoin only implements &#96;PaymentProcessor&#96;, and Credit Card processors can add &#96;Refundable&#96; and &#96;Chargebackable&#96;.**\n\n---\n\n### âš–ï¸ Trade-offs \nâœ… **Pros:**\n- Prevents unnecessary dependencies.\n- Improves readability and maintainability.\n- Easier to refactor without breaking implementations.\n- Better aligns with the **Single Responsibility Principle (SRP)**.\n\nâŒ **Cons:**\n- Can lead to **too many** small interfaces.\n- Requires **careful naming** to keep interfaces meaningful.\n- Might **increase boilerplate** in some cases.\n\n---\n\n### ðŸ’¡ Developer Hints \nâœ… **Split interfaces when:**\n- A class is implementing empty methods.\n- A class throws exceptions for methods it doesnâ€&#x2122;t support.\n- A method is only used in **some** implementations but not others.\n\nâœ… **Keep interfaces meaningful:**\n- Don't over-fragment interfaces into tiny, meaningless pieces.\n- A good rule: If **two implementations always share the same methods**, keep them together.\n\nâœ… **Use with Dependency Injection:**\n- Granular interfaces make **Dependency Injection (DI)** much cleaner.\n\n---\n\n### ðŸ Conclusion\nInterface Segregation ensures that interfaces stay clean and meaningful. Instead of bloated, one-size-fits-all contracts, ISP encourages **focused, role-specific interfaces** that keep classes lean and purposeful. By following ISP, you create software that is **modular, easy to extend, and avoids unnecessary coupling**.\n\nBy embracing ISP, your codebase stays **flexible, maintainable, and scalable**â€”just like a well-organized Paw Patrol team! ðŸš€ðŸ¶\n\n---\n\n## Dependency Inversion Principle (DIP)\n\n![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ad1eyh2ilp1exhm9p31d.png)\n(source: https://trekhleb.dev/blog/2017/solid-principles-around-you/)\n\n### ðŸ“š Academic Definition \n\u003e **High-level modules should not depend on low-level modules. Both should depend on abstractions.**\n\u003e\n\u003e **Abstractions should not depend on details. Details should depend on abstractions.**\n\n### ðŸŽ¯ Our Definition \nDIP ensures that **core logic (high-level modules)** does not directly depend on **specific implementations (low-level modules)**. Instead, both depend on a common **interface or abstraction**.\n\n### ðŸ“ Simple Definition\nInstead of hardcoding dependencies, rely on **interfaces** or **dependency injection** to allow for easier maintenance, testing, and swapping implementations.\n\n### ðŸ¾ Paw Patrol Analogy \nImagine **Ryder**, the leader of Paw Patrol, who needs a pup for a rescue mission. Instead of calling **Chase** directly, he calls for a \&quot;Police Pup.\&quot; This allows **Chase** to respond, but if another police dog joins the team, he can step in without changing Ryderâ€&#x2122;s commands.\n\nBy coding to an **abstraction (\&quot;Police Pup\&quot;)** instead of a **concrete implementation (\&quot;Chase\&quot;)**, Ryder ensures flexibility.\n\n---\n\n### ðŸ§  Key Learnings \n1ï¸âƒ£ **High-Level Modules (Core Logic) Should Not Depend on Low-Level Modules (Implementations)**  \n   - Example: An &#96;OrderService&#96; should not directly depend on &#96;MySQLDatabase&#96; but instead on &#96;DatabaseInterface&#96;.\n\n2ï¸âƒ£ **Abstractions Should Not Depend on Details**  \n   - The interface should define behavior, not implementation details.\n\n3ï¸âƒ£ **Use Dependency Injection for Flexibility**  \n   - Instead of creating objects inside a class (&#96;new MySQLDatabase()&#96;), pass them as dependencies (&#96;DatabaseInterface $db&#96;).\n\n4ï¸âƒ£ **Promotes Testing and Maintainability**  \n   - Easily mock dependencies in unit tests by swapping implementations.\n\n---\n\n### Simple Example (Violating DIP)\n#### Bad Example ðŸš¨: Hardcoded Dependency\n&#96;&#96;&#96;php\nclass MySQLDatabase {\n    public function getUser(int $id): string {\n        return \&quot;User data from MySQL\&quot;;\n    }\n}\n\nclass UserService {\n    private MySQLDatabase $database;\n    \n    public function __construct() {\n        $this-\u003edatabase = new MySQLDatabase();\n    }\n    \n    public function getUser(int $id): string {\n        return $this-\u003edatabase-\u003egetUser($id);\n    }\n}\n&#96;&#96;&#96;\nðŸ’¥ **Problem:** If we switch to &#96;PostgreSQLDatabase&#96;, we must modify &#96;UserService&#96;, violating DIP.\n\n---\n\n### The Fix: Applying DIP\n#### âœ… Good Example: Using an Interface\n&#96;&#96;&#96;php\ninterface DatabaseInterface {\n    public function getUser(int $id): string;\n}\n\nclass MySQLDatabase implements DatabaseInterface {\n    public function getUser(int $id): string {\n        return \&quot;User data from MySQL\&quot;;\n    }\n}\n\nclass PostgreSQLDatabase implements DatabaseInterface {\n    public function getUser(int $id): string {\n        return \&quot;User data from PostgreSQL\&quot;;\n    }\n}\n\nclass UserService {\n    private DatabaseInterface $database;\n    \n    public function __construct(DatabaseInterface $database) {\n        $this-\u003edatabase = $database;\n    }\n    \n    public function getUser(int $id): string {\n        return $this-\u003edatabase-\u003egetUser($id);\n    }\n}\n\n// Usage\n$service = new UserService(new MySQLDatabase());\n$service = new UserService(new PostgreSQLDatabase());\n&#96;&#96;&#96;\nâœ… **Now &#96;UserService&#96; does not depend on a specific database but on &#96;DatabaseInterface&#96;**, making it flexible.\n\n---\n\n### ðŸ›’ E-Commerce Example \n#### Bad Example ðŸš¨: Hardcoded Payment Processor\n&#96;&#96;&#96;php\nclass PaymentService {\n    private StripePaymentProcessor $processor;\n    \n    public function __construct() {\n        $this-\u003eprocessor = new StripePaymentProcessor();\n    }\n    \n    public function processPayment(float $amount) {\n        return $this-\u003eprocessor-\u003epay($amount);\n    }\n}\n&#96;&#96;&#96;\nðŸ’¥ **Issue:** Tied to Stripe; hard to replace with PayPal.\n\n#### âœ… Good Example (DIP with Interfaces)\n&#96;&#96;&#96;php\ninterface PaymentProcessor {\n    public function pay(float $amount): bool;\n}\n\nclass StripePaymentProcessor implements PaymentProcessor {\n    public function pay(float $amount): bool {\n        return true; // Process payment via Stripe\n    }\n}\n\nclass PayPalPaymentProcessor implements PaymentProcessor {\n    public function pay(float $amount): bool {\n        return true; // Process payment via PayPal\n    }\n}\n\nclass PaymentService {\n    private PaymentProcessor $processor;\n    \n    public function __construct(PaymentProcessor $processor) {\n        $this-\u003eprocessor = $processor;\n    }\n    \n    public function processPayment(float $amount) {\n        return $this-\u003eprocessor-\u003epay($amount);\n    }\n}\n\n// Usage\n$paymentService = new PaymentService(new StripePaymentProcessor());\n$paymentService = new PaymentService(new PayPalPaymentProcessor());\n&#96;&#96;&#96;\nâœ… Now the service works with **any** payment processor.\n\n---\n\n### ðŸ“Œ Advanced Insights ðŸš€\nâœ… **IoC Containers (Dependency Injection Containers)**  \nModern frameworks (Laravel, Symfony) use IoC containers to **bind interfaces to implementations**, automating dependency resolution.\n&#96;&#96;&#96;php\n$container-\u003ebind(PaymentProcessor::class, StripePaymentProcessor::class);\n$paymentService = $container-\u003emake(PaymentService::class);\n&#96;&#96;&#96;\n\nâœ… **Easier Unit Testing**  \nBy injecting dependencies, you can mock them in tests:\n&#96;&#96;&#96;php\n$mockProcessor = $this-\u003ecreateMock(PaymentProcessor::class);\n$mockProcessor-\u003emethod('pay')-\u003ewillReturn(true);\n$service = new PaymentService($mockProcessor);\n$this-\u003eassertTrue($service-\u003eprocessPayment(100));\n&#96;&#96;&#96;\n\n---\n\n### âš–ï¸ Trade-offs \n1ï¸âƒ£ **Over-Abstraction**: Too many interfaces can complicate simple cases.\n2ï¸âƒ£ **Initial Setup Overhead**: More upfront work vs. hardcoding dependencies.\n3ï¸âƒ£ **Not Always Needed**: Small scripts may not benefit from DIP.\n4ï¸âƒ£ **Performance**: Extra layers add slight performance costs.\n\n---\n\n### ðŸ’¡ Developer Hints \nðŸš€ **Use interfaces when multiple implementations are possible.**\nðŸ›  **If a dependency rarely changes, DIP might be unnecessary overhead.**\nðŸ”„ **Combine with IoC containers for better dependency management.**\n\n---\n\n### ðŸ Conclusion\nDIP helps create flexible, scalable, and testable code. While overusing it can lead to unnecessary complexity, applying it where appropriate **ensures long-term maintainability and adaptability**.\n\n---\n\n**Learnings and Findings from the Blog Post**\n\n---\n\n## **The Essence of SOLID Beyond Textbook Definitions**\n\nWe have consistently moved beyond simply memorizing the SOLID principles. Instead, we have deeply examined their real-world applications, trade-offs, and potential misuses. The key insight is that SOLID is not a rigid framework but a set of guiding principles that, when applied pragmatically, result in **maintainable, flexible, and understandable** software.\n\n### **What We Learned:**\n1ï¸âƒ£ SOLID **is a means, not an end**â€”it should improve software, not be followed blindly.\n2ï¸âƒ£ Principles should **evolve naturally** with software needs rather than being enforced prematurely.\n3ï¸âƒ£ **Balance is key**: applying SOLID too rigidly can introduce unnecessary complexity, while ignoring it leads to unmanageable abstractions.\n4ï¸âƒ£ Naming and categorization of abstract concepts help communicate intent and keep teams aligned.\n\n---\n\n### ðŸ”„ **SOLID Principles Recap**\nEach principle is a tool to write better, maintainable, and scalable software. While following them strictly isnâ€&#x2122;t always necessary, understanding them deeply allows you to make informed trade-offs when designing software.\n\n#### 1ï¸âƒ£ **Single Responsibility Principle** (SRP)\nðŸ“Œ **Rule**: A class should only have one reason to change.\nâœ… **Benefit**: Reduces complexity and improves maintainability.\nâš ï¸ **Pitfall**: Over-applying SRP can create too many small classes.\n\n#### 2ï¸âƒ£ **Open-Closed Principle** (OCP)\nðŸ“Œ **Rule**: Code should be open for extension but closed for modification.\nâœ… **Benefit**: Prevents modifying stable, tested code when adding new features.\nâš ï¸ **Pitfall**: Over-abstraction can make code difficult to understand.\n\n#### 3ï¸âƒ£ **Liskov Substitution Principle** (LSP)\nðŸ“Œ **Rule**: Subtypes must be substitutable for their base types.\nâœ… **Benefit**: Ensures a predictable, bug-free inheritance structure.\nâš ï¸ **Pitfall**: Violations often happen when child classes break parent contracts.\n\n#### 4ï¸âƒ£ **Interface Segregation Principle** (ISP)\nðŸ“Œ **Rule**: No class should be forced to depend on methods it does not use.\nâœ… **Benefit**: Creates leaner, more reusable interfaces.\nâš ï¸ **Pitfall**: Too many interfaces can create confusion or interface bloat.\n\n#### 5ï¸âƒ£ **Dependency Inversion Principle** (DIP)\nðŸ“Œ **Rule**: Depend on abstractions, not concrete implementations.\nâœ… **Benefit**: Encourages decoupled, flexible, and testable code.\nâš ï¸ **Pitfall**: Overuse can lead to too many indirections, making debugging harder.\n\n---\n\n## **Abstractions: When to Generalize and When to Copy-Paste**\n\n![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ldgeihlz2loa3hbsx9if.png)\n(source: https://www.reddit.com/r/Design/comments/6qh8ni/the_abstractometer/)\n\nThe Abstract-o-Meter reminds us that effective software design lies in finding the balance between clarity and usability. Every abstraction should:\n* Hide unnecessary details, making systems easier to understand.\n* Preserve essential clarity, ensuring they remain relevant to the real-world domain.\n\nWhether youâ€&#x2122;re designing a small utility class or architecting a large-scale system, always aim for the heart in the middle of the Abstract-o-Meter. This is the area where your abstractions remain meaningful, useful and maintainable, and only then will other developers actually use them.\n\nOne of the most significant learning is about **the right time to introduce abstractions** versus when copy-pasting is actually preferable. The classic fear of duplication (\&quot;DRY principle\&quot;) must be balanced with **avoiding premature abstractions** that introduce unnecessary coupling and complexity.\n\n### **Key Takeaways:**\n1ï¸âƒ£ **Duplication is often cheaper** than the wrong abstraction.\n2ï¸âƒ£ Generalization should be based on **real-world observed repetition**, not speculative future needs.\n3ï¸âƒ£ Over-abstraction leads to **hard-to-read, bloated code** where understanding business rules requires digging through multiple indirections.\n4ï¸âƒ£ High **cohesion and minimal dependencies** should be prioritized when designing abstractions.\n\n#### **Pragmatic Rule of Thumb:**\n- First occurrence? **Write it.**\n- Second occurrence? **Copy it.**\n- Third occurrence? **Consider abstractionâ€”but validate first.**\n\n---\n\n## **Naming and Conceptual Thinking: The \&quot;Front Garden\&quot; and \&quot;Neighborhood\&quot; Metaphors**\n\nWe explored how defining abstract **conceptual names** improves communication. The **Front Garden** and **Neighborhood** analogy illustrated the power of naming in programming and software architecture:\n- By naming **broad categories of problems**, we create **reusable mental models** that allow easier discussions.\n- Instead of explaining every case separately, we can **define an abstract concept** (like \&quot;OCP Violation\&quot; or \&quot;Front Garden Boundary\&quot;) and use it as shorthand.\n- **Rules should be flexible principles**, not rigid constraintsâ€”much like in software, where strict application of SOLID without context leads to over-engineering.\n\n---\n\n## **The \&quot;SOLID but Practical\&quot; Mindset: Knowing When to Bend the Rules**\n\nThroughout our discussions, a recurring theme was **pragmatism over dogma**. Many developers apply SOLID too rigidly, causing unnecessary complexity. The real mastery lies in knowing when to **intentionally** bend or break the rules **for the right reasons**.\n\n### **Key Lessons:**\n- **SRP (Single Responsibility Principle)**: Some responsibilities can be combined if they always change together.\n- **OCP (Open-Closed Principle)**: Sometimes modifying a class is more maintainable than excessive abstractions.\n- **LSP (Liskov Substitution Principle)**: If a subclass needs excessive modifications, reconsider the inheritance structure.\n- **ISP (Interface Segregation Principle)**: Avoid creating too many interfaces that fragment business logic.\n- **DIP (Dependency Inversion Principle)**: Use abstractions but avoid forcing yourself to abstract every dependency.\n\n---\n\n## **Final Thought: The \&quot;Future-Proof\&quot; Developer Mindset**\n\n- **Principles exist to serve the software, not the other way around.**\n- **Code should evolve naturally**, following real needs instead of speculative complexity.\n- **Naming is critical**, not just for variables but for abstract concepts that help us discuss software design effectively.\n- **Abstractions are a tool**, not a requirementâ€”sometimes, copy-pasting is the best decision.\n- **Balance pragmatism with best practices**, and donâ€&#x2122;t fear breaking SOLID rules **if it makes the code better**.\n\nBy combining **deep technical knowledge** with **practical experience**, we can write software that is both maintainable and efficientâ€”without falling into the traps of over-engineering or unnecessary complexity. Happy coding!\n\n\n\n\n&quot;,&quot;organization_id&quot;:null,&quot;canonical_url&quot;:null,&quot;cached_tag_list&quot;:&quot;programming, softwaredevelopment, php, coding&quot;,&quot;series&quot;:null,&quot;all_series&quot;:[]}" data-organizations="[]" data-version="v1" data-site-logo="&lt;a href=&quot;/&quot; class=&quot;site-logo&quot; aria-label=&quot;DEV Community Home&quot;&gt;
    &lt;img class=&quot;site-logo__img&quot;
         src=&quot;https://media2.dev.to/dynamic/image/quality=100/https://dev-to-uploads.s3.amazonaws.com/uploads/logos/resized_logo_UQww2soKuUsjaOGNB38o.png&quot;
         style=&quot;aspect-ratio: 10 / 8&quot;
         alt=&quot;DEV Community&quot;&gt;
&lt;/a&gt;
" data-cover-image-height="420" data-cover-image-crop="crop" data-scheduling-enabled="true"><form id="article-form" class="crayons-article-form" aria-label="Edit post">
<div class="crayons-article-form__content crayons-card">
<article class="crayons-article">
<div class="crayons-article__main">
<div class="crayons-article__body text-styles">
<p>TheÂ <strong>SOLID</strong>Â principles are essential guidelines for writing clean, maintainable, and scalable software. While many developers can recite them, real-world applications often struggle with their correct implementation.</p>
<p>Understanding SOLID is not just about memorizing definitions; it&#8217;s about knowing when and how to apply them effectively. Sometimes, following the rules strictly can lead to unnecessary complexity, while a pragmatic approach ensures maintainability without over-engineering.</p>
<p>In this guide, we will break down each principle with practicalÂ <strong>PHP examples</strong>,Â <strong>Paw Patrol analogies</strong>Â for clarity, andÂ <strong>trade-offs</strong>Â to consider. By the end, youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ll have a solid understanding of how these principles work together and when it&#8217;s okay to bend them for the greater good.</p>
<hr />
<h2><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#the-front-garden-amp-neighborhood-metaphor-why-naming-principles-matter" name="the-front-garden-amp-neighborhood-metaphor-why-naming-principles-matter"></a>ðŸ¡ The &#8220;Front Garden&#8221; &amp; &#8220;Neighborhood&#8221; Metaphor: Why Naming Principles Matter</h2>
<p>Imagine you donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t even know what â€œneighborâ€ or â€œfront gardenâ€ means. Someone tries to explain that you shouldnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t walk through someone elseâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s garden, so they define these terms and create a rule. But that rule would be rigid and limiting.</p>
<p>Instead, we define a broad principle that covers many similar scenarios, giving it a name so others immediately understand what we mean. This flexibility allows us to apply it beyond just neighbors and gardens while recognizing exceptionsâ€”like if the garden is yours or thereâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s an emergency.</p>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#how-this-relates-to-solid" name="how-this-relates-to-solid"></a>How This Relates to SOLID</h3>
<p>Similarly, SOLID is a set of abstract principles that define boundaries in object-oriented code. By naming these boundaries (SRP, OCP, LSP, ISP, DIP), we gain:</p>
<p>1ï¸âƒ£Â <strong>Efficient Communication</strong>Â â€“ We can say, â€œWeâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re violating OCP,â€ instead of explaining, â€œWe keep re-editing stable code to add new features.â€</p>
<p>2ï¸âƒ£Â <strong>Unified Understanding</strong>Â â€“ Whether human developers or AI-powered coding assistants, everyone recognizes the same underlying problem without a lengthy breakdown.</p>
<p>3ï¸âƒ£Â <strong>Flexible Exceptions</strong>Â â€“ Sometimes, crossing that fence is practical (if itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s your own â€œgardenâ€) or necessary (in an emergency).</p>
<p>Knowing these principles allows developers to makeÂ <strong>intentional trade-offs</strong>, rather than blindly applying or ignoring them.</p>
<hr />
<h2><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#how-to-apply-solid-without-overengineering" name="how-to-apply-solid-without-overengineering"></a>ðŸ§  How to Apply SOLID Without Over-Engineering</h2>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#apply-solid-as-needed-not-as-a-dogma" name="apply-solid-as-needed-not-as-a-dogma"></a>1ï¸âƒ£ Apply SOLID as Needed, Not as a Dogma</h3>
<ul>
<li>If a class is simple &amp; works, donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t force an interface just to follow DIP.</li>
<li>If a method is naturally cohesive, donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t split it just to follow SRP.</li>
<li>If an interface is only used once, donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t extract it just for ISP.</li>
<li><strong>Code should be SOLID but also simple.</strong></li>
</ul>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#focus-on-refactoring-not-preemptive-complexity" name="focus-on-refactoring-not-preemptive-complexity"></a>2ï¸âƒ£ Focus on Refactoring, Not Preemptive Complexity</h3>
<ul>
<li>Refactor SOLID in stepsÂ <strong>when a problem arises</strong>.</li>
<li>Donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t create an abstraction untilÂ <strong>you actually need it</strong>.</li>
</ul>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#use-the-8020-rule" name="use-the-8020-rule"></a>3ï¸âƒ£ Use the 80/20 Rule</h3>
<ul>
<li><strong>80%</strong>Â of your code should be pragmatic andÂ <strong>only 20%</strong>Â should be deeply abstracted for maintainability.</li>
</ul>
<p>ðŸ’¡Â <strong>Example:</strong></p>
<ul>
<li>AnÂ <strong>order processing system</strong>Â needs flexibility (<strong>high SOLID compliance</strong>).</li>
<li>AÂ <strong>CLI script that runs once a year</strong>? No need for extreme abstractions.</li>
</ul>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#know-when-to-break-the-rules-intentionally" name="know-when-to-break-the-rules-intentionally"></a>4ï¸âƒ£ Know When to Break the Rules (Intentionally)</h3>
<ul>
<li>Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s okay toÂ <strong>violate SRP</strong>Â if it keeps your code readable and practical.</li>
<li>SometimesÂ <strong>direct dependencies (instead of DIP)</strong>Â make sense for small projects.</li>
<li>Some classes might benefit from breakingÂ <strong>OCP</strong>Â if modifying them improves clarity.</li>
</ul>
<p>By the end of this guide, youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />llÂ <strong>not only understand SOLID</strong>Â but alsoÂ <strong>when to apply it pragmatically</strong>â€”allowing your architecture to evolve gracefully without unnecessary complexity.</p>
<hr />
<h2><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#single-responsibility-principle-srp" name="single-responsibility-principle-srp"></a>Single Responsibility Principle (SRP)</h2>
<p><a class="article-body-image-wrapper" href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzlby1sbe8xgmna1tazv0.png"><img decoding="async" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzlby1sbe8xgmna1tazv0.png" alt="Image description" /></a><br />(source:Â <a href="https://trekhleb.dev/blog/2017/solid-principles-around-you/" target="_blank" rel="noopener noreferrer">https://trekhleb.dev/blog/2017/solid-principles-around-you/</a>)</p>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#academic-definition" name="academic-definition"></a>ðŸ“š Academic Definition</h3>
<blockquote>
<p>&#8220;A class should have only one reason to change.&#8221;<br />â€” Robert C. Martin (Uncle Bob)</p>
</blockquote>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#our-definition" name="our-definition"></a>ðŸŽ¯ Our Definition</h3>
<p>A class should only doÂ <strong>one thing well</strong>Â and not be responsible for multiple unrelated concerns.</p>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#simple-definition" name="simple-definition"></a>ðŸ§‘â€ðŸ’» Simple Definition</h3>
<p>Each class shouldÂ <strong>focus on a single task</strong>Â or responsibility. If a class has multiple reasons to change, it likely violates SRP.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#paw-patrol-analogy" name="paw-patrol-analogy"></a>ðŸ¾ Paw Patrol Analogy</h3>
<p>Think ofÂ <strong>Paw Patrol</strong>:</p>
<ul>
<li><strong>Chase</strong>Â handles police duties ðŸš“</li>
<li><strong>Marshall</strong>Â fights fires ðŸš’</li>
<li><strong>Skye</strong>Â flies helicopters ðŸš</li>
</ul>
<p>Imagine if Skye had to drive the police car and fight fires tooâ€”it would beÂ <strong>chaotic</strong>! The same applies to software: one class should not doÂ <strong>everything</strong>.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#key-learnings" name="key-learnings"></a>ðŸ§  Key Learnings</h3>
<p>1ï¸âƒ£Â <strong>Identify &#8220;Axes of Change&#8221;</strong>Â â†’ If multiple teams request changes to the same class for different reasons, it&#8217;s violating SRP.<br />2ï¸âƒ£Â <strong>Avoid &#8220;God Classes&#8221;</strong>Â â†’ Large classes handling everything lead toÂ <strong>maintenance nightmares</strong>.<br />3ï¸âƒ£Â <strong>Encapsulation &amp; Separation</strong>Â â†’ Keep concernsÂ <strong>independent</strong>Â to improve testability and flexibility.<br />4ï¸âƒ£Â <strong>Avoid Premature Splitting</strong>Â â†’ If a class is small and cohesive, don&#8217;t split itÂ <strong>just because</strong>â€”followÂ <strong>YAGNI</strong>Â (You Ain&#8217;t Gonna Need It).</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#simple-example-violating-srp" name="simple-example-violating-srp"></a>Simple Example (Violating SRP)</h3>
<h4><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#bad-example-too-many-responsibilities" name="bad-example-too-many-responsibilities"></a>Bad Example ðŸš¨: Too Many Responsibilities</h4>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="kd">class</span> <span class="nc">ProfileManager</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">authenticateUser</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$username</span><span class="p">,</span> <span class="kt">string</span> <span class="nv">$password</span><span class="p">):</span> <span class="kt">bool</span> <span class="p">{</span>
        <span class="c1">// Auth logic here</span>
    <span class="p">}</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">showUserProfile</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$username</span><span class="p">):</span> <span class="kt">UserProfile</span> <span class="p">{</span>
        <span class="c1">// Display user profile logic</span>
    <span class="p">}</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">updateUserProfile</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$username</span><span class="p">,</span> <span class="kt">array</span> <span class="nv">$data</span><span class="p">):</span> <span class="kt">UserProfile</span> <span class="p">{</span>
        <span class="c1">// Update logic</span>
    <span class="p">}</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">setUserPermissions</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$username</span><span class="p">,</span> <span class="kt">array</span> <span class="nv">$permissions</span><span class="p">):</span> <span class="kt">void</span> <span class="p">{</span>
        <span class="c1">// Set permissions logic</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">Â </div>
</div>
</div>
<p>ðŸ”´Â <strong>Why is this bad?</strong></p>
<ul>
<li>Mixed responsibilities: Authentication, Profile Display, Profile Update, and PermissionsÂ <strong>should not</strong>Â be in one class.</li>
</ul>
<p><strong>Scenario</strong>:</p>
<ul>
<li>HR wants new fields for user profiles.</li>
<li>IT wants multi-factor authentication.</li>
</ul>
<p>Both modifications collide in a single class.</p>
<p>âœ…Â <strong>Fixed Version</strong></p>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="kd">class</span> <span class="nc">AuthenticationService</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">authenticateUser</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$username</span><span class="p">,</span> <span class="kt">string</span> <span class="nv">$password</span><span class="p">):</span> <span class="kt">bool</span> <span class="p">{</span>
        <span class="c1">// Authentication logic</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">UserProfileService</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">showUserProfile</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$username</span><span class="p">):</span> <span class="kt">UserProfile</span> <span class="p">{</span>
        <span class="c1">// Fetch user profile</span>
    <span class="p">}</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">updateUserProfile</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$username</span><span class="p">,</span> <span class="kt">array</span> <span class="nv">$data</span><span class="p">):</span> <span class="kt">UserProfile</span> <span class="p">{</span>
        <span class="c1">// Update user profile</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">PermissionService</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">setUserPermissions</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$username</span><span class="p">,</span> <span class="kt">array</span> <span class="nv">$permissions</span><span class="p">):</span> <span class="kt">void</span> <span class="p">{</span>
        <span class="c1">// Set user permissions</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">Â </div>
</div>
</div>
<p>âœ…Â <strong>Now, each class has only one responsibility!</strong></p>
<p>And each domain can now evolves independently, so this is often not just a technical decision, but also an organizational one.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#ecommerce-example" name="ecommerce-example"></a>ðŸ›’ E-Commerce Example</h3>
<p>Imagine anÂ <strong>OrderProcessor</strong>Â handling:</p>
<ul>
<li>Payment processing</li>
<li>Shipping details</li>
<li>Generating invoices</li>
</ul>
<p>ðŸš¨Â <strong>Bad Example</strong></p>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="kd">class</span> <span class="nc">OrderProcessor</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">processPayment</span><span class="p">(</span><span class="kt">PaymentDetails</span> <span class="nv">$payment</span><span class="p">):</span> <span class="kt">bool</span> <span class="p">{</span> <span class="cm">/* Payment logic */</span> <span class="p">}</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">generateInvoice</span><span class="p">(</span><span class="kt">Order</span> <span class="nv">$order</span><span class="p">):</span> <span class="kt">Invoice</span> <span class="p">{</span> <span class="cm">/* Invoice logic */</span> <span class="p">}</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">arrangeShipping</span><span class="p">(</span><span class="kt">Order</span> <span class="nv">$order</span><span class="p">):</span> <span class="kt">void</span> <span class="p">{</span> <span class="cm">/* Shipping logic */</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">Â </div>
</div>
</div>
<p>ðŸ”´Â <strong>Why is this bad?</strong></p>
<ul>
<li>If shipping logic changes, you need to modify OrderProcessor.</li>
<li>If invoicing logic changes, same problem!</li>
</ul>
<p>âœ…Â <strong>Fixed Version</strong></p>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="kd">class</span> <span class="nc">PaymentService</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">processPayment</span><span class="p">(</span><span class="kt">PaymentDetails</span> <span class="nv">$payment</span><span class="p">):</span> <span class="kt">bool</span> <span class="p">{</span> <span class="cm">/* Payment logic */</span> <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">InvoiceService</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">generateInvoice</span><span class="p">(</span><span class="kt">Order</span> <span class="nv">$order</span><span class="p">):</span> <span class="kt">Invoice</span> <span class="p">{</span> <span class="cm">/* Invoice logic */</span> <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">ShippingService</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">arrangeShipping</span><span class="p">(</span><span class="kt">Order</span> <span class="nv">$order</span><span class="p">):</span> <span class="kt">void</span> <span class="p">{</span> <span class="cm">/* Shipping logic */</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">Â </div>
</div>
</div>
<p>âœ…Â <strong>Each service has one responsibility!</strong></p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#advanced-insights" name="advanced-insights"></a>ðŸ“Œ Advanced Insights ðŸš€</h3>
<ul>
<li><strong>Cohesion vs. Fragmentation</strong>Â â†’ Don&#8217;t split classesÂ <strong>too much</strong>. Keep thingsÂ <strong>cohesive</strong>.</li>
<li><strong>Testability</strong>Â â†’ Small, single-responsibility classes are easier toÂ <strong>unit test</strong>.</li>
<li><strong>Microservices &amp; Modular Design</strong>Â â†’ SRP is key in both microservices and modular monoliths.</li>
<li><strong>Database Layer</strong>Â â†’ If you seeÂ <strong>fat repositories</strong>, it might be a sign of SRP violation.</li>
</ul>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#tradeoffs" name="tradeoffs"></a>âš–ï¸ Trade-offs</h3>
<p>âœ…Â <strong>Pros:</strong></p>
<ul>
<li>Easier maintenance</li>
<li>Better testability</li>
<li>More flexibility for future changes</li>
</ul>
<p>âŒÂ <strong>Cons:</strong></p>
<ul>
<li>Can introduceÂ <strong>too many</strong>Â small classes if overused</li>
<li>Might feel like &#8220;over-engineering&#8221; for small projects</li>
</ul>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#developer-hints" name="developer-hints"></a>ðŸ’¡ Developer Hints</h3>
<p>âœ…Â <strong>Ask yourself:</strong>Â &#8220;Does this class have more than one reason to change?&#8221; If yes â†’Â <strong>SRP violation!</strong><br />âœ…Â <strong>Refactor when needed</strong>Â â†’ If a class is too big, break itÂ <strong>only when necessary</strong>.<br />âœ…Â <strong>Think in modules</strong>Â â†’ Group related logic in separateÂ <strong>services</strong>.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#conclusion" name="conclusion"></a>ðŸ Conclusion</h3>
<p>TheÂ <strong>Single Responsibility Principle</strong>Â is a fundamental but often misused principle. It&#8217;s aboutÂ <strong>finding the right balance</strong>Â betweenÂ <strong>cohesion</strong>Â andÂ <strong>separation</strong>. When applied correctly, it leads toÂ <strong>more maintainable</strong>,Â <strong>testable</strong>, andÂ <strong>scalable</strong>Â software.</p>
<p>The key takeaway?Â <strong>SRP is not about splitting everythingâ€”itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s about ensuring a class has a single, well-defined purpose!</strong>Â ðŸš€</p>
<hr />
<h2><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#openclosed-principle-ocp" name="openclosed-principle-ocp"></a>Open-Closed Principle (OCP)</h2>
<p><a class="article-body-image-wrapper" href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdapoj2x076c0yq7dy1o4.png"><img decoding="async" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdapoj2x076c0yq7dy1o4.png" alt="Image description" /></a><br />(source:Â <a href="https://trekhleb.dev/blog/2017/solid-principles-around-you/" target="_blank" rel="noopener noreferrer">https://trekhleb.dev/blog/2017/solid-principles-around-you/</a>)</p>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#academic-definition" name="academic-definition"></a>ðŸ“š Academic Definition</h3>
<p>&#8220;Software entities (classes, modules, functions, etc.) should be open for extension but closed for modification.&#8221; â€” Bertrand Meyer</p>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#our-definition" name="our-definition"></a>ðŸŽ¯ Our Definition</h3>
<p>Your code should be designed in a way that allows adding new featuresÂ <strong>without modifying</strong>Â the existing, stable code.</p>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#simple-definition" name="simple-definition"></a>ðŸ“ Simple Definition</h3>
<p>Instead of changing old code every time a new feature is needed, structure your code so that you can extend itÂ <strong>without altering</strong>Â what already works.</p>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#paw-patrol-analogy" name="paw-patrol-analogy"></a>ðŸ¾ Paw Patrol Analogy</h3>
<p>WhenÂ <strong>Everest</strong>Â joined the Paw Patrol for snow rescues ðŸ”ï¸, none of the existing pups needed modification. The team wasÂ <strong>extended</strong>, not changed.</p>
<p>Likewise,Â <strong>new features</strong>Â should be added asÂ <strong>extensions</strong>, not by modifying existing code.</p>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#key-learnings" name="key-learnings"></a>ðŸ§  Key Learnings</h3>
<p>1ï¸âƒ£Â <strong>Open for Extension</strong>Â â€“ Your code should be designed in a way that allows you to add new functionality without touching the existing logic.<br />2ï¸âƒ£Â <strong>Closed for Modification</strong>Â â€“ Existing code should remain unchanged to prevent introducing new bugs.<br />3ï¸âƒ£Â <strong>Use Abstraction</strong>Â â€“ Utilize interfaces, abstract classes, or dependency injection to allow new behavior without modifying core logic.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#common-mistake-example" name="common-mistake-example"></a>Common Mistake Example âŒ</h3>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="kd">class</span> <span class="nc">AreaCalculator</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">calculateTotalArea</span><span class="p">(</span><span class="kt">array</span> <span class="nv">$shapes</span><span class="p">):</span> <span class="kt">float</span> <span class="p">{</span>
        <span class="nv">$totalArea</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
        <span class="k">foreach</span> <span class="p">(</span><span class="nv">$shapes</span> <span class="k">as</span> <span class="nv">$shape</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="nv">$shape</span> <span class="k">instanceof</span> <span class="nc">Circle</span><span class="p">)</span> <span class="p">{</span>
                <span class="nv">$totalArea</span> <span class="o">+=</span> <span class="nb">pi</span><span class="p">()</span> <span class="o">*</span> <span class="nv">$shape</span><span class="o">-&gt;</span><span class="n">radius</span> <span class="o">**</span> <span class="mi">2</span><span class="p">;</span>
            <span class="p">}</span> <span class="k">elseif</span> <span class="p">(</span><span class="nv">$shape</span> <span class="k">instanceof</span> <span class="nc">Square</span><span class="p">)</span> <span class="p">{</span>
                <span class="nv">$totalArea</span> <span class="o">+=</span> <span class="nv">$shape</span><span class="o">-&gt;</span><span class="n">sideLength</span> <span class="o">**</span> <span class="mi">2</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">}</span>
        <span class="k">return</span> <span class="nv">$totalArea</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">Â </div>
</div>
</div>
<p>ðŸš¨Â <strong>Problem:</strong>Â Every time a new shape (e.g.,Â <code>Triangle</code>) is introduced, this class needs modification, violating OCP.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#the-fix" name="the-fix"></a>The Fix âœ…</h3>
<h4><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#using-the-strategy-pattern" name="using-the-strategy-pattern"></a>Using the Strategy Pattern</h4>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="kd">interface</span> <span class="nc">Shape</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">calculateArea</span><span class="p">():</span> <span class="kt">float</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">Circle</span> <span class="kd">implements</span> <span class="nc">Shape</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="k">private</span> <span class="kt">float</span> <span class="nv">$radius</span><span class="p">)</span> <span class="p">{}</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">calculateArea</span><span class="p">():</span> <span class="kt">float</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nb">pi</span><span class="p">()</span> <span class="o">*</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">radius</span> <span class="o">**</span> <span class="mi">2</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">Square</span> <span class="kd">implements</span> <span class="nc">Shape</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="k">private</span> <span class="kt">float</span> <span class="nv">$sideLength</span><span class="p">)</span> <span class="p">{}</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">calculateArea</span><span class="p">():</span> <span class="kt">float</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">sideLength</span> <span class="o">**</span> <span class="mi">2</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">AreaCalculator</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">calculateTotalArea</span><span class="p">(</span><span class="kt">array</span> <span class="nv">$shapes</span><span class="p">):</span> <span class="kt">float</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nb">array_sum</span><span class="p">(</span><span class="nb">array_map</span><span class="p">(</span>
            <span class="k">fn</span><span class="p">(</span><span class="kt">Shape</span> <span class="nv">$shape</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nv">$shape</span><span class="o">-&gt;</span><span class="nf">calculateArea</span><span class="p">(),</span>
            <span class="nv">$shapes</span>
        <span class="p">));</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">Â </div>
</div>
</div>
<h4><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#why-is-this-better" name="why-is-this-better"></a>Why is this better?</h4>
<p>âœ…Â <strong>Open for Extension</strong>Â â€“ New shapes (e.g.,Â <code>Triangle</code>) can be added without modifyingÂ <code>AreaCalculator</code>.<br />âœ…Â <strong>Closed for Modification</strong>Â â€“ The core logic stays unchanged.<br />âœ…Â <strong>Encapsulated Behavior</strong>Â â€“ Each shape class is responsible for its own area calculation.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#ecommerce-example" name="ecommerce-example"></a>ðŸ›’ E-Commerce Example</h3>
<p>Imagine a payment system where different payment methods need to be supported:</p>
<h4><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#bad-example" name="bad-example"></a>Bad Example ðŸš¨</h4>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="kd">class</span> <span class="nc">PaymentProcessor</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">processPayment</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$type</span><span class="p">,</span> <span class="kt">float</span> <span class="nv">$amount</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="nv">$type</span> <span class="o">===</span> <span class="s1">'credit_card'</span><span class="p">)</span> <span class="p">{</span>
            <span class="c1">// Process credit card</span>
        <span class="p">}</span> <span class="k">elseif</span> <span class="p">(</span><span class="nv">$type</span> <span class="o">===</span> <span class="s1">'paypal'</span><span class="p">)</span> <span class="p">{</span>
            <span class="c1">// Process PayPal</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">Â </div>
</div>
</div>
<p>ðŸš¨Â <strong>Problem:</strong>Â Every time a new payment method is added, the class needs modification.</p>
<h4><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#fixed-example" name="fixed-example"></a>Fixed Example âœ…</h4>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="kd">interface</span> <span class="nc">PaymentMethod</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">process</span><span class="p">(</span><span class="kt">float</span> <span class="nv">$amount</span><span class="p">):</span> <span class="kt">void</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">CreditCardPayment</span> <span class="kd">implements</span> <span class="nc">PaymentMethod</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">process</span><span class="p">(</span><span class="kt">float</span> <span class="nv">$amount</span><span class="p">):</span> <span class="kt">void</span> <span class="p">{</span>
        <span class="c1">// Process credit card</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">PayPalPayment</span> <span class="kd">implements</span> <span class="nc">PaymentMethod</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">process</span><span class="p">(</span><span class="kt">float</span> <span class="nv">$amount</span><span class="p">):</span> <span class="kt">void</span> <span class="p">{</span>
        <span class="c1">// Process PayPal</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">PaymentProcessor</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="k">private</span> <span class="kt">PaymentMethod</span> <span class="nv">$paymentMethod</span><span class="p">)</span> <span class="p">{}</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">process</span><span class="p">(</span><span class="kt">float</span> <span class="nv">$amount</span><span class="p">):</span> <span class="kt">void</span> <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">paymentMethod</span><span class="o">-&gt;</span><span class="nf">process</span><span class="p">(</span><span class="nv">$amount</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">Â </div>
</div>
</div>
<h4><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#benefits" name="benefits"></a>Benefits ðŸš€</h4>
<p>âœ… Easily extendable â€“ Add new payment methods without modifying existing code.<br />âœ… Reduces risk â€“ Core payment logic remains untouched.<br />âœ… Improves readability â€“ No complexÂ <code>if</code>Â conditions.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#advanced-insights" name="advanced-insights"></a>ðŸ“Œ Advanced Insights ðŸš€</h3>
<ul>
<li><strong>Design Patterns</strong>: TheÂ <strong>Strategy Pattern</strong>Â is often used to implement OCP.</li>
<li><strong>Framework Best Practices</strong>: Laravel and Symfony implement OCP through middleware and service providers.</li>
<li><strong>OCP and Testing</strong>: Easier to unit test since components are loosely coupled.</li>
</ul>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#tradeoffs" name="tradeoffs"></a>âš–ï¸ Trade-offs</h3>
<p>âœ…Â <strong>Pros:</strong></p>
<ul>
<li><strong>Flexibility</strong>Â â€“ OCP reduces modification risks in stable code.</li>
<li><strong>Test Stability</strong>Â â€“ Existing functionality remains unchanged.</li>
</ul>
<p>âŒÂ <strong>Cons:</strong></p>
<ul>
<li><strong>More Abstraction</strong>Â â€“ Using interfaces and dependency injection adds more classes.</li>
<li><strong>Overhead</strong>Â â€“ If the system will never change, adding interfaces might be unnecessary.</li>
<li><strong>YAGNI (You Arenâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t Gonna Need It)</strong>Â â€“ Donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t over-engineer if new features are unlikely.</li>
</ul>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#developer-hints" name="developer-hints"></a>ðŸ’¡ Developer Hints</h3>
<p>âœ… UseÂ <strong>interfaces and abstract classes</strong>Â to define extension points.<br />âŒ AvoidÂ <strong>modifying stable, tested classes</strong>Â unless absolutely necessary.<br />âœ… ThinkÂ <strong>long-term scalability</strong>Â before choosing rigid, hard-coded implementations.<br />âŒ If a patternÂ <strong>adds complexity but solves no problem</strong>, you may not need it.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#conclusion" name="conclusion"></a>ðŸ Conclusion</h3>
<p>A well-designed system should be adaptable toÂ <strong>future needs</strong>Â without forcing developers to modifyÂ <strong>working, tested code</strong>. By leveragingÂ <strong>polymorphism, interfaces, and design patterns</strong>, we achieve flexibility while maintaining stability. ðŸš€</p>
<hr />
<h2><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#liskov-substitution-principle-lsp-keep-your-promises" name="liskov-substitution-principle-lsp-keep-your-promises"></a>Liskov Substitution Principle (LSP) &#8211; &#8220;Keep Your Promises&#8221;</h2>
<p><a class="article-body-image-wrapper" href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6fw8atfuyc7tmyc0vvwz.png"><img decoding="async" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6fw8atfuyc7tmyc0vvwz.png" alt="Image description" /></a><br />(source:Â <a href="https://trekhleb.dev/blog/2017/solid-principles-around-you/" target="_blank" rel="noopener noreferrer">https://trekhleb.dev/blog/2017/solid-principles-around-you/</a>)</p>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#academic-definition" name="academic-definition"></a>ðŸ“š Academic Definition</h3>
<blockquote>
<p><strong>Objects in a program should be replaceable with instances of their subtypes without altering the correctness of the program.</strong></p>
</blockquote>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#our-definition" name="our-definition"></a>ðŸŽ¯ Our Definition</h3>
<p>If a class (child) extends another class (parent), it should behave in a way that doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t break expectations set by the parent class. Any subclass should be usable in place of its superclass without unexpected behavior.</p>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#simple-definition" name="simple-definition"></a>ðŸ“ Simple Definition</h3>
<p>A subclass should respect the promises made by its parent class. If you replace the parent class with a subclass, everything should still work correctly.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#paw-patrol-analogy-the-special-snowplow-problem" name="paw-patrol-analogy-the-special-snowplow-problem"></a>ðŸ¾ Paw Patrol Analogy: The Special Snowplow Problem</h3>
<p>Imagine the Paw Patrol vehicles. Each pup has their own special ride, but all of themÂ <strong>must be drivable</strong>.</p>
<p>Now imagine if Everestâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s snowplowÂ <strong>couldnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t drive on roads</strong>Â because it was only built for ice. If a mission required her to drive on a normal road, the system would break because her vehicle doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t meet the basic expectation of â€œbeing able to drive.â€</p>
<p>Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s an LSP violationâ€”her vehicle is a â€œsubclassâ€ of the general &#8220;Paw Patrol Vehicle,&#8221; but it doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t fully substitute for it in every situation.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#key-learnings" name="key-learnings"></a>ðŸ§  Key Learnings</h3>
<ol>
<li><strong>Child classes must respect the contract of their parent classes.</strong></li>
<li><strong>Avoid violating expectations</strong>â€”subclasses must behave consistently with their base class.</li>
<li><strong>If a subclass has to override too much behavior</strong>, it might not truly be a subtype and could indicate a bad inheritance choice.</li>
<li><strong>LSP helps keep code predictable</strong>â€”it prevents unexpected failures when replacing a base class with a subclass.</li>
</ol>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#bad-example-violating-lsp-in-php" name="bad-example-violating-lsp-in-php"></a>Bad Example ðŸš¨: Violating LSP in PHP</h3>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="kd">class</span> <span class="nc">Bird</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">fly</span><span class="p">():</span> <span class="kt">string</span> <span class="p">{</span>
        <span class="k">return</span> <span class="s2">"I am flying!"</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">Penguin</span> <span class="kd">extends</span> <span class="nc">Bird</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">fly</span><span class="p">():</span> <span class="kt">string</span> <span class="p">{</span>
        <span class="k">throw</span> <span class="k">new</span> <span class="nc">Exception</span><span class="p">(</span><span class="s2">"I can't fly!"</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">function</span> <span class="n">makeBirdFly</span><span class="p">(</span><span class="kt">Bird</span> <span class="nv">$bird</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nv">$bird</span><span class="o">-&gt;</span><span class="nf">fly</span><span class="p">();</span>
<span class="p">}</span>

<span class="nv">$penguin</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Penguin</span><span class="p">();</span>
<span class="k">echo</span> <span class="nf">makeBirdFly</span><span class="p">(</span><span class="nv">$penguin</span><span class="p">);</span> <span class="c1">// âŒ Breaks expectation!</span>
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">Â </div>
</div>
</div>
<p>ðŸ”´Â <strong>Issue:</strong>Â <code>Penguin</code>Â extendsÂ <code>Bird</code>, but it breaks the expectation that all birds can fly.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#fixed-example-using-interfaces-to-respect-lsp" name="fixed-example-using-interfaces-to-respect-lsp"></a>âœ… Fixed Example: Using Interfaces to Respect LSP</h3>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="kd">interface</span> <span class="nc">Bird</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">eat</span><span class="p">():</span> <span class="kt">string</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">interface</span> <span class="nc">FlyingBird</span> <span class="kd">extends</span> <span class="nc">Bird</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">fly</span><span class="p">():</span> <span class="kt">string</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">Sparrow</span> <span class="kd">implements</span> <span class="nc">FlyingBird</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">eat</span><span class="p">():</span> <span class="kt">string</span> <span class="p">{</span>
        <span class="k">return</span> <span class="s2">"I eat seeds."</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">fly</span><span class="p">():</span> <span class="kt">string</span> <span class="p">{</span>
        <span class="k">return</span> <span class="s2">"I can fly!"</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">Penguin</span> <span class="kd">implements</span> <span class="nc">Bird</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">eat</span><span class="p">():</span> <span class="kt">string</span> <span class="p">{</span>
        <span class="k">return</span> <span class="s2">"I eat fish."</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">function</span> <span class="n">observeBird</span><span class="p">(</span><span class="kt">Bird</span> <span class="nv">$bird</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nv">$bird</span><span class="o">-&gt;</span><span class="nf">eat</span><span class="p">();</span>
<span class="p">}</span>

<span class="nv">$sparrow</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Sparrow</span><span class="p">();</span>
<span class="nv">$penguin</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Penguin</span><span class="p">();</span>

<span class="k">echo</span> <span class="nf">observeBird</span><span class="p">(</span><span class="nv">$sparrow</span><span class="p">);</span> <span class="c1">// âœ… Works fine!</span>
<span class="k">echo</span> <span class="nf">observeBird</span><span class="p">(</span><span class="nv">$penguin</span><span class="p">);</span> <span class="c1">// âœ… Works fine!</span>
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">Â </div>
</div>
</div>
<p>ðŸŸ¢Â <strong>Fix:</strong>Â Instead of forcing all birds to be able to fly, we separate &#8220;flying&#8221; behavior into a different interface. This way, penguins donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t have to pretend they can fly.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#ecommerce-example-the-free-shipping-issue" name="ecommerce-example-the-free-shipping-issue"></a>ðŸ›’ E-Commerce Example: The Free Shipping Issue</h3>
<h4><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#bad-example-breaking-the-parent-contract" name="bad-example-breaking-the-parent-contract"></a>Bad Example ðŸš¨: Breaking the Parent Contract</h4>
<p>Imagine an order system whereÂ <code>StandardOrder</code>Â has a methodÂ <code>getShippingCost()</code>. A developer extends it forÂ <code>FreeShippingOrder</code>Â but violates expectations:</p>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="kd">class</span> <span class="nc">StandardOrder</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">getShippingCost</span><span class="p">():</span> <span class="kt">float</span> <span class="p">{</span>
        <span class="k">return</span> <span class="mf">5.99</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">FreeShippingOrder</span> <span class="kd">extends</span> <span class="nc">StandardOrder</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">getShippingCost</span><span class="p">():</span> <span class="kt">float</span> <span class="p">{</span>
        <span class="k">throw</span> <span class="k">new</span> <span class="nc">Exception</span><span class="p">(</span><span class="s2">"This order has free shipping!"</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">function</span> <span class="n">processOrder</span><span class="p">(</span><span class="kt">StandardOrder</span> <span class="nv">$order</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="s2">"Shipping Cost: "</span> <span class="mf">.</span> <span class="nv">$order</span><span class="o">-&gt;</span><span class="nf">getShippingCost</span><span class="p">();</span>
<span class="p">}</span>

<span class="nv">$order</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">FreeShippingOrder</span><span class="p">();</span>
<span class="k">echo</span> <span class="nf">processOrder</span><span class="p">(</span><span class="nv">$order</span><span class="p">);</span> <span class="c1">// âŒ Unexpected exception!</span>
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">Â </div>
</div>
</div>
<p>ðŸ”´Â <strong>Issue:</strong>Â <code>FreeShippingOrder</code>Â breaks the contract by throwing an exception instead of returning a valid shipping cost.</p>
<h4><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#fixed-example-using-a-different-approach" name="fixed-example-using-a-different-approach"></a>âœ… Fixed Example: Using a Different Approach</h4>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="kd">interface</span> <span class="nc">Order</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">getShippingCost</span><span class="p">():</span> <span class="kt">float</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">StandardOrder</span> <span class="kd">implements</span> <span class="nc">Order</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">getShippingCost</span><span class="p">():</span> <span class="kt">float</span> <span class="p">{</span>
        <span class="k">return</span> <span class="mf">5.99</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">FreeShippingOrder</span> <span class="kd">implements</span> <span class="nc">Order</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">getShippingCost</span><span class="p">():</span> <span class="kt">float</span> <span class="p">{</span>
        <span class="k">return</span> <span class="mf">0.00</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">function</span> <span class="n">processOrder</span><span class="p">(</span><span class="kt">Order</span> <span class="nv">$order</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="s2">"Shipping Cost: "</span> <span class="mf">.</span> <span class="nv">$order</span><span class="o">-&gt;</span><span class="nf">getShippingCost</span><span class="p">();</span>
<span class="p">}</span>

<span class="nv">$order</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">FreeShippingOrder</span><span class="p">();</span>
<span class="k">echo</span> <span class="nf">processOrder</span><span class="p">(</span><span class="nv">$order</span><span class="p">);</span> <span class="c1">// âœ… Outputs "Shipping Cost: 0.00"</span>
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">Â </div>
</div>
</div>
<p>ðŸŸ¢Â <strong>Fix:</strong>Â Instead of forcingÂ <code>FreeShippingOrder</code>Â to inherit fromÂ <code>StandardOrder</code>, we use anÂ <code>Order</code>Â interface, ensuring all orders can return a shipping cost without surprises.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#advanced-insights" name="advanced-insights"></a>ðŸ“Œ Advanced Insights ðŸš€</h3>
<ol>
<li><strong>LSP helps prevent bad inheritance hierarchies.</strong>Â If you constantly override parent methods in a subclass, considerÂ <strong>composition</strong>Â over inheritance.</li>
<li><strong>Use Interfaces to enforce behavior contracts</strong>â€”avoid forcing all child classes into behaviors they donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t support.</li>
<li><strong>LSP violations often indicate design flaws.</strong>Â If your subclass keeps breaking expectations, your class hierarchy may be wrong.</li>
<li><strong>Invariance vs Covariance vs Contravariance:</strong>Â Be mindful of how method parameters and return types evolve in subclasses.</li>
</ol>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#tradeoffs" name="tradeoffs"></a>âš–ï¸ Trade-offs</h3>
<div class="table-wrapper-paragraph">
<table>
<thead>
<tr>
<th>âœ…Â <strong>Pros</strong></th>
<th>âŒÂ <strong>Cons</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>Ensures subclasses donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t break existing code</td>
<td>May lead to extra abstraction layers</td>
</tr>
<tr>
<td>Helps catch bad inheritance early</td>
<td>Too many interfaces can lead to complexity</td>
</tr>
<tr>
<td>Makes extending systems easier</td>
<td>Sometimes inheritance is still the simpler choice</td>
</tr>
</tbody>
</table>
</div>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#developer-hints" name="developer-hints"></a>ðŸ’¡ Developer Hints</h3>
<p>âœ…Â <strong>DO:</strong>Â Use LSP to validate your class hierarchiesâ€”if a subclass must override too many methods, itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s likely a bad fit.</p>
<p>âŒÂ <strong>DONâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />T:</strong>Â Inherit from a class just to &#8220;reuse&#8221; some methodsâ€”if the behaviors arenâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t consistent, prefer composition.</p>
<p>âœ…Â <strong>DO:</strong>Â Use interfaces and careful method contracts to ensure subclasses behave as expected.</p>
<p>âŒÂ <strong>DONâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />T:</strong>Â Assume that &#8220;all X should do Y&#8221;â€”if exceptions exist, rethink your hierarchy.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#conclusion" name="conclusion"></a>ðŸ Conclusion</h3>
<p>Liskov Substitution Principle ensures that subclasses can always stand in for their parent classÂ <strong>without surprises</strong>. Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s one of the most overlooked SOLID principles but arguably one of the most important for keeping systemsÂ <strong>extendable and predictable</strong>.</p>
<p>Use LSP to validate your class hierarchies. If your subclassÂ <strong>breaks expected behavior</strong>, it&#8217;s a sign you might needÂ <strong>a different inheritance model or composition instead</strong>. Keep your promises, and your codebase will stay clean and maintainable!</p>
<hr />
<h2><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#interface-segregation-principle-isp" name="interface-segregation-principle-isp"></a>Interface Segregation Principle (ISP)</h2>
<p><a class="article-body-image-wrapper" href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2agpndrjv1t864f2lhjh.png"><img decoding="async" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2agpndrjv1t864f2lhjh.png" alt="Image description" /></a><br />(source:Â <a href="https://trekhleb.dev/blog/2017/solid-principles-around-you/" target="_blank" rel="noopener noreferrer">https://trekhleb.dev/blog/2017/solid-principles-around-you/</a>)</p>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#academic-definition" name="academic-definition"></a>ðŸ“š Academic Definition</h3>
<blockquote>
<p>&#8220;Clients should not be forced to depend on methods they do not use.&#8221;</p>
</blockquote>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#our-definition" name="our-definition"></a>ðŸŽ¯ Our Definition</h3>
<p>Interfaces should be focused and granular, ensuring that implementing classes only need to adhere to methods that are relevant to them. This prevents classes from being bloated with unnecessary dependencies and improves code maintainability.</p>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#simple-definition" name="simple-definition"></a>ðŸ“ Simple Definition</h3>
<p>Don&#8217;t force a class to implement methods it doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t need.</p>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#paw-patrol-analogy" name="paw-patrol-analogy"></a>ðŸ¾ Paw Patrol Analogy</h3>
<p>Imagine all Paw Patrol pups had to follow the same &#8220;Rescue Operations&#8221; interface. That would mean Skye (the helicopter pup) would have to implement &#8220;Water Cannon Operation&#8221; even though she has no water cannons! Instead, it&#8217;s better to have separate interfaces: one for fire rescue (Marshall) and one for aerial rescue (Skye). This ensures that each pup only implements the operations they actually perform.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#key-learnings" name="key-learnings"></a>ðŸ§  Key Learnings</h3>
<p>âœ… Interfaces should beÂ <strong>focused</strong>Â andÂ <strong>cohesive</strong>â€”not overloaded with unrelated methods.<br />âœ… UseÂ <strong>multiple small interfaces</strong>Â instead ofÂ <strong>one large interface</strong>.<br />âœ… Helps avoid unnecessary dependencies and improves modularity.<br />âœ… Reduces the likelihood of implementing empty or throwaway methods.<br />âœ… Works well withÂ <strong>Dependency Inversion Principle (DIP)</strong>Â by defining specific contract expectations.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#advanced-insights" name="advanced-insights"></a>ðŸ“Œ Advanced Insights ðŸš€</h3>
<ul>
<li><strong>Granular Interfaces â†’ Better Code Maintainability</strong>: By keeping interfaces small, you prevent a ripple effect of unnecessary method changes in unrelated classes.</li>
<li><strong>Avoid Interface Pollution</strong>: Large interfaces force implementing classes to define methods they donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t use, leading to bad design and unnecessary complexity.</li>
<li><strong>Natural Extension of SRP</strong>: ISP is like SRP but at the interface levelâ€”ensuring each interface has a single, clear responsibility.</li>
<li><strong>Refactoring Legacy Code</strong>: If you have bloated interfaces, split them intoÂ <strong>cohesive, role-based interfaces</strong>.</li>
<li><strong>Multiple Implementations</strong>: You can mix and match smaller interfaces in various ways without forcing unrelated methods onto a class.</li>
</ul>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#bad-example-bloated-interface" name="bad-example-bloated-interface"></a>Bad Example ðŸš¨: Bloated Interface</h3>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="kd">interface</span> <span class="nc">Worker</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">work</span><span class="p">():</span> <span class="kt">void</span><span class="p">;</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">eat</span><span class="p">():</span> <span class="kt">void</span><span class="p">;</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">sleep</span><span class="p">():</span> <span class="kt">void</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">Robot</span> <span class="kd">implements</span> <span class="nc">Worker</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">work</span><span class="p">():</span> <span class="kt">void</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="s2">"I am working!"</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">eat</span><span class="p">():</span> <span class="kt">void</span> <span class="p">{</span>
        <span class="k">throw</span> <span class="k">new</span> <span class="nc">Exception</span><span class="p">(</span><span class="s2">"Robots don't eat!"</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">sleep</span><span class="p">():</span> <span class="kt">void</span> <span class="p">{</span>
        <span class="k">throw</span> <span class="k">new</span> <span class="nc">Exception</span><span class="p">(</span><span class="s2">"Robots don't sleep!"</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">Â </div>
</div>
</div>
<p>ðŸš¨Â <strong>Problem:</strong>Â TheÂ <code>Worker</code>Â interface forcesÂ <code>Robot</code>Â to implementÂ <code>eat()</code>Â andÂ <code>sleep()</code>, which donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t make sense.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#good-example-segregated-interfaces" name="good-example-segregated-interfaces"></a>Good Example: Segregated Interfaces âœ…</h3>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="kd">interface</span> <span class="nc">Workable</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">work</span><span class="p">():</span> <span class="kt">void</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">interface</span> <span class="nc">HumanNeeds</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">eat</span><span class="p">():</span> <span class="kt">void</span><span class="p">;</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">sleep</span><span class="p">():</span> <span class="kt">void</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">Robot</span> <span class="kd">implements</span> <span class="nc">Workable</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">work</span><span class="p">():</span> <span class="kt">void</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="s2">"I am working!"</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">HumanWorker</span> <span class="kd">implements</span> <span class="nc">Workable</span><span class="p">,</span> <span class="nc">HumanNeeds</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">work</span><span class="p">():</span> <span class="kt">void</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="s2">"Working hard!"</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">eat</span><span class="p">():</span> <span class="kt">void</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="s2">"Eating lunch."</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">sleep</span><span class="p">():</span> <span class="kt">void</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="s2">"Going to sleep."</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">Â </div>
</div>
</div>
<p>âœ…Â <strong>Now each class only implements the methods it actually needs!</strong></p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#ecommerce-example" name="ecommerce-example"></a>ðŸ›’ E-Commerce Example</h3>
<p>Imagine you have a largeÂ <code>PaymentProcessor</code>Â interface that forces all payment gateways (PayPal, Stripe, Bitcoin) to implement methods likeÂ <code>refund()</code>Â andÂ <code>chargeBack()</code>, even if some gateways donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t support chargebacks.</p>
<h4><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#bad-example-bloated-interface" name="bad-example-bloated-interface"></a>Bad Example ðŸš¨: Bloated Interface</h4>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="kd">interface</span> <span class="nc">PaymentProcessor</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">processPayment</span><span class="p">(</span><span class="kt">float</span> <span class="nv">$amount</span><span class="p">):</span> <span class="kt">void</span><span class="p">;</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">refund</span><span class="p">(</span><span class="kt">float</span> <span class="nv">$amount</span><span class="p">):</span> <span class="kt">void</span><span class="p">;</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">chargeBack</span><span class="p">(</span><span class="kt">float</span> <span class="nv">$amount</span><span class="p">):</span> <span class="kt">void</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">BitcoinProcessor</span> <span class="kd">implements</span> <span class="nc">PaymentProcessor</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">processPayment</span><span class="p">(</span><span class="kt">float</span> <span class="nv">$amount</span><span class="p">):</span> <span class="kt">void</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="s2">"Processing Bitcoin payment."</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">refund</span><span class="p">(</span><span class="kt">float</span> <span class="nv">$amount</span><span class="p">):</span> <span class="kt">void</span> <span class="p">{</span>
        <span class="k">throw</span> <span class="k">new</span> <span class="nc">Exception</span><span class="p">(</span><span class="s2">"Bitcoin transactions are irreversible!"</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">chargeBack</span><span class="p">(</span><span class="kt">float</span> <span class="nv">$amount</span><span class="p">):</span> <span class="kt">void</span> <span class="p">{</span>
        <span class="k">throw</span> <span class="k">new</span> <span class="nc">Exception</span><span class="p">(</span><span class="s2">"Bitcoin has no chargebacks!"</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">Â </div>
</div>
</div>
<p>âŒÂ <strong>Problem:</strong>Â Bitcoin does not support refunds or chargebacks, yet itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s forced to implement these methods.</p>
<h4><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#segregated-interfaces-good-example" name="segregated-interfaces-good-example"></a>Segregated Interfaces (Good Example) âœ…</h4>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="kd">interface</span> <span class="nc">PaymentProcessor</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">processPayment</span><span class="p">(</span><span class="kt">float</span> <span class="nv">$amount</span><span class="p">):</span> <span class="kt">void</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">interface</span> <span class="nc">Refundable</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">refund</span><span class="p">(</span><span class="kt">float</span> <span class="nv">$amount</span><span class="p">):</span> <span class="kt">void</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">interface</span> <span class="nc">Chargebackable</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">chargeBack</span><span class="p">(</span><span class="kt">float</span> <span class="nv">$amount</span><span class="p">):</span> <span class="kt">void</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">BitcoinProcessor</span> <span class="kd">implements</span> <span class="nc">PaymentProcessor</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">processPayment</span><span class="p">(</span><span class="kt">float</span> <span class="nv">$amount</span><span class="p">):</span> <span class="kt">void</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="s2">"Processing Bitcoin payment."</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">CreditCardProcessor</span> <span class="kd">implements</span> <span class="nc">PaymentProcessor</span><span class="p">,</span> <span class="nc">Refundable</span><span class="p">,</span> <span class="nc">Chargebackable</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">processPayment</span><span class="p">(</span><span class="kt">float</span> <span class="nv">$amount</span><span class="p">):</span> <span class="kt">void</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="s2">"Processing Credit Card payment."</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">refund</span><span class="p">(</span><span class="kt">float</span> <span class="nv">$amount</span><span class="p">):</span> <span class="kt">void</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="s2">"Processing refund."</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">chargeBack</span><span class="p">(</span><span class="kt">float</span> <span class="nv">$amount</span><span class="p">):</span> <span class="kt">void</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="s2">"Processing chargeback."</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">Â </div>
</div>
</div>
<p>âœ…Â <strong>Now, Bitcoin only implementsÂ <code>PaymentProcessor</code>, and Credit Card processors can addÂ <code>Refundable</code>Â andÂ <code>Chargebackable</code>.</strong></p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#tradeoffs" name="tradeoffs"></a>âš–ï¸ Trade-offs</h3>
<p>âœ…Â <strong>Pros:</strong></p>
<ul>
<li>Prevents unnecessary dependencies.</li>
<li>Improves readability and maintainability.</li>
<li>Easier to refactor without breaking implementations.</li>
<li>Better aligns with theÂ <strong>Single Responsibility Principle (SRP)</strong>.</li>
</ul>
<p>âŒÂ <strong>Cons:</strong></p>
<ul>
<li>Can lead toÂ <strong>too many</strong>Â small interfaces.</li>
<li>RequiresÂ <strong>careful naming</strong>Â to keep interfaces meaningful.</li>
<li>MightÂ <strong>increase boilerplate</strong>Â in some cases.</li>
</ul>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#developer-hints" name="developer-hints"></a>ðŸ’¡ Developer Hints</h3>
<p>âœ…Â <strong>Split interfaces when:</strong></p>
<ul>
<li>A class is implementing empty methods.</li>
<li>A class throws exceptions for methods it doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t support.</li>
<li>A method is only used inÂ <strong>some</strong>Â implementations but not others.</li>
</ul>
<p>âœ…Â <strong>Keep interfaces meaningful:</strong></p>
<ul>
<li>Don&#8217;t over-fragment interfaces into tiny, meaningless pieces.</li>
<li>A good rule: IfÂ <strong>two implementations always share the same methods</strong>, keep them together.</li>
</ul>
<p>âœ…Â <strong>Use with Dependency Injection:</strong></p>
<ul>
<li>Granular interfaces makeÂ <strong>Dependency Injection (DI)</strong>Â much cleaner.</li>
</ul>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#conclusion" name="conclusion"></a>ðŸ Conclusion</h3>
<p>Interface Segregation ensures that interfaces stay clean and meaningful. Instead of bloated, one-size-fits-all contracts, ISP encouragesÂ <strong>focused, role-specific interfaces</strong>Â that keep classes lean and purposeful. By following ISP, you create software that isÂ <strong>modular, easy to extend, and avoids unnecessary coupling</strong>.</p>
<p>By embracing ISP, your codebase staysÂ <strong>flexible, maintainable, and scalable</strong>â€”just like a well-organized Paw Patrol team! ðŸš€ðŸ¶</p>
<hr />
<h2><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#dependency-inversion-principle-dip" name="dependency-inversion-principle-dip"></a>Dependency Inversion Principle (DIP)</h2>
<p><a class="article-body-image-wrapper" href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fad1eyh2ilp1exhm9p31d.png"><img decoding="async" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fad1eyh2ilp1exhm9p31d.png" alt="Image description" /></a><br />(source:Â <a href="https://trekhleb.dev/blog/2017/solid-principles-around-you/" target="_blank" rel="noopener noreferrer">https://trekhleb.dev/blog/2017/solid-principles-around-you/</a>)</p>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#academic-definition" name="academic-definition"></a>ðŸ“š Academic Definition</h3>
<blockquote>
<p><strong>High-level modules should not depend on low-level modules. Both should depend on abstractions.</strong></p>
<p><strong>Abstractions should not depend on details. Details should depend on abstractions.</strong></p>
</blockquote>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#our-definition" name="our-definition"></a>ðŸŽ¯ Our Definition</h3>
<p>DIP ensures thatÂ <strong>core logic (high-level modules)</strong>Â does not directly depend onÂ <strong>specific implementations (low-level modules)</strong>. Instead, both depend on a commonÂ <strong>interface or abstraction</strong>.</p>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#simple-definition" name="simple-definition"></a>ðŸ“ Simple Definition</h3>
<p>Instead of hardcoding dependencies, rely onÂ <strong>interfaces</strong>Â orÂ <strong>dependency injection</strong>Â to allow for easier maintenance, testing, and swapping implementations.</p>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#paw-patrol-analogy" name="paw-patrol-analogy"></a>ðŸ¾ Paw Patrol Analogy</h3>
<p>ImagineÂ <strong>Ryder</strong>, the leader of Paw Patrol, who needs a pup for a rescue mission. Instead of callingÂ <strong>Chase</strong>Â directly, he calls for a &#8220;Police Pup.&#8221; This allowsÂ <strong>Chase</strong>Â to respond, but if another police dog joins the team, he can step in without changing Ryderâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s commands.</p>
<p>By coding to anÂ <strong>abstraction (&#8220;Police Pup&#8221;)</strong>Â instead of aÂ <strong>concrete implementation (&#8220;Chase&#8221;)</strong>, Ryder ensures flexibility.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#key-learnings" name="key-learnings"></a>ðŸ§  Key Learnings</h3>
<p>1ï¸âƒ£Â <strong>High-Level Modules (Core Logic) Should Not Depend on Low-Level Modules (Implementations)</strong></p>
<ul>
<li>Example: AnÂ <code>OrderService</code>Â should not directly depend onÂ <code>MySQLDatabase</code>Â but instead onÂ <code>DatabaseInterface</code>.</li>
</ul>
<p>2ï¸âƒ£Â <strong>Abstractions Should Not Depend on Details</strong></p>
<ul>
<li>The interface should define behavior, not implementation details.</li>
</ul>
<p>3ï¸âƒ£Â <strong>Use Dependency Injection for Flexibility</strong></p>
<ul>
<li>Instead of creating objects inside a class (<code>new MySQLDatabase()</code>), pass them as dependencies (<code>DatabaseInterface $db</code>).</li>
</ul>
<p>4ï¸âƒ£Â <strong>Promotes Testing and Maintainability</strong></p>
<ul>
<li>Easily mock dependencies in unit tests by swapping implementations.</li>
</ul>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#simple-example-violating-dip" name="simple-example-violating-dip"></a>Simple Example (Violating DIP)</h3>
<h4><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#bad-example-hardcoded-dependency" name="bad-example-hardcoded-dependency"></a>Bad Example ðŸš¨: Hardcoded Dependency</h4>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="kd">class</span> <span class="nc">MySQLDatabase</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">getUser</span><span class="p">(</span><span class="kt">int</span> <span class="nv">$id</span><span class="p">):</span> <span class="kt">string</span> <span class="p">{</span>
        <span class="k">return</span> <span class="s2">"User data from MySQL"</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">UserService</span> <span class="p">{</span>
    <span class="k">private</span> <span class="kt">MySQLDatabase</span> <span class="nv">$database</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">()</span> <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">database</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">MySQLDatabase</span><span class="p">();</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">getUser</span><span class="p">(</span><span class="kt">int</span> <span class="nv">$id</span><span class="p">):</span> <span class="kt">string</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">database</span><span class="o">-&gt;</span><span class="nf">getUser</span><span class="p">(</span><span class="nv">$id</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">Â </div>
</div>
</div>
<p>ðŸ’¥Â <strong>Problem:</strong>Â If we switch toÂ <code>PostgreSQLDatabase</code>, we must modifyÂ <code>UserService</code>, violating DIP.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#the-fix-applying-dip" name="the-fix-applying-dip"></a>The Fix: Applying DIP</h3>
<h4><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#good-example-using-an-interface" name="good-example-using-an-interface"></a>âœ… Good Example: Using an Interface</h4>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="kd">interface</span> <span class="nc">DatabaseInterface</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">getUser</span><span class="p">(</span><span class="kt">int</span> <span class="nv">$id</span><span class="p">):</span> <span class="kt">string</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">MySQLDatabase</span> <span class="kd">implements</span> <span class="nc">DatabaseInterface</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">getUser</span><span class="p">(</span><span class="kt">int</span> <span class="nv">$id</span><span class="p">):</span> <span class="kt">string</span> <span class="p">{</span>
        <span class="k">return</span> <span class="s2">"User data from MySQL"</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">PostgreSQLDatabase</span> <span class="kd">implements</span> <span class="nc">DatabaseInterface</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">getUser</span><span class="p">(</span><span class="kt">int</span> <span class="nv">$id</span><span class="p">):</span> <span class="kt">string</span> <span class="p">{</span>
        <span class="k">return</span> <span class="s2">"User data from PostgreSQL"</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">UserService</span> <span class="p">{</span>
    <span class="k">private</span> <span class="kt">DatabaseInterface</span> <span class="nv">$database</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">DatabaseInterface</span> <span class="nv">$database</span><span class="p">)</span> <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">database</span> <span class="o">=</span> <span class="nv">$database</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">getUser</span><span class="p">(</span><span class="kt">int</span> <span class="nv">$id</span><span class="p">):</span> <span class="kt">string</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">database</span><span class="o">-&gt;</span><span class="nf">getUser</span><span class="p">(</span><span class="nv">$id</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// Usage</span>
<span class="nv">$service</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">UserService</span><span class="p">(</span><span class="k">new</span> <span class="nc">MySQLDatabase</span><span class="p">());</span>
<span class="nv">$service</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">UserService</span><span class="p">(</span><span class="k">new</span> <span class="nc">PostgreSQLDatabase</span><span class="p">());</span>
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">Â </div>
</div>
</div>
<p>âœ…Â <strong>NowÂ <code>UserService</code>Â does not depend on a specific database but onÂ <code>DatabaseInterface</code></strong>, making it flexible.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#ecommerce-example" name="ecommerce-example"></a>ðŸ›’ E-Commerce Example</h3>
<h4><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#bad-example-hardcoded-payment-processor" name="bad-example-hardcoded-payment-processor"></a>Bad Example ðŸš¨: Hardcoded Payment Processor</h4>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="kd">class</span> <span class="nc">PaymentService</span> <span class="p">{</span>
    <span class="k">private</span> <span class="kt">StripePaymentProcessor</span> <span class="nv">$processor</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">()</span> <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">processor</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">StripePaymentProcessor</span><span class="p">();</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">processPayment</span><span class="p">(</span><span class="kt">float</span> <span class="nv">$amount</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">processor</span><span class="o">-&gt;</span><span class="nf">pay</span><span class="p">(</span><span class="nv">$amount</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">Â </div>
</div>
</div>
<p>ðŸ’¥Â <strong>Issue:</strong>Â Tied to Stripe; hard to replace with PayPal.</p>
<h4><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#good-example-dip-with-interfaces" name="good-example-dip-with-interfaces"></a>âœ… Good Example (DIP with Interfaces)</h4>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="kd">interface</span> <span class="nc">PaymentProcessor</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">pay</span><span class="p">(</span><span class="kt">float</span> <span class="nv">$amount</span><span class="p">):</span> <span class="kt">bool</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">StripePaymentProcessor</span> <span class="kd">implements</span> <span class="nc">PaymentProcessor</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">pay</span><span class="p">(</span><span class="kt">float</span> <span class="nv">$amount</span><span class="p">):</span> <span class="kt">bool</span> <span class="p">{</span>
        <span class="k">return</span> <span class="kc">true</span><span class="p">;</span> <span class="c1">// Process payment via Stripe</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">PayPalPaymentProcessor</span> <span class="kd">implements</span> <span class="nc">PaymentProcessor</span> <span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">pay</span><span class="p">(</span><span class="kt">float</span> <span class="nv">$amount</span><span class="p">):</span> <span class="kt">bool</span> <span class="p">{</span>
        <span class="k">return</span> <span class="kc">true</span><span class="p">;</span> <span class="c1">// Process payment via PayPal</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">PaymentService</span> <span class="p">{</span>
    <span class="k">private</span> <span class="kt">PaymentProcessor</span> <span class="nv">$processor</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">PaymentProcessor</span> <span class="nv">$processor</span><span class="p">)</span> <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">processor</span> <span class="o">=</span> <span class="nv">$processor</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">processPayment</span><span class="p">(</span><span class="kt">float</span> <span class="nv">$amount</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">processor</span><span class="o">-&gt;</span><span class="nf">pay</span><span class="p">(</span><span class="nv">$amount</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// Usage</span>
<span class="nv">$paymentService</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PaymentService</span><span class="p">(</span><span class="k">new</span> <span class="nc">StripePaymentProcessor</span><span class="p">());</span>
<span class="nv">$paymentService</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PaymentService</span><span class="p">(</span><span class="k">new</span> <span class="nc">PayPalPaymentProcessor</span><span class="p">());</span>
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">Â </div>
</div>
</div>
<p>âœ… Now the service works withÂ <strong>any</strong>Â payment processor.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#advanced-insights" name="advanced-insights"></a>ðŸ“Œ Advanced Insights ðŸš€</h3>
<p>âœ…Â <strong>IoC Containers (Dependency Injection Containers)</strong><br /><br />Modern frameworks (Laravel, Symfony) use IoC containers toÂ <strong>bind interfaces to implementations</strong>, automating dependency resolution.</p>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="nv">$container</span><span class="o">-&gt;</span><span class="nf">bind</span><span class="p">(</span><span class="nc">PaymentProcessor</span><span class="o">::</span><span class="n">class</span><span class="p">,</span> <span class="nc">StripePaymentProcessor</span><span class="o">::</span><span class="n">class</span><span class="p">);</span>
<span class="nv">$paymentService</span> <span class="o">=</span> <span class="nv">$container</span><span class="o">-&gt;</span><span class="nf">make</span><span class="p">(</span><span class="nc">PaymentService</span><span class="o">::</span><span class="n">class</span><span class="p">);</span>
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">Â </div>
</div>
</div>
<p>âœ…Â <strong>Easier Unit Testing</strong><br /><br />By injecting dependencies, you can mock them in tests:</p>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="nv">$mockProcessor</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">createMock</span><span class="p">(</span><span class="nc">PaymentProcessor</span><span class="o">::</span><span class="n">class</span><span class="p">);</span>
<span class="nv">$mockProcessor</span><span class="o">-&gt;</span><span class="nf">method</span><span class="p">(</span><span class="s1">'pay'</span><span class="p">)</span><span class="o">-&gt;</span><span class="nf">willReturn</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
<span class="nv">$service</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PaymentService</span><span class="p">(</span><span class="nv">$mockProcessor</span><span class="p">);</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">assertTrue</span><span class="p">(</span><span class="nv">$service</span><span class="o">-&gt;</span><span class="nf">processPayment</span><span class="p">(</span><span class="mi">100</span><span class="p">));</span>
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">Â </div>
</div>
</div>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#tradeoffs" name="tradeoffs"></a>âš–ï¸ Trade-offs</h3>
<p>1ï¸âƒ£Â <strong>Over-Abstraction</strong>: Too many interfaces can complicate simple cases.<br />2ï¸âƒ£Â <strong>Initial Setup Overhead</strong>: More upfront work vs. hardcoding dependencies.<br />3ï¸âƒ£Â <strong>Not Always Needed</strong>: Small scripts may not benefit from DIP.<br />4ï¸âƒ£Â <strong>Performance</strong>: Extra layers add slight performance costs.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#developer-hints" name="developer-hints"></a>ðŸ’¡ Developer Hints</h3>
<p>ðŸš€Â <strong>Use interfaces when multiple implementations are possible.</strong><br />ðŸ› Â <strong>If a dependency rarely changes, DIP might be unnecessary overhead.</strong><br />ðŸ”„Â <strong>Combine with IoC containers for better dependency management.</strong></p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#conclusion" name="conclusion"></a>ðŸ Conclusion</h3>
<p>DIP helps create flexible, scalable, and testable code. While overusing it can lead to unnecessary complexity, applying it where appropriateÂ <strong>ensures long-term maintainability and adaptability</strong>.</p>
<hr />
<p><strong>Learnings and Findings from the Blog Post</strong></p>
<hr />
<h2><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#the-essence-of-solid-beyond-textbook-definitions" name="the-essence-of-solid-beyond-textbook-definitions"></a><strong>The Essence of SOLID Beyond Textbook Definitions</strong></h2>
<p>We have consistently moved beyond simply memorizing the SOLID principles. Instead, we have deeply examined their real-world applications, trade-offs, and potential misuses. The key insight is that SOLID is not a rigid framework but a set of guiding principles that, when applied pragmatically, result inÂ <strong>maintainable, flexible, and understandable</strong>Â software.</p>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#what-we-learned" name="what-we-learned"></a><strong>What We Learned:</strong></h3>
<p>1ï¸âƒ£ SOLIDÂ <strong>is a means, not an end</strong>â€”it should improve software, not be followed blindly.<br />2ï¸âƒ£ Principles shouldÂ <strong>evolve naturally</strong>Â with software needs rather than being enforced prematurely.<br />3ï¸âƒ£Â <strong>Balance is key</strong>: applying SOLID too rigidly can introduce unnecessary complexity, while ignoring it leads to unmanageable abstractions.<br />4ï¸âƒ£ Naming and categorization of abstract concepts help communicate intent and keep teams aligned.</p>
<hr />
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#solid-principles-recap" name="solid-principles-recap"></a>ðŸ”„Â <strong>SOLID Principles Recap</strong></h3>
<p>Each principle is a tool to write better, maintainable, and scalable software. While following them strictly isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t always necessary, understanding them deeply allows you to make informed trade-offs when designing software.</p>
<h4><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#single-responsibility-principle-srp" name="single-responsibility-principle-srp"></a>1ï¸âƒ£Â <strong>Single Responsibility Principle</strong>Â (SRP)</h4>
<p>ðŸ“ŒÂ <strong>Rule</strong>: A class should only have one reason to change.<br />âœ…Â <strong>Benefit</strong>: Reduces complexity and improves maintainability.<br />âš ï¸Â <strong>Pitfall</strong>: Over-applying SRP can create too many small classes.</p>
<h4><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#openclosed-principle-ocp" name="openclosed-principle-ocp"></a>2ï¸âƒ£Â <strong>Open-Closed Principle</strong>Â (OCP)</h4>
<p>ðŸ“ŒÂ <strong>Rule</strong>: Code should be open for extension but closed for modification.<br />âœ…Â <strong>Benefit</strong>: Prevents modifying stable, tested code when adding new features.<br />âš ï¸Â <strong>Pitfall</strong>: Over-abstraction can make code difficult to understand.</p>
<h4><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#liskov-substitution-principle-lsp" name="liskov-substitution-principle-lsp"></a>3ï¸âƒ£Â <strong>Liskov Substitution Principle</strong>Â (LSP)</h4>
<p>ðŸ“ŒÂ <strong>Rule</strong>: Subtypes must be substitutable for their base types.<br />âœ…Â <strong>Benefit</strong>: Ensures a predictable, bug-free inheritance structure.<br />âš ï¸Â <strong>Pitfall</strong>: Violations often happen when child classes break parent contracts.</p>
<h4><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#interface-segregation-principle-isp" name="interface-segregation-principle-isp"></a>4ï¸âƒ£Â <strong>Interface Segregation Principle</strong>Â (ISP)</h4>
<p>ðŸ“ŒÂ <strong>Rule</strong>: No class should be forced to depend on methods it does not use.<br />âœ…Â <strong>Benefit</strong>: Creates leaner, more reusable interfaces.<br />âš ï¸Â <strong>Pitfall</strong>: Too many interfaces can create confusion or interface bloat.</p>
<h4><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#dependency-inversion-principle-dip" name="dependency-inversion-principle-dip"></a>5ï¸âƒ£Â <strong>Dependency Inversion Principle</strong>Â (DIP)</h4>
<p>ðŸ“ŒÂ <strong>Rule</strong>: Depend on abstractions, not concrete implementations.<br />âœ…Â <strong>Benefit</strong>: Encourages decoupled, flexible, and testable code.<br />âš ï¸Â <strong>Pitfall</strong>: Overuse can lead to too many indirections, making debugging harder.</p>
<hr />
<h2><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#abstractions-when-to-generalize-and-when-to-copypaste" name="abstractions-when-to-generalize-and-when-to-copypaste"></a><strong>Abstractions: When to Generalize and When to Copy-Paste</strong></h2>
<p><a class="article-body-image-wrapper" href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldgeihlz2loa3hbsx9if.png"><img decoding="async" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldgeihlz2loa3hbsx9if.png" alt="Image description" /></a><br />(source:Â <a href="https://www.reddit.com/r/Design/comments/6qh8ni/the_abstractometer/" target="_blank" rel="noopener noreferrer">https://www.reddit.com/r/Design/comments/6qh8ni/the_abstractometer/</a>)</p>
<p>The Abstract-o-Meter reminds us that effective software design lies in finding the balance between clarity and usability. Every abstraction should:</p>
<ul>
<li>Hide unnecessary details, making systems easier to understand.</li>
<li>Preserve essential clarity, ensuring they remain relevant to the real-world domain.</li>
</ul>
<p>Whether youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re designing a small utility class or architecting a large-scale system, always aim for the heart in the middle of the Abstract-o-Meter. This is the area where your abstractions remain meaningful, useful and maintainable, and only then will other developers actually use them.</p>
<p>One of the most significant learning is aboutÂ <strong>the right time to introduce abstractions</strong>Â versus when copy-pasting is actually preferable. The classic fear of duplication (&#8220;DRY principle&#8221;) must be balanced withÂ <strong>avoiding premature abstractions</strong>Â that introduce unnecessary coupling and complexity.</p>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#key-takeaways" name="key-takeaways"></a><strong>Key Takeaways:</strong></h3>
<p>1ï¸âƒ£Â <strong>Duplication is often cheaper</strong>Â than the wrong abstraction.<br />2ï¸âƒ£ Generalization should be based onÂ <strong>real-world observed repetition</strong>, not speculative future needs.<br />3ï¸âƒ£ Over-abstraction leads toÂ <strong>hard-to-read, bloated code</strong>Â where understanding business rules requires digging through multiple indirections.<br />4ï¸âƒ£ HighÂ <strong>cohesion and minimal dependencies</strong>Â should be prioritized when designing abstractions.</p>
<h4><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#pragmatic-rule-of-thumb" name="pragmatic-rule-of-thumb"></a><strong>Pragmatic Rule of Thumb:</strong></h4>
<ul>
<li>First occurrence?Â <strong>Write it.</strong></li>
<li>Second occurrence?Â <strong>Copy it.</strong></li>
<li>Third occurrence?Â <strong>Consider abstractionâ€”but validate first.</strong></li>
</ul>
<hr />
<h2><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#naming-and-conceptual-thinking-the-front-garden-and-neighborhood-metaphors" name="naming-and-conceptual-thinking-the-front-garden-and-neighborhood-metaphors"></a><strong>Naming and Conceptual Thinking: The &#8220;Front Garden&#8221; and &#8220;Neighborhood&#8221; Metaphors</strong></h2>
<p>We explored how defining abstractÂ <strong>conceptual names</strong>Â improves communication. TheÂ <strong>Front Garden</strong>Â andÂ <strong>Neighborhood</strong>Â analogy illustrated the power of naming in programming and software architecture:</p>
<ul>
<li>By namingÂ <strong>broad categories of problems</strong>, we createÂ <strong>reusable mental models</strong>Â that allow easier discussions.</li>
<li>Instead of explaining every case separately, we canÂ <strong>define an abstract concept</strong>Â (like &#8220;OCP Violation&#8221; or &#8220;Front Garden Boundary&#8221;) and use it as shorthand.</li>
<li><strong>Rules should be flexible principles</strong>, not rigid constraintsâ€”much like in software, where strict application of SOLID without context leads to over-engineering.</li>
</ul>
<hr />
<h2><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#the-solid-but-practical-mindset-knowing-when-to-bend-the-rules" name="the-solid-but-practical-mindset-knowing-when-to-bend-the-rules"></a><strong>The &#8220;SOLID but Practical&#8221; Mindset: Knowing When to Bend the Rules</strong></h2>
<p>Throughout our discussions, a recurring theme wasÂ <strong>pragmatism over dogma</strong>. Many developers apply SOLID too rigidly, causing unnecessary complexity. The real mastery lies in knowing when toÂ <strong>intentionally</strong>Â bend or break the rulesÂ <strong>for the right reasons</strong>.</p>
<h3><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#key-lessons" name="key-lessons"></a><strong>Key Lessons:</strong></h3>
<ul>
<li><strong>SRP (Single Responsibility Principle)</strong>: Some responsibilities can be combined if they always change together.</li>
<li><strong>OCP (Open-Closed Principle)</strong>: Sometimes modifying a class is more maintainable than excessive abstractions.</li>
<li><strong>LSP (Liskov Substitution Principle)</strong>: If a subclass needs excessive modifications, reconsider the inheritance structure.</li>
<li><strong>ISP (Interface Segregation Principle)</strong>: Avoid creating too many interfaces that fragment business logic.</li>
<li><strong>DIP (Dependency Inversion Principle)</strong>: Use abstractions but avoid forcing yourself to abstract every dependency.</li>
</ul>
<hr />
<h2><a href="https://dev.to/suckup_de/solid-principles-from-paw-patrol-to-linux-penguins-379b-temp-slug-530584/edit#final-thought-the-futureproof-developer-mindset" name="final-thought-the-futureproof-developer-mindset"></a><strong>Final Thought: The &#8220;Future-Proof&#8221; Developer Mindset</strong></h2>
<ul>
<li><strong>Principles exist to serve the software, not the other way around.</strong></li>
<li><strong>Code should evolve naturally</strong>, following real needs instead of speculative complexity.</li>
<li><strong>Naming is critical</strong>, not just for variables but for abstract concepts that help us discuss software design effectively.</li>
<li><strong>Abstractions are a tool</strong>, not a requirementâ€”sometimes, copy-pasting is the best decision.</li>
<li><strong>Balance pragmatism with best practices</strong>, and donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t fear breaking SOLID rulesÂ <strong>if it makes the code better</strong>.</li>
</ul>
<p>By combiningÂ <strong>deep technical knowledge</strong>Â withÂ <strong>practical experience</strong>, we can write software that is both maintainable and efficientâ€”without falling into the traps of over-engineering or unnecessary complexity. Happy coding!</p>
</div>
</div>
</article>
</div>
<div id="editor-actions" class="crayons-article-form__footer"><button class="c-btn c-btn--primary mr-2 whitespace-nowrap" type="button">Save changes</button></div>
</form></main></div>
</div>
<img loading="lazy" decoding="async" src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F01%2Fsolid-principles-from-paw-patrol-to-linux-penguin%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dsolid-principles-from-paw-patrol-to-linux-penguin&amp;action_name=SOLID%20Principles%3A%20From%20Paw%20Patrol%20to%20the%20Neighborhood&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
					<wfw:commentRss>http://suckup.de/2025/01/solid-principles-from-paw-patrol-to-linux-penguin/?pk_campaign=feed&amp;pk_kwd=solid-principles-from-paw-patrol-to-linux-penguin/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">6962</post-id>	</item>
		<item>
		<title>Why Agile Wonâ€™t Fix Your Project</title>
		<link>http://suckup.de/2025/01/why-agile-wont-fix-your-project/?pk_campaign=feed&amp;pk_kwd=why-agile-wont-fix-your-project&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=why-agile-wont-fix-your-project</link>
					<comments>http://suckup.de/2025/01/why-agile-wont-fix-your-project/?pk_campaign=feed&amp;pk_kwd=why-agile-wont-fix-your-project#respond</comments>
		
		<dc:creator><![CDATA[voku]]></dc:creator>
		<pubDate>Fri, 24 Jan 2025 01:09:16 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<guid isPermaLink="false">https://suckup.de/?p=6948</guid>

					<description><![CDATA[<p><a href="http://suckup.de/2025/01/why-agile-wont-fix-your-project/?pk_campaign=feed&#038;pk_kwd=why-agile-wont-fix-your-project">Why Agile Wonâ€™t Fix Your Project</a></p>
<p>Weâ€™ve all heard the promises of Agile: faster delivery, more flexibility, and a better team dynamic. But letâ€™s face itâ€”Agile wonâ€™t save your project if the foundation isnâ€™t right. Frameworks are tools, not magic wands, and success depends on one key factor: your people. Without commitment, purpose, and vision, even the best methodology falls flat. &#8230; <a href="http://suckup.de/2025/01/why-agile-wont-fix-your-project/?pk_campaign=feed&#038;pk_kwd=why-agile-wont-fix-your-project" class="more-link">Continue reading <span class="screen-reader-text">Why Agile Wonâ€™t Fix Your Project</span></a><img src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F01%2Fwhy-agile-wont-fix-your-project%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dwhy-agile-wont-fix-your-project&amp;action_name=Why%20Agile%20Won%C3%A2%E2%82%AC%E2%84%A2t%20Fix%20Your%20Project&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" /></p>
]]></description>
										<content:encoded><![CDATA[<p><a href="http://suckup.de/2025/01/why-agile-wont-fix-your-project/?pk_campaign=feed&#038;pk_kwd=why-agile-wont-fix-your-project">Why Agile Wonâ€™t Fix Your Project</a></p>

<p class="wp-block-paragraph">Weâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve all heard the promises of Agile: faster delivery, more flexibility, and a better team dynamic. But letâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s face itâ€”Agile wonâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t save your project if the foundation isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t right. Frameworks are tools, not magic wands, and success depends on one key factor: your people. Without commitment, purpose, and vision, even the best methodology falls flat.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Commitment Is the Foundation</strong></h3>



<p class="wp-block-paragraph">In every successful project Iâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve seen, thereâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s one constant: the team cares. Theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re passionate about the project, the technology, or the customer. When people are engaged, they bring their A-game. Without that commitment, Agile rituals become hollow motionsâ€”stand-ups where no one stands up for quality and retrospectives that only scratch the surface.</p>



<p class="wp-block-paragraph">But how do you ignite that spark?</p>



<ul class="wp-block-list">
<li><strong>Give Purpose:</strong> Teams perform better when they know why their work matters. Whether itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s a product that changes lives or a system that transforms workflows, connect the dots between their efforts and the bigger picture.</li>



<li><strong>Empower Ownership:</strong> Nothing kills commitment faster than micromanagement. Give your team the autonomy to solve problems their way, and theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ll take pride in their work.</li>



<li><strong>Set the North Star:</strong> Someone needs to have the big picture in mind. This isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t about controlling every detail; itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s about providing clarity and direction. A team without a vision is just a group of people checking tasks off a backlog.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Agile: A Framework, Not a Fix</strong></h3>



<p class="wp-block-paragraph">Agile isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t inherently badâ€”itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s just not a silver bullet. A poorly implemented Agile process can feel like busy work, creating friction instead of flow. Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve seen it: endless sprints with no tangible value, misaligned priorities, and teams that are Agile in name only.</p>



<p class="wp-block-paragraph">The truth is, Agile is just a tool, and like any tool, its effectiveness depends on how you use it. Without the right culture, mindset, and leadership, Agile canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t thrive.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>The Power of Flow</strong></h3>



<p class="wp-block-paragraph">When your team is committed and has a clear purpose, they enter the elusive â€œflowâ€ state. Flow is where the magic happens: work feels both challenging and enjoyable, and everything just clicks. Achieving flow requires more than processâ€”it demands an environment that fosters focus, removes blockers, and aligns everyone toward shared goals.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Common Pitfalls in Agile Projects</strong></h3>



<ul class="wp-block-list">
<li><strong>Lack of Vision:</strong> If the goals are unclear, the team loses direction. Agile iterations canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t compensate for a missing strategy.</li>



<li><strong>Token Empowerment:</strong> Teams are told theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re empowered, but their decisions are constantly overridden by management.</li>



<li><strong>Process Over People:</strong> Agile becomes a checkbox exercise, focusing on rituals instead of outcomes.</li>



<li><strong>Burnout Culture:</strong> Passion doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t mean working endless hours. A healthy pace is critical for long-term success.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Building the Right Environment</strong></h3>



<p class="wp-block-paragraph">Hereâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s what makes the difference:</p>



<ol class="wp-block-list">
<li><strong>Clarity and Direction</strong>: Define a clear vision and align the teamâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s work with it. Avoid vague objectivesâ€”make the goals tangible and achievable.</li>



<li><strong>Purposeful Leadership</strong>: Leaders need to support, not control. Their role is to remove obstacles, align efforts, and amplify strengths.</li>



<li><strong>Empowerment</strong>: Trust your team to make decisions. Give them the tools, autonomy, and confidence to innovate.</li>



<li><strong>Continuous Reflection</strong>: Agile emphasizes improvement, but that requires honesty. Create a safe space for open feedback and genuine introspection.</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Final Thoughts: Commitment Over Process</strong></h3>



<p class="wp-block-paragraph">At the end of the day, success isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t about following Agile to the letter. Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s about creating an environment where your team thrives. Agility is just one piece of the puzzle. Your teamâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s commitment, passion, and purpose are what truly drive results.</p>



<p class="wp-block-paragraph">So donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t just â€œgo Agile.â€ Build a culture that values people over processes, outcomes over rituals, and vision over micromanagement. Agile might not save your project, but your team will.</p>



<p class="wp-block-paragraph">ðŸš€ <strong>Because in the end, your people are your greatest asset.</strong></p>


<img loading="lazy" decoding="async" src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F01%2Fwhy-agile-wont-fix-your-project%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dwhy-agile-wont-fix-your-project&amp;action_name=Why%20Agile%20Won%C3%A2%E2%82%AC%E2%84%A2t%20Fix%20Your%20Project&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
					<wfw:commentRss>http://suckup.de/2025/01/why-agile-wont-fix-your-project/?pk_campaign=feed&amp;pk_kwd=why-agile-wont-fix-your-project/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">6948</post-id>	</item>
		<item>
		<title>LLM Prompt Optimizations: Practical Techniques for Developers</title>
		<link>http://suckup.de/2025/01/llm-prompt-optimizations-practical-techniques-for-developers/?pk_campaign=feed&amp;pk_kwd=llm-prompt-optimizations-practical-techniques-for-developers&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=llm-prompt-optimizations-practical-techniques-for-developers</link>
					<comments>http://suckup.de/2025/01/llm-prompt-optimizations-practical-techniques-for-developers/?pk_campaign=feed&amp;pk_kwd=llm-prompt-optimizations-practical-techniques-for-developers#respond</comments>
		
		<dc:creator><![CDATA[voku]]></dc:creator>
		<pubDate>Fri, 24 Jan 2025 00:16:57 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[LLM]]></category>
		<guid isPermaLink="false">https://suckup.de/?p=6940</guid>

					<description><![CDATA[<p><a href="http://suckup.de/2025/01/llm-prompt-optimizations-practical-techniques-for-developers/?pk_campaign=feed&#038;pk_kwd=llm-prompt-optimizations-practical-techniques-for-developers">LLM Prompt Optimizations: Practical Techniques for Developers</a></p>
<p>Optimizing inputs for LLMs ensures better, more consistent outputs while leveraging the full potential of the model&#8217;s underlying capabilities. By understanding core concepts like tokenization, embeddings, self-attention, and context limits, you can tailor inputs to achieve desired outcomes reliably. Below, you&#8217;ll find fundamental techniques and best practices organized into practical strategies. PS: You can use &#8230; <a href="http://suckup.de/2025/01/llm-prompt-optimizations-practical-techniques-for-developers/?pk_campaign=feed&#038;pk_kwd=llm-prompt-optimizations-practical-techniques-for-developers" class="more-link">Continue reading <span class="screen-reader-text">LLM Prompt Optimizations: Practical Techniques for Developers</span></a><img src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F01%2Fllm-prompt-optimizations-practical-techniques-for-developers%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dllm-prompt-optimizations-practical-techniques-for-developers&amp;action_name=LLM%20Prompt%20Optimizations%3A%20Practical%20Techniques%20for%20Developers&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" /></p>
]]></description>
										<content:encoded><![CDATA[<p><a href="http://suckup.de/2025/01/llm-prompt-optimizations-practical-techniques-for-developers/?pk_campaign=feed&#038;pk_kwd=llm-prompt-optimizations-practical-techniques-for-developers">LLM Prompt Optimizations: Practical Techniques for Developers</a></p>

<p class="wp-block-paragraph">Optimizing inputs for LLMs ensures better, more consistent outputs while leveraging the full potential of the model&#8217;s underlying capabilities. By understanding core concepts like tokenization, embeddings, self-attention, and context limits, you can tailor inputs to achieve desired outcomes reliably. Below, you&#8217;ll find fundamental techniques and best practices organized into practical strategies.</p>



<p>PS: You can use this content to automatically improve your prompt by asking as follows: <a class="THGLZiYzqWGWKdttMOgKMIHkarZmDticds " href="https://chatgpt.com/share/6785a41d-72a0-8002-a1fe-52c14a5fb1e5" target="_self" data-test-app-aware-link="">https://chatgpt.com/share/6785a41d-72a0-8002-a1fe-52c14a5fb1e5</a></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">ðŸŽ¯ 1. Controlling Probabilities: Guide Model Outputs</h3>



<p class="wp-block-paragraph"><a href="#-1-controlling-probabilities-guide-model-outputs"></a></p>



<p class="wp-block-paragraph">ðŸ§  <strong>Theory:</strong> LLMs always follow probabilities when generating text. For every token, the model calculates a probability distribution based on the context provided. By carefully structuring inputs or presenting examples, we can shift the probabilities toward the desired outcome:</p>



<ul class="wp-block-list">
<li>Providing more examples helps the model identify patterns and generate similar outputs.</li>



<li>Clear instructions reduce ambiguity, increasing the probability of generating focused responses.</li>



<li>Contextual clues and specific phrasing subtly guide the model to prioritize certain outputs.</li>
</ul>



<p class="wp-block-paragraph">âš<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ï¸ <strong>Technology:</strong> The model operates using token probabilities:</p>



<ul class="wp-block-list">
<li>Each token (word or part of a word) is assigned a likelihood based on the input context.</li>



<li>By influencing the input, we can make certain tokens more likely to appear in the output.</li>
</ul>



<p class="wp-block-paragraph">For example:</p>



<ul class="wp-block-list">
<li>A general query like &#8220;Explain energy sources&#8221; might distribute probabilities evenly across different energy types.</li>



<li>A more specific query like &#8220;Explain why solar energy is sustainable&#8221; shifts the probabilities toward solar-related tokens.</li>
</ul>



<p class="wp-block-paragraph">âš<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ï¸ <strong>Shifting Probabilities in Prompts:</strong> The structure and wording of your prompt significantly influence the token probabilities:</p>



<ul class="wp-block-list">
<li><strong>For specific outputs:</strong> Use targeted phrasing to increase the likelihood of desired responses: <code>Explain why renewable energy reduces greenhouse gas emissions.</code></li>



<li><strong>For diverse outputs:</strong> Frame open-ended questions to distribute probabilities across a broader range of topics: <code>What are the different ways to generate clean energy?</code></li>



<li><strong>Few-Shot Learning:</strong> Guide the model using few-shot learning to set patterns: <code>Example 1: Input: Solar energy converts sunlight into electricity. Output: Solar energy is a renewable power source. Example 2: Input: Wind energy generates power using turbines. Output: Wind energy is clean and sustainable. Task: Input: Hydropower generates electricity from flowing water. Output:</code></li>
</ul>



<p class="wp-block-paragraph">ðŸ’¡ <strong>Prompt Tips:</strong></p>



<ul class="wp-block-list">
<li>Use clear, direct instructions for precise outputs: <code>Write a PHP function that adds two integers and returns a structured response as an array.</code></li>



<li>Use contextual clues to steer the response: <code>Explain why PHP is particularly suited for web development.</code></li>
</ul>



<p class="wp-block-paragraph">ðŸ’» <strong>Code Tips:</strong> LLMs break down code and comments into tokens, so structuring your PHPDocs helps focus probabilities effectively. Provide clarity and guidance through structured documentation:</p>



<pre class="wp-block-preformatted">/**
 * Adds two integers and returns a structured response.
 *
 * @param int $a The first number.
 * @param int $b The second number.
 * 
 * @return array{result: int, message: string} A structured response with the sum and a message.
 */
function addIntegers(int $a, int $b): array {
    $sum = $a + $b;

    return [
        'result' =&gt; $sum,
        'message' =&gt; "The sum of $a and $b is $sum."
    ];
}</pre>



<ul class="wp-block-list">
<li>Include examples in PHPDocs to further refine the probabilities of correct completions: /** * Example: * Input: addIntegers(3, 5) * Output: [&#8216;result&#8217; => 8, &#8216;message&#8217; => &#8216;The sum of 3 and 5 is 8&#8217;] */</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">âœ‚ï¸ 2. Tokenization and Embeddings: Use Context Efficiently</h3>



<p class="wp-block-paragraph"><a href="#ï¸-2-tokenization-and-embeddings-use-context-efficiently"></a></p>



<p class="wp-block-paragraph">ðŸ§  <strong>Theory:</strong> LLMs break down words into tokens (numbers) to relate them to each other in multidimensional embeddings (vectors). The more meaningful context you provide, the better the model can interpret relationships and generate accurate outputs:</p>



<ul class="wp-block-list">
<li>Tokens like &#8220;renewable energy&#8221; and &#8220;sustainability&#8221; have semantic proximity in the embedding space.</li>



<li>More context allows the model to generate richer and more coherent responses.</li>
</ul>



<p class="wp-block-paragraph">âš<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ï¸ <strong>Technology:</strong></p>



<ul class="wp-block-list">
<li>Tokens are the smallest units the model processes. For example, &#8220;solar&#8221; and &#8220;energy&#8221; may be separate tokens, or in compound languages like German, one long word might be broken into multiple tokens.</li>



<li>Embeddings map these tokens into vectors, enabling the model to identify their relationships in high-dimensional space.</li>
</ul>



<p class="wp-block-paragraph">âš<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ï¸ <strong>Optimizing Tokenization in Prompts:</strong> To make the most of tokenization and embeddings:</p>



<ul class="wp-block-list">
<li><strong>Minimize irrelevant tokens:</strong> Focus on core concepts and avoid verbose instructions.</li>



<li><strong>Include context-rich phrases:</strong> Relevant terms improve the embedding connections.</li>



<li><strong>Simplify Language:</strong> Use concise phrasing to minimize token count: <code>Solar energy is renewable and reduces emissions.</code></li>



<li><strong>Remove Redundancy:</strong> Eliminate repeated or unnecessary words: <code>Explain why solar energy is sustainable.</code></li>
</ul>



<p class="wp-block-paragraph">ðŸ’¡ <strong>Prompt Tips:</strong></p>



<ul class="wp-block-list">
<li>Include only essential terms for better embedding proximity: <code>Describe how solar panels generate electricity using photovoltaic cells.</code></li>



<li>Avoid vague or verbose phrasing: <code>Explain solar energy and its uses in a way that a normal person can understand and provide details.</code></li>



<li>Use specific language to avoid diluting the context: <code>Explain why solar energy is considered environmentally friendly and cost-effective.</code></li>



<li>Avoid vague instructions that lack actionable context: <code>Explain me solar energy.</code></li>
</ul>



<p class="wp-block-paragraph">ðŸ’» <strong>Code Tips:</strong> Write compact and clear PHPDocs to save tokens and improve context:</p>



<pre class="wp-block-preformatted">/**
 * Converts raw user input into a structured format.
 *
 * @param string $input Raw input data.
 * 
 * @return array{key: int, value: string} Structured output.
 */
function parseInput(string $input): array {
    $parts = explode(":", $input);

    return [
        'key' =&gt; (int)$parts[0],
        'value' =&gt; trim($parts[1])
    ];
}</pre>



<ul class="wp-block-list">
<li>Use compact and descriptive documentation to maximize token efficiency: /** * Example: * Input: &#8220;42:Hello&#8221; * Output: [&#8216;foo&#8217; => 42, &#8216;bar&#8217; => &#8216;Hello&#8217;] */</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">ðŸ§­ 3. Self-Attention and Structure: Prioritize Context</h3>



<p class="wp-block-paragraph"><a href="#-3-self-attention-and-structure-prioritize-context"></a></p>



<p class="wp-block-paragraph">ðŸ§  <strong>Theory:</strong> LLMs work with the principle of <a href="https://towardsdatascience.com/deep-dive-into-self-attention-by-hand-%EF%B8%8E-f02876e49857" target="_blank" rel="noreferrer noopener nofollow">self-attention</a>, where the input tokens are interrelated with each other to determine the relevance and context. This mechanism assigns importance scores to tokens, ensuring that the most relevant words and their relationships are prioritized.</p>



<p class="wp-block-paragraph">âš<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ï¸ <strong>Technology:</strong></p>



<ul class="wp-block-list">
<li><strong>Self-attention layers:</strong> Compare each token with every other token in the input to generate an attention score.</li>



<li><strong>Multi-head attention:</strong> Allows the model to consider multiple perspectives simultaneously, balancing relevance and context.</li>



<li><strong>Pitfall:</strong> Too many irrelevant tokens dilute the attention scores, leading to distorted outputs.</li>
</ul>



<p class="wp-block-paragraph">âš<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ï¸ <strong>Optimizing Structure in Prompts:</strong></p>



<ul class="wp-block-list">
<li><strong>Structure Your Inputs:</strong> Use lists, steps, or sections to emphasize relationships: <code>Compare the benefits of solar and wind energy: 1. Environmental impact 2. Cost-efficiency 3. Scalability</code></li>



<li><strong>Minimize Irrelevant Tokens:</strong> Keep prompts focused and free from extraneous details.</li>
</ul>



<p class="wp-block-paragraph">ðŸ’¡ <strong>Prompt Tips:</strong></p>



<ul class="wp-block-list">
<li><strong>Well-Structured:</strong> Organize tasks into sections: <code>Explain the environmental and economic benefits of renewable energy in two sections: 1. Environmental 2. Economic</code></li>



<li><strong>Unstructured:</strong> Avoid asking everything at once: <code>What are the environmental and economic benefits of renewable energy?</code></li>
</ul>



<p class="wp-block-paragraph">ðŸ’» <strong>Code Tips:</strong> In PHPDocs, organize information logically to enhance clarity and guide models effectively:</p>



<pre class="wp-block-preformatted">/**
 * Calculates the cost efficiency of renewable energy.
 *
 * Steps:
 * 1. Evaluate savings-to-investment ratio.
 * 2. Return a percentage efficiency score.
 *
 * @param float $investment Initial investment cost.
 * @param float $savings Annual savings.
 * 
 * @return float Efficiency percentage.
 */
function calculateEfficiency(float $investment, float $savings): float {
    return ($savings / $investment) * 100;
}</pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">ðŸ§¹ 4. Context Management and Token Limits</h3>



<p class="wp-block-paragraph"><a href="#-4-context-management-and-token-limits"></a></p>



<p class="wp-block-paragraph">ðŸ§  <strong>Theory:</strong> LLMs operate within a fixed token limit (e.g., ~8k tokens for GPT-4), encompassing both input and output. Efficiently managing context ensures relevant information is prioritized while avoiding irrelevant or redundant content.</p>



<p class="wp-block-paragraph">âš<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ï¸ <strong>Technology:</strong></p>



<ul class="wp-block-list">
<li><strong>Chunking:</strong> Break long inputs into smaller, manageable parts: <code>Step 1: Summarize the introduction of the report. Step 2: Extract key arguments from Section 1. Step 3: Combine summaries for a final overview.</code></li>



<li><strong>Iterative Summarization:</strong> Condense sections before integrating them: <code>Summarize Section 1: Solar energyâ€&#x2122;s benefits. Summarize Section 2: Wind energyâ€&#x2122;s benefits. Combine both summaries.</code></li>



<li><strong>Pitfall:</strong> Excessive context can truncate critical data due to token limits.</li>
</ul>



<p class="wp-block-paragraph">ðŸ’¡ <strong>Prompt Tips:</strong></p>



<ul class="wp-block-list">
<li>For large inputs, use step-by-step processing: <code>Step 1: Summarize the introduction of the document. Step 2: Extract key arguments from Section 1. Step 3: Combine these points into a cohesive summary.</code></li>



<li>Avoid presenting the full text in a single prompt: <code>Summarize this 20-page document.</code></li>



<li>Focus on specific sections or tasks: <code>Summarize the introduction and key points from Section 1.</code></li>
</ul>



<p class="wp-block-paragraph">ðŸ’» <strong>Code Tips:</strong> Divide tasks into smaller functions to handle token limits better:</p>



<pre class="wp-block-preformatted">function summarizeSection(string $section): string {
    // Summarize section content.
}

function combineSummaries(array $summaries): string {
    // Merge individual summaries.
}</pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">ðŸŽ¨ 5. Reasoning and Goals: Strengthen Prompt Direction</h3>



<p class="wp-block-paragraph"><a href="#-5-reasoning-and-goals-strengthen-prompt-direction"></a></p>



<p class="wp-block-paragraph">ðŸ§  <strong>Theory:</strong> LLMs generate better results when the reasoning behind a task and its intended goal are explicitly stated. This guides the model&#8217;s probabilities toward meaningful and relevant outcomes.</p>



<p class="wp-block-paragraph">âš<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ï¸ <strong>Technology:</strong></p>



<ul class="wp-block-list">
<li>Explicit reasoning provides semantic depth, helping the model focus on the taskâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s purpose.</li>



<li>Explaining the goal improves alignment with user expectations and narrows token probabilities.</li>
</ul>



<p class="wp-block-paragraph">ðŸ’¡ <strong>Prompt Tips:</strong></p>



<ul class="wp-block-list">
<li>State the reason for the task and its goal: <code>Explain renewable energy because I need to create an introductory guide for high school students.</code></li>



<li>Avoid generic prompts without a clear goal: <code>Describe renewable energy.</code></li>
</ul>



<p class="wp-block-paragraph">ðŸ’» <strong>Code Tips:</strong> Use PHPDocs to explain both the reasoning and expected outcomes of a function:</p>



<pre class="wp-block-preformatted">/**
 * Generates a detailed user profile report.
 *
 * This function is designed to create a comprehensive profile report based on user data inputs. 
 * It is useful for analytical dashboards requiring well-structured user insights.
 *
 * @param array{name: string, age: int, email: string} $userData The user data array.
 * 
 * @return string A formatted profile report.
 */
function generateProfileReport(array $userData): string {
    return sprintf(
        "User Profile:\nName: %s\nAge: %d\nEmail: %s\n",
        $userData['name'],
        $userData['age'],
        $userData['email']
    );
}</pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">ðŸ› ï¸ 6. Iterative Refinement: Simplify Complex Tasks</h3>



<p class="wp-block-paragraph"><a href="#ï¸-6-iterative-refinement-simplify-complex-tasks"></a></p>



<p class="wp-block-paragraph">ðŸ§  <strong>Theory:</strong><br />Breaking down complex tasks into smaller, manageable steps improves accuracy and ensures the model generates focused and coherent outputs. This method allows you to iteratively refine results, combining outputs from smaller subtasks into a complete solution.</p>



<p class="wp-block-paragraph">âš<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ï¸ <strong>Technology:</strong></p>



<ul class="wp-block-list">
<li><strong>Chunking:</strong> Split large tasks into multiple smaller ones to avoid overwhelming the model.</li>



<li><strong>Validation:</strong> Intermediate outputs can be validated before moving to the next step, minimizing errors.</li>



<li><strong>Recombination:</strong> Smaller validated outputs are merged for the final result.</li>
</ul>



<p class="wp-block-paragraph">ðŸ’¡ <strong>Prompt Tips:</strong></p>



<ul class="wp-block-list">
<li>For multi-step tasks, provide clear, incremental instructions: <code>Step 1: Summarize the environmental benefits of solar energy. Step 2: Describe the cost savings associated with solar energy. Step 3: Combine these summaries into a single paragraph.</code></li>



<li>Avoid handling complex tasks in a single step: <code>Explain the environmental benefits and cost savings of solar energy in one response.</code></li>
</ul>



<p class="wp-block-paragraph">ðŸ’» <strong>Code Tips:</strong> Ask the LLM to create the code step by step and ask for confirmation after each step so that the LLM can focus on one aspect of the implementation at a time. Focus on one aspect of the implementation at a time.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">ðŸ”— 7. Cross-Contextual Coherence: Maintain Consistency</h3>



<p class="wp-block-paragraph"><a href="#-7-cross-contextual-coherence-maintain-consistency"></a></p>



<p class="wp-block-paragraph">ðŸ§  <strong>Theory:</strong><br />LLMs lack persistent memory between interactions, making it essential to reintroduce necessary context for consistent responses across prompts. By maintaining cross-contextual coherence, outputs remain aligned and relevant, even in multi-step interactions.</p>



<p class="wp-block-paragraph">âš<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ï¸ <strong>Technology:</strong></p>



<ul class="wp-block-list">
<li>Use <strong>context bridging</strong>: Reference key elements from previous responses to maintain relevance.</li>



<li>Store critical details in persistent structures, such as arrays or JSON, to reintroduce when needed.</li>



<li>Avoid overloading with irrelevant details, which can dilute coherence.</li>
</ul>



<p class="wp-block-paragraph">ðŸ’¡ <strong>Prompt Tips:</strong></p>



<ul class="wp-block-list">
<li>Reintroduce essential context from previous interactions: <code>Based on our discussion about renewable energy, specifically solar power, explain the benefits of wind energy.</code></li>



<li>Summarize intermediate outputs for clarity: <code>Summarize the main benefits of renewable energy. Then expand on solar and wind energy.</code></li>
</ul>



<p class="wp-block-paragraph">ðŸ’» <strong>Code Tips:</strong> Use seperated files for Code-Examples that we can provide e.g. <code>Custom GPTs</code> so it can learn from learnings/findings this way.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">ðŸŒ 8. Style and Tone: Adapt Outputs to the Audience</h3>



<p class="wp-block-paragraph"><a href="#-8-style-and-tone-adapt-outputs-to-the-audience"></a></p>



<p class="wp-block-paragraph">ðŸ§  <strong>Theory:</strong> LLMs generate better responses when the desired style and tone are explicitly stated. By matching the tone to the audience, you can make content more engaging and effective.</p>



<p class="wp-block-paragraph">âš<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ï¸ <strong>Technology:</strong></p>



<ul class="wp-block-list">
<li>The model uses semantic cues in the prompt to adjust style and tone.</li>



<li>Specific words and phrases like &#8220;formal,&#8221; &#8220;casual,&#8221; or &#8220;technical&#8221; help steer the modelâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s output.</li>
</ul>



<p class="wp-block-paragraph">ðŸ’¡ <strong>Prompt Tips:</strong></p>



<ul class="wp-block-list">
<li>Specify the tone and audience: <code>Write a technical explanation of solar panels for an engineering audience.</code></li>



<li>Adjust the style for different contexts: <code>Explain solar panels in a simple and friendly tone for kids.</code></li>
</ul>



<p class="wp-block-paragraph">ðŸ’» <strong>Code Tips:</strong> In PHPDocs, define the intended audience and tone to guide LLM-generated documentation:</p>



<pre class="wp-block-preformatted">/**
 * Calculates the total energy output of a solar panel system.
 *
 * Intended Audience: Engineers and technical experts.
 * Tone: Formal and technical.
 *
 * @param float $panelArea The total area of solar panels in square meters.
 * @param float $efficiency The efficiency rate of the solar panels (0-1).
 * @param float $sunlightHours Daily sunlight hours.
 * 
 * @return float Total energy output in kilowatt-hours.
 */
function calculateSolarOutput(float $panelArea, float $efficiency, float $sunlightHours): float {
    return $panelArea * $efficiency * $sunlightHours;
}</pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">ðŸ” 9. Fine-Tuning and Domain Expertise</h3>



<p class="wp-block-paragraph"><a href="#-9-fine-tuning-and-domain-expertise"></a></p>



<p class="wp-block-paragraph">ðŸ§  <strong>Theory:</strong> Fine-tuning allows LLMs to specialize in specific domains by further training them on domain-specific datasets. This enhances their ability to generate accurate, relevant, and nuanced outputs tailored to specialized tasks or fields.</p>



<p class="wp-block-paragraph">âš<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ï¸ <strong>Technology:</strong></p>



<ul class="wp-block-list">
<li>Fine-tuning adjusts the weights of a pre-trained model by using a curated dataset that focuses on a specific domain.</li>



<li>This process requires labeled data and computational resources but significantly improves task performance in niche areas.</li>
</ul>



<p class="wp-block-paragraph">ðŸ’¡ <strong>Prompt Tips:</strong></p>



<ul class="wp-block-list">
<li>Use fine-tuning to simplify prompts for repeated tasks: <code>Generate a legal brief summarizing the key points from this case.</code></li>



<li>Without fine-tuning, include detailed instructions and examples in your prompt: <code>Write a summary of this legal case focusing on liability and negligence, using a formal tone.</code></li>
</ul>



<p class="wp-block-paragraph">ðŸ’» <strong>Code Tips:</strong> When fine-tuning is not an option, structure your PHPDocs to include domain-specific context for LLMs:</p>



<pre class="wp-block-preformatted">/**
 * Generates a compliance report for renewable energy projects.
 *
 * This function creates a detailed compliance report tailored for regulatory agencies. It checks for adherence to
 * energy efficiency standards and sustainability guidelines.
 *
 * @param array&lt;string, mixed&gt; $projectData Details of the renewable energy project.
 * @param string $region The region for which the compliance report is generated.
 * 
 * @return string The compliance report in a formatted string.
 */
function generateComplianceReport(array $projectData, string $region): string {
    // Example report generation logic.
    return sprintf(
        "Compliance Report for %s:\nProject: %s\nStatus: %s\n",
        $region,
        $projectData['name'] ?? 'Unnamed Project',
        $projectData['status'] ?? 'Pending Review'
    );
}</pre>
<img loading="lazy" decoding="async" src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F01%2Fllm-prompt-optimizations-practical-techniques-for-developers%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dllm-prompt-optimizations-practical-techniques-for-developers&amp;action_name=LLM%20Prompt%20Optimizations%3A%20Practical%20Techniques%20for%20Developers&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
					<wfw:commentRss>http://suckup.de/2025/01/llm-prompt-optimizations-practical-techniques-for-developers/?pk_campaign=feed&amp;pk_kwd=llm-prompt-optimizations-practical-techniques-for-developers/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">6940</post-id>	</item>
		<item>
		<title>The Wild West of Coding: Why Weâ€™re Still Burning Digital Cities</title>
		<link>http://suckup.de/2025/01/the-wild-west-of-coding-why-were-still-burning-digital-cities/?pk_campaign=feed&amp;pk_kwd=the-wild-west-of-coding-why-were-still-burning-digital-cities&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=the-wild-west-of-coding-why-were-still-burning-digital-cities</link>
					<comments>http://suckup.de/2025/01/the-wild-west-of-coding-why-were-still-burning-digital-cities/?pk_campaign=feed&amp;pk_kwd=the-wild-west-of-coding-why-were-still-burning-digital-cities#comments</comments>
		
		<dc:creator><![CDATA[voku]]></dc:creator>
		<pubDate>Thu, 23 Jan 2025 23:57:41 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<guid isPermaLink="false">https://suckup.de/?p=6935</guid>

					<description><![CDATA[<p><a href="http://suckup.de/2025/01/the-wild-west-of-coding-why-were-still-burning-digital-cities/?pk_campaign=feed&#038;pk_kwd=the-wild-west-of-coding-why-were-still-burning-digital-cities">The Wild West of Coding: Why Weâ€™re Still Burning Digital Cities</a></p>
<p>The year 2050 is closer than the year 1990, yet weâ€™re still writing code like itâ€™s the 1800s. Itâ€™s 2025, and while weâ€™ve made incredible strides in software developmentâ€”automated memory management, static analysis tools, refactoring IDEs, and AI copilots like ChatGPTâ€”it still feels like the Wild West. Sure, the tools are better, but the way &#8230; <a href="http://suckup.de/2025/01/the-wild-west-of-coding-why-were-still-burning-digital-cities/?pk_campaign=feed&#038;pk_kwd=the-wild-west-of-coding-why-were-still-burning-digital-cities" class="more-link">Continue reading <span class="screen-reader-text">The Wild West of Coding: Why Weâ€™re Still Burning Digital Cities</span></a><img src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F01%2Fthe-wild-west-of-coding-why-were-still-burning-digital-cities%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dthe-wild-west-of-coding-why-were-still-burning-digital-cities&amp;action_name=The%20Wild%20West%20of%20Coding%3A%20Why%20We%C3%A2%E2%82%AC%E2%84%A2re%20Still%20Burning%20Digital%20Cities&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" /></p>
]]></description>
										<content:encoded><![CDATA[<p><a href="http://suckup.de/2025/01/the-wild-west-of-coding-why-were-still-burning-digital-cities/?pk_campaign=feed&#038;pk_kwd=the-wild-west-of-coding-why-were-still-burning-digital-cities">The Wild West of Coding: Why Weâ€™re Still Burning Digital Cities</a></p>

<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph">The year 2050 is closer than the year 1990, yet weâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re still writing code like itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s the 1800s.</p>



<p class="wp-block-paragraph">Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s 2025, and while weâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve made incredible strides in software developmentâ€”automated memory management, static analysis tools, refactoring IDEs, and AI copilots like ChatGPTâ€”it still feels like the Wild West. Sure, the tools are better, but the way we approach software remains chaotic, inefficient, and overly reliant on custom solutions.</p>



<p class="wp-block-paragraph">Every day, thousands of developers solve the same problems repeatedly. Companies roll out their own authentication systems, file upload handlers, and error trackers. Many of these are flawed. Vulnerabilities creep in because weâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re not building resilient systemsâ€”weâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re building digital bonfires.</p>



<p class="wp-block-paragraph">This isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t progress. This is the time before the First Industrial Revolution of Software Development.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Lessons from History: What the Past Teaches About Our Digital Fires</strong></h3>



<h4 class="wp-block-heading"><strong>1. The Great Fire of Hamburg (1842): Building Without Safety</strong></h4>



<p class="wp-block-paragraph">In 1842, a quarter of Hamburg burned to the ground. The cityâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s lack of fire safety standardsâ€”wooden buildings, narrow streets, no prevention systemsâ€”made disaster inevitable.</p>



<p class="wp-block-paragraph">Software today mirrors this recklessness:</p>



<ul class="wp-block-list">
<li>File upload systems without malware checks.</li>



<li>APIs with vulnerabilities because â€œitâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s faster to skip security.â€</li>



<li>Custom-built logging systems without consistency or reliability.</li>
</ul>



<p class="wp-block-paragraph">After the fire, Hamburg rebuilt with fireproof materials and strict regulations. We need the same shift in software development: adopting <strong>universal standards</strong>, <strong>secure-by-design frameworks</strong>, and <strong>centralized tools</strong> to prevent disaster before it happens.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h4 class="wp-block-heading"><strong>2. Electrical Sockets in the Early 1900s: Chaos Without Standards</strong></h4>



<p class="wp-block-paragraph">Before standardization, electrical sockets were a mess. Every region had its own plug type, making interoperability nearly impossible. Plugging in a device often meant wasting time finding the right adapter.</p>



<p class="wp-block-paragraph">Software development today is no different:</p>



<ul class="wp-block-list">
<li>APIs lack consistent patterns.</li>



<li>Libraries solve the same problem in incompatible ways.</li>



<li>Developers reinvent logging, error handling, and authentication with every project.</li>
</ul>



<p class="wp-block-paragraph">The solution? <strong>Standardized, language-agnostic tools</strong>â€”the equivalent of universal plug designs. Imagine APIs and services that integrate seamlessly across languages and frameworks:</p>



<ul class="wp-block-list">
<li>Centralized <strong>logging and error tracking APIs</strong>, similar to Sentry but designed for internal use with cross-language compatibility.</li>



<li>High-performance <strong>Unix socket APIs</strong> for tasks like logging, monitoring, and file scanning.</li>



<li>Shared SDKs for foundational needs like security or metrics collection.</li>
</ul>



<p class="wp-block-paragraph">By building shared infrastructure, we could eliminate redundant work and improve reliability across projects.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h4 class="wp-block-heading"><strong>3. The Facade Problem: Buying Software for Looks, Not Stability</strong></h4>



<p class="wp-block-paragraph">Imagine buying a house because the facade looks amazing but never checking the foundation. Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s how most software is evaluated today:</p>



<ul class="wp-block-list">
<li>Buyers focus on flashy UIs and marketing demos.</li>



<li>Security, scalability, and maintainability are often ignored.</li>
</ul>



<p class="wp-block-paragraph">This approach leads to brittle, insecure systems. Whatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s missing? <strong>Inspectors for digital bridges</strong>â€”specialized roles that assess software foundations, enforce accountability, and ensure systems are solid beneath their shiny exteriors.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Moving Toward the First Industrial Revolution of Software Development</strong></h3>



<p class="wp-block-paragraph">The Industrial Revolution replaced handcrafting with standardization and mass production. Software development is still stuck in its pre-industrial phase:</p>



<ul class="wp-block-list">
<li>Custom solutions are built repeatedly for the same problems.</li>



<li>Accountability is rareâ€”no one ensures the &#8220;bridge&#8221; (software) is stable before itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s deployed.</li>
</ul>



<p class="wp-block-paragraph">To mature as an industry, we need:</p>



<h4 class="wp-block-heading"><strong>1. Universal Blueprints</strong></h4>



<p class="wp-block-paragraph">Developers today still create bespoke solutions for common problems. We need standardized tools and APIs, such as:</p>



<ul class="wp-block-list">
<li>A <strong>unified SDK for antivirus scanning</strong>, accessible via <code>/usr/sbin/antivirus</code> or <code>unix:///var/run/antivirus</code>.</li>



<li>Centralized APIs for error tracking, metrics, and monitoring, with cross-language support.</li>
</ul>



<h4 class="wp-block-heading"><strong>2. Specialized Roles</strong></h4>



<p class="wp-block-paragraph">In the 19th century, collapsing bridges led to the creation of specialized roles: architects for design, builders for execution, and inspectors for safety. Software teams need similar specialization:</p>



<ul class="wp-block-list">
<li><strong>System Inspectors</strong> to evaluate software for security, scalability, and maintainability.</li>



<li><strong>Digital Firefighters</strong> to enforce standards and proactively address vulnerabilities.</li>
</ul>



<h4 class="wp-block-heading"><strong>3. Accountability</strong></h4>



<p class="wp-block-paragraph">When a bridge collapses, someone is held responsible. In software, failures are often patched silently or ignored. We need:</p>



<ul class="wp-block-list">
<li>Transparency: Bugs and vulnerabilities must be documented openly.</li>



<li>Retrospectives: Focused on systemic improvements, not just quick fixes.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Building Digital Cities That Donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t Burn</strong></h3>



<p class="wp-block-paragraph">Imagine a future where software is built like modern cities:</p>



<ul class="wp-block-list">
<li><strong>Fireproof Systems</strong>: Universal standards for security, maintainability, and testing.</li>



<li><strong>Digital Firefighters</strong>: Publicly funded teams safeguarding critical infrastructure.</li>



<li><strong>Inspectors for Digital Bridges</strong>: Specialized roles ensuring software is built to last.</li>
</ul>



<p class="wp-block-paragraph">AI tools like GPT can help accelerate this process, but they are not the solution. AI is like the steam engine of programmingâ€”amplifying productivity but requiring skilled operators. If we donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t lay the right foundations, AI will only magnify our inefficiencies.</p>



<p class="wp-block-paragraph">This future isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t about writing more codeâ€”itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s about creating <strong>resilient, scalable systems</strong> that stand the test of time. The tools to build fireproof digital cities are already here. The question is: are we ready to use them?</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph">Letâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s move beyond the Wild West of coding and into the Industrial Revolution our industry desperately needs. Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s time to stop building bonfires and start building something that lasts.</p>


<img loading="lazy" decoding="async" src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2025%2F01%2Fthe-wild-west-of-coding-why-were-still-burning-digital-cities%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dthe-wild-west-of-coding-why-were-still-burning-digital-cities&amp;action_name=The%20Wild%20West%20of%20Coding%3A%20Why%20We%C3%A2%E2%82%AC%E2%84%A2re%20Still%20Burning%20Digital%20Cities&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
					<wfw:commentRss>http://suckup.de/2025/01/the-wild-west-of-coding-why-were-still-burning-digital-cities/?pk_campaign=feed&amp;pk_kwd=the-wild-west-of-coding-why-were-still-burning-digital-cities/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">6935</post-id>	</item>
		<item>
		<title>Legacy Codebase: A Love Story</title>
		<link>http://suckup.de/2023/01/legacy-codebase-a-love-story/?pk_campaign=feed&amp;pk_kwd=legacy-codebase-a-love-story&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=legacy-codebase-a-love-story</link>
					<comments>http://suckup.de/2023/01/legacy-codebase-a-love-story/?pk_campaign=feed&amp;pk_kwd=legacy-codebase-a-love-story#respond</comments>
		
		<dc:creator><![CDATA[voku]]></dc:creator>
		<pubDate>Wed, 04 Jan 2023 01:45:22 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">https://suckup.de/?p=6911</guid>

					<description><![CDATA[<p><a href="http://suckup.de/2023/01/legacy-codebase-a-love-story/?pk_campaign=feed&#038;pk_kwd=legacy-codebase-a-love-story">Legacy Codebase: A Love Story</a></p>
<p>After some years, working with a > 10 years old legacy PHP codebase, I can truly say: you can escape the legacy codebase and introduce whatever is helpful, in a well-maintained system. Here are 5 important steps that I have done: Here are 5 additional steps that I already introduce: Here is what helped me &#8230; <a href="http://suckup.de/2023/01/legacy-codebase-a-love-story/?pk_campaign=feed&#038;pk_kwd=legacy-codebase-a-love-story" class="more-link">Continue reading <span class="screen-reader-text">Legacy Codebase: A Love Story</span></a><img src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2023%2F01%2Flegacy-codebase-a-love-story%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dlegacy-codebase-a-love-story&amp;action_name=Legacy%20Codebase%3A%20A%20Love%20Story&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" /></p>
]]></description>
										<content:encoded><![CDATA[<p><a href="http://suckup.de/2023/01/legacy-codebase-a-love-story/?pk_campaign=feed&#038;pk_kwd=legacy-codebase-a-love-story">Legacy Codebase: A Love Story</a></p>

<p class="wp-block-paragraph">After some years, working with a > 10 years old legacy PHP codebase, I can truly say: you can escape the legacy codebase and introduce whatever is helpful, in a well-maintained system. </p>



<p class="wp-block-paragraph">Here are <strong>5</strong> important steps that I have done:</p>



<ul class="wp-block-list">
<li> <strong>Custom error handling</strong>: Reporting notices for developers, report bad &#8220;assert&#8221; calls in the dev container, report bad indexes, reporting wrong code usage, &#8230;</li>



<li><strong>Autocompletion for everything</strong>: classes, properties, SQL queries, CSS, HTML, JavaScript in PHP (e.g. via /* @lang JavaScript */ in PhpStorm), &#8230;</li>



<li><strong>Static-Code Analysis</strong>: Preventing bugs is even better than fixing bugs, so just stop stupid bugs and use types in your code.</li>



<li><strong>Automate the refactoring</strong>: With tools like PHP-CS-Fixer or Rector you can not only fix your code one time, you can fix any future wrong usage of the code.</li>



<li><strong>Do not use strings for code</strong>: Just use constants, classes, properties, &#8230; use something that can be processes by your static-code analysis and something where you will have autocompletion.  </li>
</ul>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Here are <strong>5</strong> additional steps that I already introduce:</p>



<ul class="wp-block-list">
<li><strong>Sentry</strong>: External error collecting (aggregating) tool + custom handler to see e.g. IDs of every Active Record object.</li>



<li><strong>Generics</strong>: via PHPDocs + autocompletion via PhpStorm</li>



<li><strong>No &#8220;mixed&#8221; types</strong>: Now we use something like, e.g. &#8220;array&lt;int, string>&#8221; instead of &#8220;array&#8221;.</li>



<li><strong>PSR standards</strong>: e.g. PSR-15 request handler, PSR-11 container, PSR-3 logger, &#8230; </li>



<li><strong>Code Style</strong>: One code style to rule them all, we use PHP-CS-Fixer and PHP-Code-Sniffer to check / fix our code style for all ~ 10,000 PHP classes.</li>
</ul>





<h3>Here is what helped me mostly while working with old existing code.</h3>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">First rule, first: ðŸ¥‡ <em>think</em> or / and ask someone in the team</p>
</blockquote>



<h4 class="wp-block-heading"><span style="text-decoration: underline;">Analyzing</span>: Here are some things that helped my analyzing software problems in our codebase.</h4>



<ul class="wp-block-list">
<li><strong>Errors:</strong> Better error handling / reporting with a custom error handler, with all relevant information.</li>



<li><strong>Understandable logging</strong>: Hint, you can just use syslog for medium-sized applications.</li>



<li><strong>Grouping errors</strong>: Displaying and grouping all the stuff (PHP / JS / errors + our own custom reports) into Sentry (<a href="https://sentry.io/" target="_blank" rel="noreferrer noopener nofollow">https://sentry.io/</a>), now you can easily see how e.g. how many customers are effected from an error.</li>



<li><strong>git history</strong>: Often new bugs were introduced with the latest changes (at least in often used components), so that good commit messages are really helpful to find this changes. (<a href="https://github.com/voku/dotfiles/wiki/git-commit-messages" target="_blank" rel="noreferrer noopener">https://github.com/voku/dotfiles/wiki/git-commit-messages</a>)</li>



<li><strong>Local containers</strong>: If you can just download the application with a database dump from yesterday, you can analyze many problems without touching any external server.</li>



<li><strong>Linux tools</strong>: mytop, strace, htop, iotop, lsof, &#8230;</li>



<li><strong>Database tools</strong>:Â Â EXPLAIN [SQL],Â IDE integration / autocompletion, &#8230;</li>
</ul>



<h4 class="wp-block-heading"><span style="text-decoration: underline;">Fixing</span>: Here are some tricks for fixing existing code more easily.</h4>



<ul class="wp-block-list">
<li><strong>IDE</strong>: PhpStorm with auto-completion and suggestions (including results from static analysis)</li>



<li><strong>auto-code-style formatter</strong>: (as pre-commit hook) is also helpful because I do not need to think about this anymore while fixing codeÂ </li>



<li><strong>git stuff</strong>: sometimes it can also be helpful to understand git and how to revert or cherry-pick some changes</li>
</ul>



<h4 class="wp-block-heading"><strong><span style="text-decoration: underline;">Preventing</span></strong>: Here are some hints how you can prevent some bugs.</h4>



<ul class="wp-block-list">
<li><strong>customÂ static analysis rules</strong>: <a href="http://suckup.de/2022/07/php-code-quality-with-custom-tooling-extensions/">http://suckup.de/2022/07/php-code-quality-with-custom-tooling-extensions/</a></li>



<li><strong>root cause</strong>: fixing the root cause of a problem, sometimes this is very hard because you need to fully understand the problem first, bust mostly spending this time is a good investment</li>



<li><strong>testing</strong>: writing a test is always a good idea, at least to prevent the same problem</li>
</ul>





<hr />
<p><strong>Job</strong>: If you now would like to work with this codebase (PHP 8 | MySQL 8 | Ubuntu), please contact <a href="https://www.linkedin.com/in/larsmoelleken/">me</a> and take a look at this job offer: <a href="https://meerx.de/karriere/softwareentwickler-softwareentwicklerin/" target="_blank" rel="noopener">https://meerx.de/karriere/softwareentwickler-softwareentwicklerin/</a></p>
<img loading="lazy" decoding="async" src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2023%2F01%2Flegacy-codebase-a-love-story%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dlegacy-codebase-a-love-story&amp;action_name=Legacy%20Codebase%3A%20A%20Love%20Story&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
					<wfw:commentRss>http://suckup.de/2023/01/legacy-codebase-a-love-story/?pk_campaign=feed&amp;pk_kwd=legacy-codebase-a-love-story/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">6911</post-id>	</item>
		<item>
		<title>What have I learned so far in my job?</title>
		<link>http://suckup.de/2023/01/what-have-i-learned-so-far-in-my-job/?pk_campaign=feed&amp;pk_kwd=what-have-i-learned-so-far-in-my-job&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=what-have-i-learned-so-far-in-my-job</link>
					<comments>http://suckup.de/2023/01/what-have-i-learned-so-far-in-my-job/?pk_campaign=feed&amp;pk_kwd=what-have-i-learned-so-far-in-my-job#respond</comments>
		
		<dc:creator><![CDATA[voku]]></dc:creator>
		<pubDate>Tue, 03 Jan 2023 23:55:03 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<guid isPermaLink="false">https://suckup.de/?p=6888</guid>

					<description><![CDATA[<p><a href="http://suckup.de/2023/01/what-have-i-learned-so-far-in-my-job/?pk_campaign=feed&#038;pk_kwd=what-have-i-learned-so-far-in-my-job">What have I learned so far in my job?</a></p>
<p>I will start a new job next month (02-2023), so time to recap, I&#8217;m going to describe what I&#8217;ve learned so far. me:Â Lars MoellekenÂ &#124;> Assistant for business IT> IT specialist for system integration> IT specialist for application development What did I learn as IT specialist for system integration? â€“ You only learn as much as &#8230; <a href="http://suckup.de/2023/01/what-have-i-learned-so-far-in-my-job/?pk_campaign=feed&#038;pk_kwd=what-have-i-learned-so-far-in-my-job" class="more-link">Continue reading <span class="screen-reader-text">What have I learned so far in my job?</span></a><img src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2023%2F01%2Fwhat-have-i-learned-so-far-in-my-job%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dwhat-have-i-learned-so-far-in-my-job&amp;action_name=What%20have%20I%20learned%20so%20far%20in%20my%20job%3F&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" /></p>
]]></description>
										<content:encoded><![CDATA[<p><a href="http://suckup.de/2023/01/what-have-i-learned-so-far-in-my-job/?pk_campaign=feed&#038;pk_kwd=what-have-i-learned-so-far-in-my-job">What have I learned so far in my job?</a></p>

<p class="wp-block-paragraph">I will start a new job next month (02-2023), so time to recap, I&#8217;m going to describe what I&#8217;ve learned so far.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><em>me:Â <a href="https://www.linkedin.com/in/larsmoelleken/" target="_blank" rel="noreferrer noopener">Lars Moelleken</a>Â |</em><br /><em>> Assistant for business IT</em><br /><em>> IT specialist for system integration</em><br /><em>> IT specialist for application development</em></p>
</blockquote>



<h2 class="wp-block-heading">What did I learn as IT specialist for system integration?</h2>



<h3 class="wp-block-heading">â€“ You only learn as much as you want to learn.</h3>



<p class="wp-block-paragraph">In contrast to school / technical college, I could and had to teach and work on many things myself during the training.&nbsp;And you quickly realize that you only learn as much as you want.&nbsp;Once you&#8217;ve understood this, you&#8217;re happy to sit down and learn whatever you want. For example, local or online courses, go to meetups or conferences.&nbsp;Worry about your skill because if you do something, you should do it right.</p>



<p class="wp-block-paragraph">â€œAn investment in knowledge still pays the best interest.â€&nbsp;â€“ Benjamin Franklin</p>



<h3 class="wp-block-heading">â€“ No panic!</h3>



<p class="wp-block-paragraph">What you learn pretty quickly as a sysadmin is â€œkeep calmâ€ and think first â€“ then act.&nbsp;Hasty actionism does not help and usually even damages.&nbsp;Before you act, you should first obtain some information yourself (information from log files, hardware status, system status, &#8230;) so that you really know how to fix the error.</p>



<h3 class="wp-block-heading">â€“ Unix &amp; command line &lt;3</h3>



<p class="wp-block-paragraph">If you haven&#8217;t worked with a Unix operating system before, you unfortunately don&#8217;t know what you&#8217;re missing out on.&nbsp;If you want or have to use Windows for whatever reason, you can nowadays still use some of the advantages of Linux via WSL (Windows Subsystem for Linux).&nbsp;Leave your own comfort zone and trying out new operating systems helps to understand your computer better overall.&nbsp;At this point, I would have recommended â€œArch Linuxâ€ as sysadmin, but today I would choose something that needs less maintaining. </p>



<p class="wp-block-paragraph">One should also become familiar with the command line if you want to increase your productivity rapidly.&nbsp;For example, you should take a closer look at the following commands: e.g. find / grep / lsof / strace</p>



<h3 class="wp-block-heading">â€“ Read the official documentation.</h3>



<p class="wp-block-paragraph">It is often better to read the official documentation of the thing (hardware || software) you are currently using.&nbsp;While you start programming or learn a new programming language / framework, we often use stackoverflow.com and quickly finds answers and code examples, but the &#8220;why&#8221; and &#8220;how&#8221; is usually neglected.&nbsp;If you look at the specification / documentation first, you not only solve this problem, you also understand the problem, and maybe you will learn how to solve similar problems.</p>



<h3 class="wp-block-heading">â€“ Always make a backup (never use â€œsudoâ€ drunken).</h3>



<p class="wp-block-paragraph">Some things you have to learn the hard way,&nbsp;apparently installing &#8220;safe-rm&#8221; was part of it for me! </p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><code>apt-get&nbsp;install safe-rm</code></p>
</blockquote>



<p class="wp-block-paragraph">â€œMan has three ways of acting wisely. First, on meditation; that is the noblest. Secondly, on imitation; that is the easiest. Thirdly, on experience; that is the bitterest.&#8221;&nbsp;â€“ (Confucius)</p>



<h3 class="wp-block-heading">â€“ Be honest with customers, employees and yourself.</h3>



<p class="wp-block-paragraph">Be honest with customers, especially when things go wrong.&nbsp;If the customer&#8217;s product (e.g. server) fails, then offer solutions and no excuses and solve the problem, not the question of blame.&nbsp;No one is helped by pointing the finger at colleagues or customers, not at the server, not at the customer and ultimately not at yourself.</p>



<h3 class="wp-block-heading">â€“ Ask questions if you don&#8217;t understand something.</h3>



<p class="wp-block-paragraph">Don&#8217;t talk to customers about something you don&#8217;t understand, not knowing something (especially in training) is fine, but then ask a colleague before you talk to a customer about it! </p>



<h3 class="wp-block-heading">â€“ Think about what you are doing (not only at work).</h3>



<p class="wp-block-paragraph">If you question things and think about your work and what you do, then you can develop personally.&nbsp;Question critical, for example, whether you should really order from Amazon, or should you rather order the book directly from the publisher?&nbsp;What is the advantage for the author and do I have any disadvantages?&nbsp;Should we use Nagios or rather Icinga directly?&nbsp;Question your work and critically evaluate whether this is really a good / safe / future-oriented solution.</p>



<p class="wp-block-paragraph">If you are not sure yourself or your perspective is too limited (because you only know this one solution, for example), then you should acquire new knowledge, research other solutions or â€œbest practicesâ€ and discuss the topic with others.</p>



<h3 class="wp-block-heading">â€“ Use Google correctly â€¦</h3>



<p class="wp-block-paragraph">1. When searching an issue, look for the error message in quotes: &#8220;Lars Moelleken&#8221;</p>



<p class="wp-block-paragraph">2. You can limit the result to special URLs: <a href="https://www.google.com/search?q=inurl%3Amoelleken.org&amp;oq=inurl%3Amoelleken.org" target="_blank" rel="noreferrer noopener nofollow">inurl:moelleken.org</a></p>



<p class="wp-block-paragraph">3. Sometimes it&#8217;s helpful to find only specific files: <a href="https://www.google.com/search?q=filetype%3Atxt+inurl%3Asuckup.de&amp;oq=filetype%3Atxt+inurl%3Asuckup.de" target="_blank" rel="noreferrer noopener nofollow">filetype:txt inurl:suckup.de</a></p>



<p class="wp-block-paragraph">&gt; There are even more tricks that can help you in your daily work, just Google for it:</p>



<p class="wp-block-paragraph">Full example: <em><a href="index.of mp3 â€œM&auml;nner Sind Schweineâ€ -html -htm -php" target="_blank" rel="noreferrer noopener nofollow">intitle:index</a><a href="https://www.google.com/search?q=intitle%3Aindex.of+mp3+%E2%80%9CM%C3%A4nner+Sind+Schweine%E2%80%9D+-html+-htm+-php">.of mp3 â€œM&auml;nner Sind Schweineâ€ -html -htm -php</a></em></p>



<h2 class="wp-block-heading">What did I learn as IT specialist for application development?</h2>



<h3 class="wp-block-heading">â€“ You never stop learning&#8230;</h3>



<p class="wp-block-paragraph">When you start to deal with web programming (HTML, CSS, JS, PHP, &#8230;), you don&#8217;t even know where to start.&nbsp;There is so much to learn, and this feeling accompanies you for some time (years) until you recognize recurring concepts.&nbsp;However, the advantage in web programming is that many different things have common APIs or at least can be combined.&nbsp;I can write a class in PHP that creates data attributes for my HTML, which I can read out with JavaScript to design them accordingly using CSS classes.&nbsp;But it stays the same, you never stop learning, and that&#8217;s also what&#8217;s so exciting about this job.</p>



<h3 class="wp-block-heading">â€“ Try to write code every day.&nbsp;(but set yourself a LIMIT)</h3>



<p class="wp-block-paragraph">Even if the boss isn&#8217;t in the office today, and you don&#8217;t have any more tasks, then write some code, if you&#8217;re sitting on the couch at home (and no new series is running on Netflix), then write or read some code and if you&#8217;re on vacation, you&#8217;re on vacation!</p>



<p class="wp-block-paragraph">Here is an interesting link from &#8220;John Resig&#8221; (jQuery):<br /><a href="http://ejohn.org/blog/write-code-every-day/" target="_blank" rel="noreferrer noopener nofollow">http://ejohn.org/blog/write-code-every-day/</a></p>



<h3 class="wp-block-heading">â€“ Think in modules and packagesâ€¦</h3>



<p class="wp-block-paragraph">If you write software every day, you don&#8217;t want to code the same functionality (e.g. database connection, send e-mail or error logging &#8230;) multiple times for different projects (and remember, mostly you don&#8217;t want to code standard functions yourself).&nbsp;Therefore, every programmer should think in modules and design an application in different, preferably interchangeable parts.&nbsp;Often, the system can then also be expanded better, since there is already an interface for modules that can be used.&nbsp;The independence and decoupling of program parts also has the advantage that side effects from different places in the source code are further avoided.&nbsp;In addition, one should minimize the coupling of the corresponding modules, otherwise one gains nothing from modules.</p>



<p class="wp-block-paragraph">There are already package managers for almost everything in web development. e.g.:<br />â€“ Frontend (css, js): npm<br />â€“ Backend (php): composer</p>



<h3 class="wp-block-heading">â€“ Open-Source-Software</h3>



<p class="wp-block-paragraph">If you are already working with modules and packages, you can publish them as an OSS project + run tests via GitHub actions + code coverage + at least a small amount of documentation. For these reasons alone, publishing as open source is worthwhile.&nbsp;The code quality also increases (in my experience), since the source code is released to the public and therefore more or less conscious attention is paid to the code quality.</p>



<p class="wp-block-paragraph">The moment when you get your first pull request for your software or code together with someone from Israel, Turkey and the USA is priceless.</p>



<p class="wp-block-paragraph">At some point, you would like to have the same advantages of OSS in your daily work because often, there is no package (code is directly added into the existing code), no tests (even not for bugs) and no documentation. So, possibly, you have now collected enough arguments to convince your boss to publish some package from your code at work.</p>



<h3 class="wp-block-heading">â€“ Git &amp; Good</h3>



<p class="wp-block-paragraph">I don&#8217;t know how people can work with the PC without version control.&nbsp;I even use â€œgitâ€ for smaller private projects or for configuration files.&nbsp;The following are some advantages, but the list can certainly be extended with a few more points:</p>



<p class="wp-block-paragraph">â€“ changes can be traced (git log, git blame)<br />â€“ changes can be undone (git revert, git reset)<br />â€“ changes can be reviewed by other employees<br />â€“ employees can work on a project at the same time (git commit, git pull, git push)<br />â€“ development branches (forks) can be developed simultaneously (git checkout -b , git branches)</p>



<h3 class="wp-block-heading">â€“ Use GitHub and learn from the best.</h3>



<p class="wp-block-paragraph">GitHub itself is not  open-source, but there has been an unofficial agreement to use the platform for open-source projects.&nbsp;You can therefore find many good developers and projects there, and you can learn a lot just by reading the source code / changes.&nbsp;Especially because you can understand and follow the development of the projects: How do others structure your code?&nbsp;How do others write their &#8220;commit&#8221; messages?&nbsp;How much code should a method contain?&nbsp;How much code should a class contain?&nbsp;Which variable names are better to avoid?&nbsp;How to use specific libraries / tools? How do others test their code? &#8230;</p>



<h3 class="wp-block-heading">â€“ try { tests() }</h3>



<p class="wp-block-paragraph">Especially when you write tests for your own code, you catch yourself testing exactly the cases that you have already considered, so you should test the corresponding functionality with different (not yet considered) input. Here are some inputs for testing: <a href="https://github.com/minimaxir/big-list-of-naughty-strings" target="_blank" rel="noreferrer noopener nofollow">https://github.com/minimaxir/big-list-of-naughty-strings</a></p>



<p class="wp-block-paragraph">Hint: We should add another test whenever an error occurred, so that already fixed error does not come back to use.</p>



<h3 class="wp-block-heading">&#8211; Automate your tests.</h3>



<p class="wp-block-paragraph">Unit tests, integration tests and front-end tests only help if they are also executed, so you should deal with automated tests at an early stage and also run them automatically when the source code changes.&nbsp;Where and when these tests are run also determines how effective these tests ultimately are.&nbsp;As soon as you have written a few tests, you will understand why it is better not to use additional parameters for methods and functions, since the number of tests increases exponentially.</p>



<h3 class="wp-block-heading">â€“ Deployment is also important.</h3>



<p class="wp-block-paragraph">As soon as you work with more than one developer on a project, or the project will become more complex, you want to use some kind of deployment. As in application development, often the simplest solution is also here a good starting point: e.g. just pull the given changes into a directory and change the symlink from the existing source directory so that you can switch or rollback all files easily. PS: And you properly never need to write database-migration rollbacks, I never used them. </p>



<h3 class="wp-block-heading">â€“ Understanding concepts is more important than implementing them.</h3>



<p class="wp-block-paragraph">Understanding design patterns (programming concepts) not only helps in the current programming language, but can mostly be applied to other programming languages â€‹â€‹as well.</p>



<p class="wp-block-paragraph">Basic concepts (classes, objects, OOP, functions, ORM, MVC, DDD, unit tests, data binding, router, hooks, template engine, &#8230;) can be found in many frameworks / programming languages â€‹â€‹and once you have understood the terms and concepts, it is no longer that difficult to use new / different frameworks.&nbsp;And you can see different strengths and weaknesses of these frameworks and tools: &#8220;If you only have a hammer as a tool, you see a nail in every problem.&#8221;</p>



<h3 class="wp-block-heading">â€“ Solving problems also means understanding customers.</h3>



<p class="wp-block-paragraph">Design patterns are part of the basic equipment, but you should always ask yourself: Which problem is actually supposed to be solved with the given solution?&nbsp;If necessary, you can find an even more elegant / simpler solution.&nbsp;And sometimes the customer actually wants something thoroughly different, he just doesn&#8217;t know it yet or someone has misunderstood the customer.</p>



<h3 class="wp-block-heading">â€“ Solving problems also means understanding processes.</h3>



<p class="wp-block-paragraph">But it is just as important to understand why a certain feature is implemented, and otherwise you are programming something that is either not needed or used at all.&nbsp;One should therefore understand the corresponding task before implementation and even before planning in the overall context.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="936" height="698" data-attachment-id="6331" data-permalink="http://suckup.de/?attachment_id=6331" data-orig-file="http://suckup.de/wp-content/uploads//2016/01/projekt-schaukel-baum.png" data-orig-size="936,698" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="projekt-schaukel-baum" data-image-description="" data-image-caption="" data-large-file="http://suckup.de/wp-content/uploads//2016/01/projekt-schaukel-baum.png" src="https://suckup.de/wp-content/uploads//2016/01/projekt-schaukel-baum.png" alt="project-swing-tree" class="wp-image-6331" srcset="http://suckup.de/wp-content/uploads/2016/01/projekt-schaukel-baum.png 936w, http://suckup.de/wp-content/uploads/2016/01/projekt-schaukel-baum-300x224.png 300w, http://suckup.de/wp-content/uploads/2016/01/projekt-schaukel-baum-768x573.png 768w" sizes="auto, (max-width: 936px) 100vw, 936px" /></figure>
</div>


<h3 class="wp-block-heading">&#8211; Spread code across multiple files.</h3>



<p class="wp-block-paragraph">Use one file for a class, use one file for CSS properties of a module or a specific page, use a new file for each new view.&nbsp;Dividing the source code into different files / directories offers many advantages, so the next developer knows where new source code should be stored and you can find your way around the source code faster.&nbsp;Many frameworks already provide a predefined directory structure. </p>



<h3 class="wp-block-heading">â€“ Readability comes first!</h3>



<p class="wp-block-paragraph">The readability of source code should always come first, since you or your work colleagues will have to maintain or expand this code in the future.</p>



<p class="wp-block-paragraph">YouTube&#8217;s videos about â€œClean Codeâ€:&nbsp;<a href="https://www.youtube.com/results?search_query=%22Clean+Code%22&amp;search_sort=video_view_count" target="_blank" rel="noreferrer noopener nofollow">https://www.youtube.com/results?search_query=%22Clean+Code%22&amp;search_sort=video_view_count</a></p>



<p class="wp-block-paragraph">Best Practices:&nbsp;<a href="http://code.tutsplus.com/tutorials/top-15-best-practices-for-writing-super-readable-code-net-8118" target="_blank" rel="noreferrer noopener nofollow">http://code.tutsplus.com/tutorials/top-15-best-practices-for-writing-super-readable-code-net-8118</a></p>



<h3 class="wp-block-heading">â€“ Good naming is one of the most difficult tasks in programming.</h3>



<p class="wp-block-paragraph">It starts with the domain name / project name, goes through file names, to directory names, class names, method names, variable names, CSS class names.&nbsp;Always realize that others will read this and need to understand it.&nbsp;Therefore, you should also avoid unnecessary abbreviations and write what you want to describe.</p>



<p class="wp-block-paragraph">We want to describe what the function does and not how it is implemented.</p>



<p class="wp-block-paragraph">â‡¾ Incorrect: sendMailViaSwiftmailer(), sendHttpcallViaCurl(), &#8230;<br />â‡¾ Correct: mail-&gt;send(), http-&gt;send(), &#8230;</p>



<p class="wp-block-paragraph">Variables should describe what they contain and not how they are stored.</p>



<p class="wp-block-paragraph">â‡¾ Incorrect: $array2use, $personsArray, â€¦<br />â‡¾ Correct: $pages, $persons, â€¦</p>



<p class="wp-block-paragraph">Summary: Describe what the variable/method/function/class is, not how it is implemented: <a href="https://github.com/kettanaito/naming-cheatsheet" target="_blank" rel="noreferrer noopener nofollow">https://github.com/kettanaito/naming-cheatsheet</a></p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><a href="https://suckup-de.translate.goog/2014/05/weniger-schlecht-php-programmieren/?_x_tr_sl=de&amp;_x_tr_tl=en&amp;_x_tr_hl=de&amp;_x_tr_pto=wapp">Programming less bad PHP</a></p>
</blockquote>



<figure class="wp-block-embed is-type-wp-embed is-provider-suckup-de wp-block-embed-suckup-de"><div class="wp-block-embed__wrapper">
<blockquote class="wp-embedded-content" data-secret="O4wRWmU7Rr"><a href="http://suckup.de/2014/05/weniger-schlecht-php-programmieren/">Weniger schlecht PHP programmieren</a></blockquote><iframe loading="lazy" class="wp-embedded-content" sandbox="allow-scripts" security="restricted"  title="&#8220;Weniger schlecht PHP programmieren&#8221; &#8212; SUCKUP.de" src="http://suckup.de/2014/05/weniger-schlecht-php-programmieren/embed/#?secret=UI9fm7j9TA#?secret=O4wRWmU7Rr" data-secret="O4wRWmU7Rr" width="600" height="338" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
</div></figure>



<h3 class="wp-block-heading">â€“ Save on comments (at least inline)â€¦</h3>



<p class="wp-block-paragraph">Good comments explain &#8220;why&#8221; and not &#8220;what&#8221; the code is doing, and should offer the reader added value that is not already described in the source code.</p>



<p class="wp-block-paragraph">Sometimes it makes sense to add some &#8220;what&#8221; comments anyway, e.g. for complicated regex or some other not optimal code that needs some hints.</p>



<p class="wp-block-paragraph">Examples of inline comments:</p>



<p class="wp-block-paragraph">bad code:</p>



<pre class="wp-block-preformatted">// Check if the user is already logged in if ( isset ( $_SESSION['user_loggedin']) &amp;&amp; $_SESSION['user_loggedin'] &gt; 1 ) { ... }
       </pre>



<p class="wp-block-paragraph">slightly better code:</p>



<pre class="wp-block-preformatted">// check if the user is already logged-in 
if ( session ( 'user_loggedin' ) &gt; 1 ) { ... }
      </pre>



<p class="wp-block-paragraph">better code:</p>



<pre class="wp-block-preformatted">if ( $user-&gt;isLoggedin === true ) { ... }     </pre>



<p class="wp-block-paragraph">&#8230; and another example &#8230;</p>



<p class="wp-block-paragraph">bad code:</p>



<pre class="wp-block-preformatted">// regex: email 
if (! preg_match ( '/^(.*&lt;?)(.*)@(.*)(&gt;?)$/' , $email ) { ... }
    </pre>



<p class="wp-block-paragraph">better code:</p>



<pre class="wp-block-preformatted">define ( 'EMAIL_REGEX_SIMPLE' , '/^(.*&lt;?)(.*)@(.*)(&gt;?)$/' ); 

if (! preg_match ( EMAIL_REGEX_SIMPLE , $email ) { ... }    </pre>



<h3 class="wp-block-heading">â€“ Consistency in a project is more important than personal preferences!</h3>



<p class="wp-block-paragraph">Use the existing code and use given functions.&nbsp;If it brings benefits, then change / refactor the corresponding code, but then refactor all places in the project which are implemented in this way.</p>



<p class="wp-block-paragraph">Example: If you have formerly worked without a template system and would like to use one for &#8220;reasons&#8221;, then use this for all templates in the project and not just for your current use case; otherwise, inconsistencies will arise in the project.&nbsp;For example, if you create a new &#8220;Emailâ†’isValid()&#8221; method, then you should also replace all previous RegEx attempts in the current project with the &#8220;Email&#8221; class; otherwise inconsistencies will arise again.</p>



<p class="wp-block-paragraph">Read more about the topic: </p>



<p class="wp-block-paragraph">&#8211; &#8220;Be consistent [and try to automate this process, please]!&#8221; <a href="http://suckup.de/2020/01/do-not-fear-the-white-space-in-your-code/">http://suckup.de/2020/01/do-not-fear-the-white-space-in-your-code/</a></p>



<p class="wp-block-paragraph">&#8211; &#8220;Why do we write unreadable code?&#8221;<br /><a href="http://suckup.de/2020/07/how-to-write-readable-code/">http://suckup.de/2020/01/do-not-fear-the-white-space-in-your-code/</a></p>



<h3 class="wp-block-heading">â€“ A uniform code style has a positive effect on quality!</h3>



<p class="wp-block-paragraph">As in real life, if there is already rubbish somewhere, the inhibition threshold to dump rubbish there drops extremely.&nbsp;But if everything looks nice and tidy, then nobody just throws a â€œrandumInt() { return 4;&nbsp;}â€ function on the floor.</p>



<p class="wp-block-paragraph">It also helps to automate some refactoring because the code looks everywhere the same, you can also apply the same e.g. PHP-CS-Fixer and you do not need to think about every different coding style. </p>



<h3 class="wp-block-heading">â€“ Use functional principles &amp; object-oriented concepts.</h3>



<p class="wp-block-paragraph">A pure function (â€œPure Functionsâ€) only depends on its parameters and with the same parameters it always returns the same result.&nbsp;These principles can also be considered in OOP and create so-called immutable classes (immutable class).</p>



<p class="wp-block-paragraph"><a href="https://en.wikipedia.org/wiki/Pure_function">https://en.wikipedia.org/wiki/Pure_function</a><br /><a href="https://de.wikipedia.org/wiki/Object-oriented_programming">https://de.wikipedia.org/wiki/Object-oriented_programming</a><br /><a href="https://en.wikipedia.org/wiki/Immutable_object">https://en.wikipedia.org/wiki/Immutable_object</a></p>



<h3 class="wp-block-heading">â€“ Please do not use global variables!</h3>



<p class="wp-block-paragraph">Global variables make testing difficult because they can cause side effects.&nbsp;Also, it&#8217;s difficult to refactor code with global variables because you don&#8217;t know what effects these changes will have on other parts of the system.</p>



<p class="wp-block-paragraph">In some programming languages â€‹â€‹(e.g. JavaScript, Shell) all variables are global and only become local with a certain keyword (e.g. in the scope of a function or a class).</p>



<h3 class="wp-block-heading">&#8211; Learn to use your tools properly!</h3>



<p class="wp-block-paragraph">For example, if you&#8217;re writing code with Notepad, you can dig a hole with a spoon, which is just as efficient.&nbsp;Learn keyboard shortcuts for your programs and operating system!&nbsp;Use an IDE, e.g. from JetBrains (<a href="https://www.jetbrains.com/products.html" target="_blank" rel="noreferrer noopener nofollow">https://www.jetbrains.com/products.html</a>) and use additional plugins and settings.</p>



<p class="wp-block-paragraph">Modern IDEs also give hints/suggestions on how to improve your code.&nbsp;For example, for PHP, you can use PhpStorm + PHPStan and share the global IDE Inspections settings in the team.</p>



<h3 class="wp-block-heading">â€“ Performance?</h3>



<p class="wp-block-paragraph">In nearly every situation you don&#8217;t have to worry too much about performance, as modern programming languages â€‹â€‹/ frameworks support us and with common solutions; otherwise the motto is &#8220;profiling, profiling&#8230; profiling&#8221;!</p>



<h3 class="wp-block-heading">â€“ Exceptions === Exceptions</h3>



<p class="wp-block-paragraph">You should not use exceptions to handle normal errors.&nbsp;Exceptions are exceptions, and regular code handles the regular cases!&nbsp;&#8220;Use exceptions only in exceptional circumstances&#8221; (Pragmatic Programmers).&nbsp;And nearly under no circumstances you should â€œchoke offâ€ exceptions, e.g. by trivially catching several exceptions.</p>



<h3 class="wp-block-heading">â€“ Finish your work</h3>



<p class="wp-block-paragraph">You should finish what you started.&nbsp;For example, if you need to use &#8220;fopen()&#8221; you should also use &#8220;fclose()&#8221; in the same code block. So, nobody in the team needs to clean up your stuff after he / she uses your function. </p>



<h3 class="wp-block-heading">â€“ Source code should be searchable [Ctrl + F] â€¦</h3>



<p class="wp-block-paragraph">The source code should be easy to search through, so you should avoid using string nesting + &#8220;&amp;&#8221; with Sass, for example, and also avoid using PHP functions such as &#8220;extract()&#8221;.&nbsp;Whenever variables are not declared, but created as if by magic (e.g. using magic methods in PHP), it is no longer so easy to change the source text afterward.</p>



<p class="wp-block-paragraph">Example in PHP: (bad)</p>



<pre class="wp-block-preformatted">extract ( array ( 'bar' =&gt; 'bar' , 'lall' =&gt; 1 )); 
var_dump ( $bar ); // string 'bar' (length=3)      </pre>



<p class="wp-block-paragraph">Example in Sass: (bad)</p>



<pre class="wp-block-preformatted">. teaser { 
  font - size : 12px ; 

  &amp; __link { 
    color : rgb ( 210 , 210 , 22 ); } }
  
</pre>



<p class="wp-block-paragraph">Sass Nesting (code style):&nbsp;<a href="https://github.com/grvcoelho/css#nesting" target="_blank" rel="noreferrer noopener nofollow">https://github.com/grvcoelho/css#nesting</a></p>



<h3 class="wp-block-heading">â€“ Program for your use case!</h3>



<p class="wp-block-paragraph">A big problem in programming is that you have to try to think and program in a generalized way so that you can (easily) expand the source code if new requirements are added or you can (easily) change it.</p>



<p class="wp-block-paragraph">What does project sometimes look like?&nbsp;â†’ A customer orders 10,000 green apples from a farm, changes his order to 10,000 red apples the morning before delivery and when these are delivered, the customer would prefer 10,000 pears and would like to pay for them in 6 months.</p>



<p class="wp-block-paragraph">And precisely for this reason you should only write the source code that is really required for the current use case because you can&#8217;t map all eventualities anyway and the source code is unnecessarily complicated.</p>



<h3 class="wp-block-heading">â€“ KISS â€“ Keep it simple, stupid.</h3>



<p class="wp-block-paragraph">One should always keep in mind that the source code itself is not that valuable.&nbsp;The value only arises when other developers understand it and can adapt / configure / use it for the customer or themselves.&nbsp;This should be kept in mind during programming so that a solution can be implemented as comprehensibly and &#8220;simply&#8221; as possible.&nbsp;And if I don&#8217;t need to use a new class or nice design pattern for the current problem, I probably shouldn&#8217;t.&nbsp;However, this does not mean that you should throw all good intentions overboard and use global variables / singletons everywhere.&nbsp;However, if a simple solution already does the job, go for that one.</p>



<p class="wp-block-paragraph">A good example of what not to do is the JavaScript DOM Selector API.&nbsp;Not exactly nice to read or write&#8230;</p>



<p class="wp-block-paragraph">Bad: (DOM Selector via JS)</p>



<pre class="wp-block-preformatted">document.getElementsByTagName ( "div" ) 
document.getElementById ( "foo" ) 
document.getElementsByClassName ( "bar" ) 
document.querySelector ( ".foo" ) 
document.querySelectorAll ( "div.bar" )</pre>



<p class="wp-block-paragraph">Better: (DOM Selector via jQuery)</p>



<pre class="wp-block-preformatted">$( "div" ) 
$( "#foo" ) 
$( ".bar" ) 
$( ".foo" ) 
$( "div.bar" )</pre>



<h3 class="wp-block-heading">â€“ DRY â€“ Don&#8217;t Reap Yourself.</h3>



<p class="wp-block-paragraph">Repetitions / redundancies in the source text or in recurring work arise relatively quickly if people do not communicate with each other.&nbsp;But also unintentionally due to errors in the software design because you don&#8217;t have a better idea or don&#8217;t think you have time for it.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="543" height="407" data-attachment-id="6330" data-permalink="http://suckup.de/?attachment_id=6330" data-orig-file="http://suckup.de/wp-content/uploads//2016/01/improve.png" data-orig-size="543,407" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="improve" data-image-description="" data-image-caption="" data-large-file="http://suckup.de/wp-content/uploads//2016/01/improve.png" src="https://suckup.de/wp-content/uploads//2016/01/improve.png" alt="improve" class="wp-image-6330" srcset="http://suckup.de/wp-content/uploads/2016/01/improve.png 543w, http://suckup.de/wp-content/uploads/2016/01/improve-300x225.png 300w" sizes="auto, (max-width: 543px) 100vw, 543px" /></figure>
</div>


<p class="wp-block-paragraph">To avoid repetition, make your solution easy to find and easy to use. So that other devs will use it instead of re-creating a solution.</p>



<h3 class="wp-block-heading">â€“ The will to learn and understand something new is more important than previous knowledge.</h3>



<p class="wp-block-paragraph">If you can already program ActionScript (Flash), for example, but are not willing to learn something new, then previous knowledge is of no use because &#8220;The only constant in the universe is change.&#8221; &#8211; Heraclitus of Ephesus (about 540 &#8211; 480 BC).</p>



<h3 class="wp-block-heading">â€“ Read good books and magazines.</h3>



<p class="wp-block-paragraph">Books I have read:&nbsp;<a href="https://www.goodreads.com/user/show/3949219-lars-moelleken" target="_blank" rel="noreferrer noopener nofollow">https://www.goodreads.com/user/show/3949219-lars-moelleken</a><br />Free Books:&nbsp;<a href="https://github.com/vhf/free-programming-books/blob/master/free- programming-books.md" target="_blank" rel="noreferrer noopener nofollow">https://github.com/vhf/free-programming-books/blob/master/free- programming-books.md</a><br />books for programmers:&nbsp;<a href="http://stackoverflow.com/questions/1711/what-is-the-single-most-influential-book-every-programmer-should-read" target="_blank" rel="noreferrer noopener nofollow">http://stackoverflow.com/questions/1711/what-is-the-single-most-influential-book-every-programmer-should-read</a></p>



<h3 class="wp-block-heading">â€“ Follow other programmers on Twitter / GitHub / dev.to / YouTube / Medium / â€¦</h3>



<p class="wp-block-paragraph">It sometimes helps to motivate yourself, to write e.g. a blog post or testing some new stuff, if you know some people how has the same interest, so just follow some of them online, there are many excellent developers out there, and they share their knowledge and tricks mostly for free. :)</p>



<h3 class="wp-block-heading">â€“ Listen to podcasts &amp; subscribe to RSS feeds / newsletters &amp; watch videos, for example from web conferences</h3>



<p class="wp-block-paragraph">To find out about new technologies, techniques, standards, patterns, etc., it is best to use different media, which can be consumed in different situations.&nbsp;An interesting podcast on â€œFrontend Architectureâ€ before falling asleep or a video on â€œDevOpsâ€ while preparing lunch, reading a book on the tram in the morning entitled â€œProgramming less badlyâ€ â€¦ to name just a few examples.</p>



<p class="wp-block-paragraph">Podcasts:&nbsp;<a href="https://github.com/voku/awesome-web/blob/master/README.md#-audio-podcast" target="_blank" rel="noreferrer noopener">https://github.com/voku/awesome-web/blob/master/README.md#-audio-podcast</a><br />github is awesome: <a href="https://github.com/sindresorhus/awesome" target="_blank" rel="noreferrer noopener">https://github.com/sindresorhus/awesome</a><br />and there is more:&nbsp;<a href="https://github.com/jnv/lists" target="_blank" rel="noreferrer noopener">https://github.com/jnv/lists</a></p>



<h3 class="wp-block-heading">â€“ Attend Meetup&#8217;s &amp; web conferences and talk to other developers.</h3>



<p class="wp-block-paragraph">Meetups are groups of people who meet regularly and talk about things like Python, Scala, PHP, etc.&nbsp;Usually, someone gives a lecture on a previously agreed topic.</p>



<p class="wp-block-paragraph">â‡‰&nbsp;<a href="http://www.meetup.com/de-DE/members/136733532/" target="_blank" rel="noreferrer noopener">http://www.meetup.com/de-DE/members/136733532/</a></p>



<p class="wp-block-paragraph">Web conferencing is fun.&nbsp;Point.&nbsp;And every developer / admin should visit them because you get new impressions and meet wonderful people.&nbsp;Some conferences are expensive, but here you should contact your employer, if necessary, the company will take care of it.&nbsp;And there are also really cheap conferences.</p>



<h3 class="wp-block-heading">â€“ Post answers at quora.com ||&nbsp;stackoverflow.com ||&nbsp;in forums ||&nbsp;your blog&#8230;</h3>



<p class="wp-block-paragraph">To deal with a certain topic yourself and to really understand it, it is worth doing research and writing a text (possibly even a lecture) that others can read and criticize and thus improve.</p>



<h3 class="wp-block-heading">â€“ Don&#8217;t stay at work for so long every day; otherwise nobody will be waiting for you at home!</h3>



<p class="wp-block-paragraph">With all the enthusiasm for the &#8220;job&#8221; (even if it&#8217;s fun), you shouldn&#8217;t lose sight of the essential things.&nbsp;Again, something I had to learn the hard way.&nbsp;:-/</p>



<p class="wp-block-paragraph"></p>


<img loading="lazy" decoding="async" src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2023%2F01%2Fwhat-have-i-learned-so-far-in-my-job%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dwhat-have-i-learned-so-far-in-my-job&amp;action_name=What%20have%20I%20learned%20so%20far%20in%20my%20job%3F&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
					<wfw:commentRss>http://suckup.de/2023/01/what-have-i-learned-so-far-in-my-job/?pk_campaign=feed&amp;pk_kwd=what-have-i-learned-so-far-in-my-job/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">6888</post-id>	</item>
		<item>
		<title>PHP: Code Quality with Custom Tooling Extensions</title>
		<link>http://suckup.de/2022/07/php-code-quality-with-custom-tooling-extensions/?pk_campaign=feed&amp;pk_kwd=php-code-quality-with-custom-tooling-extensions&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=php-code-quality-with-custom-tooling-extensions</link>
					<comments>http://suckup.de/2022/07/php-code-quality-with-custom-tooling-extensions/?pk_campaign=feed&amp;pk_kwd=php-code-quality-with-custom-tooling-extensions#comments</comments>
		
		<dc:creator><![CDATA[voku]]></dc:creator>
		<pubDate>Wed, 20 Jul 2022 00:05:53 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">https://suckup.de/?p=6867</guid>

					<description><![CDATA[<p><a href="http://suckup.de/2022/07/php-code-quality-with-custom-tooling-extensions/?pk_campaign=feed&#038;pk_kwd=php-code-quality-with-custom-tooling-extensions">PHP: Code Quality with Custom Tooling Extensions</a></p>
<p>After many years of using PHPStan, PHP-CS-Fixer, PHP_CodeSniffer, &#8230; I will give you one advice: add your own custom code to extend your Code-Quality-Tooling. Nearly every project has custom code that procures the real value for the product / project, but this custom code itself is often not really improved by PHP-CS-Fixer, PHPStan, Psalm, and &#8230; <a href="http://suckup.de/2022/07/php-code-quality-with-custom-tooling-extensions/?pk_campaign=feed&#038;pk_kwd=php-code-quality-with-custom-tooling-extensions" class="more-link">Continue reading <span class="screen-reader-text">PHP: Code Quality with Custom Tooling Extensions</span></a><img src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2022%2F07%2Fphp-code-quality-with-custom-tooling-extensions%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dphp-code-quality-with-custom-tooling-extensions&amp;action_name=PHP%3A%20Code%20Quality%20with%20Custom%20Tooling%20Extensions&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" /></p>
]]></description>
										<content:encoded><![CDATA[<p><a href="http://suckup.de/2022/07/php-code-quality-with-custom-tooling-extensions/?pk_campaign=feed&#038;pk_kwd=php-code-quality-with-custom-tooling-extensions">PHP: Code Quality with Custom Tooling Extensions</a></p>

<p>After many years of using PHPStan, PHP-CS-Fixer, PHP_CodeSniffer, &#8230; I will give you one advice: add your own custom code to extend your Code-Quality-Tooling.</p>
<p>Nearly every project has custom code that procures the real value for the product / project, but this custom code itself is often not really improved by PHP-CS-Fixer, PHPStan, Psalm, and other tools. The tools do not know how this custom code is working so that we need to write some extensions for ourselves.</p>
<p>Example: At work, we have some Html-Form-Element (HFE) classes that used some properties from our Active Record classes, and back in the time we used strings to connect both classes. :-/</p>
<p><em>Hint: Strings are very flexible, but also awful to use programmatically in the future. I would recommend avoiding plain strings as much as possible.</em></p>
<h3>1. Custom PHP-CS-Fixer</h3>
<p>So, I wrote a quick script that will replace the strings with some metadata. The big advantage is that this custom PHP-CS-Fixer will also automatically fix code that will be created in the future, and you can apply / check this in the CI-pipline or e.g. in a pre-commit hook or directly in PhpStorm.</p>
<pre>&lt;?php<br /><br />declare(strict_types=1);<br /><br />use PhpCsFixer\Tokenizer\Analyzer\ArgumentsAnalyzer;<br />use PhpCsFixer\Tokenizer\Analyzer\FunctionsAnalyzer;<br />use PhpCsFixer\Tokenizer\Token;<br />use PhpCsFixer\Tokenizer\Tokens;<br /><br />final class MeerxUseMetaFromActiveRowForHFECallsFixer extends AbstractMeerxFixerHelper <br />{<br /><br />    /**<br />     * {@inheritdoc}<br />     */<br />    public function getDocumentation(): string <br />    {<br />        return 'Use ActiveRow-&gt;m() for "HFE_"-calls, if it is possible.';<br />    }<br /><br />    /**<br />     * {@inheritdoc}<br />     */<br />    public function getSampleCode(): string <br />    {<br />        return &lt;&lt;&lt;'PHP'<br />            &lt;?php<br /><br />            $element = UserFactory::singleton()-&gt;fetchEmpty();<br /><br />            $foo = HFE_Date::Gen($element, 'created_date');<br />            PHP;<br />    }<br /><br />    public function isRisky(): bool <br />    {<br />        return true;<br />    }<br /><br />    /**<br />     * {@inheritdoc}<br />     */<br />    public function isCandidate(Tokens $tokens): bool <br />    {<br />        return $tokens-&gt;isTokenKindFound(\T_STRING);<br />    }<br /><br />    public function getPriority(): int {<br />        // must be run after NoAliasFunctionsFixer<br />        // must be run before MethodArgumentSpaceFixer<br />        return -1;<br />    }<br /><br />    protected function applyFix(SplFileInfo $file, Tokens $tokens): void <br />    {<br />        if (v_str_contains($file-&gt;getFilename(), 'HFE_')) {<br />            return;<br />        }<br /><br />        $functionsAnalyzer = new FunctionsAnalyzer();<br /><br />        // fix for "HFE_*::Gen()"<br />        foreach ($tokens as $index =&gt; $token) {<br />            $index = (int)$index;<br /><br />            // only for "Gen()"-calls<br />            if (!$token-&gt;equals([\T_STRING, 'Gen'], false)) {<br />                continue;<br />            }<br /><br />            // only for "HFE_*"-classes<br />            $object = (string)$tokens[$index - 2]-&gt;getContent();<br />            if (!v_str_starts_with($object, 'HFE_')) {<br />                continue;<br />            }<br /><br />            if ($functionsAnalyzer-&gt;isGlobalFunctionCall($tokens, $index)) {<br />                continue;<br />            }<br /><br />            $argumentsIndices = $this-&gt;getArgumentIndices($tokens, $index);<br /><br />            if (\count($argumentsIndices) &gt;= 2) {<br />                [<br />                    $firstArgumentIndex,<br />                    $secondArgumentIndex<br />                ] = array_keys($argumentsIndices);<br /><br />                // If the second argument is not a string, we cannot make a swap.<br />                if (!$tokens[$secondArgumentIndex]-&gt;isGivenKind(\T_CONSTANT_ENCAPSED_STRING)) {<br />                    continue;<br />                }<br /><br />                $content = trim($tokens[$secondArgumentIndex]-&gt;getContent(), '\'"');<br />                if (!$content) {<br />                    continue;<br />                }<br /><br />                $newContent = $tokens[$firstArgumentIndex]-&gt;getContent() . '-&gt;m()-&gt;' . $content;<br /><br />                $tokens[$secondArgumentIndex] = new Token([\T_CONSTANT_ENCAPSED_STRING, $newContent]);<br />            }<br />        }<br />    }<br /><br />    /**<br />     * @param Token[]|Tokens $tokens            &lt;phpdoctor-ignore-this-line/&gt;<br />     * @param int            $functionNameIndex<br />     *<br />     * @return array&lt;int, int&gt; In the format: startIndex =&gt; endIndex<br />     */<br />    private function getArgumentIndices(Tokens $tokens, $functionNameIndex): array <br />    {<br />        $argumentsAnalyzer = new ArgumentsAnalyzer();<br /><br />        $openParenthesis = $tokens-&gt;getNextTokenOfKind($functionNameIndex, ['(']);<br />        $closeParenthesis = $tokens-&gt;findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $openParenthesis);<br /><br />        // init<br />        $indices = [];<br /><br />        foreach ($argumentsAnalyzer-&gt;getArguments($tokens, $openParenthesis, $closeParenthesis) as $startIndexCandidate =&gt; $endIndex) {<br />            $indices[$tokens-&gt;getNextMeaningfulToken($startIndexCandidate - 1)] = $tokens-&gt;getPrevMeaningfulToken($endIndex + 1);<br />        }<br /><br />        return $indices;<br />    }<br />}</pre>
<p>To use your custom fixes, you can register and enable them: <a href="https://cs.symfony.com/doc/custom_rules.html" target="_blank" rel="noopener">https://cs.symfony.com/doc/custom_rules.html</a> Â </p>
<p><strong>Example-Result:</strong></p>



<pre class="wp-block-code"><code>
$fieldGroup->addElement(HFE_Customer::Gen($element, 'customer_id'));

// &lt;- will be replaced with ->

$fieldGroup->addElement(HFE_Customer::Gen($element, $element->m()->customer_id));</code></pre>



<p><em>Hint: There are many examples for PHP_CodeSniffer and Fixer Rules on GitHub, you can often pick something that fits 50-70% for your use-case and then modify it for your needs.</em></p>
<p>The &#8220;m()&#8221; method looks like this and will call the simple &#8220;ActiveRowMeta&#8221;-class. This class will return the property name itself instead of the real value.</p>
<pre>/**<br /> * (M)ETA<br /> *<br /> * @return ActiveRowMeta|mixed|static<br /> *                                    &lt;p&gt;<br /> *                                    We fake the return "static" here because we want auto-completion for the current properties in the IDE.<br /> *                                    &lt;br&gt;&lt;br&gt;<br /> *                                    But here the properties contains only the name from the property itself.<br /> *                                    &lt;/p&gt;<br /> *<br /> * @psalm-return object{string,string}<br /> */<br />final public function m() <br />{<br />    return (new ActiveRowMeta())-&gt;create($this);<br />}</pre>
<pre>&lt;?php<br /><br />final class ActiveRowMeta <br />{<br />    /**<br />     * @return static<br />     */<br />    public function create(ActiveRow $obj): self <br />    {<br />        /** @var static[] $STATIC_CACHE */<br />        static $STATIC_CACHE = [];<br /><br />        // DEBUG<br />        // var_dump($STATIC_CACHE);<br /><br />        $cacheKey = \get_class($obj);<br />        if (!empty($STATIC_CACHE[$cacheKey])) {<br />            return $STATIC_CACHE[$cacheKey];<br />        }<br /><br />        foreach ($obj-&gt;getObjectVars() as $propertyName =&gt; $propertyValue) {<br />            $this-&gt;{$propertyName} = $propertyName;<br />        }<br /><br />        $STATIC_CACHE[$cacheKey] = $this;<br /><br />        return $this;<br />    }<br /><br />}</pre>
<h3>2. Custom PHPStan Extension</h3>
<p>In the next step, I added a <a href="https://phpstan.org/developing-extensions/dynamic-return-type-extensions" target="_blank" rel="noopener">DynamicMethodReturnTypeExtension</a> for PHPStan, so that the static code analyze knows the type of the metadata + I still have auto-completion in the IDE via phpdocs.</p>
<p><em>Note: Here I&#8217;ve also made the metadata read-only, so we can&#8217;t misuse the metadata.</em></p>
<pre>&lt;?php<br /><br />declare(strict_types=1);<br /><br />namespace meerx\App\scripts\githooks\StandardMeerx\PHPStanHelper;<br /><br />use PhpParser\Node\Expr\MethodCall;<br />use PHPStan\Analyser\Scope;<br />use PHPStan\Reflection\MethodReflection;<br />use PHPStan\Type\Type;<br /><br />final class MeerxMetaDynamicReturnTypeExtension implements \PHPStan\Type\DynamicMethodReturnTypeExtension <br />{<br /><br />    public function getClass(): string <br />    {<br />        return \ActiveRow::class;<br />    }<br /><br />    public function isMethodSupported(MethodReflection $methodReflection): bool <br />    {<br />        return $methodReflection-&gt;getName() === 'm';<br />    }<br /><br />    /**<br />     * @var \PHPStan\Reflection\ReflectionProvider<br />     */<br />    private $reflectionProvider;<br /><br />    public function __construct(\PHPStan\Reflection\ReflectionProvider $reflectionProvider) <br />    {<br />        $this-&gt;reflectionProvider = $reflectionProvider;<br />    }<br /><br />    public function getTypeFromMethodCall(<br />        MethodReflection $methodReflection,<br />        MethodCall $methodCall,<br />        Scope $scope<br />    ): Type <br />    {<br />        $exprType = $scope-&gt;getType($methodCall-&gt;var);<br /><br />        $staticClassName = $exprType-&gt;getReferencedClasses()[0];<br />        $classReflection = $this-&gt;reflectionProvider-&gt;getClass($staticClassName);<br /><br />        return new MeerxMetaType($staticClassName, null, $classReflection);<br />    }<br />}</pre>



<pre>&lt;?php<br /><br />declare(strict_types=1);<br /><br />namespace meerx\App\scripts\githooks\StandardMeerx\PHPStanHelper;<br /><br />use PHPStan\Reflection\ClassMemberAccessAnswerer;<br />use PHPStan\Type\ObjectType;<br /><br />final class MeerxMetaType extends ObjectType <br />{<br /><br />    public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope): \PHPStan\Reflection\PropertyReflection <br />    {<br />        return new MeerxMetaProperty($this-&gt;getClassReflection());<br />    }<br /><br />}</pre>



<pre>&lt;?php<br /><br />declare(strict_types=1);<br /><br />namespace meerx\App\scripts\githooks\StandardMeerx\PHPStanHelper;<br /><br />use PHPStan\Reflection\ClassReflection;<br />use PHPStan\TrinaryLogic;<br />use PHPStan\Type\NeverType;<br />use PHPStan\Type\StringType;<br /><br />final class MeerxMetaProperty implements \PHPStan\Reflection\PropertyReflection <br />{<br /><br />    private ClassReflection $classReflection;<br /><br />    public function __construct(ClassReflection $classReflection) <br />    {<br />        $this-&gt;classReflection = $classReflection;<br />    }<br /><br />    public function getReadableType(): \PHPStan\Type\Type <br />    {<br />        return new StringType();<br />    }<br /><br />    public function getWritableType(): \PHPStan\Type\Type <br />    {<br />        return new NeverType();<br />    }<br /><br />    public function isWritable(): bool <br />    {<br />        return false;<br />    }<br /><br />    public function getDeclaringClass(): \PHPStan\Reflection\ClassReflection <br />    {<br />        return $this-&gt;classReflection;<br />    }<br /><br />    public function isStatic(): bool <br />    {<br />        return false;<br />    }<br /><br />    public function isPrivate(): bool <br />    {<br />        return false;<br />    }<br /><br />    public function isPublic(): bool <br />    {<br />        return true;<br />    }<br /><br />    public function getDocComment(): ?string <br />    {<br />        return null;<br />    }<br /><br />    public function canChangeTypeAfterAssignment(): bool <br />    {<br />        return false;<br />    }<br /><br />    public function isReadable(): bool <br />    {<br />        return true;<br />    }<br /><br />    public function isDeprecated(): \PHPStan\TrinaryLogic <br />    {<br />        return TrinaryLogic::createFromBoolean(false);<br />    }<br /><br />    public function getDeprecatedDescription(): ?string <br />    {<br />        return null;<br />    }<br /><br />    public function isInternal(): \PHPStan\TrinaryLogic <br />    {<br />        return TrinaryLogic::createFromBoolean(false);<br />    }<br />}</pre>



<h2 class="wp-block-heading">Summary</h2>



<p class="wp-block-paragraph">Think about your custom code and how you can improve it, use your already used tools and extend it to understand your code. Sometimes it&#8217;s easy, and you can add some <a href="https://suckup.de/2020/02/modern-phpdoc-annotations/">modern PHPDocs</a> or you need to go down the rabbit hole and implement some custom stuff, but at last it will help your software, your team and your customers.</p>
<img loading="lazy" decoding="async" src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2022%2F07%2Fphp-code-quality-with-custom-tooling-extensions%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dphp-code-quality-with-custom-tooling-extensions&amp;action_name=PHP%3A%20Code%20Quality%20with%20Custom%20Tooling%20Extensions&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
					<wfw:commentRss>http://suckup.de/2022/07/php-code-quality-with-custom-tooling-extensions/?pk_campaign=feed&amp;pk_kwd=php-code-quality-with-custom-tooling-extensions/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">6867</post-id>	</item>
		<item>
		<title>Timeout Problems: Web Server + PHP</title>
		<link>http://suckup.de/2022/04/timeout-problems-web-server-php/?pk_campaign=feed&amp;pk_kwd=timeout-problems-web-server-php&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=timeout-problems-web-server-php</link>
					<comments>http://suckup.de/2022/04/timeout-problems-web-server-php/?pk_campaign=feed&amp;pk_kwd=timeout-problems-web-server-php#respond</comments>
		
		<dc:creator><![CDATA[voku]]></dc:creator>
		<pubDate>Tue, 12 Apr 2022 12:39:18 +0000</pubDate>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[mysql servers]]></category>
		<guid isPermaLink="false">https://suckup.de/?p=6852</guid>

					<description><![CDATA[<p><a href="http://suckup.de/2022/04/timeout-problems-web-server-php/?pk_campaign=feed&#038;pk_kwd=timeout-problems-web-server-php">Timeout Problems: Web Server + PHP</a></p>
<p>What? First there is an HTTP request and that will hit your Web server, then it will pass the request via TCP- or UNIT-Socket via FastCGI to your PHP-FPM Daemon, here we will start a new PHP process and in this process we will connect e.g. to the database and run some queries. The Problem! &#8230; <a href="http://suckup.de/2022/04/timeout-problems-web-server-php/?pk_campaign=feed&#038;pk_kwd=timeout-problems-web-server-php" class="more-link">Continue reading <span class="screen-reader-text">Timeout Problems: Web Server + PHP</span></a><img src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2022%2F04%2Ftimeout-problems-web-server-php%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dtimeout-problems-web-server-php&amp;action_name=Timeout%20Problems%3A%20Web%20Server%20%2B%20PHP&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" /></p>
]]></description>
										<content:encoded><![CDATA[<p><a href="http://suckup.de/2022/04/timeout-problems-web-server-php/?pk_campaign=feed&#038;pk_kwd=timeout-problems-web-server-php">Timeout Problems: Web Server + PHP</a></p>

<h2 class="western"><strong>What?</strong></h2>
<div id="article-body" dir="ltr">
<p>First there is an HTTP request and that will hit your Web server, then it will pass the request via TCP- or UNIT-Socket via FastCGI to your PHP-FPM Daemon, here we will start a new PHP process and in this process we will connect e.g. to the database and run some queries.</p>
</div>
<p><img loading="lazy" decoding="async" data-attachment-id="6857" data-permalink="http://suckup.de/?attachment_id=6857" data-orig-file="http://suckup.de/wp-content/uploads//2022/04/7HHxk.jpg" data-orig-size="638,359" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="PHP-Request" data-image-description="" data-image-caption="" data-large-file="http://suckup.de/wp-content/uploads//2022/04/7HHxk.jpg" class="aligncenter wp-image-6857 size-full" src="http://suckup.de/wp-content/uploads//2022/04/7HHxk.jpg" alt="PHP-Request" width="638" height="359" srcset="http://suckup.de/wp-content/uploads/2022/04/7HHxk.jpg 638w, http://suckup.de/wp-content/uploads/2022/04/7HHxk-300x169.jpg 300w" sizes="auto, (max-width: 638px) 100vw, 638px" /></p>
<div id="article-body" dir="ltr">
<h2><strong>The Problem!</strong></h2>
<p>There are different timeout problems here because we connect different pieces together and this parts need to communicate. But what if one of the pieces does not respond in a given time or, even more bad, if one process is running forever like a bad SQL-query.</p>
<h2><strong>Understand your Timeouts.</strong></h2>
<p>Timeouts are a way to limit the time that a request can run, and otherwise an attacker could simply run a denial-of-service with a simple request. But there are many configurations in several layers: Web server, PHP, application, database, curl, &#8230;</p>
<h3 class="western"><strong>&#8211; Web server</strong></h3>
<p>Mostly you will use Apache or Nginx as Web server and in the end it makes not really a difference, there are different timeout settings, but the idea is almost the same: The Web server will stop the execution and kills the PHP process, now you got a 504 HTTP error (Gateway Timeout) and you will lose your stack trace and error-tracking because we killed our application in the middle of nothing. So, we should keep the Web server running as long as needed.</p>
<p>&#8220;`grep -Ri timeout /etc/apache2/&#8220;`</p>
<blockquote>
<pre style="text-align: left;">/etc/apache2/conf-enabled/timeout.conf:Timeout 60<br /><br />/etc/apache2/mods-available/reqtimeout.conf:&lt;IfModule reqtimeout_module&gt;<br /><br />/etc/apache2/mods-available/reqtimeout.conf: # mod_reqtimeout limits the time waiting on the client to prevent an<br /><br />/etc/apache2/mods-available/reqtimeout.conf: # configuration, but it may be necessary to tune the timeout values to<br /><br />/etc/apache2/mods-available/reqtimeout.conf: # mod_reqtimeout per virtual host.<br /><br />/etc/apache2/mods-available/reqtimeout.conf: # Note: Lower timeouts may make sense on non-ssl virtual hosts but can<br /><br />/etc/apache2/mods-available/reqtimeout.conf: # cause problem with ssl enabled virtual hosts: This timeout includes<br /><br />/etc/apache2/mods-available/reqtimeout.conf: RequestReadTimeout header=20-40,minrate=500<br /><br />/etc/apache2/mods-available/reqtimeout.conf: RequestReadTimeout body=10,minrate=500<br /><br />/etc/apache2/mods-available/reqtimeout.load:LoadModule reqtimeout_module /usr/lib/apache2/modules/mod_reqtimeout.so<br /><br />/etc/apache2/mods-available/ssl.conf: # to use and second the expiring timeout (in seconds).<br /><br />/etc/apache2/mods-available/ssl.conf: SSLSessionCacheTimeout 300<br /><br />/etc/apache2/conf-available/timeout.conf:Timeout 60<br /><br />/etc/apache2/apache2.conf:# Timeout: The number of seconds before receives and sends time out.<br /><br />/etc/apache2/apache2.conf:Timeout 60<br /><br />/etc/apache2/apache2.conf:# KeepAliveTimeout: Number of seconds to wait for the next request from the<br /><br />/etc/apache2/apache2.conf:KeepAliveTimeout 5<br /><br />/etc/apache2/mods-enabled/reqtimeout.conf:&lt;IfModule reqtimeout_module&gt;<br /><br />/etc/apache2/mods-enabled/reqtimeout.conf: # mod_reqtimeout limits the time waiting on the client to prevent an<br /><br />/etc/apache2/mods-enabled/reqtimeout.conf: # configuration, but it may be necessary to tune the timeout values to<br /><br />/etc/apache2/mods-enabled/reqtimeout.conf: # mod_reqtimeout per virtual host.<br /><br />/etc/apache2/mods-enabled/reqtimeout.conf: # Note: Lower timeouts may make sense on non-ssl virtual hosts but can<br /><br />/etc/apache2/mods-enabled/reqtimeout.conf: # cause problem with ssl enabled virtual hosts: This timeout includes<br /><br />/etc/apache2/mods-enabled/reqtimeout.conf: RequestReadTimeout header=20-40,minrate=500<br /><br />/etc/apache2/mods-enabled/reqtimeout.conf: RequestReadTimeout body=10,minrate=500<br /><br />/etc/apache2/mods-enabled/reqtimeout.load:LoadModule reqtimeout_module /usr/lib/apache2/modules/mod_reqtimeout.so<br /><br />/etc/apache2/mods-enabled/ssl.conf: # to use and second the expiring timeout (in seconds).<br /><br />/etc/apache2/mods-enabled/ssl.conf: SSLSessionCacheTimeout 300</pre>
</blockquote>
<p>Here you can see all configurations for Apache2 timeouts, but we only need to change <code> etc/apache2/conf-enabled/timeout.conf`</code>` because it will overwrite `/etc/apache2/apache2.conf` anyway.</p>
<p>PS: Remember to reload / restart your Web server after you change the configurations.</p>
<p>If we want to show the user at least a custom error page, we could add something like:</p>
<blockquote>
<p>ErrorDocument503 /error.php?errorcode=503<br />ErrorDocument 504 /error.php?errorcode=504</p>
</blockquote>
<p>â€¦ into our Apache configuration or in a .htaccess file, so that we can still use PHP to show an error page, also if the requested PHP call was killed. The problem here is that we will lose the error message / stack trace / request etc. from the error, and we canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t send e.g. an error into our error logging system. (take a look at sentry, itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s really helpful)</p>
<h3><strong>&#8211; PHP-FPM</strong></h3>
<p>Our PHP-FPM (FastCGI Process Manager) pool can be configured with a timeout (<a href="https://www.php.net/manual/en/install.fpm.configuration.php#request-terminate-timeout" target="_blank" rel="noopener">request-terminate-timeout</a>), but just like the Web server setting, this will kill the PHP worker in the middle of the process, and we canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t handle the error in PHP itself. There is also a setting (<a href="https://www.php.net/manual/en/install.fpm.configuration.php#process-control-timeout" target="_blank" rel="noopener">process_control_timeout</a>) that tells the child processes to wait for this much time before executing the signal received from the parent process, but I am uncertain if this is somehow helpfully here? So, our error handling in PHP canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t catch / log / show the error, and we will get a 503 HTTP error (Service Unavailable) in case of a timeout.</p>
<p>Shutdown functions will not be executed if the process is killed with a SIGTERM or SIGKILL signal. :-/</p>
<p>Source: <a href="https://www.php.net/manual/en/function.register-shutdown-function.php" target="_blank" rel="noopener">register_shutdown_function</a></p>
<p>PS: Remember to reload / restart your PHP-FPM Daemon after you change the configurations.</p>
<h3 class="western">&#8211; PHP</h3>
<p>The first idea from most of us would be maybe to limit the PHP execution time itself, and we are done, but that sounds easier than it is because `max_execution_time` ignores time spent on I/O (system commands e.g. `sleep()`, database queries (<i>SELECT SLEEP(100)</i>). But these are the bottlenecks of nearly all PHP applications, PHP itself is fast but the external called stuff isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t.</p>
<blockquote>
<p>Theset_time_limit()function and the configuration directive <a href="https://www.php.net/manual/en/info.configuration.php#ini.max-execution-time" target="_blank" rel="noopener">max_execution_time</a> only affect the execution time of the script itself. Any time spent on activity that happens outside the execution of the script such as system calls using <a href="https://www.php.net/manual/en/function.system.php" target="_blank" rel="noopener">system()</a>, stream operations, database queries, etc. is not included when determining the maximum time that the script has been running. This is not true on Windows where the measured time is real.</p>
</blockquote>
<p>Source: <a href="https://www.php.net/manual/en/function.set-time-limit.php" target="_blank" rel="noopener"><u>set_time_limit</u></a></p>
<h3 class="western">&#8211; Database (MySQLi)</h3>
<p>Many PHP applications spend most of their time waiting for some bad SQL queries, where the developer missed adding the correct indexes and because we learned that the PHP max execution time did not work for database queries, we need one more timeout setting here.</p>
<p>There is the MYSQLI_OPT_CONNECT_TIMEOUT and MYSQLI_OPT_READ_TIMEOUT (Command execution result timeout in seconds. Available as of PHP 7.2.0. &#8211; <a href="https://www.php.net/manual/en/mysqli.options.php" target="_blank" rel="noopener">mysqli.options</a>) setting, and we can use that to limit the time for our queries.</p>
<p>In the end you will see a â€œErrno: 2006 | Error: MySQL server has gone awayâ€ error in your PHP application, but this error can be caught / reported, and the SQL query can be fixed, otherwise the Apache or PHP-FPM would kill the process, and we do not see the error because our error handler canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t handle it anyway.</p>
<h2>Summary:</h2>
<p>Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s complicated. PHP is not designed for long execution and that is good as it is, but if you need to increase the timeout it will be more complicated than I first thought. You need for example different â€œtimeoutâ€-code for testing different settings:</p>
<blockquote>
<p>// DEBUG: long-running sql-call<br />// Query(&#8216;SELECT SLEEP(600);&#8217;);<br /><br />// DEBUG: long-running system-call<br />// sleep(600);<br /><br />// DEBUG: long-running php-call<br />// while (1) { } // infinite loop</p>
</blockquote>
<h2><strong>Solution: </strong></h2>
<p>We can combine different timeout, but the timeout from the called commands e.g. database, curl, etc. will be combined with the timeout from PHP (max_execution_time) itself. The timeout from the Web server (e.g. Apache2: Timeout) and from PHP-FPM (request_terminate_timeout) need to be longer than the combined timeout from the application so that we still can use our PHP error handler.</p>
<p>e.g.: ~ 5 min. timeout</p>
<ol>
<li>MySQL read timeout: 240s â‡¾ 4 min.
<pre>link-&gt;options(MYSQLI_OPT_READ_TIMEOUT, 240);</pre>
</li>
<li>PHP timeout: 300s â‡¾ 5 min.
<pre>max_execution_time = 300</pre>
</li>
<li>Apache timeout: 360s â‡¾ 6 min.
<pre>Timeout 360</pre>
</li>
<li>PHP-FPM: 420s â‡¾ 7 min.
<pre>request_terminate_timeout = 420</pre>
</li>
</ol>
</div>
<div id="article-body" dir="ltr">
<p>Â </p>
<p>Links:</p>
<ul>
<li><a href="https://tideways.com/profiler/blog/an-introduction-to-php-fpm-tuning" target="_blank" rel="noopener">https://tideways.com/profiler/blog/an-introduction-to-php-fpm-tuning</a></li>
<li><a href="https://www.php.net/manual/en/install.fpm.php" target="_blank" rel="noopener">https://www.php.net/manual/en/install.fpm.php</a></li>
</ul>
</div>
<img loading="lazy" decoding="async" src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2022%2F04%2Ftimeout-problems-web-server-php%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dtimeout-problems-web-server-php&amp;action_name=Timeout%20Problems%3A%20Web%20Server%20%2B%20PHP&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
					<wfw:commentRss>http://suckup.de/2022/04/timeout-problems-web-server-php/?pk_campaign=feed&amp;pk_kwd=timeout-problems-web-server-php/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">6852</post-id>	</item>
		<item>
		<title>Prepare your PHP Code for Static Analysis</title>
		<link>http://suckup.de/2020/12/prepare-your-php-code-for-static-analysis/?pk_campaign=feed&amp;pk_kwd=prepare-your-php-code-for-static-analysis&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=prepare-your-php-code-for-static-analysis</link>
					<comments>http://suckup.de/2020/12/prepare-your-php-code-for-static-analysis/?pk_campaign=feed&amp;pk_kwd=prepare-your-php-code-for-static-analysis#comments</comments>
		
		<dc:creator><![CDATA[voku]]></dc:creator>
		<pubDate>Sun, 13 Dec 2020 01:28:00 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[phpstan]]></category>
		<guid isPermaLink="false">http://suckup.de/?p=6787</guid>

					<description><![CDATA[<p><a href="http://suckup.de/2020/12/prepare-your-php-code-for-static-analysis/?pk_campaign=feed&#038;pk_kwd=prepare-your-php-code-for-static-analysis">Prepare your PHP Code for Static Analysis</a></p>
<p>Prepare your PHP Code for Static Code Analysis, so that e.g. PHPStan or Psalm will understand your code.<img src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2020%2F12%2Fprepare-your-php-code-for-static-analysis%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dprepare-your-php-code-for-static-analysis&amp;action_name=Prepare%20your%20PHP%20Code%20for%20Static%20Analysis&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" /></p>
]]></description>
										<content:encoded><![CDATA[<p><a href="http://suckup.de/2020/12/prepare-your-php-code-for-static-analysis/?pk_campaign=feed&#038;pk_kwd=prepare-your-php-code-for-static-analysis">Prepare your PHP Code for Static Analysis</a></p>

<p>Three years ago I got a new job as PHP developer, before that I called myself web developer because I build ReactJS, jQuery, CSS, HTML, &#8230; and PHPÂ  stuff for a web agency. So now I am a full-time PHP developer and I converted a non typedÂ  (no PHPDoc + no native types) project with ~ 10.000 classes into a project with ~ 90% type coverage. Here is what I have learned.</p>
<h4>1. Write code with IDE autocompletion support.</h4>
<p>If you have autocompletion in the IDE most likely the Static Analysis can understand the code as well.Â </p>
<p><span style="text-decoration: underline;"><em>Example:</em></span></p>
<p>bad:</p>
<p><code>-&gt;get('DB_Connection', true, false);</code></p>
<p>still bad:</p>
<p><code>-&gt;get(DB_Connection::class);</code></p>
<p>good:</p>
<p><code>getDbConnection(): DB_Connection</code></p>
<h4>2. Magic in Code is bad for the long run!</h4>
<p>Magic methods (__get, __set, &#8230;) for example can help to implement new stuff very fast, but the problem is nobody will understand it, you will have no autocompletion, no refactoring options, other developers will need more time to read and navigate in the code and in the end it will cost you much more time than you can save with it.</p>
<h4>3. Break the spell on Magic Code &#8230;</h4>
<p>&#8230; by explaining to everyone (Devs &gt; IDE &gt; Tools) what it does.</p>
<p><span style="text-decoration: underline;"><em>Example 1:</em></span></p>
<p>We use a simple Active Record Pattern, but we put all SQL stuff into the Factory classes, so that the Active Record class can be simple. (<a href="https://github.com/voku/phpstorm_issue_53352/tree/master/src/App/modules/Foo/libs" target="_blank" rel="noopener">Example</a>) But because of missing support for Generics we had no autocompletion without adding many dummy methods into the classes. So one of my first steps was to introduce a â€œ<a href="https://gist.github.com/voku/3aba12eb898dfa209a787c398a331f9c" target="_blank" rel="noopener">PhpCsFixer</a>â€ that automatically adds the missing methods of the parent class with the correct types via â€œ@methodâ€-comments into these classes.Â </p>
<p><em><span style="text-decoration: underline;">Example 2:</span></em></p>
<p>Sometimes you can use more modern <a href="https://suckup.de/2020/02/modern-phpdoc-annotations/" target="_blank" rel="noopener">PHPDocs</a> to explain the function. Take a look at the â€œarray_firstâ€ function in the linked Post.</p>
<p><em><span style="text-decoration: underline;">Example 3:</span></em></p>
<pre>/**<br /> * Return an array which has the Property-Values of the given Objects as Values.<br /> *<br /> * @param object[]    $ObjArray<br /> * @param string      $PropertyName<br /> * @param null|string $KeyPropertyName if given uses this Property as key for the returned Array otherwise the keys from the<br /> *                                     given array are used<br /> *<br /> * @throws Exception if no property with the given name was found<br /> *<br /> * @return array<br /> */<br />function propertyArray($ObjArray, $PropertyName, $KeyPropertyName = null): array {<br />    // init<br />    $PropertyArray = [];<br /><br />    foreach ($ObjArray as $key =&gt; $Obj) {<br />        if (!\property_exists($Obj, $PropertyName)) {<br />            throw new Exception('No Property with Name ' . $PropertyName . ' in Object Found - Value');<br />        }<br /><br />        $usedKey = $key;<br />        if ($KeyPropertyName) {<br />            if (!\property_exists($Obj, $KeyPropertyName)) {<br />                throw new Exception('No Property with Name ' . $PropertyName . ' in Object Found - Key');<br />            }<br />            $usedKey = $Obj-&gt;{$KeyPropertyName};<br />        }<br /><br />        $PropertyArray[$usedKey] = $Obj-&gt;{$PropertyName};<br />    }<br /><br />    return $PropertyArray;<br />}</pre>
<p>Sometimes it&#8217;s hard to describe the specific output types, so here you need to extend theÂ  functions of your Static Code Analyze Tool, so that it knows what you are doing. â‡¾ <a href="https://gist.github.com/voku/80722c9310c21719fbcfbfeb565cc6f9" target="_blank" rel="noopener">for example here you can find a solution for PHPStan</a> â‡½Â  but there is still no support for the IDE and so maybe it&#8217;s not the best idea to use magic like that at all. And I am sure it&#8217;s more simple to use specific and simple methods instead:Â  e.g. <code>BillCollection-&gt;getBillDates()</code></p>
<h4>4. Try to not use strings for the code.</h4>
<p>Strings are simple and flexible, but they are also bad for the long run. Mostly strings are used because it looks like a simple solution, but often they are redundant, you will have typos everywhere and the IDE and/or Static Analysis can&#8217;t analyze them because it&#8217;s just text.</p>
<p><em><span style="text-decoration: underline;">Example:</span></em></p>
<p>bad:Â </p>
<pre>AjaxEditDate::generator($bill-&gt;bill_id, $bill-&gt;date, 'Bill', 'date');</pre>
<ul>
<li>&#8220;Bill&#8221; â‡¾ is not needed here, we can call e.g. <code>get_class($bill)</code> in the &#8220;generator&#8221; method</li>
<li>&#8220;date&#8221; â‡¾ is not needed here, we can <a href="https://github.com/voku/phpstorm_issue_53352/blob/master/src/Framework/ActiveRecord/ActiveRow.php#L37" target="_blank" rel="noopener">fetch the property</a> name from the class</li>
<li>&#8220;$bill-&gt;bill_id&#8221; â‡¾ is not needed here, we can get the primary id value from the class</li>
</ul>
<p>good:</p>
<pre>AjaxEditDate::generator($bill, $bill-&gt;m()-&gt;date);</pre>
<h4>5. Automate stuff via git hook and check it via CI server.</h4>
<p>Fixing bad code is only done if you disallow the same bad code for the future. With a pre-commit hook for git it&#8217;s simple to run these checks, but you need to check it again in the CI server because the developers can simply skip these checks.</p>
<p><em><span style="text-decoration: underline;">Example:</span></em></p>
<p>I introduced a check for disallowing global variables (global $foo &amp;&amp; $GLOBALS[&#8216;foo&#8217;]) via â€œ<a href="https://gist.github.com/voku/d7d530ce2c072f5b4bdaafb040d1eb55" target="_blank" rel="noopener">PHP_CodeSniffer</a>â€.Â </p>
<p><em><span style="text-decoration: underline;">Links:</span></em></p>
<ul>
<li><a href="https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks" target="_blank" rel="noopener">git-scm.com: git hooks</a></li>
<li><a href="https://github.com/captainhookphp/captainhook" target="_blank" rel="noopener">CaptainHook: git hook library for php</a></li>
</ul>
<h4>6. Use array shapes (or collections) if you need to return an array, please.</h4>
<p><a href="https://phpstan.org/writing-php-code/phpdoc-types#array-shapes" target="_blank" rel="noopener">Array shapes</a> are like arrays but with fixed keys, so that you can define the types of each key in the PHPDocs.</p>
<p>You will have <a href="https://plugins.jetbrains.com/plugin/9927-deep-assoc-completion" target="_blank" rel="noopener">autocompletion for the IDE</a> + all other devs can see what the method will return + you will notice if you&#8217;re better retuning an object because it will be very hard to describe the output for complex data structures and Static Analysis can use and check the types.Â </p>
<p><em><span style="text-decoration: underline;">Example:</span></em></p>
<pre>/**<br /> * @return array{<br /> *    missing: array&lt;ShoppingCartLib::TAB_*,string&gt;,<br /> *    disabled: array&lt;ShoppingCartLib::TAB_*,string&gt;<br /> * }<br /> */<br />private static function getShoppingCartTabStatus(): array {<br /> ...<br />}</pre>
<img loading="lazy" decoding="async" src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2020%2F12%2Fprepare-your-php-code-for-static-analysis%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dprepare-your-php-code-for-static-analysis&amp;action_name=Prepare%20your%20PHP%20Code%20for%20Static%20Analysis&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
					<wfw:commentRss>http://suckup.de/2020/12/prepare-your-php-code-for-static-analysis/?pk_campaign=feed&amp;pk_kwd=prepare-your-php-code-for-static-analysis/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">6787</post-id>	</item>
		<item>
		<title>Generics in PHP via PHPDocs</title>
		<link>http://suckup.de/2020/08/generics-in-php-via-phpdocs/?pk_campaign=feed&amp;pk_kwd=generics-in-php-via-phpdocs&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=generics-in-php-via-phpdocs</link>
					<comments>http://suckup.de/2020/08/generics-in-php-via-phpdocs/?pk_campaign=feed&amp;pk_kwd=generics-in-php-via-phpdocs#respond</comments>
		
		<dc:creator><![CDATA[voku]]></dc:creator>
		<pubDate>Sat, 29 Aug 2020 00:34:02 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[generics]]></category>
		<category><![CDATA[phpdoc]]></category>
		<guid isPermaLink="false">http://suckup.de/?p=6752</guid>

					<description><![CDATA[<p><a href="http://suckup.de/2020/08/generics-in-php-via-phpdocs/?pk_campaign=feed&#038;pk_kwd=generics-in-php-via-phpdocs">Generics in PHP via PHPDocs</a></p>
<p>Examples for Generics in PHP via PHPDocs / Template annotations.<img src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2020%2F08%2Fgenerics-in-php-via-phpdocs%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dgenerics-in-php-via-phpdocs&amp;action_name=Generics%20in%20PHP%20via%20PHPDocs&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" /></p>
]]></description>
										<content:encoded><![CDATA[<p><a href="http://suckup.de/2020/08/generics-in-php-via-phpdocs/?pk_campaign=feed&#038;pk_kwd=generics-in-php-via-phpdocs">Generics in PHP via PHPDocs</a></p>

<p style="text-align: left;">If you did not know that you can use Generics in PHP or you do not exactly know how to use it or why you should use it, then the next examples are for you.</p>
<h3 id="type-variables">Type variables via @template</h3>
<p>The&nbsp;<code>@template</code> tag allows classes and functions to declare a generic type parameter. The next examples starts with simple functions, so that we understand how it works, and then we will see the power of this in classes.</p>



<hr class="wp-block-separator is-style-wide"/>



<p><strong>A dummy function that will return the input.</strong></p>
<p><strong>â‡¾</strong> <a href="https://phpstan.org/r/1922279b-9786-4523-939d-dddcfd4ebb86" target="_blank" rel="noopener noreferrer"><strong>https://phpstan.org/r/1922279b-9786-4523-939d-dddcfd4ebb86</strong></a></p>



<pre class="wp-block-code"><code>    &lt;?php    

    /**
     * @param \Exception $param
     * @return \Exception
     *
     * @template T of \Exception
     * @psalm-param T $param
     * @psalm-return T
     */
    function foo($param) { ... }

    foo(new \InvalidArgumentException()); // The static-analysis-tool knows that 
                                          // the type is still "\InvalidArgumentException" 
                                          // because of the type variable.
</code></pre>



<p><strong>@template T of \Exception</strong> // here we create a new type variable, and we force that it must be an instance of \Exception</p>
<p><strong>@phpstan-param T $param</strong> // here we say that the static-analysis-tool need to remember the type that this variable had before (you can use @psalm-* or @phpstan-* both works with both tools)</p>
<p><strong>@phpstan-return T</strong> // and that the return type is the same as the input type&nbsp;</p>



<hr class="wp-block-separator is-style-wide"/>



<p><strong>A simple function that gets the first element of an array or a fallback.Â </strong></p>
<p>In the @param PHPDocs we write â€œmixedâ€ because this function can handle different types. But this information is not very helpful if you want to understand programmatically what the code does, so we need to give the static-analysis-tools some more information.Â </p>
<p><strong>â‡¾ <a href="https://phpstan.org/r/1900a2af-f5c1-4942-939c-409928a5ac4a" target="_blank" rel="noopener noreferrer">https://phpstan.org/r/1900a2af-f5c1-4942-939c-409928a5ac4a</a></strong></p>



<pre class="wp-block-code"><code>    &lt;?php
     
    /**
     * @param array&lt;mixed> $array
     * @param mixed        $fallback &lt;p>This fallback will be used, if the array is empty.&lt;/p>
     *
     * @return mixed|null
     *
     * @template TFirst
     * @template TFirstFallback
     * @psalm-param TFirst&#91;] $array
     * @psalm-param TFirstFallback $fallback
     * @psalm-return TFirst|TFirstFallback
     */
    function array_first(array $array, $fallback)
    {
        $key_first = array_key_first($array);
        if ($key_first === null) {
            return $fallback;
        }

        return $array&#91;$key_first];
    }

    array_first(&#91;1, 2, 3], null); 

    if ($a === 'foo') { // The static-analysis-tool knows that 
                        // === between int|null and 'foo' will always evaluate to false.
	    // ...
    }</code></pre>



<p><strong>@template TFirst</strong> // we again define your typed variables</p>
<p><strong>@template TFirstFallback</strong> // and one more because we have two inputs where we want to keep track of the types</p>
<p><strong>@psalm-param TFirst[] $array</strong> // here we define that $array is an array of TFirst types</p>
<p><strong>@psalm-param TFirstFallback $fallback</strong> // and that $fallback is some other type that comes into this function</p>
<p><strong>@psalm-return TFirst|TFirstFallback</strong> // now we define the return type as an element of&nbsp; the $array or the $fallback type&nbsp;</p>



<hr class="wp-block-separator is-style-wide"/>



<p>&nbsp;<strong>Very basic <em>Active Record</em> + Generics</strong></p>
<p>The IDE support for generics is currently not there, :-/ so that we still need some hacks (see @method) for e.g. PhpStorm to have autocompletion.</p>
<p><strong>â‡¾ </strong><a href="https://phpstan.org/r/f88f5cd4-1bb9-4a09-baae-069fddb10b12" target="_blank" rel="noopener noreferrer"><strong>https://phpstan.org/r/f88f5cd4-1bb9-4a09-baae-069fddb10b12</strong></a></p>
<p><strong><a href="https://github.com/voku/phpstorm_issue_53352/tree/master/src/Framework/ActiveRecord" target="_blank" rel="noopener noreferrer">https://github.com/voku/phpstorm_issue_53352/tree/master/src/Framework/ActiveRecord</a></strong></p>



<pre class="wp-block-code"><code>&lt;?php

class ActiveRow
{
    /**
     * @var ManagedFactory&lt;static>
     */
    public $factory;

    /**
     * @param Factory&lt;ActiveRow>|ManagedFactory&lt;static> $factory
     * @param null|array                                $row
     */
    public function __construct(Factory $factory, array $row = null) {
        $this->factory = &amp;$factory;
    }
}

/**
 * @template T
 */
abstract class Factory
{
    /**
     * @var string
     *
     * @internal
     *
     * @psalm-var class-string&lt;T>
     */
    protected $classname;

    /**
     * @return static
     */
    public static function create() {
        return new static();
    }
}

/**
 * @template  T
 * @extends   Factory&lt;T>
 */
class ManagedFactory extends Factory
{
    /**
     * @param string $classname
     *
     * @return void
     *
     * @psalm-param class-string&lt;T> $classname
     */
    protected function setClass(string $classname): void
    {
        if (\class_exists($classname) === false) {
            /** @noinspection ThrowRawExceptionInspection */
            throw new Exception('TODO');
        }

        if (\is_subclass_of($classname, ActiveRow::class) === false) {
            /** @noinspection ThrowRawExceptionInspection */
            throw new Exception('TODO');
        }

        $this->classname = $classname;
    }

    // ...
}

final class Foo extends ActiveRow {

    public int $foo_id;

    public int $user_id;

    // --------------------------------------
    // add more logic here ...
    // --------------------------------------
}

/**
 * @method Foo&#91;] fetchAll(...)
 *
 * @see Foo
 *
 * // warning -> do not edit this comment by hand, it's auto-generated and the @method phpdocs are for IDE support       
 * //         -> https://gist.github.com/voku/3aba12eb898dfa209a787c398a331f9c
 *
 * @extends ManagedFactory&lt;Foo>
 */
final class FooFactory extends ManagedFactory
{
    // -----------------------------------------------
    // add sql stuff here ...
    // -----------------------------------------------
}</code></pre>



<hr class="wp-block-separator is-style-wide"/>



<p><strong>A more complex collection example.</strong></p>
<p>In the end we can extend the â€œAbstractCollectionâ€ and the static-analysis-tools knows the types of all the methods.&nbsp;</p>
<p><strong><a href="https://github.com/voku/Arrayy/tree/master/src/Type" target="_blank" rel="noopener noreferrer">https://github.com/voku/Arrayy/tree/master/src/Type</a></strong></p>



<pre class="wp-block-code"><code>/**
 * @template TKey of array-key
 * @template T
 * @template-extends \ArrayObject&lt;TKey,T>
 * @template-implements \IteratorAggregate&lt;TKey,T>
 * @template-implements \ArrayAccess&lt;TKey|null,T>
 */
class Arrayy extends \ArrayObject implements \IteratorAggregate, \ArrayAccess, \Serializable, \JsonSerializable, \Countable
{ ... }

/**
 * @template TKey of array-key
 * @template T
 * @template-extends \IteratorAggregate&lt;TKey,T>
 * @template-extends \ArrayAccess&lt;TKey|null,T>
 */
interface CollectionInterface extends \IteratorAggregate, \ArrayAccess, \Serializable, \JsonSerializable, \Countable
{ ... }

/**
 * @template   TKey of array-key
 * @template   T
 * @extends    Arrayy&lt;TKey,T>
 * @implements CollectionInterface&lt;TKey,T>
 */
abstract class AbstractCollection extends Arrayy implements CollectionInterface
{ ... }

/**
 * @template TKey of array-key
 * @template T
 * @extends  AbstractCollection&lt;TKey,T>
 */
class Collection extends AbstractCollection
{ ... }</code></pre>



<p><strong>Links:</strong></p>
<p>â‡¾ <a href="https://phpstan.org/blog/generics-in-php-using-phpdocs" target="_blank" rel="noopener noreferrer">https://phpstan.org/blog/generics-in-php-using-phpdocs</a></p>
<p>â‡¾ <a href="https://psalm.dev/docs/annotating_code/templated_annotations/" target="_blank" rel="noopener noreferrer">https://psalm.dev/docs/annotating_code/templated_annotations/</a></p>
<p>â‡¾ <a href="https://stitcher.io/blog/php-generics-and-why-we-need-them" target="_blank" rel="noopener noreferrer">https://stitcher.io/blog/php-generics-and-why-we-need-them</a></p>
<img loading="lazy" decoding="async" src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2020%2F08%2Fgenerics-in-php-via-phpdocs%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dgenerics-in-php-via-phpdocs&amp;action_name=Generics%20in%20PHP%20via%20PHPDocs&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
					<wfw:commentRss>http://suckup.de/2020/08/generics-in-php-via-phpdocs/?pk_campaign=feed&amp;pk_kwd=generics-in-php-via-phpdocs/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">6752</post-id>	</item>
		<item>
		<title>â&#157;¤ï¸&#143; Simple PHP Code Parser</title>
		<link>http://suckup.de/2020/08/simple-php-code-parser/?pk_campaign=feed&amp;pk_kwd=simple-php-code-parser&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=simple-php-code-parser</link>
					<comments>http://suckup.de/2020/08/simple-php-code-parser/?pk_campaign=feed&amp;pk_kwd=simple-php-code-parser#comments</comments>
		
		<dc:creator><![CDATA[voku]]></dc:creator>
		<pubDate>Fri, 07 Aug 2020 00:10:59 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[code]]></category>
		<guid isPermaLink="false">http://suckup.de/?p=6733</guid>

					<description><![CDATA[<p><a href="http://suckup.de/2020/08/simple-php-code-parser/?pk_campaign=feed&#038;pk_kwd=simple-php-code-parser">â¤ï¸ Simple PHP Code Parser</a></p>
<p>Simple PHP Code Parser &#124; a simple data structure from your php code<img src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2020%2F08%2Fsimple-php-code-parser%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dsimple-php-code-parser&amp;action_name=%C3%A2%C2%9D%C2%A4%C3%AF%C2%B8%C2%8F%20Simple%20PHP%20Code%20Parser&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" /></p>
]]></description>
										<content:encoded><![CDATA[<p><a href="http://suckup.de/2020/08/simple-php-code-parser/?pk_campaign=feed&#038;pk_kwd=simple-php-code-parser">â¤ï¸ Simple PHP Code Parser</a></p>

<p>It based on code from &#8220;<a href="https://github.com/JetBrains/phpstorm-stubs" target="_blank" rel="noopener noreferrer">JetBrains/phpstorm-stubs&#8221;</a> but instead of Php-Reflection we now use nikic/PHP-Parser, BetterReflection, phpDocumentor and PHPStan/phpdoc-parser internally. So, you can get even more information about the code. For example, psalm- / phpstan-phpdoc annotations or inheritdoc from methods.</p>
<p><strong>Install</strong>:</p>
<pre>composer require voku/simple-php-code-parser</pre>
<p><strong>Link</strong>:</p>
<p><a href="https://github.com/voku/Simple-PHP-Code-Parser">voku/Simple-PHP-Code-Parser</a></p>
<p><strong>More</strong>:</p>
<ul>
<li>there is also a &#8220;.phar&#8221; version for e.g. phpdoc checks: <a href="https://github.com/voku/Simple-PHP-Code-Parser/releases">voku/Simple-PHP-Code-Parser/releases</a></li>
<li>and an API documentations helper for your README file, based on the simple php code parser: <a href="https://github.com/voku/Php-Readme-Helper">voku/Php-Readme-Helper</a></li>
</ul>



<hr class="wp-block-separator is-style-wide"/>



<p><strong>Example</strong>: get value from define in &#8220;\foo\bar&#8221; namespace</p>



<pre class="wp-block-code"><code>$code = '
  &lt;?php
  namespace foo\bar;
  define("FOO_BAR", "Lall");
';

$phpCode = PhpCodeParser::getFromString($code);
$phpConstants = $phpCode->getConstants();

$phpConstants&#91;'\foo\bar\FOO_BAR']->value; // 'Lall'</code></pre>



<hr class="wp-block-separator is-style-wide"/>



<p><strong>Example</strong>: get information about @property phpdoc from a class</p>



<pre class="wp-block-code"><code>$code = '
  &lt;?php
  /** 
   * @property int&#91;] $foo 
   */
  abstract class Foo { }
';

$phpCode = PhpCodeParser::getFromString($code);
$phpClass = $phpCode->getClass('Foo');

$phpClass->properties&#91;'foo']->typeFromPhpDoc); // int</code></pre>



<hr class="wp-block-separator is-style-wide"/>



<p><strong>Example</strong>: get classes from a string (or from a class-name or from a file or from a directory)</p>



<pre class="wp-block-code"><code>$code = '
&lt;?php
namespace voku\tests;
class SimpleClass {}
$obja = new class() {};
$objb = new class {};
class AnotherClass {}
';

$phpCode = \voku\SimplePhpParser\Parsers\PhpCodeParser::getFromString($code);
$phpClasses = $phpCode->getClasses();

var_dump($phpClasses&#91;'voku\tests\SimpleClass']); // "PHPClass"-object</code></pre>



<hr class="wp-block-separator is-style-wide"/>
<img loading="lazy" decoding="async" src="https://suckup.de/piwik/piwik.php?idsite=1&amp;rec=1&amp;url=http%3A%2F%2Fsuckup.de%2F2020%2F08%2Fsimple-php-code-parser%2F%3Fpk_campaign%3Dfeed%26pk_kwd%3Dsimple-php-code-parser&amp;action_name=%C3%A2%C2%9D%C2%A4%C3%AF%C2%B8%C2%8F%20Simple%20PHP%20Code%20Parser&amp;urlref=http%3A%2F%2Fsuckup.de%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
					<wfw:commentRss>http://suckup.de/2020/08/simple-php-code-parser/?pk_campaign=feed&amp;pk_kwd=simple-php-code-parser/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">6733</post-id>	</item>
	</channel>
</rss><!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Object Caching 60/129 objects using Memcache
Page Caching using Memcache (Page is feed) 
Content Delivery Network via N/A
Lazy Loading (feed)
Database Caching 3/21 queries in 0.014 seconds using Memcache

Served from: suckup.de @ 2026-10-22 15:25:38 by W3 Total Cache
-->