Originally published on decentphp.dev — part of the Writing decent PHP course. View this lesson on the original site.

Code rot usually starts small

Code rot usually does not arrive in one dramatic commit.
It grows from small shortcuts that never get cleaned up.

mindmap
  root((Code smells))
    Unused or unreachable
    Unreadable conditionals
    Inconsistent naming or data drift
    Open for modification drift

Small smells and what they look like

1) Unused or unreachable code

<?php

$someBoolean = false;
// $someBoolean = $this->checkBooleanValue();

if ($someBoolean === true) {
    // unreachable branch
}

2) Unreadable conditionals

<?php

if (
    $this->getSetting() === '1' ||
    $this->getSetting() === '2' ||
    ($this->getSetting() !== '1' && $this->someOtherSetting() === '1') ||
    ($this->getSetting() !== '2' && ($this->someOtherSetting() === '1' || $this->someOtherSetting() === '5'))
) {
    // hard to reason about safely
}

3) Inconsistent naming / data drift

<?php

$order = [
    'order_reference' => 'A-100',
    'order_ref' => 'A-100',
    'ref_order' => 'A-100',
];

4) Open-for-modification drift

<?php

function processOrder(array $order): void
{
    // tweak 1
    // tweak 2
    // tweak 3
    // ...years later, nobody trusts this function
}

In the next lesson, we continue this by looking at what these smells cost in real teams: more bugs, slower delivery, and lower morale.

From Writing decent PHP — What decent PHP looks like