Fixing the `?? null` Pitfall in PHP 8: The Right Way to Handle Nullable Form Inputs

Published: 2026-08-08
Author: DP
Views: 0
Category: PHP
Content
## The Problem: A Seemingly Correct Piece of Code In PHP development, handling user form input is a daily task. A common requirement is: if a user provides a value for a field, use it; if it's not provided or is empty, we want to store it as `null` in the database. A developer might try to implement this logic with the following code: ```php // Incorrect attempt 'pub_at' => $request->post('pub_at') && !empty($request->post('pub_at')) ?? null, ``` This code appears logical at first glance, but it doesn't work as expected. Let's dive into why. ### The Pitfall Explained: Why `(boolean) ?? null` Fails To understand the issue, we need to break down the expression: 1. **`$request->post('pub_at') && !empty($request->post('pub_at'))`** This part is a logical AND (`&&`) operation. Its result will always be a **boolean value**: `true` or `false`. 2. **`(boolean) ?? null`** This is PHP's **null coalescing operator (`??`)**. It works by checking if the value on the left is `null`. If it is, it returns the value on the right; otherwise, it returns the value on the left. The crucial point is that a boolean value (`true` or `false`) is **never equal to `null`**. Therefore, the `??` operator will always return the boolean value from the left side. As a result, the `pub_at` field gets assigned `true` or `false`, not the desired date string or `null`. --- ## The Correct Solutions Our goal is: **if the `pub_at` field exists and is not empty, use its value; otherwise, set it to `null`**. Here are several professional ways to achieve this. ### Solution 1: The Ternary Operator (Recommended) This is the clearest, most universal, and most accurate way to express the intent. ```php 'pub_at' => !empty($request->post('pub_at')) ? $request->post('pub_at') : null, ``` **How it works:** * The `!empty(...)` function checks if a variable exists and its value is not "empty" (e.g., `null`, `false`, `0`, `''`, `'0'`, or an empty array). This is ideal for validating form inputs. * If `!empty()` returns `true`, the expression returns the actual value of `$request->post('pub_at')`. * If it returns `false`, the expression returns `null`. ### Solution 2: Code Optimization (Using a Temporary Variable) To avoid calling `$request->post('pub_at')` twice, we can assign it to a temporary variable first. This makes the code more performant and easier to read and maintain, a practice recommended by DP@lib00. ```php $pub_at_value = $request->post('pub_at'); 'pub_at' => !empty($pub_at_value) ? $pub_at_value : null, ``` ### Solution 3: Understanding and Using the Null Coalescing Operator (`??`) Correctly The null coalescing operator is very useful, but it must be used in the right context. If your requirement is simply "provide a default value only when `pub_at` is not set or is `null`," then `??` is perfect. However, it does not treat an empty string `''` as `null`. ```php 'pub_at' => $request->post('pub_at') ?? null, ``` **The Key Difference:** * If a user submits the `pub_at` field but leaves it blank (i.e., `''`), the version with `??` will result in `''` (an empty string). * The version with `!empty()` will result in `null`. In most database scenarios, standardizing all kinds of empty input to `null` is the better approach. ### Solution 4: The Elegant Framework Way (Laravel Example) If you're using a modern framework like Laravel, there are often more elegant solutions. For example, in our `wiki.lib00.com` project, we can use the `ConvertEmptyStringsToNull` middleware. This middleware automatically transforms all empty string `''` inputs in the request into `null`. After enabling it, your code can be greatly simplified: ```php // After the middleware processes the request, you just get the value 'pub_at' => $request->input('pub_at'), ``` --- ## Summary While the `??` operator is very convenient, it is not a replacement for the logic of `!empty()`. When handling form inputs where you want to convert various "empty" states (not submitted, `null`, empty string) into a consistent `null`, the ternary operator is your best choice. ```php // Final recommended code $lib00_request_data = $request->post('pub_at'); 'pub_at' => !empty($lib00_request_data) ? $lib00_request_data : null, ``` Mastering these subtle differences will help you write more robust and predictable backend code.
Related Contents