Tips
Bite-sized engineering patterns, performance techniques, and idiomatic snippets.
Render Multiple Field Validation Errors with Flux UI and Blade
Suppress default single-error tooltips in Flux UI components and iterate over all validation messages per field using Blade error directives. When a single f...
Optimize Large Wildcard Array Validation in Laravel 13.24
Laravel 13.24 introduces dramatic performance optimizations for validating large nested arrays with wildcard rules, reducing validation execution time from 8...
Never Return Statements inside Finally Blocks in PHP
Placing a return statement inside a try-catch finally block silently overrides exceptions and previous return statements. A return statement inside a finally...
Restrict Array Keys with the array_keys Validation Rule in Laravel 13.24
Laravel 13.24 adds the arraykeys validation rule to reject any unexpected keys in an array input, keeping input strictly limited to allowed keys. When buildi...
Extract Dominant Colors and Handle HEIC/AVIF Images in Laravel 13.24
Laravel 13.24 adds dominantColor() to the Image API for extracting the primary color of an image, plus native support for HEIC and AVIF formats. Extracting a...
Use modelKeys() on the Eloquent Builder in Laravel 13.24
Laravel 13.24 adds modelKeys() directly to the Eloquent query builder, replacing hardcoded pluck('id') calls with a method that uses the model primary key. I...
Move Filament Global Search to Sidebar
Customize your Filament admin panel layout by moving the global search bar to the top of the navigation sidebar. In Filament admin panels, the global search...
Enable Test Impact Analysis (TIA) by Default in pest.php
Configure Pest to run Test Impact Analysis by default in pest.php so only tests covering modified files execute. Running full test suites on every minor edit...
Automate PHP Readonly Class Refactoring with Rector
Use Rector rules to automatically convert immutable DTOs and value objects into native PHP 8.2 readonly classes. Manually adding readonly keywords across doz...
Conditional Dependency Binding with #[BindWhen] in Laravel 13.22
Laravel 13.22 introduces the #[BindWhen] attribute for declarative, conditional service container bindings directly on implementation classes. Instead of clu...
Format Blade Templates with Laravel Pint v1.30.0
Laravel Pint v1.30.0 adds native Blade template formatting via the Pint/laravelblade rule, using Prettier under the hood. Blade gets opinionated formatting i...
Monthly Log Rotation with Laravel 13.23
Laravel 13.23 adds a built-in monthly logging driver that rotates log files once per month instead of daily. Daily log rotation creates hundreds of log files...
Use sole() Instead of firstOrFail() for Single Record Guarantees
When you expect exactly one matching record, use sole() instead of firstOrFail(). It guards against multiple records by throwing MultipleRecordsFoundExceptio...
Protect Custom Artisan Commands from AI Agents with Prohibitable
Use Laravel's Prohibitable trait on custom Artisan commands to selectively block AI agents from running destructive domain operations. While DB::prohibitDest...
Detect AI Agents in Laravel with AgentDetector and PAO
Laravel's AgentDetector detects whether an AI coding agent is interacting with your app, and PAO optimizes CLI output for agents. AI agents are part of moder...
Avoid Duplicating Authorization Logic with Gate::define() and Gate::authorize()
Centralize authorization checks in Gate::define() and call Gate::authorize() in controllers instead of repeating manual if checks. Scattering authorization c...
Stream Large Datasets: cursor() vs lazy() in Eloquent
cursor() hydrates single model instances sequentially using database cursors; lazy() streams records in chunks backed by LazyCollection. When iterating milli...
Choose the Right Processing Method: chunk(), lazy(), chunkById(), lazyById()
Understand offset vs keyset pagination when processing large datasets to avoid missing records during updates. Updating records inside chunk() modifies the r...
Avoid map() When Not Transforming: Use each()
Use each() for iteration side effects like sending emails; use map() exclusively when returning a transformed collection. Using map() purely for side effects...
Stop Using get() Before Collection Chains: Use lazy()
Calling get() loads all matching rows into memory before filtering. Use lazy() to process database records lazily. Chaining collection methods like filter()...
UI Controls Are Not Security Layers: Always Enforce Policies
Hiding buttons in Blade or Vue does not restrict access. Always enforce authorization policies in controller or request layers. Hiding an edit button using @...
Selecting Specific Columns Can Break Eloquent Relationships
Always include foreign key and primary key columns when using select() alongside eager loaded relationships. Using select('name') on a query with eager loade...
Don't Load Full Models for Single Columns: Use pluck() or value()
Use value() for single scalar values and pluck() for single-column arrays instead of instantiating full Eloquent models. Querying full Eloquent model instanc...
Dispatch Jobs After Transaction Commit with DB::afterCommit()
Use DB::afterCommit() to defer job dispatching until surrounding database transactions complete successfully. Dispatching queue jobs inside active DB transac...
Combine Filter and Eager Loading with withWhereHas()
Use withWhereHas() to filter records based on relationship conditions and eager load the filtered relationship in a single method. Filtering models by relati...
Prevent Skipped Records When Updating Chunks: Use chunkById()
Always use chunkById() instead of chunk() when modifying columns present in your query filters to avoid offset pagination shifts. Updating records inside sta...
Never Save $request->all(): Use $request->validated()
Always pass $request-validated() or $request-safe() into model creation methods to prevent mass-assignment vulnerabilities. Passing $request-all() directly i...
Fetch Specific Related Attributes with withAggregate()
Use withAggregate() to pull a single column value from a relationship via a SQL subquery without eager loading full model instances. When you need a single a...
Assert JSON Columns and Backed Enums with assertDatabaseHas
In Laravel and Pest tests, assertDatabaseHas() natively queries nested JSON properties using arrow syntax and accepts backed Enum instances directly. Testing...
Scaffold Actions, Builders, and Collections with Artisan
Extend your generator commands to scaffold common domain patterns like Actions, Custom Query Builders, or Collections. Pushing business logic into Action cla...
Add a Reusable whereLike Macro for Eloquent Searching
Simplify multi-column wildcard searches across model attributes by registering a clean whereLike macro on the Eloquent Builder. Searching across multiple str...
Streamline Testing with Pest Test Impact Analysis (TIA)
Enable Test Impact Analysis (TIA) in Pest to only run tests directly covering code that changed since the last commit. Running full test suites on every tiny...
Protect Production with Laravel Prohibitable Commands
Prevent catastrophic accidents like db:wipe or migrate:fresh in production using Laravel's Prohibitable trait and DB::prohibitDestructiveCommands(). Accident...
Customize Relative Timestamps with diffForHumans() Options
Pass Carbon options to diffForHumans() to control syntax flags, short units, and multi-part granularity. Carbon's diffForHumans() displays human-readable dat...
Why strip_tags() Is Not Enough for XSS Protection
striptags() removes HTML elements but fails to sanitize inline attributes or malformed HTML payload vectors. Use HTMLPurifier for rich text input. A common s...
Clean Up Collections with Higher-Order Collection Messages
Use higher-order collection proxies like $users-each-archive() or $orders-sum-total to replace verbose closure callbacks. Writing closures for single method...
Clean Up Complex Multi-Step Operations with Illuminate Pipeline
Process complex data sequences or multi-stage order checks through Laravel's built-in Pipeline facade to replace massive controller methods. When processing...
Extract Complex Controller Responses into Responsable Classes
Implement the Responsable interface to create dedicated response objects that handle headers, view data, and formatting outside controllers. When controller...
Avoid whereDate() on Large Tables: Use Range Queries Instead
whereDate() wraps the column in a DATE() function, preventing the database from using indexes. Use whereBetween() with full timestamps for index-friendly fil...
Remove Global Eager Loading with withoutRelation()
Use withoutRelation() or unsetRelation() to remove eager loaded relationships on specific Eloquent queries or model instances. Models with $with properties e...
Use blank() and filled() Instead of empty() in Laravel
PHP's empty() treats 0, '0', and false as empty. Laravel's blank() and filled() helpers handle these values intuitively without silent bugs. PHP's empty() is...
Match Multiple Values in a Single Match Arm in PHP
Separate multiple comma-delimited values within a single match expression arm to group identical execution branches. When multiple inputs share the exact sam...
Squash Legacy Database Migrations Carefully
Use php artisan schema:dump to collapse hundreds of old migration files into a single SQL schema file while preserving new migrations. As applications age, r...
Seed Large Database Dumps with SchemaState::load()
Use SchemaState::load() to load large raw SQL dump files directly through database CLI tools instead of slow DB::unprepared() execution. Executing massive ra...
Simplify Class Instantiation with Constructor Property Promotion
Combine property declarations and constructor parameter assignments in PHP 8 for concise class definitions. Declaring class properties, parameter signatures,...
Run Post-Request Callbacks with afterResponse() in Laravel 12.44
Laravel 12.44 adds the afterResponse() hook to the HTTP client, allowing you to attach response logging, metrics, and error handling callbacks cleanly inside...
Use Fluent Date Validation Rule Helpers in Laravel 12.44
Laravel 12.44 introduces fluent date validation helpers on the Rule facade, replacing string-based date comparisons with self-documenting method calls. Valid...
Enable Compact Test Output Printer in Pest
Use the --compact flag or configure compact output in pest.php for minimal single-character test progress indicators. When running large test suites with hun...
Handle Model Relationships Explicitly in Queue Jobs
Re-load or pass model primary keys into queued jobs instead of relying on stale serialized relationship collections. When Eloquent models are serialized for...
Clean Up Pest Test Configuration in tests/Pest.php
Organize base test case bindings, helper functions, and global traits cleanly inside tests/Pest.php. Duplicate uses() declarations across every test file clu...
Optimize Queue Worker Polling Overheads in Production
Use queue:work with appropriate sleep configuration or Redis blocking pops to reduce database CPU polling overheads. Queue workers set to poll databases with...
Unpack Arrays with Spread Syntax in PHP 8.1
Use array unpacking (...) inside square bracket array literals for string-keyed and indexed array merging. PHP 8.1 expanded array unpacking to support string...
Auto-Scale Queue Workers with --stop-when-empty-for in Laravel
The --stop-when-empty-for option keeps queue workers alive for a specific grace period after the queue empties, preventing rapid process churn during bursty...
Simplify Default Values with Null Coalescing Assignment (??=)
Replace verbose ternary checks and null coalescing reassignments with PHP null coalescing assignment operator (??=). Setting default values on nullable varia...
Prevent Duplicate Redis and Database Lookups with Cache::memo()
Use Cache::memo() to combine persistent cache stores with per-request memory caching, preventing repetitive network roundtrips during a single HTTP request....
Automate Short Closure Conversions with Laravel Pint
Enable the usearrowfunctions rule in pint.json to automatically refactor single-line closures into arrow functions. Manually converting single-line function...
Combine Multiple Alpine.data Objects Inside a Single x-data
Spread multiple Alpine.data component factories into a single x-data directive to compose modular frontend state. When a single UI element requires state fro...
Use Real-Time Facades with the Facades Prefix
Prefix any application class import with Facades\ to instantly treat it as a mockable Laravel Facade. Creating explicit Facade classes for internal services...
Master Essential PHP Predefined and Magic Constants
A practical cheat sheet covering PHP magic constants, filesystem path helpers, error reporting masks, and CLI stream handles. PHP provides built-in magic and...
Lint PHP Files Instantly with php -l CLI Syntax Check
Run fast, zero-dependency PHP syntax validation from the terminal using php -l on individual files or recursively across entire projects. Before running stat...
Selectively Fake Jobs in Tests with Queue::fakeExceptFor()
Use Queue::fakeExceptFor() to execute specific background jobs synchronously during a test while preventing all other jobs from running. When testing a featu...
Focus Test Runs Instantly with Pest ->only() Method
Append -only() to any Pest test declaration to execute only that specific test without writing long CLI filter strings. Filtering specific test names via CLI...
Use $model->touch() Instead of Manual Timestamp Updates
Use the built-in touch() method to update updatedat timestamps on Eloquent records cleanly. Manually assigning $model-updatedat = now(); $model-save(); is re...
Reduce Indentation with Early Returns and Guard Clauses
Replace deeply nested if statements with guard clauses that exit functions early when preconditions fail. Deeply nested if-else blocks make code hard to read...
Prefer dispatch(new Job(...)) Over Static Job::dispatch()
Use dispatch(new ProcessReport($data)) for superior IDE constructor auto-completion and static analysis type checking. Static Job::dispatch(...) relies on ma...
Accelerate TALL Stack Development with FilamentPHP
Use FilamentPHP to build full-featured administrative panels, forms, and tables using Livewire and Alpine.js. Building custom admin dashboards from scratch r...
Ditch sleep() in Tests: Use Laravel Time Travel Helpers
Use $this-travelTo() or freezeTime() in test suites to test date-sensitive logic without slowing down test execution with sleep(). Using sleep() in tests slo...
Integer Enums: Start Indexing from 1, Avoid 0
When creating integer-backed PHP Enums, index starting from 1 to avoid false-y evaluation bugs in loose comparisons. In PHP, 0 evaluates as false-y in loose...
Retrieve and Override Configurations with the config() Helper
Use config('app.name') to retrieve settings and config(['app.debug' =true]) to set runtime overrides. The config() helper accesses application configuration...
Format Single-Line Property Promotion Constructors with Pint
Configure Laravel Pint to collapse empty constructor bodies with promoted properties onto a single line for compact PHP 8 class declarations. PHP 8 construct...
Enforce Strict Typing Across PHP Classes and Methods
Declare declare(stricttypes=1); at the top of PHP files to prevent unexpected scalar type coercions. By default, PHP coerces types scalar values (e.g. string...
Subquery Attribute Loading with withAttribute() in Eloquent
Load specific relationship column values directly into model attributes using withAttribute() without loading complete child model instances. When you only n...
Automate Laravel 11 casts() Method Upgrade with Rector
Use Rector to automatically refactor legacy protected $casts array properties into the modern casts() method across your entire Laravel codebase. Laravel 11...
Customize Artisan Code Generators with stub:publish
Publish and customize Artisan generator stubs using php artisan stub:publish to enforce custom code conventions across your team. Standard php artisan make:c...
Cast Model Attributes to Backed Enums in Eloquent
Define PHP Backed Enums on model $casts to automatically hydrate strings and integers into typed Enums. Storing status strings like 'active' or 'pending' as...
Clear Query Order Constraints with reorder()
Use reorder() to clear previous orderBy clauses from a query builder before applying new sorting constraints. When modifying existing query builders or model...
Build Conditional Queries Cleanly with when() and unless()
Use when() and unless() on query builders to apply conditional clauses without breaking method chains with if statements. Building dynamic search queries oft...
Combine Custom Casts and Enums for Complex Attributes
Use Eloquent custom casts (CastsAttributes) to handle complex JSON serialization and Backed Enum arrays cleanly. When model attributes contain complex JSON s...
Queue Heavy Artisan Commands with Artisan::queue()
Use Artisan::queue() to push long-running Artisan commands to background queues instead of blocking HTTP requests. Running heavy Artisan commands like databa...
Filter Records by JSON Array Size with whereJsonLength()
Use whereJsonLength() to query database records based on the number of elements in a JSON array attribute. Filtering records by the number of elements stored...
Copy Datasets Between Tables Instantly with insertUsing()
Use insertUsing() to execute INSERT INTO ... SELECT queries for copying data between database tables in SQL. Fetching records into PHP memory and re-insertin...
Build Framework-Free Dropdowns with Tailwind and nextElementSibling
Create lightweight, zero-dependency toggle dropdowns using inline JavaScript nextElementSibling calls with Tailwind CSS hidden classes. For simple marketing...
Import Multiple Classes in Blade with Array @use Syntax
Import multiple PHP classes or custom aliases inside Blade templates using array arguments in the @use directive. The Blade @use directive allows importing P...
Never Use env() Outside Config Files + Enforce with Pest Arch
env() returns null when config is cached in production. Always use config() and enforce this with Pest architecture tests. In production environments running...
Essential Laravel Production Deployment Command Sequence
Execute standard caching and optimization Artisan commands during production CI/CD deployment scripts. Deploying Laravel applications without caching routes,...
Understand dispatch() vs dispatch_sync() in Laravel Jobs
Know when to push background jobs to asynchronous queues with dispatch() versus executing them immediately in the current HTTP request process using dispatch...
Avoid auth() and session() Inside Event Listeners
Pass authenticated user objects or session data explicitly inside Event payloads instead of relying on global session helpers in listeners. Accessing global...
Work Around MySQL Subquery Restrictions on Target Tables
MySQL prevents updating a table while selecting from it in a subquery. Wrap subqueries in an intermediate alias table. Executing UPDATE table WHERE id IN (SE...
Preview Mailables Instantly in Browser Routes
Return Mailable instances directly from route callbacks to preview compiled HTML emails in your browser without sending test emails. Testing email layouts by...
Adopt Tailwind CSS for Utility-First Component Styling
Leverage Tailwind CSS utility classes to compose custom responsive designs directly in HTML without CSS stylesheet bloat. Writing custom CSS classes for ever...
Simplify Nested Routes with Shallow Resource Controllers
Use shallow nesting on resource routes to keep URLs concise while preserving parent-child relationships for creation and listing endpoints. Deeply nested res...
Stream and Download Files Efficiently in Laravel Controllers
Return proper HTTP file responses using response()-download(), response()-streamDownload(), and response()-file() for downloads and inline previews. Serving...
Customize Missing Model Binding Behavior in Laravel
Use missing() callbacks on route model bindings to return custom JSON responses or specialized error pages when records are not found. By default, implicit r...
Understand Input Trimming & Empty String Normalization
Laravel automatically trims request strings and converts empty string inputs to null via default global middleware. Laravel includes TrimStrings and ConvertE...
Flatten Transformed Collections with flatMap()
Use flatMap() to map over a collection and collapse the nested array result into a flat collection in a single operation. Mapping over a collection where cal...
Improve Large Number Readability with Numeric Literal Separators
Use underscores () as visual numeric literal separators in PHP code to improve number readability. Reading large numbers like 1000000000 requires counting ze...
Eager Load Nested Relationships with Dot Notation
Use dot-notation strings inside with() to eager load deeply nested relationships in single database query chains. When fetching models that require multi-lev...
Dynamically Append Model Casts with mergeCasts()
Use mergeCasts() to dynamically append attribute casting rules to Eloquent model instances at runtime. When working with dynamic attributes or traits on mode...
Query JSON and Array ID Columns with Array-Column Relationships
Define relationships on models where foreign keys are stored as JSON arrays or comma-separated lists rather than traditional single-id foreign keys. When dea...
Convert Nested Arrays to URL Query Strings with Arr::query()
Use Arr::query() to build properly encoded URL query strings directly from nested associative arrays. Building complex query parameters manually using httpbu...
Simplify App Translations with JSON Translation Files
Use JSON files in lang/ for localization to write default language strings directly as translation keys. Managing translation key strings like messages.welco...
Control Pagination Link Density with onEachSide()
Use onEachSide() on paginated Eloquent queries to adjust the number of page links shown beside the current page. Default pagination controls can show too man...
Use CSS Container Queries for Modular Component Layouts
Use CSS Container Queries (@container) to adjust component layouts based on parent container width rather than viewport size. Media queries (@media) check to...
No matching tips found
Try adjusting your search query or choosing another category filter.
// Got a tip or want to contribute? github.com/MrPunyapal/tips