Bạn lưu dữ liệu theo ID trong khóa mảng, gộp thêm một nhóm dữ liệu rồi phát hiện các khóa 101 và 205 biến thành 0 và 1. Đây có thể là hành vi đúng của hàm đã chọn, không phải PHP làm mất dữ liệu ngẫu nhiên. Trước khi gộp mảng, hãy xác định khóa là vị trí trong danh sách hay danh tính của bản ghi.
1. Khóa số không được xử lý giống khóa chuỗi
Tài liệu array_merge quy định các phần tử có khóa số được nối và đánh lại chỉ số từ 0; với khóa chuỗi trùng nhau, giá trị ở mảng phía sau thắng. Vì vậy, cùng một hàm nhưng kết quả phụ thuộc loại khóa.
$base = [101 => 'Draft', 205 => 'Review'];
$incoming = [205 => 'Approved', 309 => 'New'];
$merged = array_merge($base, $incoming);
// [0 => 'Draft', 1 => 'Review',
// 2 => 'Approved', 3 => 'New']
Nếu đây là danh sách nhãn, việc nối có thể hợp lý. Nếu khóa là ID công việc, cấu trúc mới không còn ánh xạ ID ban đầu. Đừng chỉ kiểm tra số lượng phần tử hoặc các giá trị rồi kết luận đã gộp đúng.
2. Thay thế theo khóa bằng array_replace
Theo tài liệu array_replace, hàm tạo mảng kết quả theo khóa, giá trị ở mảng phía sau ghi đè khi trùng khóa. Khóa mới cũng được đưa vào kết quả.
$base = [101 => 'Draft', 205 => 'Review'];
$incoming = [205 => 'Approved', 309 => 'New'];
$updated = array_replace($base, $incoming);
// [101 => 'Draft', 205 => 'Approved', 309 => 'New']
// $base van giu nguyen.
Ở đây, ID 205 được cập nhật, ID 101 được giữ và ID 309 được thêm. Đây là chính sách “mảng sau thắng”, không phải cơ chế phát hiện xung đột. Nếu hai nguồn không được phép ghi đè lẫn nhau, phải kiểm tra khóa trùng trước khi tạo kết quả.
3. Với khóa chuỗi, vẫn phải đọc thứ tự ưu tiên
$defaults = ['theme' => 'light', 'page_size' => 20];
$overrides = ['theme' => 'dark'];
$settings = array_replace($defaults, $overrides);
// ['theme' => 'dark', 'page_size' => 20]
Trong ví dụ toàn khóa chuỗi này, array_merge cũng cho cùng giá trị kết quả. Nhưng không nên suy ra hai hàm thay thế được cho nhau khi dữ liệu đổi sang khóa số. Đặt tên biến defaults và overrides để người đọc hiểu chiều ghi đè, đồng thời viết test giữ nguyên giá trị mặc định khi không có override.
4. Ghi đè cấp ngoài không phải gộp sâu
$defaults = [
'display' => ['theme' => 'light', 'density' => 'normal'],
];
$overrides = [
'display' => ['theme' => 'dark'],
];
$settings = array_replace($defaults, $overrides);
// ['display' => ['theme' => 'dark']]
Khóa display được thay bằng toàn bộ giá trị mới, nên density không còn trong kết quả. Nếu muốn giữ density, cần quyết định cách gộp ở cấp display. Không đổi sang một hàm đệ quy chỉ vì tên có chữ recursive: danh sách, bản đồ và giá trị null có thể cần những chính sách khác nhau.
Với cấu hình nhỏ có schema cố định, gộp tường minh từng nhóm sau validation thường dễ review hơn một cơ chế gộp sâu dùng cho mọi trường hợp. Viết rõ null nghĩa là xóa, không thiết lập hay một giá trị hợp lệ.
5. Gộp dữ liệu không thay thế validation
Không truyền nguyên request của người dùng vào mảng cấu hình nội bộ. Chọn các trường được phép, kiểm tra kiểu và miền giá trị rồi mới gộp. Ví dụ tùy chọn hiển thị không nên cho phép ghi đè quyền truy cập, đường dẫn lưu trữ hay cấu hình kết nối.
Các đoạn mã trong bài chỉ thao tác trên mảng trong bộ nhớ. Chúng không tự ghi database, không kiểm tra phân quyền và không xử lý cập nhật đồng thời. Nếu dữ liệu gắn với bản ghi thật, cần giữ các bước bảo vệ đó ở tầng ứng dụng.
6. Checklist kiểm thử
- Khóa số không liên tiếp: có còn đúng ID sau gộp không?
- Khóa trùng: nguồn nào được phép thắng?
- Khóa mới: có được thêm hay phải từ chối?
- Mảng lồng: thay toàn bộ hay gộp từng trường?
- Giá trị null và mảng rỗng: có ý nghĩa gì trong hợp đồng?
- Mảng đầu vào: có giữ nguyên như dự kiến không?
Kết luận: Chọn hàm theo ý nghĩa của khóa. Nối một danh sách và cập nhật bản đồ theo ID là hai thao tác khác nhau; kiểm tra cả khóa lẫn giá trị giúp tránh lỗi âm thầm sau khi gộp.




Chưa có bình luận. Hãy là người đầu tiên chia sẻ ý kiến.