michael-rubel/nullify
Nullify is a Laravel package that converts empty values to null, helping keep request and model data consistent and making validation and database storage more predictable.
Install the package with Composer:
composer require michael-rubel/nullify
Laravel package discovery should register the service provider automatically. There is no required configuration for the basic helper; start by reading the package README and the small src/ directory so you know exactly what it considers “empty.”
The first use case is normalizing optional, nested input before validation or persistence:
$payload = nullify([
'name' => '',
'nickname' => ' ',
'tags' => [],
'meta' => ['notes' => ''],
'active' => false,
'count' => 0,
]);
// Typically:
// ['name' => null, 'nickname' => null, 'tags' => null,
// 'meta' => ['notes' => null], 'active' => false, 'count' => 0]
Use it where Laravel’s ConvertEmptyStringsToNull middleware does not reach: nested arrays, JSON payloads, console commands, jobs, imports, and service-layer input.
Normalize in a Form Request before validation
prepareForValidation() is the natural boundary for request normalization:
protected function prepareForValidation(): void
{
$this->merge(
nullify($this->except(['password', 'password_confirmation'])) ?? []
);
}
Then define rules with nullable:
'nickname' => ['nullable', 'string', 'max:255'],
'tags' => ['nullable', 'array'],
Normalize API payloads outside the HTTP middleware
For JSON endpoints or third-party webhooks, normalize the decoded payload before validation:
$data = nullify($request->all()) ?? [];
$validated = Validator::make($data, [
'email' => ['required', 'email'],
'company.name' => ['nullable', 'string'],
'company.vat' => ['nullable', 'string'],
])->validate();
Normalize at DTO / action boundaries
Keep normalization at the edge of your application, not scattered through domain logic:
final class CreateCustomerData
{
public function __construct(
public readonly string $email,
public readonly ?string $companyName,
public readonly ?array $tags,
) {}
public static function fromArray(array $input): self
{
$input = nullify($input) ?? [];
return new self(
email: $input['email'],
companyName: $input['company_name'] ?? null,
tags: $input['tags'] ?? null,
);
}
}
Use mutators for model-level normalization
If a model should always store blanks as NULL, wrap the attribute setter:
use Illuminate\Database\Eloquent\Casts\Attribute;
protected function nickname(): Attribute
{
return Attribute::make(
set: fn ($value) => nullify($value),
);
}
Use it for “empty means no filter” query logic
$status = nullify($request->input('status'));
$query->when(
$status === null,
fn ($q) => $q->whereNull('status'),
fn ($q) => $q->where('status', $status),
);
Keep Laravel’s middleware for top-level request strings
Do not replace ConvertEmptyStringsToNull. Let Laravel handle ordinary form fields and use Nullify for recursion, arrays, collections, imports, and non-HTTP code.
blank() treats 0, '0', and false as non-empty; PHP’s empty() does not. Confirm which behavior the package uses before sending numeric or boolean fields through it.null. If a downstream type hint is array rather than ?array, normalize earlier or wrap with ?? []. This is especially important for DTO constructors and service methods.NOT NULL.nullify($request->all()) calls unless you explicitly want that behavior.$request->all() contains uploaded files or domain objects, normalize only the scalar/array fields you intend to touch.php artisan config:cache in deployment environments.dd(nullify($value)) on representative inputs is usually faster than reasoning about edge cases.null is different from passing [] to sync(), JSON columns, or APIs that distinguish between “missing” and “empty.” Normalize deliberately at those boundaries.How can I help you explore Laravel packages today?