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

时间:2013-04-02 09:49:06

标签: php loops memory foreach ini

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

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 ..

    }
}

我正在使用一些带有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);
}

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

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

我注意到大部分时间我都在执行循环, 它将在20-25次迭代后停止。有时甚至只有10个。

我的第一个嫌疑人是time limitmax_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 ..
    }
}

正如您所看到的,为了以防万一,我已将INSIDEOUTSIDE添加到函数本身中。

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

ini_set('memory_limit','128M');

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

define('WP_MEMORY_LIMIT', '128M'); 

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

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

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

编辑我

我已粘贴脚本HERE   。它实际上是simplehtmldom lib包含的示例中稍微修改过的scrap_slashdot()函数。

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

编辑II 使用@Allendar评论echo ini_get('memory_limit');似乎可行,并设置为128M ..

2 个答案:

答案 0 :(得分: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();

我已添加$current = 0;来取消Xdebug发出的警告。

内存使用量仅输出282304字节(约275,69千字节)。

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

ini_set('max_execution_time', 0);

..将解决此问题,但不建议使用;)

如果您仍然发现要突然停止的脚本,那么它必须位于您有注释的部分,您写的是代码。该代码可能对PHP守护进程的有效负载足够重。除此之外,还有主机(如果脚本在线)阻止您设置ini值,甚至可能会杀死PHP进程,如果它“长时间”“僵尸”。

答案 1 :(得分:0)

首先,这不是“长”脚本,我一直在使用数组 - 实际上是16个数组,所有数据都超过650个(= 14 X 650 = 9100个索引,nvm,如果我在计算中错了)。并且它在几分之一秒内加载,因此它似乎没有问题。我相信你做的事情严重错误。它工作正常(如果我知道的话) [(tested here online, on php 5)]],即使没有ini_set();(网站禁用),而且记忆用法是63072(以字节为单位~63kbs~0.063mb> 128mb)

想告诉你,你从哪里设置$current?您的my_function()没有参数,我还建议您打开错误报告 error_reporting(E_ALL); ini_set('display_errors', '1');

你正在使用的在线编译器应该有问题,试试我使用的或下载apache服务器,你也可以尝试一些免费的主机。