2010-03-16 23 views
13

Chúng tôi đang chạy PHP trên máy chủ Windows (một nguồn của nhiều vấn đề thực sự, nhưng việc di chuyển không phải là một tùy chọn hiện tại). Có một vài điểm mà hành động do người dùng thực hiện sẽ cần phải khởi động một vài điều mất một thời gian và người dùng không cần phải biết liệu họ có thành công hay không thành công, chẳng hạn như gửi email hoặc đảm bảo một số tài khoản của bên thứ ba được cập nhật. Nếu tôi có thể chỉ cần ngã ba với pcntl_fork(), điều này sẽ rất đơn giản, nhưng các chức năng PCNTL không có sẵn trong Windows.Phân nhánh bằng PHP trên Windows

Có vẻ như gần nhất tôi có thể nhận được là làm điều gì đó của thiên nhiên này:

exec('php-cgi.exe somescript.php'); 

Tuy nhiên, đây sẽ là xa phức tạp hơn. Các hành động tôi cần phải khởi động dựa vào rất nhiều ngữ cảnh đã tồn tại trong tiến trình đang chạy; để sử dụng ví dụ trên, tôi cần phải tìm ra dữ liệu cần thiết và cung cấp cho tập lệnh mới theo một cách nào đó. Nếu tôi có thể ngã ba, nó chỉ là vấn đề để cho quá trình cha mẹ trở lại sớm, để cho đứa trẻ làm việc trên một vài thứ nữa.

Tôi đã tìm thấy một số người nói về công việc của riêng họ khi nhận các chức năng PCNTL khác nhau được biên dịch trên Windows, nhưng dường như không có bất kỳ thứ gì (liên kết bị hỏng, v.v.).

Mặc dù this question có tên thực tế giống như tôi, có vẻ như vấn đề đã hết thời gian chờ thực hiện hơn là cần phải ngã ba. Vì vậy, là lựa chọn tốt nhất của tôi để chỉ refactor một chút để đối phó với gọi php-cgi, hoặc là có các tùy chọn khác?

Chỉnh sửa: Có vẻ như exec() sẽ không hoạt động cho điều này, ít nhất là không có tôi để tìm một số khía cạnh khác của nó, vì nó đợi cho đến khi cuộc gọi trở lại. Tôi figured tôi có thể sử dụng START, loại giống như exec('start php-cgi.exe somescript.php');, nhưng nó vẫn chờ đợi cho đến khi kịch bản khác kết thúc.

+0

bạn có coi công việc cron cho việc này không? (có một số tùy chọn có sẵn, http://www.google.com/search?q = cron + windows) – user187291

+0

Từ những gì tôi có thể thấy, có vẻ như nó sẽ làm việc cũng như sử dụng psexec, nhưng tôi chỉ có những thứ làm việc với psexec vì vậy tôi có lẽ sẽ chỉ dính vào đó. –

Trả lời

13

thế nào về installing psexec và sử dụng -d (không chờ đợi) option

exec('psexec -d php-cgi.exe somescript.php'); 
+0

Tuyệt vời, tôi đã làm việc đó. Tôi đang bối rối bởi vì tại sao thực hiện với 'bắt đầu' không thể làm những gì tôi cần. Ngoài ra, tôi cần gọi psexec với tham số -accepteula, mặc dù tôi đã tự chấp nhận nó chạy nó trên máy chủ. –

+0

Nếu bạn đang tìm kiếm một cách để vượt qua các biến sau đó sử dụng 'exec (' psexec-php-cgi.exe somescript.php 'var1' 'var2' 'var3' ");' Sau đó, trong tập lệnh php bạn ' gửi các biến đến, sử dụng '$ argv [1]', '$ argv [2]', và '$ argv [3]'. –

3

Nhận PSExec và chạy lệnh:

exec("psexec -d php-cgi.exe myfile.php"); 
+2

cũng câu trả lời này không có liên kết nhưng câu trả lời khác không có – SeanDowney

1

Bạn có thể tạo một quá trình daemon/nền để chạy mã (ví dụ như gửi email) và yêu cầu sẽ chỉ phải thêm các mục vào hàng đợi, để cho deamon thực hiện việc nâng hạng nặng.

Ví dụ, một tập tin send_emails.bat:

cls 
C:\PHP533\php.exe D:\web\server.php 
exit 

cửa sổ đang mở task scheduler, và có send_emails.bat trên chạy mỗi 30 phút. Hãy chắc chắn rằng chỉ một cá thể chạy tại một thời điểm hoặc bạn có thể chạy từng tác vụ theo bội số hoặc gửi từng email hai lần. Tôi nói 30 phút trong trường hợp một cái gì đó tạm thời bị hỏng (vấn đề bộ nhớ, cơ sở dữ liệu không có sẵn, vv), nó sẽ bắt đầu lại mỗi 30 phút thay vì có một quá trình không bao giờ kết thúc mà chỉ dừng lại. Sau đây là một daemon xương ... chưa hoàn chỉnh hoặc thử nghiệm Tôi chỉ cần gõ ra một ví dụ:

<?php 
set_time_limit(60*30); // don't run 
$keepgoing = true; 
$timeout = time()+ 60*29; // 29 minutes 

while(time() < $timeout) 
{ 
    // grab emails from database 
    $result = $db->query('select subject, body, to_email FROM email_queue'); 
    if($result->num_rows == 0) 
    { 
     sleep(10); // so we are not taxing the database 
    } 
    else 
    { 
     while($row = $result->fetch_assoc()) 
     { 
     // send email 
     } 
    } 
} 
exit; 
?> 

Cuối cùng, bạn chỉ cần yêu cầu thêm các mục vào hàng đợi trong một cơ sở dữ liệu, và để cho các xử lý daemon việc nâng hạng nặng.

$db->query('insert into email_queue(to,subject,body) values ('[email protected]','important email','<b>html body!</b>'); 
Các vấn đề liên quan