2012-08-05 34 views
7

tôi thấy những người sử dụng bầy như thế này:php bầy và fread và fwrite

if (!$fp = fopen($file_name, 'wb')) 
{ 
    return FALSE; 
} 

if (flock($fp, LOCK_EX)) 
{ 
    fwrite($fp, serialize($data)); 
    flock($fp, LOCK_UN); 
} 

Ngoài này:

if (!$fp = @fopen($file_name, 'rb')) 
{ 
    return FALSE; 
} 

flock($fp, LOCK_SH); 

$data = ''; 

if (filesize($file_name) > 0) 
{ 
    $data = unserialize(fread($fp, filesize($file_name))); 
} 

Nhưng không có một cơ hội mà người khác sẽ chỉnh sửa các tập tin giữa Cuộc gọi fopen và cuộc gọi flock? và câu hỏi tương tự cho fread


EDIT:
Để làm rõ lý do tại sao tôi yêu cầu này ... Tôi dựa câu hỏi của tôi về mã here, Trong một tình huống bộ nhớ đệm mysql, có chuyện gì để ngăn chặn 20 người từ tất cả đều có thể truy cập tập tin cùng một lúc nếu tất cả chúng có thể ở giữa fopen và đàn?

Mã đó có đáng tin cậy không?

Trả lời

6

Bạn hỏi:

là không có một cơ hội mà một người nào đó người nào khác sẽ chỉnh sửa tập tin giữa cuộc gọi fopen và cuộc gọi đàn? và cùng một câu hỏi cho fread

Có, không, có thể. Câu trả lời ngắn: giả sử "có" và hành động cẩn thận.

Có, trong đó khóa dựa trên truyền thống() chỉ đơn thuần là tư vấn, vì vậy các quy trình khác (hoặc thậm chí cùng một quy trình) được tự do bỏ qua các khóa. Trong thực tế, đây không phải là vấn đề, vì flock() được sử dụng bởi mã máy khách tốt - bạn không đọc cho đến khi bạn nhận được một LOCK_SH, và bạn không viết trừ khi bạn đã nhận được một LOCK_EX - trên ứng dụng- các tệp cụ thể.

Không, trong việc thực hiện của PHP mà các bầy() có thể bắt buộc trên hệ điều hành nhất định, theo documentation, mà cũng có thể yêu cầu sự hỗ trợ từ hệ thống tập tin (ví dụ như với các tùy chọn mand dưới Linux). Vì vậy, các quy trình khác không thể bỏ qua những khóa đó.

Có thể, trong đó hệ thống con luồng trong PHP 5 triển khai một số locking bookkeeping ngoài phạm vi được cung cấp bởi hệ điều hành. Điều này có thể, ví dụ, ngăn chặn quá trình tương tự (nhưng không khác) từ bỏ qua các khóa tư vấn khác của chính nó. Hành vi might surprise một số. Mặc dù vậy, loại khóa này sẽ không bắt buộc giữa các quy trình không liên quan.

Đối với tính di động, chỉ cần giả định ngữ nghĩa yếu nhất ("có" ở trên) và hạn chế đổ() vào mã được xử lý tốt trên các tệp khóa dành riêng cho ứng dụng được chọn trước.

+0

Trong trường hợp bộ nhớ cache chỉ được sử dụng bởi tập lệnh cụ thể đó, sẽ không có gì xảy ra. Nếu ai đó sẽ đánh tập tin từ đó, chắc chắn, những điều xấu sẽ xảy ra. – favoretti

+0

Có, nhưng nó không phải là trường hợp mà LOCK_EX, ví dụ, bằng cách nào đó lực lượng 'fread' để" trả lại không có gì ", như một bình luận đã nêu. – pilcrow

+0

Nếu bạn đọc các ý kiến ​​trên trang web của PHP để bầy(), nó thực sự làm, mặc dù thực tế là khóa là tư vấn. Điều đó đang được nói, bắt buộc khóa trên, ví dụ, Linux chỉ có thể đạt được trong khi làm việc với các hệ thống tập tin hỗ trợ rõ ràng nó và được gắn kết như vậy. – favoretti

2

Đoạn mã đầu tiên là chống lừa đảo, nếu bạn không thể lấy khóa trên tệp, bạn không viết. Nếu ai đó đã chỉnh sửa tệp giữa fopen()flock(), xử lý tệp của bạn sẽ trỏ đến hóa thân mới nhất, vì fopen() liên kết với luồng chứ không phải là 'ảnh chụp nhanh'.

Ví dụ thứ hai không được đảm bảo để hoạt động, vì giá trị trả lại của flock() không được chọn, vì vậy nếu bạn chưa mua khóa, mã tiếp theo sẽ được thực thi.

[sửa] loại bỏ tuyên bố rằng khóa đọc không quan trọng, nó thực sự làm, như được giải thích trong ý kiến ​​dưới đây :)

+0

Tôi đang đặt câu hỏi của mình trên mã [** tại đây, **] (http://www.jongales.com/blog/2009/02/18/simple-file-based-php-cache-class /) Trong một tình huống bộ nhớ đệm mysql, những gì để ngăn chặn 20 người từ tất cả có thể truy cập vào tập tin cùng một lúc trong trường hợp đó dựa trên mã trong lớp đó? – qwertymk

+0

Để đọc - không có gì, rất có thể là những gì bạn muốn, truy cập đọc bộ nhớ cache đồng thời, thay vì độc quyền. Đối với văn bản, chính xác mà có được khóa sẽ ngăn chặn người khác từ văn bản vào bộ nhớ cache. Điều gì chính xác làm phiền bạn với mã đó? – favoretti

+0

Tôi đoán một vấn đề nhỏ, nếu 100.000 người cố gắng đặt cùng một tệp bộ nhớ cache và 20.000 được gọi giữa fopen và bầy đàn, sẽ có 19.999 fritites không cần thiết, một số người sẽ kiểm tra xem liệu bộ nhớ cache là mới và sẽ bỏ lỡ filetime mới mà nó nhận được. Đó có phải là một vấn đề? – qwertymk

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