DEV Community

thiCha
thiCha

Posted on

Magic Strings & Magic Numbers 🪄

Magic numbers are literal numeric values that are used in code without any explanation of their meaning. Magic strings are strings literals without any explanation either.

Why is it a problem ?

First of all, it is not easy to read when there is only a number that is written in code. Let's look at an example:

$myModel = new Model();
$myModel->status_id = 3; // A magic number
$myModel->save();
Enter fullscreen mode Exit fullscreen mode

Here there is no explanation of the meaning behind the value "3". I can probably find the answer by looking at the code surrounding this snippet or look for a corresponding value elsewhere (like in a database table).


Also the number "3" is not important in itself for my comprehension of the code. The status should correspond to a more realistic status of my business like "Created", "Sent", "Archived".


The same applies to Magic Strings:

switch ($request->code_response) {
  case "code_1": // Magic String
    doAnAction();
    break;
  case "code_2": // Also a Magic String
    doAnotherAction();
    break;
...
Enter fullscreen mode Exit fullscreen mode

I can probably guess the utility of these code values by looking at the code of the doAnAction() and doAnotherAction() functions but it would greatly help to have a code more readable at this stage.

How to solve this problem ?

Different solutions can be used. The simplest one is to use a named variable:

$statusCreated = 3;

$myModel = new Model();
$myModel->status_id = $statusCreated;
$myModel->save();
Enter fullscreen mode Exit fullscreen mode

A better solution is to use constant values in a separate class or even an enum.

enum MyModelStatuses {
...
  case CREATED = 3;
  case ARCHIVED = 4;
...
}

$myModel = new Model();
$myModel->status_id = MyModelStatuses::CREATED->value; // don't forget to import the new class
$myModel->save();
Enter fullscreen mode Exit fullscreen mode

A separate class allow you to have a global logic behind these values that can be reused elsewhere.


Another solution when the Magic Number is only used in one class is to use a const variable in the class:
From:

class MyClass {
  public function myFunction() {
    for ($i = 0; $i < 10; $i++) { // Here 10 is a Magic Number
      // Do something
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

To:

class MyClass {
  private const NUMBER_OF_ITERATIONS = 10;

  public function myFunction() {
    for ($i = 0; $i < self::NUMBER_OF_ITERATIONS; $i++) {
      // Do something
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Such constants are used as parameters inside your class and can be easily replaced by new values.


Let's see a last use case of avoiding Magic Numbers.

$myModel = new MyModel();
$myModel->duration = 60; // Magic Number
$myModel->save();
Enter fullscreen mode Exit fullscreen mode

Here the value 60 can be confusing. What is its unit ? It could me seconds, it could be minutes or even hours !

$secondsInAMinute = 60;

$myModel = new MyModel();
$myModel->duration = $secondsInAMinute;
$myModel->save();
Enter fullscreen mode Exit fullscreen mode

The name of the new variable itself helps to make the code readable. Also the same number could refer to different meanings (in this case we could have 60 as $minutesInAnHour somewhere else in the code).


That's it ! I hope that this article helped you understand what are Magic Numbers (and Magic Strings) and how to remove them from your code !

Top comments (0)