PHP cho phép bạn tạo các đối tượng có thể lặp lại. Chúng có thể được sử dụng trong vòng lặp thay vì mảng vô hướng. Iterables thường được sử dụng làm bộ sưu tập đối tượng. Chúng cho phép bạn đánh máy đối tượng đó trong khi vẫn duy trì hỗ trợ cho vòng lặp
Lặp lại đơn giản
Để lặp lại một mảng trong PHP, bạn sử dụng vòng lặp
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }0
foreach [["1", "2", "3"] as $i] { echo [$i . " "]; }
Ví dụ này sẽ phát ra
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }1
Bạn cũng có thể lặp lại một đối tượng
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }
Ví dụ này sẽ phát ra
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }2
Vấn đề thu thập
Đối với các lớp cơ bản có thuộc tính công khai, một
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }0 đơn giản hoạt động tốt. Bây giờ hãy xem xét một lớp khác
class UserCollection { protected array $items = []; public function add[UserDomain $user] : void { $this -> items[] = $user; } public function containsAnAdmin[] : bool { return [count[array_filter[ $this -> items, fn [UserDomain $i] : bool => $i -> isAdmin[] ]] > 0]; } }
Lớp này đại diện cho một tập hợp các trường hợp
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }4. Vì PHP không hỗ trợ các mảng đã nhập, nên các lớp như thế này là cần thiết khi bạn muốn gợi ý một mảng chỉ có thể chứa một loại giá trị. Bộ sưu tập cũng giúp bạn tạo các phương thức tiện ích, như
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }5, tạo điều kiện tương tác tự nhiên với các mục mảng
Thật không may, cố gắng lặp lại bộ sưu tập này sẽ không mang lại kết quả mong muốn. Lý tưởng nhất là phép lặp hoạt động trên mảng
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }6, không phải chính lớp đó
Thực hiện Iterator
Có thể thêm phép lặp tự nhiên bằng giao diện
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }7. Bằng cách triển khai ________ 07, bạn có thể xác định hành vi của PHP khi các phiên bản của lớp của bạn được sử dụng với ________ 00
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }7 có năm phương pháp mà bạn sẽ cần thực hiện
class UserCollection { protected array $items = []; public function add[UserDomain $user] : void { $this -> items[] = $user; } public function containsAnAdmin[] : bool { return [count[array_filter[ $this -> items, fn [UserDomain $i] : bool => $i -> isAdmin[] ]] > 0]; } }
1 – Nhận mục ở vị trí hiện tại trong lần lặpclass UserCollection { protected array $items = []; public function add[UserDomain $user] : void { $this -> items[] = $user; } public function containsAnAdmin[] : bool { return [count[array_filter[ $this -> items, fn [UserDomain $i] : bool => $i -> isAdmin[] ]] > 0]; } }
2 – Lấy khóa ở vị trí hiện tại trong lần lặpclass UserCollection { protected array $items = []; public function add[UserDomain $user] : void { $this -> items[] = $user; } public function containsAnAdmin[] : bool { return [count[array_filter[ $this -> items, fn [UserDomain $i] : bool => $i -> isAdmin[] ]] > 0]; } }
3 – Di chuyển đến vị trí tiếp theo trong lần lặpclass UserCollection { protected array $items = []; public function add[UserDomain $user] : void { $this -> items[] = $user; } public function containsAnAdmin[] : bool { return [count[array_filter[ $this -> items, fn [UserDomain $i] : bool => $i -> isAdmin[] ]] > 0]; } }
4 – Tua lại vị trí bắt đầu lặp lạiclass UserCollection { protected array $items = []; public function add[UserDomain $user] : void { $this -> items[] = $user; } public function containsAnAdmin[] : bool { return [count[array_filter[ $this -> items, fn [UserDomain $i] : bool => $i -> isAdmin[] ]] > 0]; } }
5 – Nhận xem vị trí hiện tại có giá trị hay không
Những phương pháp này có thể gây nhầm lẫn lúc đầu. Mặc dù vậy, việc triển khai chúng rất đơn giản – bạn đang chỉ định những việc cần làm ở mỗi giai đoạn thực hiện
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }0
Mỗi khi đối tượng của bạn được sử dụng với
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }0, thì
class UserCollection { protected array $items = []; public function add[UserDomain $user] : void { $this -> items[] = $user; } public function containsAnAdmin[] : bool { return [count[array_filter[ $this -> items, fn [UserDomain $i] : bool => $i -> isAdmin[] ]] > 0]; } }8 sẽ được gọi. Phương thức
class UserCollection { protected array $items = []; public function add[UserDomain $user] : void { $this -> items[] = $user; } public function containsAnAdmin[] : bool { return [count[array_filter[ $this -> items, fn [UserDomain $i] : bool => $i -> isAdmin[] ]] > 0]; } }9 được gọi tiếp theo, thông báo cho PHP liệu có giá trị ở vị trí hiện tại hay không. Nếu có,
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }30 và
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }31 được gọi để lấy giá trị và khóa tại vị trí đó. Cuối cùng, phương thức
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }32 được gọi để nâng cao con trỏ vị trí. Vòng lặp quay lại gọi
class UserCollection { protected array $items = []; public function add[UserDomain $user] : void { $this -> items[] = $user; } public function containsAnAdmin[] : bool { return [count[array_filter[ $this -> items, fn [UserDomain $i] : bool => $i -> isAdmin[] ]] > 0]; } }9 để xem có mục nào khác không
Đây là một triển khai điển hình của
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }7
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }3
Đây là những gì sẽ xảy ra khi lặp lại
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }35
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }0
Trình vòng lặp của bạn cần duy trì một bản ghi về vị trí vòng lặp, kiểm tra xem có phần tử nào ở vị trí vòng lặp hiện tại hay không [thông qua
class UserCollection { protected array $items = []; public function add[UserDomain $user] : void { $this -> items[] = $user; } public function containsAnAdmin[] : bool { return [count[array_filter[ $this -> items, fn [UserDomain $i] : bool => $i -> isAdmin[] ]] > 0]; } }9] và trả về khóa và giá trị ở vị trí hiện tại
PHP sẽ không cố truy cập khóa hoặc giá trị khi vị trí vòng lặp không hợp lệ. Trả về
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }37 từ
class UserCollection { protected array $items = []; public function add[UserDomain $user] : void { $this -> items[] = $user; } public function containsAnAdmin[] : bool { return [count[array_filter[ $this -> items, fn [UserDomain $i] : bool => $i -> isAdmin[] ]] > 0]; } }9 ngay lập tức chấm dứt vòng lặp
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }0. Thông thường, đây sẽ là khi bạn đi đến cuối mảng
IteratorAggregate
Viết trình vòng lặp nhanh chóng bị lặp đi lặp lại. Hầu hết làm theo công thức chính xác hiển thị ở trên.
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }00 là một giao diện giúp bạn nhanh chóng tạo các đối tượng có thể lặp lại
Triển khai phương thức
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }01 và trả về một
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }02 [giao diện cơ bản của
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }7]. Nó sẽ được sử dụng làm trình vòng lặp khi đối tượng của bạn được sử dụng với
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }0. Đây thường là cách dễ nhất để thêm phép lặp vào lớp bộ sưu tập
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }0
Khi làm việc với các bộ sưu tập, ba dòng mã thường là tất cả những gì bạn cần để thiết lập phép lặp. Một
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }05 được trả về dưới dạng
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }02. Đây là lớp tự động tạo một
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }7 từ một mảng. Giờ đây, bạn có thể lặp lại các giá trị logic trong đối tượng của mình, thay vì các thuộc tính trực tiếp của đối tượng
Sử dụng Trình lặp PHP dựng sẵn
Bạn sẽ cần viết các trình vòng lặp của riêng mình nếu bạn có logic phức tạp. Hiếm khi cần phải bắt đầu lại từ đầu vì PHP cung cấp một số trình vòng lặp nâng cao do SPL cung cấp
Các lớp dựng sẵn bao gồm
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }08,
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }09,
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }00 và các trình lặp đệ quy khác nhau. Đây là một số trình vòng lặp chung hữu ích nhất
Giới hạnIterator
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }01 cho phép bạn lặp lại một tập hợp con của một mảng. Bạn không cần ghép mảng trước hoặc theo dõi thủ công vị trí bên trong
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }0 của mình
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }9
Ví dụ này sẽ phát ra
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }03. Lưu ý rằng
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }01 chấp nhận một
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }7 khác, không phải một mảng. Ví dụ sử dụng
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }05, lớp tích hợp xây dựng một
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }7 từ một mảng
InfiniteIterator
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }08 không bao giờ kết thúc vòng lặp, vì vậy bạn sẽ cần phải
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }09 từ vòng lặp theo cách thủ công. Mặt khác, trình vòng lặp sẽ tự động quay trở lại đầu mảng khi nó đến cuối
Trình lặp này đặc biệt hữu ích khi làm việc với các giá trị dựa trên thời gian. Đây là một cách dễ dàng để xây dựng lịch ba năm, cũng sử dụng
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }01 được mô tả ở trên
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }8
Điều này tạo ra số tháng có giá trị trong ba năm
Bộ lọcIterator
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }91 là một lớp trừu tượng mà bạn phải mở rộng. Triển khai phương pháp
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }92 để lọc ra các giá trị không mong muốn sẽ bị bỏ qua trong quá trình lặp lại
class UserCollection { protected array $items = []; public function add[UserDomain $user] : void { $this -> items[] = $user; } public function containsAnAdmin[] : bool { return [count[array_filter[ $this -> items, fn [UserDomain $i] : bool => $i -> isAdmin[] ]] > 0]; } }1
Ví dụ này sẽ phát ra
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }93
Các giá trị mảng cao hơn 5 được lọc ra và không xuất hiện trong
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }0
Loại "có thể lặp lại"
Đôi khi bạn có thể viết một hàm chung sử dụng vòng lặp
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }0 nhưng không biết gì về các giá trị mà nó sẽ lặp lại. Một ví dụ là trình xử lý lỗi trừu tượng chỉ đơn giản là loại bỏ các giá trị mà nó nhận được
Bạn có thể đánh máy
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }96 trong những trường hợp này. Đây là một loại giả sẽ chấp nhận một
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }97 hoặc bất kỳ đối tượng nào triển khai
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }02
class UserCollection { protected array $items = []; public function add[UserDomain $user] : void { $this -> items[] = $user; } public function containsAnAdmin[] : bool { return [count[array_filter[ $this -> items, fn [UserDomain $i] : bool => $i -> isAdmin[] ]] > 0]; } }8
Loại
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }96 rất mơ hồ nên các bạn suy nghĩ kỹ trước khi sử dụng. Tuy nhiên, nó có thể hữu ích như là phương án cuối cùng nếu bạn cần đảm bảo giá trị đầu vào sẽ hoạt động với
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }0
Phần kết luận
Việc sử dụng các trình vòng lặp giúp bạn viết mã rõ ràng theo mô-đun hơn. Bạn có thể di chuyển các phương thức hoạt động trên các mảng đối tượng vào các lớp bộ sưu tập chuyên dụng. Sau đó, chúng có thể được đánh máy riêng lẻ trong khi vẫn hoàn toàn tương thích với
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }0
Hầu hết thời gian, việc thêm hỗ trợ lặp lại có thể đạt được bằng cách triển khai
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }00 và trả về một
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }05 được định cấu hình với các mục trong bộ sưu tập của bạn. Các loại trình lặp khác của PHP, có xu hướng không được các nhà phát triển sử dụng, có thể đơn giản hóa rất nhiều các vòng lặp cụ thể hơn. Chúng cung cấp các hành vi logic phức tạp mà không yêu cầu theo dõi con trỏ thủ công trong câu lệnh
$cls = new StdClass[]; $cls -> foo = "bar"; foreach [$cls as $i] { echo $i; }0 của bạn