<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="en">
	<title>alies.dev</title>
	<subtitle>Alies Lapatsin — Staff Engineer writing about AI, PHP, Laravel, code quality, and developer tooling.</subtitle>
	<link href="https://alies.dev/feed/feed.xml" rel="self"/>
	<link href="https://alies.dev/"/>
	<updated>2026-03-25T00:00:00Z</updated>
	<id>https://alies.dev/</id>
	<author>
		<name>Alies Lapatsin</name>
		<email>hi@alies.dev</email>
	</author>
	
	<entry>
		<title>Stop Wasting 89% of Your AI Agent&#39;s Tokens on CLI Noise</title>
		<link href="https://alies.dev/articles/cli-output-for-ai/"/>
		<updated>2026-03-25T00:00:00Z</updated>
		<id>https://alies.dev/articles/cli-output-for-ai/</id>
		<content type="html">&lt;div class=&quot;tokenizer-hero&quot;&gt;
	&lt;div class=&quot;tokenizer-text&quot;&gt;&lt;span class=&quot;t1&quot;&gt;PHP&lt;/span&gt;&lt;span class=&quot;t2&quot;&gt;Unit&lt;/span&gt;&lt;span class=&quot;t3&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t4&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;t5&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;t6&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;t7&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;t8&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;t9&quot;&gt; by&lt;/span&gt;&lt;span class=&quot;t10&quot;&gt; Sebastian&lt;/span&gt;&lt;span class=&quot;t1&quot;&gt; Berg&lt;/span&gt;&lt;span class=&quot;t2&quot;&gt;mann&lt;/span&gt;&lt;span class=&quot;t3&quot;&gt; and&lt;/span&gt;&lt;span class=&quot;t4&quot;&gt; contributors&lt;/span&gt;&lt;span class=&quot;t5&quot;&gt;.
&lt;p&gt;&lt;/p&gt;&lt;/span&gt;&lt;span class=&quot;t6&quot;&gt;Runtime&lt;/span&gt;&lt;span class=&quot;t7&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;t8&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;t9&quot;&gt; PHP&lt;/span&gt;&lt;span class=&quot;t1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t2&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;t3&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;t4&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;t5&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;t6&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;t7&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;t8&quot;&gt;Configuration&lt;/span&gt;&lt;span class=&quot;t9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;t10&quot;&gt; /&lt;/span&gt;&lt;span class=&quot;t1&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;t2&quot;&gt;/www&lt;/span&gt;&lt;span class=&quot;t3&quot;&gt;/html&lt;/span&gt;&lt;span class=&quot;t4&quot;&gt;/php&lt;/span&gt;&lt;span class=&quot;t5&quot;&gt;unit&lt;/span&gt;&lt;span class=&quot;t6&quot;&gt;.xml&lt;/span&gt;&lt;span class=&quot;t7&quot;&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;/span&gt;&lt;span class=&quot;t8&quot;&gt;................................&lt;/span&gt;&lt;span class=&quot;t9&quot;&gt;........................&lt;/span&gt;&lt;span class=&quot;t1&quot;&gt;.......&lt;/span&gt;&lt;span class=&quot;t2&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;t3&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t4&quot;&gt;63&lt;/span&gt;&lt;span class=&quot;t5&quot;&gt; /&lt;/span&gt;&lt;span class=&quot;t6&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t7&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;t8&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;t9&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t10&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;t1&quot;&gt;%)
&lt;/span&gt;&lt;span class=&quot;t2&quot;&gt;................................&lt;/span&gt;&lt;span class=&quot;t3&quot;&gt;........................&lt;/span&gt;&lt;span class=&quot;t4&quot;&gt;.......&lt;/span&gt;&lt;span class=&quot;t5&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t6&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t7&quot;&gt;126&lt;/span&gt;&lt;span class=&quot;t8&quot;&gt; /&lt;/span&gt;&lt;span class=&quot;t9&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t1&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;t2&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;t3&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t4&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;t5&quot;&gt;%)
&lt;/span&gt;&lt;span class=&quot;t6&quot;&gt;................................&lt;/span&gt;&lt;span class=&quot;t7&quot;&gt;........................&lt;/span&gt;&lt;span class=&quot;t8&quot;&gt;.......&lt;/span&gt;&lt;span class=&quot;t9&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t10&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t1&quot;&gt;189&lt;/span&gt;&lt;span class=&quot;t2&quot;&gt; /&lt;/span&gt;&lt;span class=&quot;t3&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t4&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;t5&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;t6&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t7&quot;&gt;37&lt;/span&gt;&lt;span class=&quot;t8&quot;&gt;%)
&lt;/span&gt;&lt;span class=&quot;t9&quot;&gt;................................&lt;/span&gt;&lt;span class=&quot;t1&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;t2&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;t3&quot;&gt;........................&lt;/span&gt;&lt;span class=&quot;t4&quot;&gt;....&lt;/span&gt;&lt;span class=&quot;t5&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t6&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t7&quot;&gt;252&lt;/span&gt;&lt;span class=&quot;t8&quot;&gt; /&lt;/span&gt;&lt;span class=&quot;t9&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t10&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;t1&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;t2&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t3&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;t4&quot;&gt;%)
&lt;/span&gt;&lt;span class=&quot;t5&quot;&gt;................................&lt;/span&gt;&lt;span class=&quot;t6&quot;&gt;........................&lt;/span&gt;&lt;span class=&quot;t7&quot;&gt;.......&lt;/span&gt;&lt;span class=&quot;t8&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t9&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t1&quot;&gt;315&lt;/span&gt;&lt;span class=&quot;t2&quot;&gt; /&lt;/span&gt;&lt;span class=&quot;t3&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t4&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;t5&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;t6&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t7&quot;&gt;63&lt;/span&gt;&lt;span class=&quot;t8&quot;&gt;%)
&lt;/span&gt;&lt;span class=&quot;t9&quot;&gt;................................&lt;/span&gt;&lt;span class=&quot;t10&quot;&gt;........................&lt;/span&gt;&lt;span class=&quot;t1&quot;&gt;.......&lt;/span&gt;&lt;span class=&quot;t2&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t3&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t4&quot;&gt;378&lt;/span&gt;&lt;span class=&quot;t5&quot;&gt; /&lt;/span&gt;&lt;span class=&quot;t6&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t7&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;t8&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;t9&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t1&quot;&gt;75&lt;/span&gt;&lt;span class=&quot;t2&quot;&gt;%)
&lt;/span&gt;&lt;span class=&quot;t3&quot;&gt;................................&lt;/span&gt;&lt;span class=&quot;t4&quot;&gt;........................&lt;/span&gt;&lt;span class=&quot;t5&quot;&gt;.......&lt;/span&gt;&lt;span class=&quot;t6&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t7&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t8&quot;&gt;441&lt;/span&gt;&lt;span class=&quot;t9&quot;&gt; /&lt;/span&gt;&lt;span class=&quot;t10&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t1&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;t2&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;t3&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t4&quot;&gt;87&lt;/span&gt;&lt;span class=&quot;t5&quot;&gt;%)
&lt;/span&gt;&lt;span class=&quot;t6&quot;&gt;................................&lt;/span&gt;&lt;span class=&quot;t7&quot;&gt;........................&lt;/span&gt;&lt;span class=&quot;t8&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;t9&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;t1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t2&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;t3&quot;&gt; /&lt;/span&gt;&lt;span class=&quot;t4&quot;&gt; &lt;/span&gt;&lt;span class=&quot;t5&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;t6&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;t7&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;t8&quot;&gt;%)&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;tokenizer-label&quot;&gt;~250 tokens of PHPUnit output — 45% is noise from progress dots&lt;/div&gt;&lt;p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;style&gt;
	.tokenizer-hero {
		max-width: 800px;
		background-color: #f8f9fa;
		border-radius: 10px;
		padding: 24px;
		box-shadow: 0 0 10px rgba(0,0,0,0.08);
		overflow: hidden;
		margin: 0 auto;
		font-family: &#39;Courier New&#39;, Courier, monospace;
	}

	.tokenizer-text {
		font-size: 13px;
		line-height: 1.7;
		white-space: pre;
		overflow-x: auto;
	}

	.tokenizer-label {
		margin-top: 16px;
		font-family: -apple-system, BlinkMacSystemFont, &#39;Segoe UI&#39;, Roboto, sans-serif;
		font-size: 13px;
		color: #6b7280;
		text-align: center;
	}

	.tokenizer-hero .t1  { background-color: #bfdbfe; color: #1e3a5f; }
	.tokenizer-hero .t2  { background-color: #fde68a; color: #713f12; }
	.tokenizer-hero .t3  { background-color: #bbf7d0; color: #14532d; }
	.tokenizer-hero .t4  { background-color: #fecaca; color: #7f1d1d; }
	.tokenizer-hero .t5  { background-color: #e9d5ff; color: #4c1d95; }
	.tokenizer-hero .t6  { background-color: #fed7aa; color: #7c2d12; }
	.tokenizer-hero .t7  { background-color: #a5f3fc; color: #155e75; }
	.tokenizer-hero .t8  { background-color: #d1d5db; color: #374151; }
	.tokenizer-hero .t9  { background-color: #c7d2fe; color: #312e81; }
	.tokenizer-hero .t10 { background-color: #fca5a5; color: #7f1d1d; }

	@media (prefers-color-scheme: dark) {
		.tokenizer-hero {
			background-color: #1e2e3e;
			box-shadow: 0 0 10px rgba(0,0,0,0.3);
		}
		.tokenizer-label {
			color: #9ca3af;
		}
		.tokenizer-hero .t1  { background-color: #1e3a5f; color: #bfdbfe; }
		.tokenizer-hero .t2  { background-color: #713f12; color: #fde68a; }
		.tokenizer-hero .t3  { background-color: #14532d; color: #bbf7d0; }
		.tokenizer-hero .t4  { background-color: #7f1d1d; color: #fecaca; }
		.tokenizer-hero .t5  { background-color: #4c1d95; color: #e9d5ff; }
		.tokenizer-hero .t6  { background-color: #7c2d12; color: #fed7aa; }
		.tokenizer-hero .t7  { background-color: #155e75; color: #a5f3fc; }
		.tokenizer-hero .t8  { background-color: #374151; color: #d1d5db; }
		.tokenizer-hero .t9  { background-color: #312e81; color: #c7d2fe; }
		.tokenizer-hero .t10 { background-color: #7f1d1d; color: #fca5a5; }
	}

	.code-sm [class^=&quot;language-&quot;],
	.code-sm [class*=&quot; language-&quot;] {
		font-size: 13px;
	}

	.tokenizer-text span {
		opacity: 0;
	}
	.tokenizer-text span.visible {
		opacity: 1;
	}
&lt;/style&gt;
&lt;script&gt;
	(function () {
		const tokens = document.querySelectorAll(&#39;.tokenizer-text span&#39;);
		const delay = 13;
		const observer = new IntersectionObserver(function (entries) {
			if (!entries[0].isIntersecting) return;
			observer.disconnect();
			tokens.forEach(function (token, i) {
				setTimeout(function () { token.classList.add(&#39;visible&#39;); }, i * delay);
			});
		});
		observer.observe(document.querySelector(&#39;.tokenizer-hero&#39;));
	})();
&lt;/script&gt;
&lt;p&gt;AI coding agents - Claude Code, Cursor, GitHub Copilot, Windsurf - run your CLI tools and feed the output back into the LLM context window.
The problem: most CLI tools were built for humans staring at terminals, not for machines parsing results.&lt;/p&gt;
&lt;p&gt;Progress bars, color codes, box-drawing borders, ASCII art banners - all meaningless noise for an LLM. And you&#39;re paying for every token of it.&lt;/p&gt;
&lt;h2 id=&quot;the-numbers&quot; tabindex=&quot;-1&quot;&gt;The numbers &lt;a class=&quot;header-anchor&quot; href=&quot;https://alies.dev/articles/cli-output-for-ai/#the-numbers&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Over ~2,900 CLI commands measured by &lt;a href=&quot;https://www.rtk-ai.app/&quot;&gt;rtk-ai&lt;/a&gt;, &lt;strong&gt;11.6M input tokens were consumed, of which 10.3M (89.2%) were noise&lt;/strong&gt;.
A typical 2-hour AI coding session generates ~210K tokens of raw CLI output - enough to overflow a 200K context window with mostly garbage.&lt;/p&gt;
&lt;p&gt;A team of 10 developers wastes approximately &lt;strong&gt;$1,750/month&lt;/strong&gt; on noise tokens alone.&lt;/p&gt;
&lt;h2 id=&quot;a-phpunit-example&quot; tabindex=&quot;-1&quot;&gt;A PHPUnit example &lt;a class=&quot;header-anchor&quot; href=&quot;https://alies.dev/articles/cli-output-for-ai/#a-phpunit-example&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Here&#39;s the default PHPUnit output for a test suite with 500 tests, 1 failure:&lt;/p&gt;
&lt;div class=&quot;code-sm no-copy&quot;&gt;
&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;PHPUnit 12.5.14 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.4.19
Configuration: /var/www/html/phpunit.xml

...............................................................   63 / 500 ( 12%)
...............................................................  126 / 500 ( 25%)
...............................................................  189 / 500 ( 37%)
..................................F............................  252 / 500 ( 50%)
...............................................................  315 / 500 ( 63%)
...............................................................  378 / 500 ( 75%)
...............................................................  441 / 500 ( 87%)
...........................................................      500 / 500 (100%)

Time: 00:12.345, Memory: 256.00 MB

There was 1 failure:

1) Tests&#92;Unit&#92;AppHelperTest::get_morph_class_accepts_model_instance
Failed asserting that two strings are identical.
--- Expected
+++ Actual
@@ @@
-&#39;App&#92;Models&#92;Role&#39;
+&#39;App&#92;Models&#92;Role---error&#39;

/var/www/html/tests/Unit/AppHelperTest.php:20

FAILURES!
Tests: 500, Assertions: 1200, Failures: 1.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;~250 tokens.&lt;/strong&gt; The progress lines, banner, timing, and memory stats account for most of it. The actual failure information is only ~85 tokens.&lt;/p&gt;
&lt;p&gt;Now the same result with &lt;code&gt;--no-progress&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;code-sm no-copy&quot;&gt;
&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;PHPUnit 12.5.14 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.4.19
Configuration: /var/www/html/phpunit.xml

Time: 00:12.345, Memory: 256.00 MB

There was 1 failure:

1) Tests&#92;Unit&#92;AppHelperTest::get_morph_class_accepts_model_instance
Failed asserting that two strings are identical.
--- Expected
+++ Actual
@@ @@
-&#39;App&#92;Models&#92;Role&#39;
+&#39;App&#92;Models&#92;Role---error&#39;

/var/www/html/tests/Unit/AppHelperTest.php:20

FAILURES!
Tests: 500, Assertions: 1200, Failures: 1.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;~140 tokens.&lt;/strong&gt; Same failure details. The banner and footer are still there (PHPUnit doesn&#39;t let you suppress them), but the 500 progress dots are gone. &lt;strong&gt;~45% reduction&lt;/strong&gt; - and on a 5,000-test suite, the savings are even larger.&lt;/p&gt;
&lt;h2 id=&quot;what-wastes-the-most-tokens&quot; tabindex=&quot;-1&quot;&gt;What wastes the most tokens &lt;a class=&quot;header-anchor&quot; href=&quot;https://alies.dev/articles/cli-output-for-ai/#what-wastes-the-most-tokens&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Token waster&lt;/th&gt;
&lt;th&gt;Impact&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Progress bars (&lt;code&gt;████&lt;/code&gt;, dots)&lt;/td&gt;
&lt;td&gt;500-2000 tokens per run&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Box-drawing borders (&lt;code&gt;+---+&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;2-5x more tokens than plain text&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ASCII art banners&lt;/td&gt;
&lt;td&gt;50-200 tokens per logo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Repeated dots (PHPUnit)&lt;/td&gt;
&lt;td&gt;~1 token per dot, hundreds per suite&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Note: ANSI color codes (&lt;code&gt;&#92;x1b[31m&lt;/code&gt;) are often cited as a waste, but most CLI tools &lt;strong&gt;auto-detect TTY&lt;/strong&gt; and disable colors when output is piped - which is always the case with AI agents. Flags like &lt;code&gt;--colors=never&lt;/code&gt;, &lt;code&gt;--no-ansi&lt;/code&gt;, and &lt;code&gt;--monochrome&lt;/code&gt; are usually redundant. The flags below focus on what actually matters.&lt;/p&gt;
&lt;h2 id=&quot;the-fix-one-flag-per-tool&quot; tabindex=&quot;-1&quot;&gt;The fix: one flag per tool &lt;a class=&quot;header-anchor&quot; href=&quot;https://alies.dev/articles/cli-output-for-ai/#the-fix-one-flag-per-tool&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Every PHP quality tool has flags to disable the noise. Here&#39;s the cheat sheet:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# PHPUnit / ParaTest&lt;/span&gt;
--no-progress

&lt;span class=&quot;token comment&quot;&gt;# PHPStan - use raw format (file:line:message, one per line)&lt;/span&gt;
--no-progress --error-format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;raw

&lt;span class=&quot;token comment&quot;&gt;# Psalm - use text format (file:line:col:severity, one per line)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Psalm 7: use --output-format=compact (one-line, relative paths, no URLs)&lt;/span&gt;
--no-progress --no-suggestions --output-format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;text

&lt;span class=&quot;token comment&quot;&gt;# phpcs - use emacs format (file:line:col:severity, one per line)&lt;/span&gt;
&lt;span class=&quot;token parameter variable&quot;&gt;--report&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;emacs &lt;span class=&quot;token parameter variable&quot;&gt;-q&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# PHP-CS-Fixer&lt;/span&gt;
--show-progress&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;none &lt;span class=&quot;token parameter variable&quot;&gt;-q&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Rector&lt;/span&gt;
--no-progress-bar --output-format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;github

&lt;span class=&quot;token comment&quot;&gt;# Pint - use agent format (auto-detected in Claude Code/OpenCode)&lt;/span&gt;
./vendor/bin/pint &lt;span class=&quot;token parameter variable&quot;&gt;--test&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--format&lt;/span&gt; agent

&lt;span class=&quot;token comment&quot;&gt;# Composer&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;composer&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-q&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;PHPStan 2.x note:&lt;/strong&gt; When &lt;code&gt;CLAUDECODE=1&lt;/code&gt; is set (always true in Claude Code), PHPStan injects a ~940-byte preamble with AI instructions and adds &lt;code&gt;[identifier=X]&lt;/code&gt; suffixes to every error. This agent detection overhead can be larger than the format difference itself. If it bothers you, set &lt;code&gt;CLAUDECODE=0&lt;/code&gt; before running PHPStan.&lt;/p&gt;
&lt;h2 id=&quot;where-to-put-these-flags&quot; tabindex=&quot;-1&quot;&gt;Where to put these flags &lt;a class=&quot;header-anchor&quot; href=&quot;https://alies.dev/articles/cli-output-for-ai/#where-to-put-these-flags&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Don&#39;t memorize them. Put them in your &lt;code&gt;CLAUDE.md&lt;/code&gt; or &lt;code&gt;AGENTS.md&lt;/code&gt; file - this is read by Claude Code, Cursor, Gemini CLI, OpenCode, and others:&lt;/p&gt;
&lt;div class=&quot;code-sm&quot;&gt;
&lt;pre class=&quot;language-markdown&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-markdown&quot;&gt;&lt;span class=&quot;token title important&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;##&lt;/span&gt; Running Tools&lt;/span&gt;

Always use these flags when running CLI tools:

&lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; Tests: &lt;span class=&quot;token code-snippet code keyword&quot;&gt;`vendor/bin/phpunit --no-progress`&lt;/span&gt;
&lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; PHPStan: &lt;span class=&quot;token code-snippet code keyword&quot;&gt;`vendor/bin/phpstan analyse --no-progress --error-format=raw`&lt;/span&gt;
&lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; Psalm: &lt;span class=&quot;token code-snippet code keyword&quot;&gt;`vendor/bin/psalm --no-progress --no-suggestions --output-format=text`&lt;/span&gt;
&lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; phpcs: &lt;span class=&quot;token code-snippet code keyword&quot;&gt;`vendor/bin/phpcs --report=emacs -q`&lt;/span&gt;
&lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; PHP-CS-Fixer: &lt;span class=&quot;token code-snippet code keyword&quot;&gt;`vendor/bin/php-cs-fixer fix --show-progress=none -q -n`&lt;/span&gt;
&lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; Rector: &lt;span class=&quot;token code-snippet code keyword&quot;&gt;`vendor/bin/rector process --no-progress-bar --output-format=github`&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id=&quot;the-pattern&quot; tabindex=&quot;-1&quot;&gt;The pattern &lt;a class=&quot;header-anchor&quot; href=&quot;https://alies.dev/articles/cli-output-for-ai/#the-pattern&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Across all tools, the pattern is the same:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Disable progress bars&lt;/strong&gt; - the #1 token waster&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use one-line-per-error format&lt;/strong&gt; - &lt;code&gt;raw&lt;/code&gt;, &lt;code&gt;text&lt;/code&gt;, &lt;code&gt;emacs&lt;/code&gt;, &lt;code&gt;github&lt;/code&gt; or &lt;code&gt;compact&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don&#39;t switch to JSON&lt;/strong&gt; - it has ~50% overhead from key repetition. Plain text is more token-efficient for error lists&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skip color flags&lt;/strong&gt; - most tools auto-detect TTY and disable colors when piped&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Do this once, save thousands of tokens per session, and stop feeding your AI agent junk.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Token counts in this article are measured with the &lt;a href=&quot;https://github.com/openai/tiktoken&quot;&gt;cl100k_base&lt;/a&gt; tokenizer (GPT-4). Claude, Gemini, and other models use different tokenizers, so exact counts will vary — but the ratios and savings hold across models.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;whats-else&quot; tabindex=&quot;-1&quot;&gt;What&#39;s else? &lt;a class=&quot;header-anchor&quot; href=&quot;https://alies.dev/articles/cli-output-for-ai/#whats-else&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This article covers PHP, but the same problem exists in every ecosystem.
I&#39;ve collected quiet-mode flags for &lt;strong&gt;Node, Python, Go, Rust, Ruby, Java, Kotlin, Swift, and .NET&lt;/strong&gt; in one place: &lt;strong&gt;&lt;a href=&quot;https://github.com/alies-dev/awesome-ai-friendly-cli&quot;&gt;awesome-ai-friendly-cli&lt;/a&gt;&lt;/strong&gt; — a curated list of CLI flags that cut token waste across languages and tools.&lt;/p&gt;
&lt;p&gt;If you want to go further, check out &lt;strong&gt;&lt;a href=&quot;https://www.rtk-ai.app/&quot;&gt;rtk&lt;/a&gt;&lt;/strong&gt; - a CLI proxy that sits between your AI agent and your tools, automatically filtering noise tokens in real time.
No flags to remember, no &lt;code&gt;CLAUDE.md&lt;/code&gt; to maintain.
It measured the 89% waste number at the top of this article.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>First hour of a new Laravel project</title>
		<link href="https://alies.dev/articles/laravel-first-hour-setup/"/>
		<updated>2024-07-05T00:00:00Z</updated>
		<id>https://alies.dev/articles/laravel-first-hour-setup/</id>
		<content type="html">&lt;div class=&quot;terminal-hero&quot;&gt;
	&lt;div class=&quot;terminal-header&quot;&gt;
		&lt;div class=&quot;terminal-button close&quot;&gt;&lt;/div&gt;
		&lt;div class=&quot;terminal-button minimize&quot;&gt;&lt;/div&gt;
		&lt;div class=&quot;terminal-button maximize&quot;&gt;&lt;/div&gt;
	&lt;/div&gt;
	&lt;div class=&quot;terminal-content&quot;&gt;
		&lt;div class=&quot;output&quot;&gt;
			&lt;div class=&quot;output-info&quot;&gt;&lt;span class=&quot;info&quot;&gt;INFO&lt;/span&gt; Preparing database.&lt;/div&gt;
			Creating migration table .............................................. 2.71ms &lt;span class=&quot;done&quot;&gt;DONE&lt;/span&gt;&lt;br&gt;
			&lt;div class=&quot;output-info&quot;&gt;&lt;span class=&quot;info&quot;&gt;INFO&lt;/span&gt; Running migrations.&lt;/div&gt;
			0001_01_01_000000_create_users_table .................................. 2.88ms &lt;span class=&quot;done&quot;&gt;DONE&lt;/span&gt;&lt;br&gt;
			0001_01_01_000001_create_cache_table .................................. 1.00ms &lt;span class=&quot;done&quot;&gt;DONE&lt;/span&gt;&lt;br&gt;
			0001_01_01_000002_create_jobs_table ................................... 2.08ms &lt;span class=&quot;done&quot;&gt;DONE&lt;/span&gt;&lt;br&gt;
		&lt;/div&gt;
		&lt;div class=&quot;prompt&quot;&gt;
			&lt;span class=&quot;prompt&quot;&gt;~/code/alies-dev/new-project&lt;/span&gt; ⮀ &lt;span class=&quot;branch&quot;&gt;⭠ main&lt;/span&gt;  ⮀ &lt;span class=&quot;cursor cursor-blinking&quot; contenteditable=&quot;&quot;&gt;&amp;nbsp;&lt;/span&gt;
		&lt;/div&gt;
	&lt;/div&gt;
&lt;/div&gt;
&lt;style&gt;
	.terminal-hero {
		max-width: 800px;
		height: 300px;
		background-color: #000;
		border-radius: 10px;
		padding: 20px;
		box-shadow: 0 0 10px rgba(255,255,255,0.1);
		overflow: hidden;
		margin: 0 auto;
		font-family: monospace;
	}

	.terminal-header {
		display: flex;
		justify-content: flex-start;
		margin-bottom: 10px;
	}

	.terminal-button {
		width: 12px;
		height: 12px;
		border-radius: 50%;
		margin-right: 6px;
	}

	.close { background-color: #ff5f56; }
	.minimize { background-color: #ffbd2e; }
	.maximize { background-color: #27c93f; }

	.terminal-content {
		padding-top: 15px;
		color: #ffffff;
		font-size: 14px;
		line-height: 1.5;
	}

	.output {
		margin-bottom: 25px;
		color: #d6d6d6;
	}

	.output-info {
		margin: 15px 0 15px 0;
	}

	.info {
		padding: 3px;
		background-color: rgb(50 88 125);
		color: rgb(128 128 128);
	}
	.done { color: #2ecc71; }
	.prompt {color: #e74c3c; }
	.branch { color: #f1c40f; }

	.cursor {
		display: inline-block;
		color: #d6d6d6;
	}

	.cursor-blinking:not(:focus) {
		animation: blink 1s step-end infinite;
		background-color: #ffffff;
	}

	@keyframes blink {
		0% { opacity: 0; }
		50% { opacity: 1; }
		100% { opacity: 0; }
	}
&lt;/style&gt;
&lt;p&gt;Great! You&#39;ve just created a new Laravel project and want to do everything right from the start, correct?
This guide will walk you through essential steps to optimize your new Laravel project in its first hour.&lt;/p&gt;
&lt;h2 id=&quot;configure-eloquent-strictness&quot; tabindex=&quot;-1&quot;&gt;Configure Eloquent Strictness &lt;a class=&quot;header-anchor&quot; href=&quot;https://alies.dev/articles/laravel-first-hour-setup/#configure-eloquent-strictness&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Laravel provides the &lt;a href=&quot;https://github.com/laravel/framework/blob/83e28d065b7bc53f3e53a5c188806844eee30161/src/Illuminate/Database/Eloquent/Model.php#L409-L414&quot;&gt;&lt;code&gt;Model::shouldBeStrict&lt;/code&gt;&lt;/a&gt; method that does three things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Prevents lazy loading (addressing the N+1 problem). See &lt;a href=&quot;https://laravel.com/docs/master/eloquent-relationships#preventing-lazy-loading&quot;&gt;Preventing Lazy Loading&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Prevents silently discarding attributes (throws an exception when attempting to fill an unfillable attribute)&lt;/li&gt;
&lt;li&gt;Prevents accessing missing attributes&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The &amp;quot;lazy loading&amp;quot; prevention often depends on database data, so it&#39;s better to avoid throwing an exception in production.
For the other two, you can enable them in all environments:&lt;/p&gt;
&lt;pre class=&quot;language-php&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// AppServiceProvider.php or any other service provider&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;boot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword return-type&quot;&gt;void&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Model&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;preventLazyLoading&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isProduction&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Model&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;preventSilentlyDiscardingAttributes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Model&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;preventAccessingMissingAttributes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;choose-primary-key-type&quot; tabindex=&quot;-1&quot;&gt;Choose Primary Key Type &lt;a class=&quot;header-anchor&quot; href=&quot;https://alies.dev/articles/laravel-first-hour-setup/#choose-primary-key-type&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There are three common types of primary keys:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Auto-incrementing integer (technically, by default it&#39;s an &lt;code&gt;UNSIGNED BIGINT&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;UUID (example: &lt;code&gt;6e48762e-8c54-43ab-b2f2-09eebb59ad9b&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;ULID (example: &lt;code&gt;01j2qxp0rg5618brj9c9kmrk6h&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Choosing the right type is a big topic (you can start by reading the &lt;a href=&quot;https://laravel.com/docs/master/eloquent#uuid-and-ulid-keys&quot;&gt;Laravel documentation&lt;/a&gt;).
If you choose UUID or ULID, you can instruct Laravel to use the proper morph key type
when you use &lt;code&gt;$table-&amp;gt;morphs()&lt;/code&gt; and &lt;code&gt;$table-&amp;gt;nullableMorphs()&lt;/code&gt; in migrations:&lt;/p&gt;
&lt;pre class=&quot;language-php&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// AppServiceProvider.php or any other service provider&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;boot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword return-type&quot;&gt;void&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;morphUsingUuids&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// for UUID&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;morphUsingUlids&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// for ULID&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Other packages may (and should) also respect this setting (e.g., Laravel Nova).&lt;/p&gt;
&lt;h2 id=&quot;enforce-morph-map&quot; tabindex=&quot;-1&quot;&gt;Enforce Morph Map &lt;a class=&quot;header-anchor&quot; href=&quot;https://alies.dev/articles/laravel-first-hour-setup/#enforce-morph-map&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you plan to rename your Models (rename a class or change a namespace),
I recommend enforcing a morph map to avoid data corruption.
This way, Laravel will not store the fully qualified class name (FQCN) in the database, but a short alias instead.
If an alias is not set, Laravel will throw a &lt;code&gt;&#92;Illuminate&#92;Database&#92;ClassMorphViolationException&lt;/code&gt; exception.&lt;/p&gt;
&lt;pre class=&quot;language-php&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// AppServiceProvider.php or any other service provider&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;boot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword return-type&quot;&gt;void&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Relation&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;enforceMorphMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&#39;user&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string single-quoted-string&quot;&gt;&#39;team&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;Team&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;prohibit-destructive-commands-on-production&quot; tabindex=&quot;-1&quot;&gt;Prohibit Destructive Commands on Production &lt;a class=&quot;header-anchor&quot; href=&quot;https://alies.dev/articles/laravel-first-hour-setup/#prohibit-destructive-commands-on-production&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To avoid accidental data loss, you can prohibit destructive commands on production.
Laravel provides a handy &lt;a href=&quot;https://laravel-news.com/prevent-destructive-commands-from-running-in-laravel-11&quot;&gt;&lt;code&gt;DB::prohibitDestructiveCommands&lt;/code&gt;&lt;/a&gt; method to do this:&lt;/p&gt;
&lt;pre class=&quot;language-php&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// AppServiceProvider.php or any other service provider&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;boot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword return-type&quot;&gt;void&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;prohibitDestructiveCommands&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&#39;production&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;use-immutable-dates&quot; tabindex=&quot;-1&quot;&gt;Use immutable dates &lt;a class=&quot;header-anchor&quot; href=&quot;https://alies.dev/articles/laravel-first-hour-setup/#use-immutable-dates&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, Laravel uses mutable Carbon instances.
In practice, that means to avoid changing values of &lt;code&gt;created_at&lt;/code&gt; and &lt;code&gt;updated_at&lt;/code&gt; attributes, you need to first clone Carbon objects:&lt;/p&gt;
&lt;pre class=&quot;language-php&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$monthAfterRegistration&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;created_at&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clone&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addMonth&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can instruct Laravel to always create immutable Carbon instances:&lt;/p&gt;
&lt;pre class=&quot;language-php&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// AppServiceProvider.php or any other service provider&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Carbon&lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;CarbonImmutable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token package&quot;&gt;Illuminate&lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;Support&lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;Facades&lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;boot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword return-type&quot;&gt;void&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name static-context&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name static-context&quot;&gt;CarbonImmutable&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With a small cost of memory consumption, you can avoid many bugs related to mutable dates and eliminate the need to call the &lt;code&gt;clone()&lt;/code&gt; method.&lt;/p&gt;
&lt;pre class=&quot;language-diff&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-diff&quot;&gt;&lt;span class=&quot;token deleted-sign deleted&quot;&gt;&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt; $monthAfterRegistration = $user-&gt;created_at-&gt;clone()-&gt;addMonth();
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt; $monthAfterRegistration = $user-&gt;created_at-&gt;addMonth();
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;install-composer-packages&quot; tabindex=&quot;-1&quot;&gt;Install Composer Packages &lt;a class=&quot;header-anchor&quot; href=&quot;https://alies.dev/articles/laravel-first-hour-setup/#install-composer-packages&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;clockwork&quot; tabindex=&quot;-1&quot;&gt;Clockwork &lt;a class=&quot;header-anchor&quot; href=&quot;https://alies.dev/articles/laravel-first-hour-setup/#clockwork&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In my opinion, &lt;a href=&quot;https://underground.works/clockwork/&quot;&gt;Clockwork&lt;/a&gt; is the best tool of the &amp;quot;Laravel debug bar&amp;quot; type, as it doesn&#39;t change your HTML output.&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;composer&lt;/span&gt; require itsgoingd/clockwork &lt;span class=&quot;token parameter variable&quot;&gt;--dev&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;larastan&quot; tabindex=&quot;-1&quot;&gt;Larastan &lt;a class=&quot;header-anchor&quot; href=&quot;https://alies.dev/articles/laravel-first-hour-setup/#larastan&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/larastan/larastan&quot;&gt;Larastan&lt;/a&gt; is an essential static analysis tool for Laravel projects.
With a minimal time investment, you can get a great reporting tool for potential bugs.&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;composer&lt;/span&gt; require larastan/larastan &lt;span class=&quot;token parameter variable&quot;&gt;--dev&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;paratest&quot; tabindex=&quot;-1&quot;&gt;Paratest &lt;a class=&quot;header-anchor&quot; href=&quot;https://alies.dev/articles/laravel-first-hour-setup/#paratest&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/paratestphp/paratest&quot;&gt;Paratest&lt;/a&gt; enables parallel testing for PHPUnit/Pest,
which will make your tests run faster (proportional to the number of cores in your CPU).&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;composer&lt;/span&gt; require brianium/paratest &lt;span class=&quot;token parameter variable&quot;&gt;--dev&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After installation, please check the official Laravel documentation on &lt;a href=&quot;https://laravel.com/docs/master/testing#running-tests-in-parallel&quot;&gt;Running Tests in Parallel&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;composer-dependency-analyser&quot; tabindex=&quot;-1&quot;&gt;Composer Dependency Analyser &lt;a class=&quot;header-anchor&quot; href=&quot;https://alies.dev/articles/laravel-first-hour-setup/#composer-dependency-analyser&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/shipmonk-rnd/composer-dependency-analyser&quot;&gt;Composer Dependency Analyser&lt;/a&gt; provides fast detection of composer dependency issues such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Unused dependencies&lt;/li&gt;
&lt;li&gt;Shadow dependencies&lt;/li&gt;
&lt;li&gt;Misplaced dependencies&lt;/li&gt;
&lt;li&gt;Dev dependency on production code&lt;/li&gt;
&lt;li&gt;Production dependency that is only in dev code&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;language-shell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;composer&lt;/span&gt; require &lt;span class=&quot;token parameter variable&quot;&gt;--dev&lt;/span&gt; shipmonk/composer-dependency-analyser&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;set-up-a-ci-cd-pipeline&quot; tabindex=&quot;-1&quot;&gt;Set up a CI/CD Pipeline &lt;a class=&quot;header-anchor&quot; href=&quot;https://alies.dev/articles/laravel-first-hour-setup/#set-up-a-ci-cd-pipeline&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Set up a CI/CD pipeline with GitHub Actions, GitLab CI, or any other CI/CD service.
I&#39;ve prepared a simple &lt;a href=&quot;https://gist.github.com/alies-dev/4d40a4facee0271ce88bf5d0282e97ea&quot;&gt;Laravel GitHub workflows starting pack&lt;/a&gt;
that includes three workflows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Main (runs tests, security checks, and deploys)&lt;/li&gt;
&lt;li&gt;Code quality (non-blocking deployment)&lt;/li&gt;
&lt;li&gt;Code style check (non-blocking deployment)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;document-your-project&quot; tabindex=&quot;-1&quot;&gt;Document Your Project &lt;a class=&quot;header-anchor&quot; href=&quot;https://alies.dev/articles/laravel-first-hour-setup/#document-your-project&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Create a comprehensive README.md and list all commands needed to run, test, develop, and deploy the project.
Even if you&#39;re the only developer, your future self will thank you for this thorough documentation.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion &lt;a class=&quot;header-anchor&quot; href=&quot;https://alies.dev/articles/laravel-first-hour-setup/#conclusion&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Since we&#39;re limited to one hour, I&#39;ll conclude here.
These initial steps will set a solid foundation for your development process.
There are many more ways to improve your Laravel project, most of which are project-specific.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>sscanf simplifies your regex</title>
		<link href="https://alies.dev/articles/sscanf/"/>
		<updated>2024-07-04T00:00:00Z</updated>
		<id>https://alies.dev/articles/sscanf/</id>
		<content type="html">&lt;p&gt;The &lt;a href=&quot;https://www.php.net/manual/en/function.sscanf.php&quot;&gt;&lt;code&gt;sscanf&lt;/code&gt;&lt;/a&gt; PHP function offers a powerful alternative to regular expression functions like &lt;code&gt;preg_match&lt;/code&gt; for parsing strings.
While less flexible than regex, &lt;code&gt;sscanf&lt;/code&gt; can be more readable and efficient for simple parsing tasks.&lt;/p&gt;
&lt;p&gt;Surprisingly, &lt;code&gt;sscanf&lt;/code&gt; is a hidden gem in PHP, and many developers are unaware of its existence.
It&#39;s a wrapper around the C library function, and it&#39;s available in PHP since the early days.&lt;/p&gt;
&lt;h2 id=&quot;basic-examples&quot; tabindex=&quot;-1&quot;&gt;Basic examples &lt;a class=&quot;header-anchor&quot; href=&quot;https://alies.dev/articles/sscanf/#basic-examples&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Example 1: Basic usage&lt;/p&gt;
&lt;pre class=&quot;language-php&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$input&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&#39;John 25 New York&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;sscanf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&#39;%s %d %s&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$age&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$city&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Example 2: Parsing a date string&lt;/p&gt;
&lt;pre class=&quot;language-php&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$date&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&#39;2023-07-08&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;sscanf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&#39;%d-%d-%d&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$year&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$month&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$day&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Example 3: Parsing a complex log entry&lt;/p&gt;
&lt;pre class=&quot;language-php&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$logEntry&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;2023-07-08 14:30:45 [WARNING] User authentication failed: username=johndoe, ip=192.168.1.100&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$pattern&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;%d-%d-%d %d:%d:%d [%s] %[^:]: username=%[^,], ip=%s&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;sscanf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$logEntry&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$pattern&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$year&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$month&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$day&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$hour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$minute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$second&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$level&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$username&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;sscanf-vs-preg-match&quot; tabindex=&quot;-1&quot;&gt;sscanf vs preg_match &lt;a class=&quot;header-anchor&quot; href=&quot;https://alies.dev/articles/sscanf/#sscanf-vs-preg-match&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Parsing a URL example, diff:&lt;/p&gt;
&lt;pre class=&quot;language-diff-php&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-diff-php&quot;&gt;&lt;span class=&quot;token deleted-sign deleted language-php&quot;&gt;&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;preg_match&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&#39;/^(&#92;S+):&#92;/&#92;/([^&#92;/]+)&#92;/(.*)$/&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$matches&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$scheme&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$matches&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$domain&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$matches&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$path&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$matches&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted language-php&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sscanf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;%[^:]://%[^/]/%s&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$scheme&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$domain&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4 lines vs. 1 line!!
Of course, it’s a simplified example (for real URL parsing, please use &lt;code&gt;parse_url&lt;/code&gt;), but shares the idea.
While &lt;code&gt;sscanf&lt;/code&gt; isn&#39;t a complete replacement for regex, it can simplify many common string parsing tasks in PHP.&lt;/p&gt;
&lt;p&gt;Still need to write a regex?
Check out a great &lt;a href=&quot;https://php.watch/articles/php-regex-readability&quot;&gt;Writing better Regular Expressions in PHP&lt;/a&gt; article.&lt;/p&gt;
</content>
	</entry>
</feed>
