1

我正在编写一个脚本来为具有约 700k 产品的电子商务网站创建站点地图。电子商务包已经有一个内置的站点地图生成器,但它的格式不适合大型产品数据库(带有 gzip 压缩 50k url 文件的链接的主数据库)。

我在运行脚本时遇到了内存管理问题,似乎脚本超过了 php 的垃圾收集能力。这是我所拥有的:

function buildSitemapFile()
{
    // prep sitemap string
    $content = "sitemap header info";

    $max_entries_per_sitemap = 50000;
    $current_batch = 0;

    while (buildSitemapZip($current_batch, $content, $max_entries_per_sitemap))
    {
        $current_batch++;
    }

    // finish sitemap string, open/create file, write to it, close file

}

function buildSitemapZip($batch, &$main_content, $max_urls = 50000)
{
    $file_name = *create file path string*

    // add this file to the index file's content string
    $main_content .= *this sitemap info*

    // open and prep this batch's site map file
    $handle = fopen($file_name, "w");

    $content = *sitemap header info*

    require_once('path_to_Product.class.php');
    $product = new Product();

    $group_size = 1000;

    // on first time called, $group_start = 0 (0 * 50000), group_start loops till >= 50000 ((0+1) * 50000), and group_start increments by $group_size on each pass 
    for ($group_start = $batch * $max_urls; $group_start < ($batch + 1) * $max_urls; $group_start += $group_size)
    {
        // request the next group of products. the query ends with "order by id limit $group_start, $group_size"
        $prods = $product->query_db_for_products($group_start, $group_size);

        // loop product set adding urls to the content string
        foreach($prods as $key => $prod)
        {
            $content .= *get info from product object to fill out the sitemap content string*
        }       

        if (count($prods) != $group_size)
        {
            // end of list
            $return_val = *stop looping*
            break;
        }
    }

    // complete sitemap string, write it to file, close file
    // create and open gzip file, write to it, close it, erase temp sitemap file

    return $return_val;
}

当我使用较小的 $group_size 值运行脚本时,它似乎不是这样的问题,但它非常慢并且开始减慢对数据库的访问(通过重复查询)。

eccomerce 包的对象上没有 __destruct 方法的 __construct。

我上次运行测试时 $group_size 为 10k(应该是 1k...),并且内存使用失控。我停止了脚本,但内存使用量(根据 top shell 命令)不断增加,几个小时后还没有发布。

关于脚本可能会导致问题的任何想法?

4

0 回答 0