Tips and notes about PHP and web development.

Create Project-Specific PHPStan and PHPCS Rules with AI Agents

TL;DR: Writing rules for AI agents helps, but AI is non-deterministic — violations will slip through. Enforce project-specific constraints with custom PHPStan/PHPCS rules for mechanical checking. Let an AI agent draft the custom rules for you, and you can implement them quickly. CLAUDE.md Alone Isn’t Enough If you’re using an AI agent like Claude Code, you probably write project rules in CLAUDE.md or rule files. Things like: “Use ‘Plan’ instead of the old term ‘Course’ everywhere in the code” “DateTime::createFromTimestamp() must always receive a timezone as the second argument” “Core domain classes must not call infrastructure directly” The agent respects these rules and writes compliant code — most of the time. But AI is non-deterministic. The same instruction doesn’t always produce the same output. When the context gets long or the agent is in the middle of a complex refactoring, it can “accidentally” generate code that violates the rules, even though they’re written right there in the rule files. ...

April 10, 2026 · nojimage

Reduce Node.js Docker Image Size with Multi-Stage Builds

TL;DR: Use Docker multi-stage builds to separate “build” and “production” stages in your Dockerfile. Dev dependencies and build tools stay out of the final image. In one of my projects, this cut the image size from nearly 2 GB down to under 1 GB. Why Smaller Images Matter Keeping your Docker image small has real benefits: Faster deployments — Smaller images mean faster pulls, which speeds up CI/CD pipelines and auto-scaling container startups Lower storage costs — Less registry storage (ECR, GCR, etc.) and less data transfer Reduced security risk — Fewer packages and tools in the image means a smaller attack surface The Problem: Dev Dependencies Bloat Your Image When building a Node.js app with Docker, you might write a single-stage Dockerfile like this: ...

April 1, 2026 · nojimage

Teach Claude Code Your Available UNIX Commands to Boost Efficiency

TL;DR: Tell Claude Code about your installed commands (rg, fd, jq, etc.) via a user rule file (~/.claude/rules/), and it’ll automatically prefer rg over grep, fd over find, and so on. One prompt does the whole inventory. Background Claude Code knows basic UNIX commands like grep, find, and cat, but it doesn’t know whether your machine has rg (ripgrep) or fd installed. So even though you have faster tools available, Claude Code ends up using grep every time, or runs which rg to check before using it. A bit wasteful, right? ...

March 30, 2026 · nojimage

How to Get macOS Notifications When Claude Code Is Waiting for Input

TL;DR: Set up a Claude Code hook to get macOS desktop notifications with sound and speech when Claude Code finishes a task or waits for input. SAY!! Background Claude Code sometimes runs tasks for a while, and you want to know when it’s done, right? There’s an official notification setting, but notifications don’t always fire or are easy to miss. So let’s use a custom hook to get reliable macOS desktop notifications with text-to-speech. ...

March 28, 2026 · nojimage

Released CakePHP Plugin - SlugGuard to Prevent User Slug and URL Route Collision

TL;DR: I released a CakePHP 5.x plugin that validates user-input URL slugs against reserved words and application routes to prevent collisions. elstc/cakephp-slug-guard: CakePHP plugin for URL-safe slug validation and reserved-word collision prevention What Does This Plugin Do? In web applications, you often want to let users choose their own profile URL slug – something like example.com/nojimage. But if a user registers a slug like admin, login, or api, it collides with your application’s routes and causes serious problems. ...

March 27, 2026 · nojimage