
array_filter() trong PHP: Lọc Dữ Liệu Mảng Linh Hoạt Với Hàm Callback!
Mục lục
Bạn đang có một mảng chứa đầy dữ liệu, nhưng bạn chỉ muốn giữ lại những phần tử thỏa mãn một điều kiện cụ thể nào đó? Ví dụ, bạn có danh sách người dùng và chỉ muốn hiển thị những người dùng đang "hoạt động" hoặc những người dùng có "tuổi trên 18". Hoặc bạn có một mảng các số và muốn lọc ra chỉ những số chẵn.
Việc lọc dữ liệu là một tác vụ cực kỳ phổ biến trong lập trình, và nếu phải tự viết vòng lặp foreach
kết hợp với if
để thực hiện điều này, code của bạn sẽ trở nên dài dòng và kém linh hoạt khi điều kiện lọc thay đổi. May mắn thay, PHP cung cấp một hàm sinh ra để làm chính xác công việc này một cách thanh lịch và hiệu quả: array_filter()
!
Trong series "Tìm hiểu các function trong PHP" hôm nay, chúng ta sẽ đi sâu vào array_filter()
– một hàm mạnh mẽ cho phép bạn lọc các phần tử của mảng dựa trên một hàm so sánh tùy chỉnh (callback function). Dù bạn là người mới bắt đầu hay một lập trình viên PHP lâu năm, bài viết này sẽ cung cấp cho bạn cái nhìn toàn diện về cách sử dụng, ứng dụng thực tế và lịch sử phát triển của hàm này.
Trong phát triển phần mềm, việc xử lý và tinh gọn dữ liệu là yếu tố then chốt để xây dựng các ứng dụng hiệu suất cao. Theo các thống kê về việc sử dụng các hàm mảng, các hàm có khả năng sử dụng callback như array_filter()
được đánh giá cao vì tính linh hoạt và khả năng tái sử dụng code. Điều này giúp lập trình viên giảm thiểu việc viết các vòng lặp thủ công, từ đó tối ưu hóa thời gian phát triển và duy trì code.
I. Tại Sao Cần Lọc Dữ Liệu Mảng?
Nhu cầu lọc dữ liệu trong mảng phát sinh trong vô số tình huống:
- Hiển thị dữ liệu có điều kiện: Chỉ hiển thị các sản phẩm "còn hàng", các đơn hàng "chưa xử lý", hoặc các bài viết "đã xuất bản".
- Xác thực và làm sạch dữ liệu: Loại bỏ các phần tử rỗng,
null
, hoặc không hợp lệ khỏi mảng trước khi xử lý. - Phân nhóm dữ liệu: Chia một mảng lớn thành các nhóm nhỏ hơn dựa trên các tiêu chí khác nhau.
- Tìm kiếm nâng cao: Tìm kiếm các phần tử thỏa mãn một tập hợp các điều kiện phức tạp.
- Tối ưu hóa bộ nhớ: Giảm kích thước của mảng bằng cách loại bỏ các phần tử không cần thiết, giúp tiết kiệm bộ nhớ, đặc biệt khi làm việc với các tập dữ liệu lớn.
Nếu không có array_filter()
, bạn sẽ phải tạo một mảng rỗng mới, sau đó duyệt qua mảng gốc bằng foreach
, kiểm tra từng phần tử bằng if
, và chỉ thêm vào mảng mới nếu thỏa mãn điều kiện. Điều này không chỉ dài dòng mà còn kém linh hoạt khi điều kiện lọc thay đổi.
II. array_filter()
Là Gì?
Hàm array_filter()
là một hàm dựng sẵn trong PHP, được sử dụng để lọc các phần tử của một mảng bằng cách lặp qua từng giá trị của mảng đó và truyền chúng vào một hàm callback do người dùng định nghĩa. Hàm này trả về một mảng mới chỉ chứa các phần tử mà hàm callback trả về true
(hoặc một giá trị được coi là true
trong ngữ cảnh boolean).
2.1 Cú Pháp Hàm array_filter()
Cú pháp của hàm như sau:
array_filter(array $array, ?callable $callback = null, int $mode = 0): array
Trong đó:
$array
: (Bắt buộc) Mảng đầu vào mà bạn muốn lọc.$callback
: (Tùy chọn) Một hàm callback do người dùng định nghĩa.- Nếu được cung cấp, hàm này sẽ được gọi cho từng giá trị trong
$array
. - Nó sẽ nhận một hoặc nhiều đối số tùy thuộc vào
$mode
. - Nếu hàm callback trả về
true
(hoặc một giá trị được coi làtrue
), phần tử đó sẽ được giữ lại trong mảng kết quả. Ngược lại, nó sẽ bị loại bỏ. - Nếu
$callback
không được cung cấp (hoặc lànull
),array_filter()
sẽ loại bỏ tất cả các phần tử có giá trị được coi làempty()
(tương đươngfalse
,0
,""
,null
, v.v.). Đây là hành vi mặc định.
- Nếu được cung cấp, hàm này sẽ được gọi cho từng giá trị trong
$mode
: (Tùy chọn) Một hằng số xác định các đối số được truyền cho$callback
. Có ba giá trị khả thi:0
hoặcARRAY_FILTER_USE_VALUE
(Mặc định): Hàm callback sẽ nhận giá trị của phần tử làm đối số duy nhất.ARRAY_FILTER_USE_KEY
: Hàm callback sẽ nhận khóa của phần tử làm đối số duy nhất.ARRAY_USE_BOTH
: Hàm callback sẽ nhận cả giá trị và khóa của phần tử làm hai đối số (giá trị trước, khóa sau).
Giá trị trả về:
- Một mảng mới chứa các phần tử đã được lọc. Các khóa của mảng gốc được bảo toàn.
2.2 Ví Dụ Cơ Bản
Hãy cùng xem các ví dụ cụ thể để hiểu rõ hơn:
Ví dụ 1: Lọc bỏ các giá trị "rỗng" (Hành vi mặc định)
<?php
$data = [0, 1, "hello", "", false, null, "world", [], "0"];
echo "--- Mảng gốc ---\n";
print_r($data);
// Lọc bỏ các giá trị rỗng (callback là null)
$filteredData = array_filter($data);
echo "\n--- Mảng sau khi lọc bỏ giá trị rỗng (mặc định) ---\n";
print_r($filteredData);
/* Output:
Array
(
[1] => 1
[2] => hello
[6] => world
)
*/
// Lưu ý: 0, "", false, null, [], "0" đều được coi là rỗng và bị loại bỏ.
?>
Ví dụ 2: Lọc các số chẵn (Sử dụng ARRAY_FILTER_USE_VALUE
)
<?php
$numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Lọc các số chẵn
$evenNumbers = array_filter($numbers, function($num) {
return $num % 2 == 0;
});
echo "\n--- Các số chẵn ---\n";
print_r($evenNumbers);
/* Output:
Array
(
[1] => 2
[3] => 4
[5] => 6
[7] => 8
[9] => 10
)
*/
// Các khóa gốc được bảo toàn.
?>
Ví dụ 3: Lọc các phần tử dựa trên khóa (Sử dụng ARRAY_FILTER_USE_KEY
)
<?php
$config = [
"db_host" => "localhost",
"db_user" => "root",
"db_pass" => "secret",
"debug_mode" => true,
"log_level" => "info"
];
// Giữ lại các cấu hình liên quan đến 'db_'
$dbConfig = array_filter($config, function($key) {
return str_starts_with($key, "db_"); // Từ PHP 8.0, hoặc dùng strpos($key, "db_") === 0
}, ARRAY_FILTER_USE_KEY);
echo "\n--- Các cấu hình cơ sở dữ liệu ---\n";
print_r($dbConfig);
/* Output:
Array
(
[db_host] => localhost
[db_user] => root
[db_pass] => secret
)
*/
?>
Ví dụ 4: Lọc dựa trên cả khóa và giá trị (Sử dụng ARRAY_USE_BOTH
)
<?php
$products = [
"P001" => ["name" => "Laptop", "price" => 1200, "stock" => 10],
"P002" => ["name" => "Mouse", "price" => 25, "stock" => 0],
"P003" => ["name" => "Keyboard", "price" => 150, "stock" => 5],
"P004" => ["name" => "Monitor", "price" => 300, "stock" => 20]
];
// Lọc các sản phẩm có sẵn trong kho (stock > 0) và giá trên 100
$availableHighValueProducts = array_filter($products, function($product, $sku) {
return $product['stock'] > 0 && $product['price'] > 100;
}, ARRAY_FILTER_USE_BOTH);
echo "\n--- Sản phẩm còn hàng và giá trị cao ---\n";
print_r($availableHighValueProducts);
/* Output:
Array
(
[P001] => Array
(
[name] => Laptop
[price] => 1200
[stock] => 10
)
[P003] => Array
(
[name] => Keyboard
[price] => 150
[stock] => 5
)
[P004] => Array
(
[name] => Monitor
[price] => 300
[stock] => 20
)
)
*/
?>
Đây là ví dụ điển hình về việc array_filter()
giải quyết các điều kiện lọc phức tạp một cách gọn gàng.
III. Ứng Dụng Thực Tế của array_filter()
array_filter()
là một trong những hàm xử lý mảng linh hoạt nhất của PHP, với vô số ứng dụng:
-
Làm sạch dữ liệu đầu vào: Loại bỏ các trường rỗng hoặc
null
từ dữ liệu form trước khi lưu vào database.<?php $formData = $_POST; // Giả sử nhận được từ POST $cleanedData = array_filter($formData); // Loại bỏ các trường rỗng mặc định print_r($cleanedData); ?>
-
Lọc danh sách người dùng theo trạng thái/quyền:
<?php $users = [ ["id" => 1, "name" => "Alice", "status" => "active", "role" => "admin"], ["id" => 2, "name" => "Bob", "status" => "inactive", "role" => "editor"], ["id" => 3, "name" => "Charlie", "status" => "active", "role" => "viewer"], ["id" => 4, "name" => "David", "status" => "pending", "role" => "guest"], ]; $activeUsers = array_filter($users, function($user) { return $user['status'] === 'active'; }); print_r($activeUsers); $adminUsers = array_filter($users, function($user) { return $user['role'] === 'admin'; }); print_r($adminUsers); ?>
-
Lọc các file theo phần mở rộng hoặc kích thước: Khi đọc danh sách file trong một thư mục, bạn có thể lọc chỉ những file
.txt
hoặc những file có kích thước lớn hơn một ngưỡng nào đó.<?php $files = ["document.pdf", "image.jpg", "report.txt", "notes.txt", "data.json"]; $textFiles = array_filter($files, function($file) { return str_ends_with($file, ".txt"); // Hoặc dùng pathinfo() }); print_r($textFiles); ?>
-
Tạo các tập con dữ liệu cho các báo cáo hoặc phân tích: Chỉ lấy những dữ liệu cần thiết cho một báo cáo cụ thể, giảm tải xử lý cho các bước tiếp theo.
IV. array_filter()
Qua Các Phiên Bản PHP
Hàm array_filter()
là một hàm mảng cơ bản và đã là một phần của PHP từ rất sớm (phiên bản PHP 4). Nó đã duy trì sự ổn định, không bị loại bỏ hay thay đổi cú pháp đáng kể qua các phiên bản. Các cải tiến chủ yếu liên quan đến hiệu suất tổng thể của PHP và các hàm callback trong PHP 7 và 8.
Dưới đây là bảng đối chiếu về trạng thái của array_filter()
qua các phiên bản PHP từ 5.2 đến 8.3:
| Phiên Bản PHP | Trạng Thái array_filter()
| Ghi Chú và Cải Tiến Liên Quan | | :------------ | :-------------------------- | :----------------------------- | | PHP 5.2 | Có sẵn | Đã hoạt động bình thường. | | PHP 5.3 | Có sẵn | Hỗ trợ thêm Anonymous Functions (closures) có thể dùng làm $callback
, giúp code gọn gàng hơn. | | PHP 5.4 | Có sẵn | Không có thay đổi cụ thể nào đối với hàm này, mặc dù cú pháp []
cho mảng được giới thiệu. | | PHP 5.5 | Có sẵn | Không có thay đổi cụ thể nào đối với hàm này. | | PHP 5.6 | Có sẵn | Không có thay đổi cụ thể nào đối với hàm này. | | PHP 7.0 | Có sẵn | Được hưởng lợi từ các cải tiến hiệu suất tổng thể của PHP 7.0, đặc biệt là về việc sử dụng bộ nhớ cho mảng và gọi hàm callback nhanh hơn. | | PHP 7.1 | Có sẵn | Không có thay đổi cụ thể nào đối với hàm này. | | PHP 7.2 | Có sẵn | Không có thay đổi cụ thể nào đối với hàm này. | | PHP 7.3 | Có sẵn | Không có thay đổi cụ thể nào đối với hàm này. | | PHP 7.4 | Có sẵn | Hỗ trợ Arrow Functions có thể được dùng làm $callback
với cú pháp ngắn gọn hơn, đặc biệt hữu ích cho các hàm callback đơn giản. | | PHP 8.0 | Có sẵn | Vẫn hoạt động bình thường và được hưởng lợi từ các tối ưu hóa của PHP 8, bao gồm JIT compiler. | | PHP 8.1 | Có sẵn | Không có thay đổi cụ thể nào đối với hàm này. | | PHP 8.2 | Có sẵn | Không có thay đổi cụ thể nào đối với hàm này. | | PHP 8.3 | Có sẵn | Không có thay đổi cụ thể nào đối với hàm này. |
Kết luận về các phiên bản: Hàm array_filter()
là một hàm cực kỳ ổn định và đã tồn tại trong PHP qua nhiều phiên bản mà không có bất kỳ thay đổi lớn nào về chức năng hoặc cú pháp. Sự phát triển của Anonymous Functions và Arrow Functions trong các phiên bản PHP sau này đã làm cho việc sử dụng array_filter()
trở nên tiện lợi và mạnh mẽ hơn bao giờ hết.
V. Lưu Ý Quan Trọng Khi Sử Dụng array_filter()
- Hàm callback: Nếu bạn không cung cấp callback, hàm sẽ loại bỏ các phần tử mà giá trị của chúng được coi là
empty()
. Hãy chắc chắn rằng bạn hiểu định nghĩa của "rỗng" trong PHP (False, 0, "", null, [], "0"). - Tham số
$mode
: Luôn nhớ sử dụng tham số$mode
(ARRAY_FILTER_USE_VALUE, ARRAY_FILTER_USE_KEY, ARRAY_USE_BOTH) để kiểm soát dữ liệu được truyền vào hàm callback. Nếu không, mặc định chỉ có giá trị được truyền. - Bảo toàn khóa:
array_filter()
bảo toàn các khóa của mảng gốc trong mảng kết quả. Nếu bạn cần các khóa được đánh số lại (re-indexed) từ 0, hãy sử dụngarray_values()
sau khi lọc.php $filteredAndReindexed = array_values(array_filter($data, $callback));
- Hiệu suất: Tương tự như các hàm mảng dựng sẵn khác của PHP,
array_filter()
được tối ưu hóa ở cấp độ ngôn ngữ (C) và thường nhanh hơn đáng kể so với việc bạn tự viết vòng lặpforeach
thủ công để thực hiện cùng một tác vụ, đặc biệt với các mảng lớn.
VI. Tối Ưu Hóa SEO cho Nội Dung Blog
Để bài viết này đạt hiệu quả SEO cao nhất, hãy đảm bảo các yếu tố sau:
- Sử dụng từ khóa chính và phụ một cách tự nhiên: Từ khóa như "array_filter PHP", "lọc mảng PHP", "hàm callback PHP", "loại bỏ phần tử mảng", "lọc dữ liệu mảng", "tùy chỉnh lọc mảng", "hàm mảng PHP" cần được phân bổ hợp lý trong tiêu đề, các heading, đoạn mở đầu, kết luận và xuyên suốt nội dung.
- Chất lượng nội dung là vua: Đảm bảo bài viết cung cấp thông tin chính xác, đầy đủ và dễ hiểu, giải quyết được vấn đề thực tế mà người đọc có thể gặp phải (như việc cần lọc dữ liệu theo điều kiện phức tạp).
- Cấu trúc Heading rõ ràng: Sử dụng
H1
,H2
,H3
một cách logic để chia nhỏ nội dung, giúp cả người đọc và công cụ tìm kiếm dễ dàng nắm bắt cấu trúc bài viết. - Ví dụ code minh họa: Các đoạn code cần được định dạng rõ ràng, dễ đọc và dễ sao chép, giúp người đọc dễ dàng thử nghiệm.
- Liên kết nội bộ (Internal Linking): Đặt các liên kết đến các bài viết khác trong series "Tìm hiểu các function trong PHP" (ví dụ:
array()
,array_chunk()
,array_column()
,array_fill()
,array_fill_keys()
) để khuyến khích người đọc khám phá thêm nội dung trên blog của bạn. - Liên kết ngoài (External Linking): Tham chiếu đến các nguồn uy tín như tài liệu PHP chính thức (php.net) để tăng tính xác thực và cung cấp thêm thông tin cho độc giả.
Tham khảo thêm:
- Tài liệu chính thức về
array_filter()
: https://www.php.net/manual/en/function.array-filter.php - W3Schools về
array_filter()
: https://www.w3schools.com/php/func_array_filter.asp - Tìm hiểu về hàm
empty()
trong PHP: https://www.php.net/manual/en/function.empty.php
VII. Kết Luận
array_filter()
là một hàm cực kỳ mạnh mẽ và linh hoạt, cho phép bạn lọc dữ liệu mảng dựa trên các điều kiện tùy chỉnh một cách hiệu quả và gọn gàng. Khả năng sử dụng hàm callback và các chế độ lọc khác nhau biến nó thành một công cụ không thể thiếu trong bộ công cụ của lập trình viên PHP, giúp bạn dễ dàng làm sạch, tinh gọn và trích xuất thông tin có giá trị từ dữ liệu của mình.
Bằng cách tận dụng array_filter()
, bạn sẽ viết code sạch hơn, dễ đọc hơn và quan trọng nhất là hiệu quả hơn. Hãy luôn ghi nhớ các tham số và hành vi của nó để áp dụng một cách chính xác nhất trong các dự án của bạn!
Bạn đã từng sử dụng array_filter()
để giải quyết những vấn đề phức tạp nào trong dự án của mình? Hãy chia sẻ những kinh nghiệm hoặc mẹo hay của bạn ở phần bình luận bên dưới nhé!
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.