Fundamentals 10 min read

Master Extract Method Refactoring: Simplify Your PHP Code with Real Examples

This article explains the Extract Method refactoring technique, its definition, benefits, and step‑by‑step PHP examples that show how to split a long method into smaller, well‑named methods, improving readability, reusability, and adherence to the Single Responsibility Principle.

21CTO
21CTO
21CTO
Master Extract Method Refactoring: Simplify Your PHP Code with Real Examples

Today we discuss the refactoring technique called Extract Method, one of the most frequently used approaches.

Definition

Martin Fowler defines it as: if you have a code fragment that can be grouped, turn that fragment into a method whose name explains its purpose.

The key is the method name; a good name conveys the intent and often eliminates the need for extra comments.

Why Refactor?

Refactoring brings many benefits: it simplifies code, makes it more readable, enables reuse, and replaces noisy comments with expressive method names.

Extract Method Example

Consider a PHP method that prints all items in a shopping cart and the total price.

public function printCartDetails()
{
    // print items in the cart
    echo "Your shopping cart contains the following items:<br>";
    echo "<table>";
    echo "<th>Name</th> <th>Price</th>";
    foreach($this->items as $item)
    {
        echo "<tr>";
        echo "<td>{$item->getName()}</td>";
        echo "<td>${$item->getPrice()}</td>";
        echo "</tr>";
    }
    echo "</table>";

    // calculate the total price
    $totalPrice = 0;
    foreach($this->items as $item)
        $totalPrice += $item->getPrice();

    // print the total price
    printf("The total price: $%d", $totalPrice);
}

This method is too long, mixes responsibilities, and relies on comments.

Case 1: No Local Variables

Extract the code that prints items into a private method.

public function printCartDetails()
{
    $this->printItemsInCart();
    // calculate the total price
    $totalPrice = 0;
    foreach($this->items as $item)
        $totalPrice += $item->getPrice();
    printf("The total price: $%d", $totalPrice);
}

private function printItemsInCart()
{
    echo "Your shopping cart contains the following items:<br>";
    echo "<table>";
    echo "<th>Name</th> <th>Price</th>";
    foreach($this->items as $item)
    {
        echo "<tr>";
        echo "<td>{$item->getName()}</td>";
        echo "<td>${$item->getPrice()}</td>";
        echo "</tr>";
    }
    echo "</table>";
}

Case 2: Using a Local Variable

Extract the total‑price printing into a method that receives the local variable.

public function printCartDetails()
{
    $this->printItemsInCart();
    // calculate the total price
    $totalPrice = 0;
    foreach($this->items as $item)
        $totalPrice += $item->getPrice();
    $this->printTotalPrice($totalPrice);
}

private function printTotalPrice($totalPrice)
{
    printf("The total price: $%d", $totalPrice);
}

Case 3: Reassigning a Local Variable

When the extracted method needs to modify the original variable, return the new value.

public function printCartDetails()
{
    $this->printItemsInCart();
    $totalPrice = 0;
    $totalPrice = $this->calculateTotalPrice($totalPrice);
    $this->printTotalPrice($totalPrice);
}

private function calculateTotalPrice($totalPrice)
{
    foreach($this->items as $item)
        $totalPrice += $item->getPrice();
    return $totalPrice;
}

If the initialization can be moved, do it inside the extracted method.

public function printCartDetails()
{
    $this->printItemsInCart();
    $totalPrice = $this->calculateTotalPrice();
    $this->printTotalPrice($totalPrice);
}

private function calculateTotalPrice()
{
    $totalPrice = 0;
    foreach($this->items as $item)
        $totalPrice += $item->getPrice();
    return $totalPrice;
}

When the initial value depends on the caller, keep the parameter.

public function printCartDetails($previousAmount)
{
    $this->printItemsInCart();
    $totalPrice = $previousAmount * 1.1;
    $totalPrice = $this->calculateTotalPrice($totalPrice);
    $this->printTotalPrice($totalPrice);
}

private function calculateTotalPrice($totalPrice)
{
    $result = $totalPrice;
    foreach($this->items as $item)
        $result += $item->getPrice();
    return $result;
}

Comparison

Before refactoring:

public function printCartDetails()
{
    // print items in the cart
    echo "Your shopping cart contains the following items:<br>";
    echo "<table>";
    echo "<th>Name</th> <th>Price</th>";
    foreach($this->items as $item)
    {
        echo "<tr>";
        echo "<td>{$item->getName()}</td>";
        echo "<td>${$item->getPrice()}</td>";
        echo "</tr>";
    }
    echo "</table>";
    // calculate the total price
    $totalPrice = 0;
    foreach($this->items as $item)
        $totalPrice += $item->getPrice();
    // print the total price
    printf("The total price: $%d", $totalPrice);
}

After refactoring:

public function printCartDetails()
{
    $this->printItemsInCart();
    $totalPrice = $this->calculateTotalPrice();
    $this->printTotalPrice($totalPrice);
}

The refactored version is much clearer: it first prints items, then calculates and prints the total price.

Conclusion

Extract Method refactoring is powerful and easy to apply; start using it today to make your code more understandable and maintainable.

Translation link: http://www.codeceo.com/article/programmer-break-method.html Original English article: "Break Your Method Into Smaller Ones" Translator: CodeCeo – Xiao Feng
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

software designrefactoringcode readabilityextract-method
21CTO
Written by

21CTO

21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.