When building arrays or JSON responses in Laravel, empty strings from operations like implode() or join() can be inconsistent with explicit null values. The Elvis operator (?:) provides a clean way to coalesce empty results to null.
The Problem
Mixing explicit nulls with empty strings creates inconsistency:
$data = [
'name' => $user->name, // 'John Doe'
'email' => $user->email ?: null, // null if empty
'tags' => implode(', ', $user->tags), // '' if no tags (empty string)
];
// JSON: {"name":"John Doe","email":null,"tags":""}
// Inconsistent - some nulls, some empty strings
The Solution
Use the Elvis operator for consistent null handling:
$data = [
'name' => $user->name,
'email' => $user->email ?: null,
'tags' => implode(', ', $user->tags) ?: null, // Consistent null
];
// JSON: {"name":"John Doe","email":null,"tags":null}
// Better - consistent null handling
Practical Examples
String concatenation:
'full_address' => trim("{$user->street} {$user->city} {$user->zip}") ?: null,
Array operations:
'permissions' => implode(', ', $user->permissions) ?: null,
'roles' => join(' | ', $user->roles->pluck('name')->all()) ?: null,
Filtered collections:
'active_projects' => $user->projects
->where('status', 'active')
->pluck('name')
->implode(', ') ?: null,
Complex string building:
'metadata' => collect([
$user->department,
$user->title,
$user->location,
])
->filter()
->implode(' • ') ?: null,
Why This Matters
1. API Consistency
Frontend code can check if (value === null) instead of if (!value || value === '').
2. Database Consistency
NULL vs empty string handling in database columns is explicit.
3. Type Safety
TypeScript/PHP strict typing works better with explicit nulls:
interface User {
name: string;
email: string | null; // Clear intent
tags: string | null; // Not string | null | ''
}
Combine with Null Coalescing for Defaults
Chain the Elvis operator with null coalescing for fallback values:
'display_name' => implode(' ', [
$user->first_name,
$user->last_name,
]) ?: $user->email ?? 'Unknown User',
// Evaluation order:
// 1. Try implode (may return '')
// 2. Elvis converts '' to null
// 3. Null coalescing provides fallback
Common patterns:
// Tags with fallback
'tags_display' => implode(', ', $post->tags) ?: 'No tags',
// Joined data with fallback
'categories' => join(' / ', $product->categories) ?: 'Uncategorized',
// Filtered list with fallback
'assigned_to' => $task->assignees
->pluck('name')
->implode(', ') ?: 'Unassigned',
The pattern makes your API responses predictable and easier to work with on both backend and frontend.