简体   繁体   English

通过计数避免最长执行时间-PHP

[英]Avoid maximum execution time with a count - PHP

I have a script which is basically cleaning things up. 我有一个脚本,基本上是在清理东西。

One part of the script requires checking if images exist, using file_get_contents 脚本的一部分需要使用file_get_contents检查图像是否存在

I KNOW this is going to run into problems and I'm going to get Fatal error: Maximum execution time of 30 seconds exceeded from time to time and want to avoid that. 知道这会遇到问题,并且会出现Fatal error: Maximum execution time of 30 seconds exceeded并希望避免这种情况。

Is there a way to set a counter that starts counting and if file_get_contents fails after say 25 seconds the script ignores then carries on. 有没有一种方法可以设置一个开始计数的计数器,如果在说25秒后file_get_contents失败,脚本将忽略然后继续。

I will say, I know I can but I do not want to increase the time limit. 我会说,我知道可以,但我不想增加时限。

This is the basic script: 这是基本脚本:

$query = "select table_id, image_url from table";

$res = $mysqli->query($query) or trigger_error($mysqli->error."[$query]");

while($row = $res->fetch_array()){

    // save the image
    $img = '/path/to/'.$row[table_id].'.jpg';

    //## need to start counting to 25 secs here

    $saveImage = file_put_contents($img, file_get_contents($row[image_ur]));

    //## check if 25 seconds realised, if so with no $saveImage then continue

    if($saveImage){
        // do something else
    }

}

Instead of fetching the whole file, you could just "ping" it using CURL, so you only fetch its headers and get the status code (200 = file exists, 404 = file does not exist). 除了获取整个文件外,您还可以使用CURL对它进行“ ping”操作,因此仅获取其标头并获取状态代码(200 =文件存在,404 =文件不存在)。

If the files are NOT remote, use file_exists() . 如果文件不是远程文件,请使用file_exists() It would also be interesting wether PHPs wrappers are included into file_exists so you can do: 如果file_exists中包含PHP包装器,这也将很有趣,因此您可以执行以下操作:

file_exists('http://image.url.com/file.jpg');

I'm not sure wether this works or does check only for status code but it's worth a try. 我不确定这是否可行或是否仅检查状态码,但值得尝试。

Otherwise use CURL with the option not to download the body: 否则,请使用带有不下载正文的选项的CURL:

curl_setopt($curl, CURLOPT_NOBODY, true);

Its also good to run this script in CLI rather than through the browser then set the timeout to 2 hours and let it run.. 在CLI中运行此脚本而不是通过浏览器运行该脚本,然后将超时设置为2小时并使其运行,这也很好。

If you can't change the timeout, have a look at Gearman, and simply dispatch your job after hitting your script with the browser. 如果您无法更改超时,请查看Gearman,然后在使用浏览器点击脚本后简单地分派工作。

Update 更新

You don't have to "count to 25", you can set this timeout with options: 您不必“计数到25”,可以使用以下选项设置此超时:

CURL: http://php.net/manual/en/function.curl-setopt.php - CURLOPT_CONNECTTIMEOUT CURL: http://php.net/manual/en/function.curl-setopt.phpCURLOPT_CONNECTTIMEOUT

string file_get_contents ( string $filename
      [, bool $use_include_path = false
      [, resource $context [, int $offset = -1 [, int $maxlen ]]]] )

Use $context : 使用$context

resource stream_context_create ([ array $options [, array $params ]] )

In combination with stream_set_timeout : stream_set_timeout结合使用:

bool stream_set_timeout ( resource $stream , int $seconds [, int $microseconds = 0 ] )

I strongly suggest to use CURL with the options NOBODY and TIMEOUT so your script will run 10x faster AND have set a timeout (25 is way too much, use 5 or something lower). 我强烈建议将CURL与NOBODY和TIMEOUT选项一起使用,以便您的脚本运行速度提高10倍,并设置了超时时间(25太多了,使用5或更低的值)。

CURL also uses Keep-Alive , file_get_contents doesnt. CURL还使用Keep-Alivefile_get_contents不使用。

If you really want to do that you can use php micrtotime or time function to determine how long is the script running if you need to terminate the script after 25 seconds. 如果您确实想这样做,则可以使用php micrtotime或time函数来确定该脚本运行了多长时间(如果需要在25秒后终止该脚本)。 This are the documentation entries for them: http://php.net/time and http://php.net/microtime 这是它们的文档条目: http : //php.net/timehttp://php.net/microtime

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM