PHP Code Review: What a Senior Will Say and How Not to Embarrass Yourself

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why Is Your Code Being Rewritten?

\n\n

You wrote the code. It works. You're proud of yourself. But then code review comes, and the senior developer leaves 15 comments, half of which start with "What if..." or "Let's rewrite this as...". Sound familiar?

\n\n

PHP code review is not about nitpicking. It's about project survival. Seniors don't just look at "works/doesn't work," but at how the code will behave under load, how another developer will maintain it, and how much time you'll spend hunting for a bug six months from now.

\n\n

In this article, we'll break down the most common comments you'll hear during a code review from an experienced PHP developer. I'll show real code examples and explain how to fix them. After reading, you'll be able to anticipate 80% of the comments and write code you won't be ashamed to show.

\n\n

1. "Magic Numbers" and Strings: Code Should Speak for Itself

\n\n

The first thing a senior will notice is unclear numbers and strings scattered throughout the code. Magic numbers are an antipattern that kills readability.

\n\n

Bad Example

\n
if ($user->getAge() > 18) {\n    $discount = $price * 0.1;\n}
\n\n

What Will the Senior Say?

\n
    \n
  • Why exactly 18? Is this the age of majority or a discount threshold?
  • \n
  • Why 0.1? Is that 10%? What if the discount changes?
  • \n
\n\n

Good Example

\n
const ADULT_AGE = 18;\nconst DISCOUNT_RATE = 0.1; // 10%\n\nif ($user->getAge() > ADULT_AGE) {\n    $discount = $price * DISCOUNT_RATE;\n}
\n\n

Now the code tells a story. The senior will approve: constants can be reused, changed in one place, and they don't require comments.

\n\n

2. Lack of Types: PHP 8 Is No Excuse for Dynamic Typing

\n\n

PHP is a weakly typed language, but that doesn't mean you should write code like it's 2005. Strict typing saves you from bugs that are hard to catch.

\n\n

Bad Example

\n
function calculateTotal($items, $tax) {\n    $total = 0;\n    foreach ($items as $item) {\n        $total += $item['price'] * $item['quantity'];\n    }\n    return $total * (1 + $tax);\n}
\n\n

Senior's Comments

\n
    \n
  • What is $items? An array? An object? A collection?
  • \n
  • What is the structure of an element? Why no DTO?
  • \n
  • What if $tax is passed as the string "0.2"? Will it concatenate?
  • \n
\n\n

Good Example

\n
declare(strict_types=1);\n\nclass OrderItem {\n    public function __construct(\n        public readonly float $price,\n        public readonly int $quantity\n    ) {}\n}\n\nfunction calculateTotal(array $items, float $taxRate): float {\n    $total = 0.0;\n    foreach ($items as $item) {\n        if (!$item instanceof OrderItem) {\n            throw new InvalidArgumentException('Expected OrderItem');\n        }\n        $total += $item->price * $item->quantity;\n    }\n    return $total * (1 + $taxRate);\n}
\n\n

The senior will say: "Good job, you're using DTO, readonly properties, and strict typing. The code is predictable." This is a PHP 8+ best practice.

\n\n

3. Deep Nesting and Early Return

\n\n

When you see 5 levels of if...else inside a single method, the senior grabs their head. Such code is impossible to read, test, and debug.

\n\n

Bad Example

\n
public function processOrder($order) {\n    if ($order->isPaid()) {\n        if ($order->hasStock()) {\n            if ($order->isShippable()) {\n                // 50 lines of logic\n                return $this->ship($order);\n            } else {\n                throw new \\Exception('Order cannot be shipped');\n            }\n        } else {\n            throw new \\Exception('Out of stock');\n        }\n    } else {\n        throw new \\Exception('Order not paid');\n    }\                

Blogs

Book Recommendations