array_intersect_ukey(): Lọc Mảng PHP Với Logic Key Tùy Chỉnh
Thư Viện Hàm PHP: Tra Cứu Toàn Diện Theo Chức Năng

array_intersect_ukey(): Lọc Mảng PHP Với Logic Key Tùy Chỉnh

<?xml encoding="utf-8" ?>

Trong lập trình PHP, việc lọc một mảng dựa trên các key của một mảng khác là một tác vụ cực kỳ phổ biến. Chúng ta thường nghĩ ngay đến array_intersect_key(). Nó nhanh, hiệu quả và hoạt động hoàn hảo… miễn là các key của bạn trùng khớp một cách chính xác.

Nhưng thực tế không phải lúc nào cũng lý tưởng. Điều gì sẽ xảy ra nếu bạn cần lọc dữ liệu từ một mảng có key'UserID' dựa trên một mảng khác có key'user_id'? Hoặc key có các tiền tố khác nhau như 'prod_123''product-123'? array_intersect_key() sẽ "bó tay" trong những trường hợp này.

Đây chính là lúc "người hùng thầm lặng" array_intersect_ukey() xuất hiện. Hàm này trao cho bạn toàn quyền kiểm soát logic so sánh key, cho phép bạn giải quyết những bài toán phức tạp một cách thanh lịch.


array_intersect_ukey() là gì?

Hãy cùng phân tích tên của hàm để hiểu rõ bản chất của nó:

  • array_intersect: Tìm phần giao nhau, tức là các phần tử chung.
  • u: Viết tắt của "user-defined". Báo hiệu rằng sẽ có một hàm callback do người dùng định nghĩa.
  • key: Nhấn mạnh rằng phép toán này chỉ dựa trên key của mảng.

Tổng hợp lại, array_intersect_ukey() là hàm trả về một mảng chứa tất cả các phần tử của mảng đầu tiên mà key của chúng được xem là tồn tại trong tất cả các mảng còn lại. Việc hai key có "tồn tại" hay "trùng khớp" hay không được quyết định bởi một hàm so sánh callback do người dùng cung cấp.

Điểm cốt lõi cần nhớ:

  • chỉ quan tâm đến key.
  • Các value hoàn toàn bị bỏ qua trong quá trình so sánh.
  • Các cặp key => value trong kết quả được lấy từ mảng đầu tiên.

Cú pháp của hàm

Cú pháp của hàm array_intersect_ukey() như sau:

array_intersect_ukey(array $array1, array $array2, ..., callable $key_compare_func): array

Trong đó:

  • $array1: Mảng nguồn, kết quả sẽ chứa các phần tử từ mảng này.
  • $array2: Mảng thứ hai dùng để so sánh key.
  • ...: (Tùy chọn) Các mảng tiếp theo để so sánh.
  • $key_compare_func: Một hàm callback mà bạn viết để định nghĩa logic so sánh hai key. Hàm này nhận hai key làm tham số và phải trả về một số nguyên theo quy ước:
    • Trả về 0 nếu hai key bằng nhau.
    • Trả về số nguyên < 0 nếu key1 nhỏ hơn key2.
    • Trả về số nguyên > 0 nếu key1 lớn hơn key2.

Hàm strcmp()strcasecmp() tích hợp sẵn trong PHP là những ví dụ hoàn hảo tuân thủ quy tắc này.


Ví dụ điển hình: So sánh Key không phân biệt chữ hoa

Đây là cách sử dụng array_intersect_ukey() phổ biến và dễ hình dung nhất.

<?php
// Dữ liệu cấu hình mặc định
$default_config = [
    'Host' => 'localhost',
    'Username' => 'root',
    'Password' => 'default_pass',
    'Port' => 3306
];

// Cấu hình do người dùng cung cấp, không nhất quán về viết hoa
$user_config = [
    'host' => '127.0.0.1',
    'password' => 'user_secret_123'
];

// Lọc ra các cấu hình mặc định mà người dùng đã cung cấp (ghi đè)
// Chúng ta muốn 'Host' và 'host' được coi là một
$overridden_keys = array_intersect_ukey($default_config, $user_config, 'strcasecmp');

print_r($overridden_keys);
?>

Kết quả:

Array
(
    [Host] => localhost
    [Password] => default_pass
)

Phân tích kết quả:

  • Hàm đã dùng strcasecmp để so sánh các key từ $default_config với các key từ $user_config.
  • strcasecmp('Host', 'host') trả về 0 (bằng nhau). Vì vậy, key 'Host' được giữ lại.
  • strcasecmp('Password', 'password') trả về 0 (bằng nhau). Vì vậy, key 'Password' được giữ lại.
  • key 'Username' và 'Port' không tìm thấy key tương ứng trong $user_config nên bị loại bỏ.
  • Quan trọng: Các value được trả về ('localhost', 'default_pass') được lấy từ mảng đầu tiên là $default_config. Các value trong $user_config hoàn toàn không ảnh hưởng đến kết quả, chúng chỉ dùng để cung cấp key cho việc so sánh.

Ví dụ thực tế nâng cao: So sánh Key có định dạng khác nhau

Đây là lúc sức mạnh thực sự của array_intersect_ukey() được thể hiện. Hãy tưởng tượng bạn cần khớp dữ liệu sản phẩm từ hai hệ thống khác nhau, nơi ID sản phẩm được định dạng khác nhau.

<?php
// Dữ liệu sản phẩm từ hệ thống kho
$warehouse_stock = [
    'SKU-001' => 150,
    'SKU-002' => 80,
    'SKU-005' => 200
];

// Dữ liệu sản phẩm từ hệ thống bán hàng online
$online_sales_data = [
    'product_id_1' => ['name' => 'Laptop ABC', 'sales' => 30],
    'product_id_3' => ['name' => 'Bàn phím cơ', 'sales' => 15],
    'product_id_5' => ['name' => 'Màn hình 24 inch', 'sales' => 55]
];

// Hàm callback tùy chỉnh để so sánh key
// Logic: chỉ lấy phần số ở cuối mỗi key và so sánh chúng
$key_compare_logic = function ($key1, $key2) {
    // Loại bỏ mọi ký tự không phải là số
    $num1 = (int) preg_replace('/[^0-9]/', '', $key1);
    $num2 = (int) preg_replace('/[^0-9]/', '', $key2);

    // Sử dụng toán tử <=> (spaceship operator, có từ PHP 7)
    // để trả về -1, 0, hoặc 1.
    return $num1 <=> $num2;
};

// Tìm các sản phẩm trong kho có dữ liệu bán hàng online
$stock_with_sales = array_intersect_ukey($warehouse_stock, $online_sales_data, $key_compare_logic);

print_r($stock_with_sales);
?>

Kết quả:

Array
(
    [SKU-001] => 150
    [SKU-005] => 200
)

Trong ví dụ này, hàm callback của chúng ta đã "thông minh" hơn. Nó hiểu rằng 'SKU-001''product_id_1' đều nói về sản phẩm có ID là 1, và do đó coi chúng là trùng khớp. Đây là điều mà không một hàm array_intersect tiêu chuẩn nào có thể làm được.


So sánh array_intersect_ukey() và các hàm "anh em"

Để tránh nhầm lẫn, hãy đặt array_intersect_ukey() bên cạnh các hàm liên quan khác trong một bảng so sánh.

Hàm So sánh dựa trên Logic so sánh Mục đích chính
array_intersect_key() Chỉ Key So sánh bằng nghiêm ngặt (===) Tìm key trùng khớp chính xác.
array_intersect_ukey() Chỉ Key Dùng hàm callback Tìm key trùng khớp theo logic tùy chỉnh.
array_intersect_assoc() Cả Key và Value So sánh bằng (== cho value, === cho key) Tìm cặp key => value trùng khớp chính xác.
array_intersect_uassoc() Cả Key và Value So sánh bằng (==) cho value, callback cho key Tìm value trùng khớp và key trùng khớp theo logic tùy chỉnh.

Bảng này cho thấy rõ vị trí độc đáo của array_intersect_ukey(): nó là phiên bản nâng cấp, linh hoạt của array_intersect_key() khi bạn cần quyền kiểm soát việc so sánh key.


Lịch sử và tính tương thích qua các phiên bản PHP

array_intersect_ukey() là một hàm đã được kiểm chứng qua thời gian. Nó được giới thiệu trong PHP 5.1.0, có nghĩa là nó đã tồn tại và hoạt động ổn định trong một thời gian rất dài.

Phiên bản PHP Trạng thái Ghi chú chi tiết
5.2 ✅ Còn sử dụng Ra mắt từ PHP 5.1.0, tương thích hoàn toàn.
5.3 ✅ Còn sử dụng Hỗ trợ hàm ẩn danh (anonymous functions) cho callback.
5.4 - 5.6 ✅ Còn sử dụng Hoạt động ổn định.
7.0 - 7.4 ✅ Còn sử dụng Có thể dùng toán tử spaceship (<=>) trong callback cho code ngắn gọn hơn.
8.0 - 8.3 ✅ Còn sử dụng Hoàn toàn tương thích và tiếp tục được hỗ trợ.

Bạn có thể tự tin sử dụng hàm này trong mọi dự án mà không cần lo lắng về các vấn đề tương thích. Tham khảo thêm tại trang tài liệu chính thức của PHP.


Kết luận

array_intersect_ukey() là một công cụ chuyên dụng nhưng vô cùng mạnh mẽ trong kho vũ khí xử lý mảng của lập trình viên PHP. Nó giải quyết một cách triệt để bài toán lọc mảng theo key khi các quy tắc so sánh đơn giản không còn đáp ứng được.

Tóm tắt các điểm chính:

  • Chuyên môn: Lọc mảng chỉ dựa trên key.
  • Sức mạnh: Sử dụng một hàm callback để bạn tự định nghĩa thế nào là hai key "trùng khớp".
  • Ứng dụng: Lý tưởng cho việc xử lý dữ liệu từ các nguồn không đồng nhất, nơi định dạng key có thể khác nhau (viết hoa, tiền tố, v.v.).

Lần tới, khi bạn thấy mình đang phải viết một vòng lặp foreach lồng nhau chỉ để so sánh các key theo một logic phức tạp, hãy dừng lại và nhớ đến array_intersect_ukey(). Nó sẽ giúp code của bạn không chỉ ngắn gọn hơn mà còn rõ ràng và dễ hiểu hơn rất nhiều.

Kelvin Zeng

Senior Website Developer

👨‍💻 Senior PHP Developer, hiện đảm nhận vai trò Techlead. Tôi có kinh nghiệm làm việc trong môi trường công ty Nhật Bản, từng tham gia thiết kế tài liệu kỹ thuật (Basic Design, Detail Design) và lập kế hoạch dự án với vai trò như một Project Lead. Trong sự nghiệp, tôi đã tham gia xây dựng và triển khai nhiều hệ thống E-commerce cũng như làm việc với nhiều framework khác nhau. Ngoài lập trình, tôi quan tâm đến SEO, automation và marketing, đặc biệt yêu thích việc phát triển các công cụ giúp tối ưu công việc. Tôi luôn sẵn sàng chia sẻ kiến thức, đồng hành cùng đồng đội để nâng cao chuyên môn và đạt được những mục tiêu lớn hơn.