如何拆分需要很长时间才能运行到较小块的PHP脚本?

时间:2021-05-28 04:03:12

I have a PHP script that initialises an image gallery. It loops through all images, checks if they are thumbnailed and watermarks them.

我有一个PHP脚本初始化图像库。它遍历所有图像,检查它们是否被缩略图并为它们添加水印。

My shared hosting account only lets me have 30 seconds of execution per script, as set in the php.ini settings. I can't change that.

我的共享主机帐户只允许每个脚本执行30秒,如php.ini设置中所设置的那样。我无法改变这一点。

What can I do to get round this? Currently I refresh the page after every 5 images, this prevents the script timing out, but the browser recognises that the script won't complete and gives an error. That's ok, but it's not really user friendly.

我该怎么做才能绕过这个?目前我在每5张图片后刷新页面,这可以防止脚本超时,但浏览器会识别出脚本无法完成并出错。没关系,但它不是真的用户友好。

Any suggestions?

8 个解决方案

#1


3  

three ideas:

  1. you could offload this to a script that runs on the server (PHP CLI perhaps?) and have your current script check the progress (still running! check back later!).

    您可以将其卸载到服务器上运行的脚本(也许是PHP CLI?)并让您当前的脚本检查进度(仍在运行!稍后再回来查看!)。

  2. if javascript is ok in your environment, perhaps you could make ajax calls to handle this as well. the first solution allows the user to keep wandering around the site though, not sure if that's an important consideration in your case.

    如果您的环境中的javascript正常,也许您可​​以进行ajax调用来处理这个问题。第一种解决方案允许用户继续在网站上游荡,但不确定这是否是您案例中的重要考虑因素。

  3. you could get the PHP script to just do a certain batch (say 10 images at a time), then refresh the page with a progress report and go for 10 more, instead of an arbitrary time based refresh.

    您可以让PHP脚本只执行一定的批处理(一次说10个图像),然后使用进度报告刷新页面并再进行10次,而不是基于任意时间的刷新。

#2


4  

Perhaps you should avoid batching and make a proxy-generation script that does the process for each image on-demand.

也许您应该避免批处理并制作代理生成脚本,以便按需为每个映像执行该过程。

Rewrite the conversion code in a proxy PHP script which checks if the image is already thumbnailed and if not, does what needs to be done. The thumbnailed or watermarked file can be then be loaded and sent to the client using fpassthru().

在代理PHP脚本中重写转换代码,该脚本检查图像是否已经缩略图,如果没有,则执行需要执行的操作。然后可以使用fpassthru()加载缩略图或带水印的文件并将其发送到客户端。

Your webpage should only refer to the proxy-script, like

您的网页应该只引用代理脚本,例如

<img src="/image.php?DSC001.JPG">

If your provider supports Apache/rewriting, you can do even more magic by bypassing the proxy/generation script if the thumbnail has already been created.

如果您的提供程序支持Apache /重写,如果已经创建了缩略图,则可以通过绕过代理/生成脚本来实现更多魔力。

#3


3  

get a list of images and then loop through them for example you get a total of 500 imgs you can take 5 at a time and after you're finished with them output a meta refresh tag that will reload the script in 2 seconds for example with the image number you're currently at as a parameter .

得到一个图像列表,然后循环遍历它们,例如,你可以一次获取总共500个imgs,并且在你完成它们之后输出一个元刷新标记,它将在2秒内重新加载脚本,例如您当前所在的图像编号作为参数。

<meta http-equiv="refresh" content="2;url=script.php?start=5">

and in your script also check what $_GET['start'] is and continue from there with next 5 images then output start=10 and so one... until you loop through all of them.

并在你的脚本中还检查$ _GET ['start']是什么,并从那里继续下5个图像,然后输出start = 10,所以一个...直到你遍历所有这些。

#4


1  

You could use set_time_limit() although some hosts may not support this, but most do now.

您可以使用set_time_limit(),虽然有些主机可能不支持此功能,但大多数主机现在都支持。

#5


1  

You might also want to try optimizing your script. Are you doing too much in your loop? Could you move something out of the loop? What are you using to get the list of files? Is there a more light-weight way to do that? These are the sort of questions you can ask yourself about your script so that instead of splitting it up you might get the whole shebang to run in time.

您可能还想尝试优化脚本。你在循环中做得太多了吗?你可以把一些东西移出循环吗?你用什么来获取文件列表?有更轻量级的方法吗?这些是你可以问自己关于你的脚本的问题,这样你可以让整个shebang及时运行,而不是将它分开。

Failing that, I agree with Owen's suggestion of using AJAX. When the user kicks the process off you'll output a page as normal and then send back requests to process files out of band and then write status updates to the page as they come in.

如果不这样做,我同意Owen关于使用AJAX的建议。当用户关闭该过程时,您将正常输出页面,然后将请求发送回带外处理文件,然后在页面进入时将状态更新写入页面。

#6


0  

What about some kind of task list, for example:

某种任务列表怎么样,例如:

  1. First script makes a list of images that need thumbnails or watermarking
  2. 第一个脚本生成需要缩略图或水印的图像列表

  3. Second script checks this list and does the first 5 or so (however many can be done in the time limit) and removes them from the list
  4. 第二个脚本检查此列表并执行前5个左右(但可以在时间限制内完成许多)并将其从列表中删除

  5. Have the script in step 2 return a value that tells you if the list is empty, if not then repeat step 2 (probably easiest with ajax)
  6. 让步骤2中的脚本返回一个值,告诉您列表是否为空,如果没有,则重复步骤2(可能最简单的使用ajax)

Using this method, the only thing 'running' for the whole time is the page in your browser, each script only runs for 30 seconds.

使用这种方法,整个时间内唯一“运行”的是浏览器中的页面,每个脚本只运行30秒。

#7


0  

I think that it's a sign of something else going awry if each page load is taking over 30 seconds. How many images do you have? Are you storing the watermarked/thumbnailed versions on disk? If you're not doing that, then there's your answer: sure, it might take up a bit of space, but it'll avoid this problem altogether, as well as allow clients to cache the images.

如果每个页面加载超过30秒,我认为这是其他错误的迹象。你有几个图像?您是否将水印/缩略图版本存储在磁盘上?如果您没有这样做,那么您的答案就是:确定,它可能会占用一些空间,但它会完全避免这个问题,并允许客户端缓存图像。

If you are sure that the way you're doing it is the only way, then look at the set_time_limit function to increase script running time.

如果您确定以这种方式进行操作是唯一的方法,那么请查看set_time_limit函数以增加脚本运行时间。

#8


0  

On a shared hosting env, I would not recommend you run a script that might take more than 30 seconds to process and do n't even think about set_time_limit. What I would recommend is that you either do your thumbnails and watermarking on picture upload ? or picture request and mark the picture as done so you don't have to do it again. The other option is to run a batch that will process for instance 10 pictures every minute or 10 minutes but run the script via cli in the crontab....

在共享主机环境中,我不建议您运行可能需要超过30秒才能处理的脚本,甚至不要考虑set_time_limit。我建议您使用缩略图和图片上传水印?或图片请求并将图片标记为已完成,因此您无需再次执行此操作。另一种选择是运行一个批处理,每分钟或10分钟处理10个图片,但是通过crontab中的cli运行脚本....

It's a good practice to always know how much resources your script might be using when running a batch script....especially in a shared hosting env....this can affect other users easily.

在运行批处理脚本时,始终知道脚本可能使用了多少资源,这是一个很好的做法....特别是在共享主机环境中....这可能会轻易影响其他用户。

#1


3  

three ideas:

  1. you could offload this to a script that runs on the server (PHP CLI perhaps?) and have your current script check the progress (still running! check back later!).

    您可以将其卸载到服务器上运行的脚本(也许是PHP CLI?)并让您当前的脚本检查进度(仍在运行!稍后再回来查看!)。

  2. if javascript is ok in your environment, perhaps you could make ajax calls to handle this as well. the first solution allows the user to keep wandering around the site though, not sure if that's an important consideration in your case.

    如果您的环境中的javascript正常,也许您可​​以进行ajax调用来处理这个问题。第一种解决方案允许用户继续在网站上游荡,但不确定这是否是您案例中的重要考虑因素。

  3. you could get the PHP script to just do a certain batch (say 10 images at a time), then refresh the page with a progress report and go for 10 more, instead of an arbitrary time based refresh.

    您可以让PHP脚本只执行一定的批处理(一次说10个图像),然后使用进度报告刷新页面并再进行10次,而不是基于任意时间的刷新。

#2


4  

Perhaps you should avoid batching and make a proxy-generation script that does the process for each image on-demand.

也许您应该避免批处理并制作代理生成脚本,以便按需为每个映像执行该过程。

Rewrite the conversion code in a proxy PHP script which checks if the image is already thumbnailed and if not, does what needs to be done. The thumbnailed or watermarked file can be then be loaded and sent to the client using fpassthru().

在代理PHP脚本中重写转换代码,该脚本检查图像是否已经缩略图,如果没有,则执行需要执行的操作。然后可以使用fpassthru()加载缩略图或带水印的文件并将其发送到客户端。

Your webpage should only refer to the proxy-script, like

您的网页应该只引用代理脚本,例如

<img src="/image.php?DSC001.JPG">

If your provider supports Apache/rewriting, you can do even more magic by bypassing the proxy/generation script if the thumbnail has already been created.

如果您的提供程序支持Apache /重写,如果已经创建了缩略图,则可以通过绕过代理/生成脚本来实现更多魔力。

#3


3  

get a list of images and then loop through them for example you get a total of 500 imgs you can take 5 at a time and after you're finished with them output a meta refresh tag that will reload the script in 2 seconds for example with the image number you're currently at as a parameter .

得到一个图像列表,然后循环遍历它们,例如,你可以一次获取总共500个imgs,并且在你完成它们之后输出一个元刷新标记,它将在2秒内重新加载脚本,例如您当前所在的图像编号作为参数。

<meta http-equiv="refresh" content="2;url=script.php?start=5">

and in your script also check what $_GET['start'] is and continue from there with next 5 images then output start=10 and so one... until you loop through all of them.

并在你的脚本中还检查$ _GET ['start']是什么,并从那里继续下5个图像,然后输出start = 10,所以一个...直到你遍历所有这些。

#4


1  

You could use set_time_limit() although some hosts may not support this, but most do now.

您可以使用set_time_limit(),虽然有些主机可能不支持此功能,但大多数主机现在都支持。

#5


1  

You might also want to try optimizing your script. Are you doing too much in your loop? Could you move something out of the loop? What are you using to get the list of files? Is there a more light-weight way to do that? These are the sort of questions you can ask yourself about your script so that instead of splitting it up you might get the whole shebang to run in time.

您可能还想尝试优化脚本。你在循环中做得太多了吗?你可以把一些东西移出循环吗?你用什么来获取文件列表?有更轻量级的方法吗?这些是你可以问自己关于你的脚本的问题,这样你可以让整个shebang及时运行,而不是将它分开。

Failing that, I agree with Owen's suggestion of using AJAX. When the user kicks the process off you'll output a page as normal and then send back requests to process files out of band and then write status updates to the page as they come in.

如果不这样做,我同意Owen关于使用AJAX的建议。当用户关闭该过程时,您将正常输出页面,然后将请求发送回带外处理文件,然后在页面进入时将状态更新写入页面。

#6


0  

What about some kind of task list, for example:

某种任务列表怎么样,例如:

  1. First script makes a list of images that need thumbnails or watermarking
  2. 第一个脚本生成需要缩略图或水印的图像列表

  3. Second script checks this list and does the first 5 or so (however many can be done in the time limit) and removes them from the list
  4. 第二个脚本检查此列表并执行前5个左右(但可以在时间限制内完成许多)并将其从列表中删除

  5. Have the script in step 2 return a value that tells you if the list is empty, if not then repeat step 2 (probably easiest with ajax)
  6. 让步骤2中的脚本返回一个值,告诉您列表是否为空,如果没有,则重复步骤2(可能最简单的使用ajax)

Using this method, the only thing 'running' for the whole time is the page in your browser, each script only runs for 30 seconds.

使用这种方法,整个时间内唯一“运行”的是浏览器中的页面,每个脚本只运行30秒。

#7


0  

I think that it's a sign of something else going awry if each page load is taking over 30 seconds. How many images do you have? Are you storing the watermarked/thumbnailed versions on disk? If you're not doing that, then there's your answer: sure, it might take up a bit of space, but it'll avoid this problem altogether, as well as allow clients to cache the images.

如果每个页面加载超过30秒,我认为这是其他错误的迹象。你有几个图像?您是否将水印/缩略图版本存储在磁盘上?如果您没有这样做,那么您的答案就是:确定,它可能会占用一些空间,但它会完全避免这个问题,并允许客户端缓存图像。

If you are sure that the way you're doing it is the only way, then look at the set_time_limit function to increase script running time.

如果您确定以这种方式进行操作是唯一的方法,那么请查看set_time_limit函数以增加脚本运行时间。

#8


0  

On a shared hosting env, I would not recommend you run a script that might take more than 30 seconds to process and do n't even think about set_time_limit. What I would recommend is that you either do your thumbnails and watermarking on picture upload ? or picture request and mark the picture as done so you don't have to do it again. The other option is to run a batch that will process for instance 10 pictures every minute or 10 minutes but run the script via cli in the crontab....

在共享主机环境中,我不建议您运行可能需要超过30秒才能处理的脚本,甚至不要考虑set_time_limit。我建议您使用缩略图和图片上传水印?或图片请求并将图片标记为已完成,因此您无需再次执行此操作。另一种选择是运行一个批处理,每分钟或10分钟处理10个图片,但是通过crontab中的cli运行脚本....

It's a good practice to always know how much resources your script might be using when running a batch script....especially in a shared hosting env....this can affect other users easily.

在运行批处理脚本时,始终知道脚本可能使用了多少资源,这是一个很好的做法....特别是在共享主机环境中....这可能会轻易影响其他用户。