2011-12-17 31 views
10

Kịch bản:cách đơn giản nhất để bắt đầu một quá trình mới/thread trong PHP

  1. Shared hosting, vì vậy không khả năng cài đặt phần mở rộng mới + không CRON
  2. Một gửi yêu cầu cần thực hiện một số quy trình nặng.
  3. Tôi muốn câu trả lời cho khách hàng để đi càng nhanh càng tốt, và nâng nặng để tiếp tục ngay lập tức, nhưng không dừng lại khách hàng.
  4. có thể là một chủ đề mới (nếu có thể) cũng không có vấn đề gì khi bắt đầu một quy trình mới.

Cách tốt nhất để làm điều này là gì?

+0

PHP có thể không (hiện tại) là đa luồng. * Nhiều * đến sự không hài lòng thường xuyên của tôi. – DaveRandom

+0

Vâng, một số điều có thể được mô phỏng. –

Trả lời

11

On * nix:

exec('/path/to/executable > /dev/null 2>&1 &'); 

Trên Windows:

$WshShell = new COM('WScript.Shell'); 
$oExec = $WshShell->Run('C:\path\to\executable.exe', 0, false); 

Cả hai sẽ đẻ trứng một quá trình mới mà sẽ chạy một-đồng bộ, hoàn toàn ngắt kết nối từ công ty mẹ. Miễn là máy chủ của bạn cho phép bạn làm điều đó.

+0

Tôi có thể thay đổi/dev/null thành tệp nhật ký mà tôi chọn không? –

+0

Tôi nghĩ như vậy, miễn là bạn chuyển hướng STDOUT * và * STDERR đến một nơi nào đó không phải là quá trình cha mẹ, và hậu tố với '&', nó sẽ làm việc.TBH, tôi đã luôn luôn chỉ '/ dev/null'ed nó, do đó, thực sự bạn sẽ chỉ phải suck nó và xem ... – DaveRandom

+0

Bắt đầu một quá trình bên ngoài tùy ý trên chia sẻ lưu trữ? Chúc may mắn với điều đó. –

1

Không có chủ đề nào trong PHP. Bạn có thể gian lận bằng cách gửi lại một trang HTML kích hoạt một cuộc gọi Ajax để bắt đầu quá trình nặng nề trong một yêu cầu mới. Nhưng nếu nó được chia sẻ lưu trữ, tôi đoán là bạn sẽ nhanh chóng đạt các giới hạn về bộ nhớ, thời gian hoặc sử dụng CPU áp đặt bởi nhà cung cấp hosting của bạn.

+0

[Rõ ràng, có các chủ đề trong PHP bây giờ] (http://docs.php.net/manual/en/class.thread.php) nhưng bạn có thể phải [cài đặt chúng] (http: //docs.php. net/manual/en/pthreads.installation.php). Tuy nhiên, tôi chỉ mới học được điều này tối nay, vì vậy tôi chưa thử nó. – Volomike

0
$WshShell = new COM('WScript.Shell'); 
$oExec = $WshShell->Run('C:\xampp\php\php.exe C:\xampp\htdocs\test.php -a asdf', 0, true); 

Không thể chuyển argv đến test.php.

var_dump($argv); 
+1

Tôi cho rằng đây là cửa sổ ...? –

2

Bạn có thể google bằng phím: php tiếp tục xử lý sau khi đóng kết nối.

Các liên kết sau có liên quan đến vấn đề của bạn, bao gồm:

Bạn có thể sử dụng thuộc về lệnh để tiếp tục thực hiện mà không cần người dùng hủy

ignore_user_abort(true); 
set_time_limit(0); 

Bạn sử dụng fastcgi_finish_request để thông báo cho khách hàng ngừng sản lượng phản hồi. Và các tập lệnh của bạn sẽ tiếp tục được thực hiện.

Một ví dụ:

// redirecting... 
ignore_user_abort(true); 
set_time_limit(0); 
header("Location: ".$redirectUrl, true); 
header("Connection: close", true); 
header("Content-Length: 0", true); 
ob_end_flush(); 
flush(); 
fastcgi_finish_request(); // important when using php-fpm! 

sleep (5); // User won't feel this sleep because he'll already be away 

// do some work after user has been redirected 
+0

Chào mừng bạn đến với SO. Bạn nên xem lại định dạng câu trả lời của mình. Hiện tại, có vẻ như bạn đặt tất cả mọi thứ trong một khối mã, trong khi đó là một phần của câu trả lời của bạn không phải là mã. – Laf

+0

Cảm ơn Laf. Tôi định dạng lại câu trả lời của mình. –

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