Tại sao nên sử dụng iterator trong PHP?

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ặp
  • 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];
        }
     
    }
    2 – Lấy khóa ở vị trí hiện tại trong lần lặp
  • 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];
        }
     
    }
    3 – Di chuyển đến vị trí tiếp theo trong lần lặp
  • 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];
        }
     
    }
    4 – Tua lại vị trí bắt đầu 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];
        }
     
    }
    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

Tại sao chúng ta sử dụng iterator trong PHP?

Trình lặp chứa danh sách các mục và cung cấp các phương thức để lặp qua chúng . Nó giữ một con trỏ tới một trong các phần tử trong danh sách. Mỗi mục trong danh sách phải có một khóa có thể được sử dụng để tìm mục đó.

Tại sao iterator được sử dụng?

Trình lặp thường được sử dụng để lặp qua các đối tượng của bộ sưu tập, đọc và xóa chúng .

Iterator là gì và tại sao iterator lại cần thiết?

Trình lặp là một đối tượng [như con trỏ] trỏ đến phần tử bên trong vùng chứa . Chúng ta có thể sử dụng các trình vòng lặp để di chuyển qua nội dung của vùng chứa. Chúng có thể được hình dung như một cái gì đó tương tự như một con trỏ trỏ đến một số vị trí và chúng ta có thể truy cập nội dung tại vị trí cụ thể đó bằng cách sử dụng chúng.

Trình lặp mảng trong PHP là gì?

Lớp ArrayIterator ¶

Chủ Đề