本文目录导读:

在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);
最佳实践建议
-
根据复杂度选择:
- 简单逻辑:用函数或匿名函数
- 中等复杂度:用类方法
- 复杂业务:用设计模式
-
保持单一职责:每个提取的代码块只做一件事
-
测试友好:提取后的代码更容易单元测试
-
性能考虑:
// 避免在循环内创建闭包 $transformer = function($item) { return $item * 2; }; foreach ($items as $item) { $result = $transformer($item); // 复用闭包 }
选择哪种方法取决于你的具体场景、代码复杂度以及团队规范。