2011-02-03 33 views
17
for($i=0; $i<3; $i++) { 
    echo '$i = ' . $i . '<br/>' ; 
} 
echo 'out of loop, $i = ' . $i; 

đầu ra ở trên:Tại sao PHP KHÔNG xóa bộ nhớ sau khi thoát khỏi vòng lặp?

$i = 0 
$i = 1 
$i = 2 
out of loop, $i = 3 

Nó không có ý nghĩa với tôi rằng $ i là vẫn còn nhìn thấy thậm chí sau khi hiển thị nó ra khỏi phạm vi vòng lặp. Tại sao điều này xảy ra (trong java nó tự động thu gom rác)?

Và có cách nào để yêu cầu php tự động tự động sau khi thoát khỏi phạm vi vòng lặp không? Mã của tôi trông xấu xí khi tôi phải gọi unset() sau mỗi vòng lặp.

+9

là một tính năng. – Arvin

+20

PHP không phải là java –

+0

@Mark Yeah tốt hơn thế, không yêu cầu gc, http://us2.php.net/manual/en/language.variables.scope.php –

Trả lời

42

Đây không phải là về bộ sưu tập rác, đó là về phạm vi.

Trong PHP, đối với vòng lặp không tạo phạm vi của riêng chúng. $i được tạo trong cùng phạm vi với vòng lặp, vì vậy nó vẫn tồn tại sau khi vòng lặp kết thúc. Nó sẽ không phải là rác thu thập được nhiều hơn một biến bạn khai báo trên dòng trước khi vòng lặp sẽ được.

Hãy coi đó là một đối tượng địa lý vì nó thường được sử dụng làm đối tượng địa lý. Ví dụ, bạn không phải khai báo bộ đếm vòng lặp của bạn trước vòng lặp để biết giá trị của nó là gì sau khi thoát khỏi vòng lặp.

Nếu bạn thực hiện theo cách thủ công unset biến, bạn có thể bắt buộc thu thập rác với gc_collect_cycles kể từ PHP 5.3.

+0

Chỉ cần thêm: _Every_ biến bên ngoài phương thức/chức năng là toàn cầu. Điều này đặc biệt có nghĩa là bạn (@evilReiko) không phải 'unset()' biến của bạn, nếu bạn lặp lại bên trong một phương thức/hàm. – KingCrunch

+2

Xin lưu ý rằng trong một ví dụ tầm thường như thế này (và, trên thực tế, trong 99.999% các trường hợp), gọi GC là không cần thiết hoặc thậm chí được đề nghị. Có lẽ nếu bạn đang làm việc với các cơ sở dữ liệu khổng lồ sớm trong thời gian sử dụng kịch bản của bạn, nhưng thậm chí sau đó, nó có thể tốt hơn nếu bạn không. – fwielstra

8

Từ Variable scope

Phạm vi của một biến là bối cảnh trong đó nó được định nghĩa. Đối với hầu hết các phần, tất cả các biến PHP chỉ có một phạm vi duy nhất. Phạm vi duy nhất này bao gồm và các tập tin cần thiết là tốt. […] Trong các hàm do người dùng định nghĩa, một phạm vi hàm cục bộ được giới thiệu. Bất kỳ biến nào được sử dụng bên trong một hàm được mặc định giới hạn trong phạm vi hàm cục bộ.

Biến sẽ không được thu gom rác vì bạn vẫn có tham chiếu đến $i trong phạm vi sau khi thoát khỏi vòng lặp. Lưu ý rằng việc sử dụng unset sẽ không thực hiện bất kỳ bộ sưu tập rác nào, nhưng nó sẽ chỉ đánh dấu bộ nhớ không còn được tham chiếu cho số Garbage Collector để thu thập lần sau khi GC được chạy. Bạn có thể buộc thu gom rác thải với gc_collect_cycles.

4

nếu bạn sử dụng hàm đệ quy để thay thế vòng lặp, các biến còn lại sẽ bị xóa.

chỉ cần đặt vòng lặp trong một chức năng khác bất kỳ nó phải ở trong một phạm vi khác, chỉ cần chuyển dữ liệu vào và ra khỏi nó.

+0

giải pháp thú vị! – evilReiko

Các vấn đề liên quan