Doing stricter checks in PHP

Search for a command to run...

I do prefer data_get over the array key approach. Mainly because it simplifies the getting, as well as having a default null or value.
Geni Jaho array_key_exists() and isset() are not interchangeable, because they have different use cases.
Of course most of the time you can use array_key_exists instead of isset but in some cases, you can not.
See here for more details
I think yes, it's at the same level as empty($a), but the point is we're letting go of a tiny bit of readability in exchange for a more trusted/clear code. When we do $a === [] we know for sure that it's a plain array and not an Arrayable object or similar. It's down to personal preference anyway.
Testing is almost always difficult when developing applications that interact with external services, APIs, or complex features. One way to make testing easier is to use stub classes. Here's how I usually work with them. Quick intro on benefits Stubs...

We're upgrading from Laravel 9 to 10, and PHPUnit 9 to 10, and, if all goes well, we'll top it off by migrating to Pest, the latest version. To keep the positive vibes on I'll skip an upgrade from PHP 8.1 to 8.2, just because I don't want to restart ...

GitHub's 2000 minutes per month of free usage of GitHub Actions is usually enough to handle light workflows. However, as more tech is run automatically, we are forced to upgrade to a paid plan or optimize our workflows. Currently, I am running Rector...

Laravel 10 is making the headlines these days. However, many apps are stuck in older versions, or at least still use the syntax and methods of older releases. One of the most significant changes introduced in Laravel 9 is the syntax for accessors and...

A nice refactoring I've learned recently is to utilize types in conditionals.
For years I’ve been doing if (!empty($posts)), but Rector, a tool to automatically refactor code, changed that to if ($posts === []). The main advantage of using $posts === [] is that it is more explicit and less prone to unexpected behavior.
It might not seem like much, but it's quite telling of the codebase you're working with. Using $posts === [] demonstrates a higher level of attention to detail and a commitment to writing more reliable and predictable code. It shows that you are thinking about the specific requirements of your code and taking steps to ensure that it behaves as expected.
On the other hand, using !empty($posts) can suggest a more casual approach to programming, where you are relying on PHP's default behavior rather than explicitly defining the expected behavior of your code. While this may be acceptable for smaller projects, it can lead to unexpected bugs and difficulties as your codebase grows and becomes more complex.
Here are some other refactorings I've learned that make me feel like I'm in charge of the code, and not the way around.
// Before
if ($username == null) {}
if (!$username) {}
// After
if ($username === null) {}
The first two conditions check if $user is not truthy, which includes checking if it's null, false, 0, or an empty string. With the after example, we can use the strict comparison operator === to specifically check if $username is null.
function calculate(int $x, int $y) {
// Do something
}
In this example, the int type hint ensures that $x and $y are integers. If a non-integer value is passed to the function, PHP will throw a TypeError.
array_key_exists() to check for array keys:// Before
if (isset($data['username'])) {
// Do something
}
// After
if (array_key_exists('username', $data)) {
// Do something
}
In the before example, we're using the isset() function to check if $userData['username'] exists. With the after example, we can use the array_key_exists() function to specifically check if the 'username' key exists in $userData.
// Before
if (isset($userData['username'])) {
$username = $userData['username'];
} else {
$username = 'Guest';
}
// After
$username = $userData['username'] ?? 'Guest';
In the before example, we're using an if statement to check if $userData['username'] exists and setting $username accordingly. With the after example, we can use the null coalescing operator ?? to set $username to $userData['username'] if it exists, and 'Guest' if it doesn't. Additionally, we can use the null coalescing assignment operator ??= to assign the default value to $username only if it's not already set.
These stricter checks help us write more reliable and predictable code, catch errors early, and save ourselves from potential headaches in the future. While some of these refactorings may take some getting used to, they are worth the effort to improve the quality of our code. Or, just install Rector and let it handle them for you. Happy coding!