Tìm kiếm bài viết

Yield là gì trong PHP

01.05.2019

5.0/5 (1 Reviews)

Yield là gì trong PHP. Tìm hiểu mọi thứ về Yield trong PHP. Tối ưu tốc độ xử lý trong php bằng generator function.

    Yield là gì?

    Yield là một hàm Generator giống như một hàm bình thường, ngoại trừ việc thay vì trả về một giá trị, Generator sẽ mang lại nhiều giá trị như nó cần. Nhìn vào ví dụ sau để dễ hiểu nhé:

    function getValues() {
        yield 'value';
    }
    // print the string "value"
    echo getValues();

    Tất nhiên, đây không phải là cách nó hoạt động, ví dụ trước sẽ cho bạn một lỗi nghiêm trọng: Không thể chuyển đổi đối tượng của lớp Trình tạo thành chuỗi, chúng ta hãy làm rõ hơn bên dưới đây.

    Yield là gì trong PHP

    Khác nhau giữa yield và return

    Lỗi trước có nghĩa là hàm getValues ​​() không trả về một chuỗi như mong đợi, chúng ta hãy kiểm tra kiểu của nó:

    function getValues() {
        return 'value';
    }
    var_dump(getValues()); // string(5) "value" đây là 1 string được trả về kiểu chuổi.
    
    function getValues() {
        yield 'value';
    }
    var_dump(getValues()); // class Generator#1 (0) {} đây là 1 Object Generator được trả về từ 1 Class Generator.

    Lớp Generator  triển khai giao diện Iterator, có nghĩa là bạn phải lặp qua hàm getValue () để có được các giá trị:

    foreach (getValues() as $value) {
       echo $value;
    }
    // using variable is also alright
    $values = getValues();
    foreach ($values as $value) {
       echo $value;
    }

    Nhưng đây không phải là sự khác biệt duy nhất!

    Generator cho phép bạn viết mã sử dụng foreach để lặp lại một tập hợp dữ liệu mà không cần xây dựng một mảng trong bộ nhớ, điều này có thể khiến bạn vượt quá giới hạn bộ nhớ. Quá tốt nếu bạn đang cần sử dụng loop lồng nhau rồi.

    Trong ví dụ sau, chúng tôi sẽ xây dựng một mảng gồm 800.000 phần tử và trả về nó từ hàm getValues() , và trong khi đó, chúng ta sẽ lấy bộ nhớ được phân bổ cho tập lệnh này bằng cách sử dụng hàm memory_get_usage() , chúng ta sẽ sử dụng bộ nhớ sau mỗi 200.000 phần tử được thêm vào, có nghĩa là chúng ta sẽ đặt bốn điểm kiểm tra.

    <?php
    function getValues() {
       $valuesArray = [];
       // sử dụng bộ nhớ ban đầu
       echo round(memory_get_usage() / 1024 / 1024, 2) . ' MB' . PHP_EOL;
       for ($i = 1; $i < 800000; $i++) {
          $valuesArray[] = $i;
          // đo lường việc sử dụng bộ nhớ
          if (($i % 200000) == 0) {
             // sử dụng bộ nhớ tính bằng megabyte
             echo round(memory_get_usage() / 1024 / 1024, 2) . ' MB'. PHP_EOL;
          }
       }
       return $valuesArray;
    }
    $myValues = getValues(); // xây dựng mảng ở đây một khi chúng ta gọi hàm
    foreach ($myValues as $value) {}

    Điều đã xảy ra trong ví dụ trước là việc tiêu thụ bộ nhớ và đầu ra của tập lệnh này không:

    0.34 MB
    8.35 MB
    16.35 MB
    32.35 MB

    Điều đó có nghĩa là tập lệnh vài dòng của chúng tôi đã tiêu thụ hơn 30 Megabyte bộ nhớ (Ôi trời ơi), mỗi khi bạn thêm một phần tử vào mảng $valueArray, bạn sẽ tăng kích thước của nó trong bộ nhớ. Chương trình càng loop nhiều thì càng dễ crash nhé. Giời hãy cùng LPTech thử với Yield xem như thế nào.

    <?php
    function getValues() {
       // get the initial memory usage
       echo round(memory_get_usage() / 1024 / 1024, 2) . ' MB' . PHP_EOL;
       for ($i = 1; $i < 800000; $i++) {
          yield $i;
          // let us do profiling, so we measure the memory usage
          if (($i % 200000) == 0) {
             // get memory usage in megabytes
             echo round(memory_get_usage() / 1024 / 1024, 2) . ' MB'. PHP_EOL;
          }
       }
    }
    $myValues = getValues(); // no action taken until we loop over the values
    foreach ($myValues as $value) {} // start generating values here

    Đầu ra của kịch bản này là đáng ngạc nhiên đến cả LPTech cũng giật mình:

    0.34 MB
    0.34 MB
    0.34 MB
    0.34 MB

    Điều đó không có nghĩa là bạn chuyển từ biểu thức return thành yield, nhưng nếu bạn đang xây dựng các mảng lớn trong ứng dụng của mình, điều này gây ra các vấn đề về bộ nhớ trên máy chủ, thì yield phù hợp với trường hợp của bạn.

    Tuỳ chọn của Yield là gì ?

    Có nhiều lựa chọn cho yield, tôi sẽ làm nổi bật vài trong số chúng:

    Sử dụng yield, bạn cũng có thể sử dụng return;

    function getValues() {
       yield 'value';
       return 'returnValue';
    }
    $values = getValues();
    foreach ($values as $value) {}
    echo $values->getReturn(); // 'returnValue'

    Trả về keys-values

    function getValues() {
       yield 'key' => 'value';
    }
    $values = getValues();
    foreach ($values as $key => $value) {
       echo $key . ' => ' . $value;
    }

    Kết luận

    Lý do chính của chủ đề này của LPTech là để làm rõ sự khác biệt giữa yieldreturn đặc biệt về bộ nhớ, hiển thị một số ví dụ vì tôi thấy nó thực sự quan trọng đối với bất kỳ lập trình viên nào đang đi theo hướng thiết kế website

    Tài liệu tham khảo

    http://php.net/manual/en/language.generators.syntax.php
    http://php.net/manual/en/class.generator.php
    http://php.net/manual/en/language.generators.php
    http://php.net/manual/en/function.memory-get-usage.php
    CÓ THỂ BẠN QUAN TÂM

    Bài Viết Cùng Chuyên Mục

    XEM THÊM
    thumbnail

    Kubernetes bài 6 - Vận hành k8s Day-Two Operations và Quản trị bằng GitOps

    22.05.2026

    Khi cụm Kubernetes của bạn đã được bảo mật cấu hình, tối ưu tài nguyên và thiết lập tự phục hồi, câu hỏi đặt ra là làm sao để duy trì sự ổn định đó trong nhiều năm tiếp theo mà không bị phụ thuộc

    thumbnail

    Kubernetes bài 5 - bảo mật Cloud Native và chuẩn DevSecOps cho K8s

    22.05.2026

    Việc siết chặt an ninh (Hardening) không phải là cấu hình một vài thông số rồi bỏ đó, mà là một tư duy phòng thủ chiều sâu.

    thumbnail

    Kubernetes bài 4 - Tối ưu Resource Auto-Healing và Scale Zero-Downtime

    22.05.2026

    Bài viết này sẽ đi sâu vào các cơ chế ở tầng Kernel giúp hệ thống tự phục hồi, chống lại các đợt tấn công cạn kiệt tài nguyên và cập nhật phiên bản mới mà người dùng không hề hay biết.

    thumbnail

    Kubernetes bài 3 - Bảo mật cấu hình k8s và config Security trên Production

    22.05.2026

    Kubernetes giải quyết bài toán này bằng hai đối tượng chuyên biệt nhưng nếu không hiểu rõ bản chất bảo mật ở tầng dưới, bạn đang tự tay dâng toàn bộ chìa khóa hệ thống cho hacker.

    thumbnail

    Kubernetes bài 2 - Mạng lưới k8s và luồng Traffic ở Packet Level

    22.05.2026

    Pod không chỉ là một container: Rất nhiều người nhầm lẫn Pod 1-1 với Container. Thực chất, Pod là đơn vị triển khai nhỏ nhất, có thể chứa một hoặc nhiều container

    Mục lục bài viết