13 Modern PHP Tips & Tricks from 201513 Modern PHP Tips & Tricks from 2015

PHP has undergone a massive transformation over the last decade. If you’re still writing PHP like it’s 2015, you’re missing out on massive performance gains, cleaner syntax, and better security.

I ran into a nice blog post 13 PHP Tips That Make Development Faster from Linet M. that covered tips for PHP of that era: that was PHP 7.0 at that time. It is interesting to discover the way we have covered since that moment, so I read the whole piece. That was really good, and it also showed a bit of age. Probably like myself anyway.

Let’s take a modern look at the tips that still matter in 2026, the ones you need to forget, and the new tricks you should be using today.

🗑️ The “Dead and Buried” Tips

Before we get to the good stuff, let’s clear out the obsolete advice from older blog posts:

  • “Use single quotes instead of double quotes for performance”. Modern PHP engines parse both equally fast. Use double quotes for string interpolation ("Hello {$name}") and single quotes when you don’t need interpolation. Readability matters more than micro-optimizations.
  • “Use echo instead of print“. First, nobody is using print anymore anyway, and the performance difference is non-existent in PHP 8.x.
  • “Avoid require_once because it’s slow”. Everyone use Composer and PSR-4 autoloading for classes now, so manual require/require_once for classes is indeed obsolete — though bootstrap files and front controllers still require things on purpose, even in fully Composer-driven apps.
  • “Pre-increment ++$i is faster than $i++“. The PHP engine optimized this years ago. Use whichever makes sense in terms of readability.
  • “Suppress errors with @“. This one is actually harmful. Never do this, or in well monitored situations. Modern PHP prefers typed errors and exceptions over a silenced failure (though not everything became an exception in PHP 8 — plenty of E_WARNING/E_DEPRECATED notices still exist the old-fashioned way). Suppressing errors hides bugs and makes debugging a nightmare.

✅ The Modern, Updated PHP Tips

The numbers is the reference in the original article.

1. Always Use Strict Types

In 2026, loosely typed PHP is a thing of the past. Always declare strict_types at the very top of your PHP files. This forces PHP to enforce the types you declare in function signatures, preventing sneaky bugs caused by automatic type coercion.

<?php
declare(strict_types=1);

function calculateTotal(int $price, float $tax): float {
    return $price + ($price * $tax);
}
?>

2. Use === for Strict Comparison

This was true a decade ago, and it’s true today. Use === to check both value and type. PHP’s == (a.k.a. relaxed comparison) still has weird edge cases — null == false is still true, for one. The classic 0 == "a" example, though, is no longer one of them: since PHP 8.0’s “saner string to number comparisons”, a number is compared against a non-numeric string as a string, so 0 == "a" is false today. That old chestnut belongs in the “dead and buried” pile above, not here — but the edge cases that remain are reason enough to keep using === and not leave it to chance.

3. Leverage the Nullsafe Operator (?->)

Stop writing deeply nested if statements just to check if an object property exists. The nullsafe operator allows you to chain method calls or property accesses. If any part of the chain evaluates to null, the entire chain short-circuits and returns null safely.

<?php
// Old way (yuck)
$country = null;
if ($user !== null) {
    $address = $user->getAddress();
    if ($address !== null) {
        $country = $address->getCountry();
    }
}

// 2026 way (clean)
$country = $user?->getAddress()?->getCountry();
?>

4. Use Enums Instead of “Magic Strings”

Before PHP 8.1, developers used constants or “magic strings” to represent states. Now, use Enums — or, as here, a backed enum when each case needs a scalar value attached. They are type-safe, readable, and prevent typos.

<?php
enum OrderStatus: string {
    case Pending = 'pending';
    case Shipped = 'shipped';
    case Delivered = 'delivered';
}

function updateOrder(OrderStatus $status) {
    // You are guaranteed to only receive a valid status here
}
?>

5. Use match Instead of switch

The switch statement is verbose and prone to bugs, like forgetting a break. The match expression is shorter, uses strict comparison ===, returns a value directly, and throws an error if no condition is met.

<?php
// Old way
switch ($status) {
    case 'active':
        $message = 'User is active';
        break;
    case 'inactive':
        $message = 'User is inactive';
        break;
    default:
        $message = 'Unknown';
}

// 2026 way
$message = match($status) {
    'active' => 'User is active',
    'inactive' => 'User is inactive',
    default => 'Unknown',
};
?>

6. Stop Counting in Loops

This tip survived the update amd it is worth repeating: Do not put function calls inside loop conditions.

<?php
// Bad: count() is called on every single iteration
for ($i = 0; $i < count($array); $i++) { ... }

// Good: count() is called once
$count = count($array);
for ($i = 0; $i < $count; $i++) { ... }
?>

7. Use str_contains, str_starts_with, and str_ends_with

Stop using strpos() !== false to check if a string exists within another string. PHP 8 gave us dedicated, highly readable functions for this, starting with str_contains().

<?php
// Old way
if (strpos($haystack, $needle) !== false) { ... }

// 2026 way
if (str_contains($haystack, $needle)) { ... }
?>

8. Use Readonly Properties and Classes

Immutability is key to bug-free code. Use the readonly keyword for class properties that should only be initialized once. This is especially useful for Data Transfer Objects (DTOs) and value objects.

<?php
class User {
    public function __construct(
        public readonly string $name,
        public readonly string $email
    ) {}
}

$user = new User('Alice', 'alice@example.com');
$user->name = 'Bob'; // Throws an Error! Cannot modify readonly property.
?>

9. Take Advantage of Property Hooks

If you are using PHP 8.4 or newer, you no longer need to write verbose getters and setter methods for every property. Property hooksallow you to inline access logic directly in the property declaration.

<?php
class Product {
    public string $name {
        get => strtoupper($this->name);
        set => $value;
    }
}
?>

10. Use Named Arguments

You no longer need to pass null for optional parameters just to reach the one you actually want to change. Named arguments allow you to pass values by their parameter name — the real name from the signature, mind you, or PHP throws Unknown named parameter.

<?php
// Old way
setcookie("user", "Alice", time() + 3600, "/", "", true, true);

// 2026 way
setcookie(
    name: "user", 
    value: "Alice", 
    expires: time() + 3600, 
    httponly: true
);
?>

(The original draft named that third parameter expires_or_options — a plausible-looking guess, but setcookie()‘s actual parameter is $expires; the array-based overload’s parameter is $options, not a portmanteau of the two.)

11. Use PDO with Prepared Statements

The golden rule of database interactions hasn’t changed: Never put user input directly into an SQL query. SQL injection is still the #1 web vulnerability. Always use PDO (or a modern ORM like Eloquent/Doctrine) with prepared statements.

<?php
// Safe
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email");
$stmt->execute(['email' => $userInput]);
?>

You might also consider going one step further with an ORM. But that might be overkill for a PHP tips.

12. Use Arrow Functions for Simple Closures

Writing multi-line function() use ($var) closures is clunky for simple array operations. Arrow functions (fn()) automatically capture variables by value and allow one-line expressions.

<?php
// Old way
$multiplied = array_map(function($n) use ($factor) {
    return $n * $factor;
}, $numbers);

// 2026 way
$multiplied = array_map(fn($n) => $n * $factor, $numbers);
?>

13. Rely on OPcache and JIT

Instead of spending hours trying to optimize string concatenation or array syntax, ensure your production server has OPcache enabled. Furthermore, if you are running CPU-heavy applications, like math processing or image manipulation, enable JIT (Just-In-Time) compilation in your php.ini. This compiles PHP code into native machine code — worth knowing, though, that the “massive performance boosts” mostly show up on CPU-bound, numeric workloads; a typical request-response web app spends most of its time waiting on a database or the network, so don’t expect JIT alone to rescue a slow endpoint. It’s OPcache, not JIT, that does the heavy lifting for ordinary apps. Either way, both make old-school micro-optimizations irrelevant.

What a decade did to this list

Going through it line by line, what strikes me most isn’t the new tips that appeared: it’s how little needed fixing at all. Thirteen tips, written for a PHP that was still years away from union types, enums, or a JIT, and eleven of them read today exactly as they did then, no asterisk required. === over ==, prepared statements over string concatenation, don’t call count() from inside a loop condition: these aren’t PHP 7 tips that happened to survive, they’re just good engineering advice that PHP’s version number was never going to change. That kind of stability is rare, and it says something about the original instinct for which parts of a “tips” article age like the language and which parts age like a haircut.