2009-11-01 24 views
14

Ví dụ: có một tập lệnh PHP rất đơn giản cập nhật một số bảng trên cơ sở dữ liệu, nhưng quá trình này mất một thời gian dài (có thể là 10 phút). Do đó, tôi muốn tập lệnh này tiếp tục xử lý ngay cả khi người dùng đã đóng trình duyệt, bởi vì đôi khi người dùng không đợi và họ đóng trình duyệt hoặc truy cập trang web khác.Các tập lệnh PHP có thể tiếp tục chạy ngay cả khi người dùng đã đóng trình duyệt không?

+0

Vì vậy, nếu tôi muốn bỏ yêu cầu trình duyệt khỏi thực thi công việc, làm cách nào tôi có thể yêu cầu một tập lệnh php khác, trong khi yêu cầu hiện tại của người dùng tiếp tục bình thường. Vì vậy, khi người dùng yêu cầu bất kỳ url nào, yêu cầu này sẽ khởi chạy một tập lệnh khác (hoạt động độc lập với trình duyệt của người dùng và các yêu cầu khác). Và người dùng sẽ tiếp tục lướt trên trang web thông thường –

+0

Câu hỏi hay! +1 –

Trả lời

7

Để trả lời câu hỏi của bạn trực tiếp, xem ignore_user_abort

Nói rộng hơn, bạn có thể có một vấn đề kiến ​​trúc ở đây.

Nếu nhiều người dùng có thể khởi tạo công cụ này, bạn sẽ muốn ứng dụng web thêm công việc vào một số loại hàng đợi và có một số quy trình nền nhai qua tất cả công việc.

-1

Tập lệnh phía máy chủ sẽ tiếp tục hoạt động của ứng dụng bất kể khách hàng đang làm gì.

EDIT: Nhân tiện, bạn có chắc chắn muốn có các trang mất 10 phút để mở không? Tôi đề nghị bạn sử dụng một hàng đợi công việc (các mục của họ được thực hiện bởi cron trên cơ sở kịp thời) và chuyển hướng người dùng đến trang "ok, tôi đang ở trên đó".

+0

... không hoàn toàn đúng: thông thường, có những nhân viên bảo vệ để "giết" các tập lệnh php chạy dài: chúng có dạng mục nhập crontab. – jldupont

+1

Không phải lúc nào cũng đúng: http://php.net/manual/en/function.ignore-user-abort.php – timdev

+0

@jldupont: Tôi không phải là anh chàng php, nhưng những đoạn mã này có liên quan gì đến khách hàng không? – shanyu

3

nếu tập lệnh hoàn toàn dựa trên máy chủ (không có phản hồi cho người dùng), việc này sẽ được thực hiện ngay cả khi khách hàng bị đóng.

Kiến trúc chung của PHP là khách hàng gửi yêu cầu đến tập lệnh cung cấp câu trả lời cho người dùng. nếu không có gì được trả lại cho người dùng thì tập lệnh sẽ vẫn thực thi ngay cả khi người dùng không ở phía bên kia nữa. Đơn giản hơn: chúng không có kết nối liên tục giữa máy chủ và máy khách trên tập lệnh thông thường.

+1

Lưu ý luôn đúng: http://php.net/manual/en/function.ignore-user-abort.php – timdev

1

Bạn có thể làm cho tập lệnh PHP chạy 20 phút một lần bằng tệp crontab chứa thời gian và lệnh nào sẽ chạy trong trường hợp này, đó là tập lệnh php.

+0

ngoài câu hỏi được yêu cầu ở đây ... – jldupont

0

Có. Máy chủ không biết liệu người dùng đã đóng trình duyệt hay chưa. Ít nhất nó không nhận ra điều đó ngay lập tức.

Không: máy chủ có thể (tùy thuộc vào cách được cấu hình) sẽ không cho phép tập lệnh php chạy trong 10 phút. Trên một lưu trữ chia sẻ giá rẻ tôi sẽ không dựa vào một kịch bản chạy lâu hơn một thời gian phản ứng hợp lý.

15

Nếu tác vụ mất 10 phút, không sử dụng trình duyệt để thực thi nó trực tiếp. Bạn có nhiều tùy chọn khác:

  • Sử dụng cronjob để thực hiện tác vụ theo định kỳ.
  • Có yêu cầu trình duyệt chèn một hàng mới vào một bảng cơ sở dữ liệu để thường xuyên cronjob có thể xử lý hàng mới và thực thi kịch bản PHP với lập luận thích hợp
  • Có yêu cầu trình duyệt viết một tin nhắn hệ thống xếp hàng có số người đăng ký lắng nghe các sự kiện như vậy (sau đó thực hiện thực thi tập lệnh).

Mặc dù một số đề xuất này có thể quá mức cần thiết cho tình huống của bạn, phím, tính năng kết hợp là để loại bỏ yêu cầu trình duyệt khỏi thực thi công việc, để nó có thể được hoàn thành không đồng bộ.

Nếu bạn cần cửa sổ trình duyệt được cập nhật với tiến trình, bạn sẽ cần sử dụng yêu cầu AJAX được thực thi theo định kỳ để truy xuất trạng thái công việc.

+1

+1 cho phiên bản trả lời thú vị và đẹp hơn nhiều. – timdev

+0

Vì vậy, nếu tôi muốn bỏ yêu cầu trình duyệt từ việc thực hiện công việc, làm thế nào tôi có thể yêu cầu một tập lệnh php khác, trong khi yêu cầu hiện tại của người dùng tiếp tục bình thường. Vì vậy, khi người dùng yêu cầu bất kỳ url nào, yêu cầu này sẽ khởi chạy một tập lệnh khác (hoạt động độc lập với trình duyệt của người dùng và các yêu cầu khác). Và người dùng sẽ tiếp tục lướt trên trang web thông thường Tôi có thể làm như thế nào? –

+0

Xem các dấu đầu dòng đó? Đó là tất cả các cách để làm điều này. Trong hầu hết các trường hợp, việc thiết lập một bảng cơ sở dữ liệu nhỏ chứa các đầu vào cho quá trình nền hoạt động tốt. Sau đó, bạn có thể khởi chạy một số tập lệnh PHP để thực hiện các công việc, hoặc thông qua cron, hoặc một số phương pháp khác. – timdev

4

Tập lệnh PHP sẽ tiếp tục chạy sau khi máy khách chấm dứt kết nối (không làm như vậy sẽ là một nguy cơ bảo mật), nhưng chỉ lên đến max_execution_time (được đặt trong php.ini hoặc thông qua tập lệnh PHP, thường là 30 giây theo mặc định) ..

Ví dụ:

<?php 
    $fh = fopen("bluh.txt", 'w'); 
    for($i=0; $i<20; $i++) { 
     echo $i."<br/>"; 
     fwrite($fh,$i."\n"); 
     sleep(1); 
    } 
    fclose($fh); 
?> 

Bắt đầu chạy trong trình duyệt của bạn và đóng trình duyệt trước khi nó hoàn thành. Bạn sẽ thấy rằng sau 20 giây tệp chứa tất cả các giá trị của $i.

Thay đổi giới hạn trên của vòng lặp for thành 100 thay vì 20 và bạn sẽ thấy nó chỉ chạy từ 0 đến 29. Vì mã PHP max_execution_time của tập lệnh hết thời gian chờ và chết.

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