PHP项目如何提取循环内重复代码

wen PHP项目 30

本文目录导读:

PHP项目如何提取循环内重复代码

  1. 函数封装(最基础)
  2. 匿名函数/闭包
  3. 使用array_map等数组函数
  4. 创建迭代器类
  5. 使用Traits复用代码
  6. 使用管道模式
  7. 使用设计模式:策略模式
  8. 最佳实践建议

在PHP项目中提取循环内重复代码,常见的方法有以下几种:

函数封装(最基础)

// 原始重复代码
foreach ($users as $user) {
    $processedName = trim(strtolower($user['name']));
    $processedEmail = trim(strtolower($user['email']));
    // 处理逻辑...
}
// 提取后
function processUserData(array $user): array {
    return [
        'name' => trim(strtolower($user['name'])),
        'email' => trim(strtolower($user['email']))
    ];
}
foreach ($users as $user) {
    $processed = processUserData($user);
    // 处理逻辑...
}

匿名函数/闭包

// 提取处理逻辑
$processItem = function($item) {
    return [
        'value' => $item * 2,
        'timestamp' => time()
    ];
};
foreach ($items as $item) {
    $result = $processItem($item);
    // 其他逻辑...
}

使用array_map等数组函数

// 原始代码
$results = [];
foreach ($items as $item) {
    $results[] = [
        'id' => $item['id'],
        'name' => strtoupper($item['name'])
    ];
}
// 提取后
$processItem = fn($item) => [
    'id' => $item['id'],
    'name' => strtoupper($item['name'])
];
$results = array_map($processItem, $items);

创建迭代器类

class UserProcessor {
    private $users;
    public function __construct(array $users) {
        $this->users = $users;
    }
    public function process(): Generator {
        foreach ($this->users as $user) {
            yield $this->processSingle($user);
        }
    }
    private function processSingle(array $user): array {
        return [
            'name' => trim($user['name']),
            'email' => strtolower($user['email']),
            'role' => $this->determineRole($user)
        ];
    }
    private function determineRole(array $user): string {
        return $user['is_admin'] ? 'admin' : 'user';
    }
}
// 使用
$processor = new UserProcessor($users);
foreach ($processor->process() as $processedUser) {
    // 处理逻辑
}

使用Traits复用代码

trait DataProcessorTrait {
    protected function processItems(array $items, callable $callback): array {
        return array_map($callback, $items);
    }
    protected function validateItem($item): bool {
        return !empty($item) && is_array($item);
    }
}
class UserService {
    use DataProcessorTrait;
    public function processUsers(array $users): array {
        return $this->processItems($users, function($user) {
            if (!$this->validateItem($user)) {
                return null;
            }
            return $this->transformUser($user);
        });
    }
    private function transformUser(array $user): array {
        return [
            'name' => $user['name'],
            'role' => $user['role']
        ];
    }
}

使用管道模式

class Pipeline {
    private $stages = [];
    public function pipe(callable $stage): self {
        $this->stages[] = $stage;
        return $this;
    }
    public function process($input) {
        $result = $input;
        foreach ($this->stages as $stage) {
            $result = $stage($result);
        }
        return $result;
    }
}
// 使用
$pipeline = (new Pipeline())
    ->pipe(fn($item) => array_map('trim', $item))
    ->pipe(fn($item) => array_map('strtolower', $item))
    ->pipe(fn($item) => array_filter($item));
foreach ($data as $item) {
    $processed = $pipeline->process($item);
    // 处理逻辑
}

使用设计模式:策略模式

interface ProcessingStrategy {
    public function process($item): mixed;
}
class UserProcessingStrategy implements ProcessingStrategy {
    public function process($item): mixed {
        return [
            'name' => strtoupper($item['name']),
            'email' => strtolower($item['email'])
        ];
    }
}
class ItemProcessor {
    private $strategy;
    public function __construct(ProcessingStrategy $strategy) {
        $this->strategy = $strategy;
    }
    public function processItems(array $items): array {
        return array_map([$this->strategy, 'process'], $items);
    }
}
// 使用
$processor = new ItemProcessor(new UserProcessingStrategy());
$results = $processor->processItems($users);

最佳实践建议

  1. 根据复杂度选择

    • 简单逻辑:用函数或匿名函数
    • 中等复杂度:用类方法
    • 复杂业务:用设计模式
  2. 保持单一职责:每个提取的代码块只做一件事

  3. 测试友好:提取后的代码更容易单元测试

  4. 性能考虑

    // 避免在循环内创建闭包
    $transformer = function($item) { return $item * 2; };
    foreach ($items as $item) {
        $result = $transformer($item); // 复用闭包
    }

选择哪种方法取决于你的具体场景、代码复杂度以及团队规范。

抱歉,评论功能暂时关闭!