Checklist các case thường gặp khi review code PHP (Fuel, Laravel, Symfony) và cách refactor cho ngắn gọn, dễ hiểu, tối ưu.
// antes
if ($user) {
if ($user->is_active) {
return $user;
}
}
return null;
// depois
if (!$user || !$user->is_active) {
return null;
}
return $user;// antes
if ($role === 'admin') {
$permission = 10;
} elseif ($role === 'editor') {
$permission = 5;
} else {
$permission = 1;
}
// depois (mapping)
$map = [
'admin' => 10,
'editor' => 5,
];
$permission = $map[$role] ?? 1;// antes
if (($age > 18 && $is_student) || ($age > 60 && !$is_student)) { ... }
// depois
$eligibleYoung = $age > 18 && $is_student;
$eligibleSenior = $age > 60 && !$is_student;
if ($eligibleYoung || $eligibleSenior) { ... }// antes
foreach ($users as $user) {
foreach ($user->posts as $post) {
$titles[] = $post->title;
}
}
// depois (collection helper)
$titles = array_merge(...array_map(fn($u) => array_column($u->posts, 'title'), $users));// antes
if ($plan < 3) { ... }
// depois
if ($plan < self::PLAN_PREMIUM) { ... }// antes
$price1 = $product1->getTaxedPrice();
$price2 = $product2->getTaxedPrice();
// depois
$prices = array_map(fn($p) => $p->getTaxedPrice(), [$product1, $product2]);// antes
if ($status === 'draft' || $status === 'pending' || $status === 'rejected') {
return false;
}
// depois
if (in_array($status, ['draft', 'pending', 'rejected'], true)) {
return false;
}// antes
$str = '';
foreach ($items as $i) {
$str .= $i . ',';
}
// depois
$str = implode(',', $items);// antes
$result = $a;
foreach ($b as $item) {
$result[] = $item;
}
// depois
$result = array_merge($a, $b);// antes
$value = isset($data['key']) ? $data['key'] : null;
// depois
$value = $data['key'] ?? null;// antes
foreach ($users as $u) {
$posts = DB::select('*')->from('posts')->where('user_id', $u['id'])->execute();
}
// depois
$users = DB::select('users.*', 'posts.*')
->from('users')
->join('posts', 'LEFT')->on('users.id', '=', 'posts.user_id')
->execute();// antes
$found = false;
foreach ($list as $item) {
if ($item === $target) {
$found = true;
}
}
// depois
$found = false;
foreach ($list as $item) {
if ($item === $target) {
$found = true;
break; // tối ưu
}
}// antes
$sum = 0;
foreach ($arr as $x) {
$sum += $x;
}
// depois
$sum = array_sum($arr);// antes
try {
$this->process();
} catch (Exception $e) {}
// depois
try {
$this->process();
} catch (SpecificException $e) {
Log::error($e->getMessage());
throw $e; // hoặc xử lý hợp lý
}// antes
if (!$user) {
throw new Exception("User not found");
}
// depois (fail fast với custom exception)
if (!$user) {
throw new UserNotFoundException();
}// antes
DB::query('DELETE FROM users')->execute();
DB::query('DELETE FROM posts')->execute();
// depois (transaction)
DB::start_transaction();
try {
DB::query('DELETE FROM users')->execute();
DB::query('DELETE FROM posts')->execute();
DB::commit_transaction();
} catch (Exception $e) {
DB::rollback_transaction();
throw $e;
}// antes
$name = $user->profile->name;
// depois
$name = $user->profile->name ?? 'Guest';// antes
DB::query("SELECT * FROM users WHERE id = $id");
// depois
DB::query("SELECT * FROM users WHERE id = :id")
->parameters(['id' => $id])
->execute();// antes
DB::select('*')->from('users')->execute();
// depois
DB::select('id', 'name', 'email')->from('users')->execute();// antes
$users = Model_User::query()->where('status', 1)->where('deleted_at', null)->get();
// depois (ngắn gọn)
$users = Model_User::query()->where([['status', 1], ['deleted_at', null]])->get();// antes
public function getUsers($active = true) { ... }
// depois → tách hàm
public function getActiveUsers() { ... }
public function getInactiveUsers() { ... }// antes
if ($user) {
return $user;
} else {
return null;
}
// depois
if (!$user) return null;
return $user;// antes
function add($a, $b) {
return $a + $b;
}
// depois
function add(int $a, int $b): int {
return $a + $b;
}- ❌ Không để
var_dump,print_r,echotrong code. - ✅ Dùng
Log::debug(),Log::info(),Log::error().
// antes
print_r($data);
// depois
Log::debug('User data', $data);- Tên biến phải rõ nghĩa, có đơn vị nếu cần (
$priceUsd,$durationMinutes). - Comment giải thích WHY chứ không phải WHAT.
- Không viết tắt khó hiểu (
$cnt,$tmp).
- Sử dụng
isset()nhanh hơnarray_key_exists()trong nhiều trường hợp. - Dùng
count($arr)một lần, không gọi nhiều lần trong loop. - Cache kết quả query nếu dữ liệu không thay đổi thường xuyên.
- Dùng
foreachthay vìforkhi không cần index để code gọn hơn. - Prefetch/Chunk dữ liệu lớn thay vì load tất cả vào memory.
Dán trực tiếp vào PR comment để check nhanh:
- Código seguro contra valores nulos, sem falhas com entradas vazias/nulas
- Validação correta de tipo/formato para entradas (GET/POST)
- Sem SQL injection (sempre usar parâmetros vinculados)
- Sem valores fixos/mágicos no código
- Sem queries aninhadas dentro de loops (evitar N+1 query)
- Exceções são registradas e tratadas (não ignorar erros)
- Sem var_dump, print_r, echo para debug
- Nomes de variáveis/funções claros e seguindo convenções
- Sem código redundante ou comentado
- Funções curtas, testáveis, com responsabilidade única
- Evitar SELECT * — selecionar apenas os campos necessários
- Sem lógica duplicada (refatorar para helpers quando possível)
- Com testes unitários ou casos de teste para lógica importante
- Performance adequada (loops curtos, queries otimizadas, sem carregamento excessivo de dados)
- Segurança garantida (escape de saída, sem log de dados sensíveis)
Khi review code:
- Refatore para que o código seja conciso, legível e sem repetições.
- Priorize: segurança contra valores nulos, validação, segurança em queries, tratamento de exceções e performance. Pense sempre:
- "Se a entrada estiver errada, o fluxo falhar ou a query der erro... o que acontece?"