5

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

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

我正在使用一些输出进度和刷新来跟踪进度

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

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

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

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

由于我正在研究 wp,我也尝试过

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

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

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

请注意 - 脚本没有给出任何错误,它只是在某个循环处停止。

编辑我

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

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

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

4

2 回答 2

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 进程“僵尸”时杀死它。

于 2013-04-02T09:56:16.833 回答
1

首先,这不是“长”脚本,我一直在使用数组 - 实际上 16 个数组都有超过 650 个索引(= 14 X 650 = 9100 个索引,如果我计算错误,则为 nvm)。它在几秒钟内加载,所以它似乎没有问题。我敢肯定你做错了什么。它工作正常(如果我知道正确的话)[(在线测试,在 php 5 上)] ],即使没有ini_set();(被网站禁用)并且内存使用量为 63072(以字节为单位 ~ 63kbs ~ 0.063mb > 128mb)

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

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

于 2013-04-02T10:10:15.507 回答