如何执行大型PHP脚本?

时间:2022-05-19 01:02:23

Well basically I may want to execute a script that may take as much as 1 hours as well.

基本上我可能想要执行一个可能需要1个小时的脚本。

What I really want to do is Send SMS to my users using a third party API. So its basically like I supply my script with an array of phone numbers and fire the method to send SMS.

我真正想做的是使用第三方API向我的用户发送短信。所以它基本上就像我为我的脚本提供一系列电话号码并触发发送短信的方法。

However assuming it take 5 seconds to send 1 SMS and I want to send 1000 SMS which is roughly 1 - 2 hours. I can't use set_time_limit() because I am on shared host.

然而,假设发送1条短信需要5秒钟,我想发送大约1至2小时的1000条短信。我不能使用set_time_limit()因为我在共享主机上。

One way to do this is store numbers in a session and execute each SMS and use javascript to refresh that page until end. This way I need to keep my browser open and the execution will stop if my Internet Connection is disconnected.

一种方法是在会话中存储号码并执行每个SMS并使用javascript刷新该页面直到结束。这样我需要保持浏览器打开,如果我的Internet连接断开连接,执行将停止。

So, Is there any better way to do this ?

那么,有没有更好的方法呢?

Hope I am clear enough to explain what I want? I want to execute a large script that may take hours to execute without getting timeout.

希望我清楚地解释我想要什么?我想执行一个大脚本,可能需要几个小时才能执行而不会超时。

7 个解决方案

#1


4  

If your host lets you, cron jobs are the best solution. A cron job is basically a normal php script that is automatically run by the web server at a specific time interval. For your needs I would create a script that runs every 5 mins and processes your numbers in batches of 100 (obviously you'll want to tweak the time interval and batch size to suit). This will keep your server load down and prevent you getting in trouble with your hosting provider for hogging resources.

如果您的主机允许您,cron作业是最佳解决方案。一个cron作业基本上是一个普通的PHP脚本,由Web服务器以特定的时间间隔自动运行。根据您的需要,我将创建一个每5分钟运行一次的脚本,并以100个批量处理您的数字(显然,您需要调整时间间隔和批量大小以适应)。这将使您的服务器负载降低,并防止您与托管服务提供商遇到麻烦来占用资源。

In order to track which batch your script should be processing, I would setup a track_batch table. These columns should give you a good indication of how to approach the problem:

为了跟踪脚本应该处理的批处理,我将设置一个track_batch表。这些列应该为您提供如何解决问题的良好指示:

id, date_run, start_record, end_record, final_run

id,date_run,start_record,end_record,final_run

Essentially:

主要有:

  • Check to see the date of the last batch run. If it isn't the current date (or whatever other identifier you choose to use) for the current batch, then proceed.
  • 检查以查看上次批次运行的日期。如果它不是当前批次的当前日期(或您选择使用的任何其他标识符),则继续。
  • If the last batch run was for the current date, then check the final_run column to see whether you've already finished processing all the numbers.
  • 如果最后一批运行是针对当前日期,则检查final_run列以查看您是否已经完成了所有数字的处理。
  • If you still have numbers to process, use the start and end records in conjunction with MySQL's LIMIT to build the db query that your script will use to get the next batch.
  • 如果仍有要处理的数字,请将开始和结束记录与MySQL的LIMIT结合使用,以构建脚本将用于获取下一批的db查询。
  • Process your numbers.
  • 处理你的号码。
  • Store all the info from this batch in the track_batch table.
  • 将此批次中的所有信息存储在track_batch表中。
  • If the amount of numbers the query returns is ever less than the maximum batch size, you've reached the end and can set the final_run column to 1.
  • 如果查询返回的数字量小于最大批量大小,则您已到达结尾并可将final_run列设置为1。

Once you've got your script, you'll need to setup the cron job itself. Shared hosts are likely to have their own custom interfaces for doing this, so they are probably the best people to ask once you've got your script working.

获得脚本后,您需要自己设置cron作业。共享主机可能有自己的自定义界面来执行此操作,因此一旦您的脚本正常工作,它们可能是最好的人。

#2


20  

A PHP script executed from the command-line or from a shell script, cron job, etc. does not have a timeout.

从命令行或shell脚本,cron作业等执行的PHP脚本没有超时。

For CLI-invoked scripts, even if you set the PHP script's timeout dynamically with the set_time_limit() function, it has no effect.

对于CLI调用的脚本,即使使用set_time_limit()函数动态设置PHP脚本的超时,它也不起作用。

#3


5  

PHP scripts running from the command line aren't affected by max_execution_time option.
So you don't have to worry at all.

从命令行运行的PHP脚本不受max_execution_time选项的影响。所以你根本不必担心。

#4


3  

It's not the best options to use set_time_limit(0), because that'd means it'll run indefinitely even if you have a bug and your script enters an infinite loop.

这不是使用set_time_limit(0)的最佳选项,因为即使你有一个bug并且你的脚本进入无限循环,这意味着它将无限期地运行。

Instead, if you estimate each SMS is going to take 5 seconds, use this approach:

相反,如果您估计每条SMS需要5秒钟,请使用以下方法:

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

  // Do your sending, blah blah
}

That way, the time limit will be sequentially updated to 30 seconds. Of course you might have the infinite loop problem with that single while, but if you have other calls inside that while that limit will prevent those calls to be to blame.

这样,时间限制将按顺序更新为30秒。当然,你可能会遇到那个单独的无限循环问题,但如果你内部有其他调用,那么这个限制将阻止这些调用。

#5


0  

You can or you can't use set_time_limit()?

你可以或者你不能使用set_time_limit()?

If you can.. Use it:

如果可以..使用它:

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

#6


0  

An alternative to using JavaScript is to add the Refresh meta tag to your page:

使用JavaScript的另一种方法是将Refresh元标记添加到您的页面:

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

The two in content="2; url=.. tells the browser to load the url 2 second after the page has loaded.

内容中的两个=“2; url = ..告诉浏览器在页面加载后加载网址2秒。

#7


0  

IN THE CASE YOU CAN RUN CRON JOBS

在这种情况下,你可以运行CRON JOBS

I usually have a queue, a manager and workers. Unless you can call the sms api once at the time this model can help you, and you souldn't worry about timeouts since each worker will manage it selves.

我通常有一个队列,一个经理和工人。除非您可以在此模型可以帮助您时调用短信api,并且您不必担心超时,因为每个工作人员都会自行管理。

I have something like:

我有类似的东西:

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

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

and send.php will send each sms. Right now I have this running at a rate of 300/minute since is the max frequency that you can setup on a cron job

和send.php将发送每个短信。现在我以300 /分钟的速度运行,因为你可以在cron作业上设置的最大频率

#1


4  

If your host lets you, cron jobs are the best solution. A cron job is basically a normal php script that is automatically run by the web server at a specific time interval. For your needs I would create a script that runs every 5 mins and processes your numbers in batches of 100 (obviously you'll want to tweak the time interval and batch size to suit). This will keep your server load down and prevent you getting in trouble with your hosting provider for hogging resources.

如果您的主机允许您,cron作业是最佳解决方案。一个cron作业基本上是一个普通的PHP脚本,由Web服务器以特定的时间间隔自动运行。根据您的需要,我将创建一个每5分钟运行一次的脚本,并以100个批量处理您的数字(显然,您需要调整时间间隔和批量大小以适应)。这将使您的服务器负载降低,并防止您与托管服务提供商遇到麻烦来占用资源。

In order to track which batch your script should be processing, I would setup a track_batch table. These columns should give you a good indication of how to approach the problem:

为了跟踪脚本应该处理的批处理,我将设置一个track_batch表。这些列应该为您提供如何解决问题的良好指示:

id, date_run, start_record, end_record, final_run

id,date_run,start_record,end_record,final_run

Essentially:

主要有:

  • Check to see the date of the last batch run. If it isn't the current date (or whatever other identifier you choose to use) for the current batch, then proceed.
  • 检查以查看上次批次运行的日期。如果它不是当前批次的当前日期(或您选择使用的任何其他标识符),则继续。
  • If the last batch run was for the current date, then check the final_run column to see whether you've already finished processing all the numbers.
  • 如果最后一批运行是针对当前日期,则检查final_run列以查看您是否已经完成了所有数字的处理。
  • If you still have numbers to process, use the start and end records in conjunction with MySQL's LIMIT to build the db query that your script will use to get the next batch.
  • 如果仍有要处理的数字,请将开始和结束记录与MySQL的LIMIT结合使用,以构建脚本将用于获取下一批的db查询。
  • Process your numbers.
  • 处理你的号码。
  • Store all the info from this batch in the track_batch table.
  • 将此批次中的所有信息存储在track_batch表中。
  • If the amount of numbers the query returns is ever less than the maximum batch size, you've reached the end and can set the final_run column to 1.
  • 如果查询返回的数字量小于最大批量大小,则您已到达结尾并可将final_run列设置为1。

Once you've got your script, you'll need to setup the cron job itself. Shared hosts are likely to have their own custom interfaces for doing this, so they are probably the best people to ask once you've got your script working.

获得脚本后,您需要自己设置cron作业。共享主机可能有自己的自定义界面来执行此操作,因此一旦您的脚本正常工作,它们可能是最好的人。

#2


20  

A PHP script executed from the command-line or from a shell script, cron job, etc. does not have a timeout.

从命令行或shell脚本,cron作业等执行的PHP脚本没有超时。

For CLI-invoked scripts, even if you set the PHP script's timeout dynamically with the set_time_limit() function, it has no effect.

对于CLI调用的脚本,即使使用set_time_limit()函数动态设置PHP脚本的超时,它也不起作用。

#3


5  

PHP scripts running from the command line aren't affected by max_execution_time option.
So you don't have to worry at all.

从命令行运行的PHP脚本不受max_execution_time选项的影响。所以你根本不必担心。

#4


3  

It's not the best options to use set_time_limit(0), because that'd means it'll run indefinitely even if you have a bug and your script enters an infinite loop.

这不是使用set_time_limit(0)的最佳选项,因为即使你有一个bug并且你的脚本进入无限循环,这意味着它将无限期地运行。

Instead, if you estimate each SMS is going to take 5 seconds, use this approach:

相反,如果您估计每条SMS需要5秒钟,请使用以下方法:

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

  // Do your sending, blah blah
}

That way, the time limit will be sequentially updated to 30 seconds. Of course you might have the infinite loop problem with that single while, but if you have other calls inside that while that limit will prevent those calls to be to blame.

这样,时间限制将按顺序更新为30秒。当然,你可能会遇到那个单独的无限循环问题,但如果你内部有其他调用,那么这个限制将阻止这些调用。

#5


0  

You can or you can't use set_time_limit()?

你可以或者你不能使用set_time_limit()?

If you can.. Use it:

如果可以..使用它:

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

#6


0  

An alternative to using JavaScript is to add the Refresh meta tag to your page:

使用JavaScript的另一种方法是将Refresh元标记添加到您的页面:

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

The two in content="2; url=.. tells the browser to load the url 2 second after the page has loaded.

内容中的两个=“2; url = ..告诉浏览器在页面加载后加载网址2秒。

#7


0  

IN THE CASE YOU CAN RUN CRON JOBS

在这种情况下,你可以运行CRON JOBS

I usually have a queue, a manager and workers. Unless you can call the sms api once at the time this model can help you, and you souldn't worry about timeouts since each worker will manage it selves.

我通常有一个队列,一个经理和工人。除非您可以在此模型可以帮助您时调用短信api,并且您不必担心超时,因为每个工作人员都会自行管理。

I have something like:

我有类似的东西:

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

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

and send.php will send each sms. Right now I have this running at a rate of 300/minute since is the max frequency that you can setup on a cron job

和send.php将发送每个短信。现在我以300 /分钟的速度运行,因为你可以在cron作业上设置的最大频率