PHP - 执行长脚本时可能遇到的障碍

Obm*_*nen 5 php memory foreach ini loops

我有一个很长的循环在一个函数中运行,但没有完成所有的最终迭代和停止而没有给出任何错误:

function my_function(){

    foreach (range(100,999) as $art_id){ 


    $current++;//see bottom flush functions...
    outputProgress($current, $art_id );//see bottom flush functions...

// do a lot of stuff on remote URL...
    // including download images , 
    // scraping HTMl etc ..

    }
}
Run Code Online (Sandbox Code Playgroud)

我正在使用一些输出进度与flush来跟踪进度

function outputProgress($current, $total) {
    // echo "<span style='background:red;font-size:1.5em;color:#fff;'>" . round($current / $total * 100) . "% </span>";
    echo "<span style='background:red;font-size:1.5em;color:#fff;'>" . $current .'/'. $total  . "% </span>";
    myFlush();
    sleep(1);
}
Run Code Online (Sandbox Code Playgroud)

function myFlush() {
    echo(str_repeat(' ', 256));
    if (@ob_get_contents()) {
        @ob_end_flush();
    }
    flush();
}
Run Code Online (Sandbox Code Playgroud)

(不要介意百分比计算,它现在被禁用,只显示迭代的ID)

我注意到大多数时候我正在执行循环,它将在20-25次迭代后停止.有时甚至只有10.

我的第一个犯罪嫌疑人的time limit,而且max_execution time,所以我说:

set_time_limit(99999);
ini_set('max_execution_time', 99999);

function my_function(){

    foreach (range(410,499) as $art_id){ // done 500-600

    set_time_limit(99999);
    ini_set('max_execution_time', 99999);

    // do a lot of stuff on remote URL...
    // including download images , 
    // scraping HTMl etc ..
    }
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我已经添加了这两者INSIDEOUTSIDE函数本身,以防万一.

但它没有多大帮助,循环仍然停止.我的下一个嫌疑人是Memory limit,所以我补充说:

ini_set('memory_limit','128M');
Run Code Online (Sandbox Code Playgroud)

因为我正在研究wp,所以我也试过了

define('WP_MEMORY_LIMIT', '128M'); 
Run Code Online (Sandbox Code Playgroud)

但无济于事.经过一些迭代后,scipt仍然停止.

  • 这种行为的其他可能原因是什么,以及可能的补救措施?

请注意 - 脚本不会出现任何错误,只是在某个循环停止.

编辑我

我在这里粘贴了剧本 .它实际上是一个略微修改的scrap_slashdot()函数,来自simplehtmldom lib包含的例子.

它被修改为插入wordpress帖子,同时下载图像并附加它们.

编辑II 使用@Allendar评论echo ini_get('memory_limit');看起来像是有效的,它设置为128M ..

小智 1

我已经加紧usleep(50000);测试了。此代码在 PHP 上只需一秒钟即可完成5.4,并且不会导致内存泄漏:

ini_set('memory_limit', '32M'); // Force back to default X/W/L/M/AMP

function my_function(){
    $current = 0;

    foreach (range(100,999) as $art_id){ 
        $current++;
        outputProgress($current, $art_id );
    }
}

function outputProgress($current, $total) {
    echo "<span style='background:red;font-size:1.5em;color:#fff;'>" . $current .'/'. $total  . "% </span>";
    myFlush();
    usleep(50000);
}

function myFlush() {
    echo(str_repeat(' ', 256));
    if (@ob_get_contents()) {
        @ob_end_flush();
    }
    flush();
}

my_function();

echo memory_get_usage();
Run Code Online (Sandbox Code Playgroud)

我添加了$current = 0;取消 Xdebug 发出的警告的功能。

内存使用情况仅输出 282304 字节(约 275,69 KB)。

每个周期等待 1 秒可能会导致脚本在执行时中止。

ini_set('max_execution_time', 0);
Run Code Online (Sandbox Code Playgroud)

..会解决这个问题,但不推荐;)

如果你仍然发现脚本突然停止,那么它确实一定是在你有注释的部分,你写了代码。该代码可能对 PHP 守护程序的有效负载来说足够重,以致于中止。除此之外,还有一些主机(如果脚本在线)会阻止您设置 ini 值,甚至可能会终止 PHP 进程(如果它“僵尸”太久)。