2010-05-15 28 views
17

Về cơ bản, tôi có thể muốn thực thi một tập lệnh có thể mất tới 1 giờ.Làm cách nào để thực thi một Tập lệnh PHP lớn?

Điều tôi thực sự muốn làm là Gửi SMS cho người dùng của mình bằng API của bên thứ ba. Vì vậy, về cơ bản nó giống như tôi cung cấp kịch bản của tôi với một loạt các số điện thoại và cháy phương pháp để gửi tin nhắn SMS.

Tuy nhiên giả sử mất 5 giây để gửi 1 SMS và tôi muốn gửi 1000 SMS trong khoảng 1 - 2 giờ. Tôi không thể sử dụng set_time_limit() vì tôi đang ở trên máy chủ chia sẻ.

Một cách để thực hiện việc này là lưu số trong phiên và thực hiện từng SMS và sử dụng javascript để làm mới trang đó cho đến khi kết thúc. Bằng cách này, tôi cần phải giữ cho trình duyệt của tôi mở và việc thực thi sẽ dừng lại nếu kết nối Internet của tôi bị ngắt kết nối.

Vì vậy, có cách nào tốt hơn để thực hiện việc này không?

Hy vọng tôi đủ rõ ràng để giải thích những gì tôi muốn? Tôi muốn thực thi một tập lệnh lớn có thể mất nhiều giờ để thực thi mà không bị hết thời gian chờ.

+0

Đang nói chuyện với API từ máy tính cục bộ nơi bạn có thể tăng giới hạn thời gian cho câu hỏi? –

+1

Bạn có khả năng thiết lập công việc cron trên máy chủ chia sẻ của mình không? – Mathew

+0

Có, tôi có quyền truy cập vào các công việc cron –

Trả lời

4

Nếu máy chủ của bạn cho phép bạn, công việc cron là giải pháp tốt nhất. Một công việc cron cơ bản là một tập lệnh php bình thường được tự động chạy bởi máy chủ web tại một khoảng thời gian cụ thể. Đối với nhu cầu của bạn, tôi sẽ tạo một kịch bản chạy 5 phút một lần và xử lý các số của bạn theo lô 100 (rõ ràng là bạn sẽ muốn tinh chỉnh khoảng thời gian và kích cỡ lô cho phù hợp). Điều này sẽ giữ cho máy chủ của bạn tải xuống và ngăn bạn gặp rắc rối với nhà cung cấp dịch vụ lưu trữ của bạn về tài nguyên hogging.

Để theo dõi lô nào mà tập lệnh của bạn sẽ được xử lý, tôi sẽ thiết lập bảng track_batch.Các cột này sẽ cho bạn một dấu hiệu tốt của cách tiếp cận vấn đề:

id, date_run, start_record, end_record, final_run

Về cơ bản:

  • Kiểm tra để xem ngày của đợt cuối cùng chạy. Nếu đó không phải là ngày hiện tại (hoặc bất kỳ số nhận dạng nào khác bạn chọn để sử dụng ) cho lô hiện tại, thì sẽ tiếp tục.
  • Nếu lô hàng cuối cùng chạy cho ngày hiện tại, sau đó kiểm tra cột final_run để xem liệu bạn đã hoàn thành xử lý tất cả các số.
  • Nếu bạn vẫn có số để xử lý, hãy sử dụng đầu và cuối bản ghi cùng với số LIMIT của MySQL để tạo truy vấn db mà tập lệnh của bạn sẽ sử dụng để nhận lô tiếp theo.
  • Xử lý số của bạn.
  • Lưu trữ tất cả thông tin từ lô này trong bảng track_batch.
  • Nếu số lượng các số truy vấn trả về là bao giờ nhỏ hơn kích thước mẻ tối đa, bạn đã đạt đến cuối và có thể thiết lập các cột final_run để 1.

Một khi bạn đã có bạn script, bạn sẽ cần thiết lập cron job. Máy chủ được chia sẻ có thể có giao diện tùy chỉnh của riêng họ để thực hiện việc này, vì vậy, có lẽ họ là những người tốt nhất để hỏi khi bạn đã làm việc với tập lệnh của mình.

5

Các tập lệnh PHP chạy từ dòng lệnh không bị ảnh hưởng bởi tùy chọn max_execution_time.
Vì vậy, bạn không phải lo lắng gì cả.

+0

Và làm cách nào để chạy chúng dưới dạng CLI trên máy chủ chia sẻ? Tôi không nghĩ rằng tôi sẽ có quyền truy cập vào nó. –

+0

vâng đúng. cảm ơn :) –

+1

Xem bạn có phần "cron" trong bảng điều khiển hay không. Điều đó sẽ cho phép bạn chạy các tập lệnh PHP thông qua dòng lệnh. – zundi

0

Bạn thể hoặc bạn không thể sử dụng set_time_limit()?

Nếu bạn có thể .. Sử dụng nó:

<?php 
// Runs forever and ever... 
set_time_limit(-1); 
?> 
+8

Hehe, tôi sẽ không downvote bởi vì nó về mặt kỹ thuật chính xác, nhưng bạn sẽ đề nghị ông cho phép một kịch bản để chạy mãi mãi nếu anh ta * * hàng xóm của bạn trên một máy chủ chia sẻ ?!:) – Mathew

20

Một kịch bản PHP thực hiện từ dòng lệnh hoặc từ một kịch bản shell, công việc định kỳ vv không có thời gian chờ.

Đối với tập lệnh được CLI gọi, ngay cả khi bạn đặt thời gian chờ của tập lệnh PHP động với chức năng set_time_limit(), nó không có hiệu lực.

+0

vui lòng trả lời câu hỏi của tôi trên: http://unix.stackexchange.com/questions/98642/run-a-php-script-in-centos-and-time-and-timeout?noredirect=1#comment150287_98642 –

3

Đây không phải là lựa chọn tốt nhất để sử dụng set_time_limit(0), vì điều đó có nghĩa là nó sẽ chạy vô thời hạn ngay cả khi bạn có lỗi và tập lệnh của bạn nhập vào vòng lặp vô hạn.

Thay vào đó, nếu bạn ước tính mỗi SMS sẽ mất 5 giây, sử dụng phương pháp này:

while($there_are_more_sms_to_be_sent){ 
    set_time_limit(30); // enough spare time, just in case. 

    // Do your sending, blah blah 
} 

Bằng cách đó, thời hạn sẽ được tuần tự cập nhật đến 30 giây. Tất nhiên bạn có thể gặp vấn đề về vòng lặp vô hạn với while đơn lẻ đó, nhưng nếu bạn có các cuộc gọi khác bên trong đó while giới hạn đó sẽ ngăn chặn các cuộc gọi đó là để đổ lỗi.

+0

vì vậy mỗi lần nó lặp lại, là thiết lập lại truy cập? –

+0

Đúng vậy. Tôi đã giả sử bạn đang sử dụng một cronjob cũng. Bạn nên sử dụng nó cùng với mẹo này, do đó, bạn xử lý, nói, 100 tin nhắn mỗi lần nhưng bạn cũng đảm bảo rằng bạn không hết thời gian. – Seb

+0

Bạn có chắc chắn rằng bạn có thể ngừng các công việc cron như thế này? – zehelvion

0

Một thay thế cho việc sử dụng JavaScript để thêm thẻ meta Refresh vào trang của bạn:

<meta http-equiv="Refresh" content="2; url=http://yoururl/script.php&step=x" ?> 

Hai trong content="2; url=.. cho trình duyệt để tải url 2 giây sau khi trang đã được nạp.

+1

Cảm ơn nhưng, tôi đã xác định điều này trong câu hỏi của mình. Tôi đã tìm kiếm một cái gì đó được thực hiện bởi Server Side. Tôi cũng biết về CRON nhưng tôi nghĩ rằng có thể có nhiều cách để làm việc này –

+0

anh ấy rõ ràng hỏi làm thế nào để .... PHP workaround công nghệ không phải là giải pháp tốt nhất –

+0

Tôi không biết tại sao bạn nghĩ rằng nó cần thiết để phản ứng trên một bài đăng gần 7 tuổi, nhưng để trả lời: trong khi sử dụng cron hoặc lệnh dòng lệnh là một giải pháp rất tốt để chạy các hoạt động hàng loạt lớn, tách một công việc thành các bước nhỏ và thực hiện chúng từng bước chỉ là hợp lệ. Cron là tốt đẹp nơi bạn có thể sử dụng nó, nhưng tôi đã chạy thành công các kịch bản mất hơn 12 giờ trong trình duyệt khi tôi không có quyền truy cập trình bao. – Matijs

0

TRONG TRƯỜNG HỢP BẠN CÓ THỂ RUN CRON JOBS

Tôi thường có hàng đợi, người quản lý và công nhân. Trừ khi bạn có thể gọi sms api một lần tại thời điểm mô hình này có thể giúp bạn, và bạn không nên lo lắng về thời gian chờ vì mỗi nhân viên sẽ quản lý bản thân nó.

Tôi có một cái gì đó như:

<?php 
// PSEUDO CODE 
// grab pending from queue 

// <for> { 
// update to running 
exec("/usr/bin/php /path/to/send.php {$id} > /dev/null &"); 
// } 

và send.php sẽ gửi cho mỗi sms. Hiện tại, tôi có tốc độ tối đa là 300/phút kể từ khi tần suất tối đa mà bạn có thể thiết lập trên công việc cron

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