PHP TUTORIALS
Hướng dẫn tạo domain ảo tại localhost với XAMPP trên Window Có gì mới trong PHP 8 (Tính năng, Cải tiến và Trình biên dịch JIT) Hướng dẫn viết ứng dụng kiểm tra năm sinh theo âm lịch bằng PHP Xử lý realtime trong PHP sử dụng pusher Hướng dẫn gửi mail trong PHP với PHPMailer Bóc tách dữ liệu từ trang khác bằng PHP Simple HTML DOM Parser Cách sửa lỗi hình ảnh khi đăng bài viết lên Facebook Hướng dẫn tạo thông báo realtime với pushcrew Kích thước chuẩn và cách làm FavIcon icon Tìm hiểu bản chất vòng lặp foreach trong php Những vấn đề nâng cao kỹ năng lập trình trong php Sử Dụng Vòng Lặp Xuất Dữ Liệu Bảng Tính Lương Tìm hiểu thuật toán phân trang trong php Giới hạn số trang trong thuật toán phân trang Bài 01: Đệ quy menu đa cấp với php và mysql - phần 1 Bài 02: Đệ quy menu đa cấp với php và mysql - phần 2 Tích hợp bộ search google vào website Nên dùng count() hay sizeof() để đếm số phần tử của mảng Bài 01: Lấy dữ liệu từ mysql lưu vào file excel với PHPExcel Tạo slug tự động bằng JavaScript và PHP RSS là gì? Cách Tạo RSS cho Website PHP CMS là gì? Các CMS phổ biến hiện nay (update 2024) Web động là gì? Web tĩnh là gì? Chặn referrer từ website simple-share-buttons.com Bảng mã ASCII chuẩn các hệ nhị phân - thập phân - thập lục phân Hướng dẫn tạo Facebook App để lấy App ID và Secret Key Download Facebook SDK cho PHP Mối liên hệ giữa HTML - PHP - MYSQL Tự động post bài viết lên tường với hootsuite.com Kiểm tra người dùng đã đăng nhập hay chưa bằng PHP Lấy video kênh Youtube mới nhất bằng jQuery và Youtube API V3 Đệ quy chuyên mục đa cấp trong PHP toàn tập Font Awesome là gì? Cách sử dụng Font Awesome Tích hợp đăng nhập Google vào Website Thuật toán phân trang với PHP và MySQL Cài đặt LAMP trên Fedora
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

Tìm hiểu bản chất vòng lặp foreach trong php

Nhiều lập trình viên mới vào nghề hay thậm chí cả những lập trình viên chuyên nghiệp đều biết cách sử dụng vòng lặp foreach nhưng không thực sự hiểu sâu về nó, vì vậy họ rất bối rối khi gặp những câu hỏi hoc búa mà các nhà tuyển dụng phỏng vấn. Vì thế trong bài này tôi và các bạn lập trình viên sẽ cùng nhau thảo luận vấn đề này nhé. Nếu có gì sai các bạn góp ý để cùng nhau hiểu và nắm vững các cách sử dụng vòng lặp foreach trong php.

test php

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

Như các bạn đã biết ở mỗi vòng lặp foreach php sẽ tạo ra các bản sao để chúng ta lấy dữ liệu của phần tử đang lặp đó, bản sao này sẽ được loại bỏ ngay lập tức sau khi kết thúc vòng lặp. Và ở mỗi vòng lặp sẽ kiểm tra còn phần tử liền kề hay không? nếu còn thì vòng lặp được tiếp tục, ngược lại thì sẽ dừng. Ví dụ dưới đây là một cách sử dụng vòng lặp foreach trong php rất thông dụng:

$mang = array('Trường', 'Sa', 'Hoàng', 'Sa', 'Là', 'Của', 'Việt', 'Nam');
foreach ( $mang AS $item ) {
    echo $item.'<br/>';
}

Chạy lên kết quả sẽ là:

Bài viết này được đăng tại [free tuts .net]

Trường
Sa
Hoàng
Sa

Của
Việt
Nam

Các bạn thấy mặc dù các bản sao của biến $mang được tạo ra nhưng các nhà phát triển không nhận thấy, tại vì sau khi thực thi vòng lặp các bạn thử xem giá trị mảng hoàn toàn không bị thay đổi, các bạn xem lại ví dụ dưới đây:

$mang = array('Trường', 'Sa', 'Hoàng', 'Sa', 'Là', 'Của', 'Việt', 'Nam');
foreach ( $mang AS $item ) {
    $item = strtoupper($item);
}
echo '<pre>';
print_r($mang);

Kết quả sẽ là:

Array
(
    [0] => Trường
    [1] => Sa
    [2] => Hoàng
    [3] => Sa
    [4] => Là
    [5] => Của
    [6] => Việt
    [7] => Nam
)

Các bạn thấy, trong vòng lặp mình đã biến đổi giá trị của các phần tử sang chữ hoa, nhưng kết thúc vòng lặp mình in ra giá trị của mảng thì nó không hề thay đổi.

Vậy có cách nào để thay đổi giá trị của phẩn tử đang lặp thông qua biến copy $item? Nếu các bạn từng học C hay C++ thì các bạn sẽ biết đến con trỏ, con trỏ sẽ tham chiếu đến vị trí trong ô nhớ của biến nào đó. Nhưng trong PHP thì khái niệm con trỏ không có mà chúng ta sử dụng tham chiếu cũng y như con trỏ. Vì thế để thay đổi giá trị của phần tử hiện tại ta sẽ sử dụng tham chiếu để thay đổi địa chỉ trong ô nhớ của phần tử trong mảng, như vậy trình biên dịch sẽ tự hiểu chạy vào mảng gốc chứ không copy mảng mới. Các bạn xem ví dụ:

$mang = array('Trường', 'Sa', 'Hoàng', 'Sa', 'Là', 'Của', 'Việt', 'Nam');
foreach ( $mang AS &$item ) {
    $item = strtoupper($item);
}
echo '<pre>';
print_r($mang);

Kết quả:

Array
(
    [0] => TRườNG
    [1] => SA
    [2] => HOàNG
    [3] => SA
    [4] => Là
    [5] => CủA
    [6] => VIệT
    [7] => NAM
)

Các bạn thấy rõ ràng giá trị các phần tử của mảng đã bị thay đổi sang chữ in hoa sau khi vòng lặp foreach kết thúc. Như vậy ta có kết luận rằng khi bắt đầu vòng lặp foreach, PHP sẽ tạo ra một bảng sao của mảng để lặp nên khi chúng ta thay đổi hoàn toàn không ảnh hưởng, nhưng nếu chúng ta sử dụng tham chiếu để truy xuất đến mảng gốc thì sẽ không có vụ tạo mảng copy nên mọi thứ đều gọi tới mảng gốc, từ đó ta có thể thay đổi giá trị cho mảng gốc. Các bạn xem tiếp ví dụ dưới đây:

$mang = array('Trường', 'Sa', 'Hoàng', 'Sa', 'Là', 'Của', 'Việt', 'Nam');
foreach ( $mang AS $item ) {
   $mang[] = $item;
}
echo '<pre>';
print_r($mang);

Kết quả:

Trường Sa Hoàng Sa Là Của Việt Nam

Array
(
    [0] => Trường
    [1] => Sa
    [2] => Hoàng
    [3] => Sa
    [4] => Là
    [5] => Của
    [6] => Việt
    [7] => Nam
    [8] => Trường
    [9] => Sa
    [10] => Hoàng
    [11] => Sa
    [12] => Là
    [13] => Của
    [14] => Việt
    [15] => Nam
)

Các bạn thấy trong mỗi vòng lặp ta đã gán thêm một phẩn tử vào mảng thì đáng lẽ ra vòng lặp sẽ dẫn đến lặp vô hạn. Nhưng không, tại vì trong vòng lặp đang lặp mảng copy của mảng gốc, vì thế khi ta thay đổi mảng gốc thì không ảnh hưởng gì, và sau khi vòng lặp kết thúc mảng copy sẽ được xóa và mảng gốc đã bị thay đổi.

Bây giờ giả sử tôi sử dụng tham chiếu các phần tử trong mỗi lần lặp xem thế nào?

$mang = array('Trường', 'Sa', 'Hoàng', 'Sa', 'Là', 'Của', 'Việt', 'Nam');
foreach ( $mang AS &$item ) {
   $mang[] = $item;
   echo $item . ' ';
}
echo '<pre>';
print_r($mang);

Chạy lên các bạn sẽ thấy rõ ràng vòng lặp foreach bị lặp vô hạn. Tại sao vậy? Tại vì mảng copy KHÔNG được tạo ra, vì vậy nó sẽ sử dụng đến mảng gốc và sau mỗi vòng lặp mảng gốc sẽ thêm một phần tử, ở cuối mỗi vòng lặp foreach sẽ kiểm tra còn phần tử liền kề hay không để tiếp tục lặp, rõ ràng ta đang truy xuất đến mảng gốc nên phần tử liền kề luôn luôn tồn tại. Nhưng giả sử mảng chỉ có một phần tử thì sao? Các bạn xem ví dụ:

$mang = array('Trường');
foreach ( $mang AS $key => &$item ) {
   $mang[] = $item;
   echo($item);
}

Chạy lên thì nó lại không lặp vô hạn. Tại vì theo như trên tôi trình bày trình biên dịch sẽ kiểm tra còn phần tử kế tiếp hay không, lúc này chỉ có 1 phần tử nên nó chạy luôn và sẽ ngưng. Tuy nhiên bạn vẫn có thể thay đổi giá trị cho mảng đó nhé vì ta đang tham chiếu mà.

Nhưng mọi chuyện không phải đơn giản như vậy, ta xét ví dụ tiếp theo sau đây:

$mang = array('Trường', 'Sa');
$a = &$mang;
foreach ( $mang AS $item ) {
   $mang[] = $item;
   echo($item);
}

Chạy lên vòng lặp foreach vẫn bị lặp vô hạn. Như vậy nếu mảng bị tham chiếu ở ngoài vòng lặp thì bản thân nó vẫn bị lặp vô hạn. Trường hợp này tôi không thể giải thích một cách chính xác, nhưng tôi nghĩ lý do là do lúc ta tham chiếu thế này thì ta đã có 2 biến tham chiếu đến vị trí ô nhớ đó nên trình biên dịch sẽ không copy mà chạy thẳng vào mảng gốc. Vì thế dẫn đến vô hạn.

Xét ví dụ tiếp theo:

$mang = array('Trường', 'Sa', 'Hoàng', 'Sa', 'Là', 'Của', 'Việt', 'Nam');
$a = &$mang;
foreach ( $mang AS $item ) {
    $item = strtoupper($item);
}
echo '<pre>';
print_r($mang);

kết quả sẽ là:

Array
(
    [0] => Trường
    [1] => Sa
    [2] => Hoàng
    [3] => Sa
    [4] => Là
    [5] => Của
    [6] => Việt
    [7] => Nam
)

Các bạn thấy trong vòng lặp tôi đã thay đổi giá trị của các phần tử sang in hoa nhưng kết thúc vòng lặp mảng lại không bị ảnh hưởng.

Lời Kết:

Trong bài này tôi chỉ đưa ra những vấn đề về vòng lặp foreach với hy vọng nhận được các ý kiến đóng góp của các lập trình viên chuyên nghiệp để bài viết được hoàn hảo hơn. Lời cuối cùng xin cám ơn các bạn đã dành thời gian đọc bài này.

P/s: Mình có một serie php căn bản bạn có hứng thú thì vào đọc bài nhé.

Cùng chuyên mục:

Hàm key_exists() trong PHP

Hàm key_exists() trong PHP

Cách sử dụng key_exists() trong PHP

Hàm mysqli_fetch_row() trong PHP

Hàm mysqli_fetch_row() trong PHP

Cách sử dụng mysqli_fetch_row() trong PHP

Hàm end() trong PHP

Hàm end() trong PHP

Cách sử dụng end() trong PHP

Hàm mysqli_field_count() trong PHP

Hàm mysqli_field_count() trong PHP

Cách sử dụng mysqli_field_count() trong PHP

Hàm count() trong PHP

Hàm count() trong PHP

Cách sử dụng count() trong PHP

Hàm mysqli_field_seek() trong PHP

Hàm mysqli_field_seek() trong PHP

Cách sử dụng mysqli_field_seek() trong PHP

Hàm compact() trong PHP

Hàm compact() trong PHP

Cách sử dụng compact() trong PHP

Hàm mysqli_field_tell() trong PHP

Hàm mysqli_field_tell() trong PHP

Cách sử dụng mysqli_field_tell() trong PHP

Hàm array_values() trong PHP

Hàm array_values() trong PHP

Cách sử dụng array_values() trong PHP

Hàm mysqli_free_result() trong PHP

Hàm mysqli_free_result() trong PHP

Cách sử dụng mysqli_free_result() trong PHP

Hàm array_unshift() trong PHP

Hàm array_unshift() trong PHP

Cách sử dụng array_unshift() trong PHP

Hàm mysqli_get_charset() trong PHP

Hàm mysqli_get_charset() trong PHP

Cách sử dụng mysqli_get_charset() trong PHP

Hàm array_shift() trong PHP

Hàm array_shift() trong PHP

Cách sử dụng array_shift() trong PHP

Hàm mysqli_get_client_stats() trong PHP

Hàm mysqli_get_client_stats() trong PHP

Cách sử dụng mysqli_get_client_stats() trong PHP

Hàm array_unique() trong PHP

Hàm array_unique() trong PHP

Cách sử dụng array_unique() trong PHP

Hàm mysqli_get_client_version() trong PHP

Hàm mysqli_get_client_version() trong PHP

Cách sử dụng mysqli_get_client_version() trong PHP

Hàm array_uintesect() trong PHP

Hàm array_uintesect() trong PHP

Cách sử dụng array_uintesect() trong PHP

Hàm mysqli_get_connection_stats() trong PHP

Hàm mysqli_get_connection_stats() trong PHP

Cách sử dụng mysqli_get_connection_stats() trong PHP

Hàm array_sum() trong PHP

Hàm array_sum() trong PHP

Cách sử dụng array_sum() trong PHP

Hàm mysqli_get_host_info() trong PHP

Hàm mysqli_get_host_info() trong PHP

Cách sử dụng mysqli_get_host_info() trong PHP

Top