How to Eliminate Redundant Code: A Practical DRY Refactoring Guide in PHP
This article explains the DRY (Do Not Repeat Yourself) principle, demonstrates how duplicated PHP code in a Report class can be refactored by extracting shared logic into reusable methods, and shows the final clean implementation that improves readability and maintainability.
Do Not Repeat Yourself (DRY) is a fundamental software development principle that aims to eliminate duplicated code.
The original Report class prints report data directly in the show method, and a later requirement to save the report to a file leads to duplicated logic.
class Report {
public function show(array $data) {
echo "Report: " . ucwords(strtolower($data["name"])) . "
";
echo "Product: " . ucwords(strtolower($data["product"])) . "
";
echo "Start date: " . date("Y/m/d", $data["startDate"]) . "
";
echo "End date: " . date("Y/m/d", $data["endDate"]) . "
";
echo "Total: " . $data["total"] . "
";
echo "Average x day: " . floor($data["total"] / 365) . "
";
echo "Average x week: " . floor($data["total"] / 52) . "
";
}
}When a new saveToFile method is added, the same printing logic is duplicated, violating DRY.
class Report {
public function saveToFile(array $data) {
echo "Report: " . ucwords(strtolower($data["name"])) . "
";
// ... same duplicated code ...
file_put_contents("./report.txt", $report);
}
}Refactoring extracts the common report‑building code into a private createReport method, which both show and saveToFile call.
class Report {
public function show(array $data) {
echo $this->createReport($data);
}
public function saveToFile(array $data) {
file_put_contents("./report.txt", $this->createReport($data));
}
private function createReport(array $data): string {
$report = '';
$report .= "Report: " . ucwords(strtolower($data["name"])) . "
";
$report .= "Product: " . ucwords(strtolower($data["product"])) . "
";
$report .= "Start date: " . date("Y/m/d", $data["startDate"]) . "
";
$report .= "End date: " . date("Y/m/d", $data["endDate"]) . "
";
$report .= "Total: " . $data["total"] . "
";
$report .= "Average x day: " . floor($data["total"] / 365) . "
";
$report .= "Average x week: " . floor($data["total"] / 52) . "
";
return $report;
}
}Further duplication (name formatting, date formatting, average calculations) is removed by adding helper methods normalizeName, formatDate, and calculateAverage.
private function normalizeName($name): string {
return ucwords(strtolower($name));
}
private function formatDate($date): string {
return date("Y/m/d", $date);
}
private function calculateAverage(array $data, $period): string {
return floor($data["total"] / $period);
}The final refactored Report class combines these helpers, resulting in concise, reusable code that adheres to the DRY principle.
class Report {
public function show(array $data) {
echo $this->createReport($data);
}
public function saveToFile(array $data) {
file_put_contents("./report.txt", $this->createReport($data));
}
private function createReport(array $data) {
$report = '';
$report .= "Report: " . $this->normalizeName($data["name"]) . "
";
$report .= "Product: " . $this->normalizeName($data["product"]) . "
";
$report .= "Start date: " . $this->formatDate($data["startDate"]) . "
";
$report .= "End date: " . $this->formatDate($data["endDate"]) . "
";
$report .= "Total: " . $data["total"] . "
";
$report .= "Average x day: " . $this->calculateAverage($data, 365) . "
";
$report .= "Average x week: " . $this->calculateAverage($data, 52) . "
";
$report .= "Average x month: " . $this->calculateAverage($data, 12) . "
";
return $report;
}
private function formatDate($date): string {
return date("Y/m/d", $date);
}
private function calculateAverage(array $data, $period): string {
return floor($data["total"] / $period);
}
private function normalizeName($name): string {
return ucwords(strtolower($name));
}
}Applying DRY throughout the codebase improves readability, reduces maintenance effort, and helps developers build more robust software.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
21CTO
21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
