服务器错误执行大文件

时间:2013-08-07 08:49:24

标签: php xml magento xmlreader

我创建了一个脚本,它读取XML文件并将其添加到数据库中。我正在使用XML Reader。 问题是我的XML包含500,000个产品。这会导致我的页面超时。我有办法实现这个目标吗?

我的代码如下:

$z = new XMLReader;
$z->open('files/NAGardnersEBook.xml');

$doc = new DOMDocument;

# move to the first node
while ($z->read() && $z->name !== 'EBook');

# now that we're at the right depth, hop to the next <product/> until the end of the tree
while ($z->name === 'EBook')
{

    $node = simplexml_import_dom($doc->importNode($z->expand(), true));

    # Get the value of each node
    $title = mysql_real_escape_string($node->Title);
    $Subtitle = mysql_real_escape_string($node->SubTitle);
    $ShortDescription = mysql_real_escape_string($node->ShortDescription);
    $Publisher = mysql_real_escape_string($node->Publisher);
    $Imprint = mysql_real_escape_string($node->Imprint);

    # Get attributes
    $isbn = $z->getAttribute('EAN');

    $contributor = $node->Contributors;
    $author = $contributor[0]->Contributor;
    $author = mysql_real_escape_string($author);

    $BicSubjects = $node->BicSubjects;
    $Bic = $BicSubjects[0]->Bic;

    $bicCode = $Bic[0]['Code'];

    $formats = $node->Formats;
    $type  = $formats[0]->Format;
    $price = $type[0]['Price'];
    $ExclusiveRights = $type[0]['ExclusiveRights'];
    $NotForSale = $type[0]['NotForSale'];


    $arr[] = "UPDATE onix_d2c_data SET is_gardner='Yes', TitleText = '".$title."', Subtitle = '".$Subtitle."', PersonName='".$author."', ImprintName = '".$Imprint."', PublisherName = '".$Publisher."', Text = '".$ShortDescription."', BICMainSubject = '".$bicCode."', ExcludedTerritory='".$NotForSale."', RightsCountry='".$ExclusiveRights."', PriceAmount='".$price."', custom_category= 'Uncategorised', drm_type='adobe_drm' WHERE id='".$isbn."' ";

    # go to next <product />

    $z->next('EBook');
    $isbns[] = $isbn;
}


foreach($isbns as $isbn){

    $sql = "SELECT * FROM onix_d2c_data WHERE id='".$isbn."'";

    $query = mysql_query($sql);

    $count = mysql_num_rows($query);
    if($count >0){

    } else{
        $sql = "INSERT INTO onix_d2c_data (id) VALUES ('".$isbn."')";               
        $query = mysql_query($sql);
    }

}



foreach($arr as $sql){
    mysql_query($sql);
}

谢谢,

儒略

6 个答案:

答案 0 :(得分:1)

您可以使用函数set_time_limit来延长允许的脚本执行时间或在php.ini中设置max_execution_time

答案 1 :(得分:0)

您是否尝试在PHP文件上添加set_time_limit(0);

编辑:

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

在那里指定你的限制。

答案 2 :(得分:0)

您需要设置这些变量。确保您有权更改它们

set_time_limit(0);
ini_set('max_execution_time', '6000');

答案 3 :(得分:0)

如果您不想按照其他人的建议更改max_execution时间,那么您还可以将任务拆分为几个较小的任务,并让服务器在几个时间间隔内运行cron - 作业。

E.g。每分钟10.000件产品

答案 4 :(得分:0)

  1. 您正在为每个ISBN执行两个查询,只是为了检查ISBN是否已存在。相反,将ISBN列设置为unique(如果它不是,它应该是),然后继续插入而不检查。如果MySQL检测到您可以处理的重复项,它将返回错误。这将减少查询次数并提高性能。
  2. 您正在插入每个标题,并单独调用数据库。相反,使用扩展的INSERT语法在一个查询中批量处理许多插入 - 请参阅MySQL手册以获取完整的语法。例如,批量处理250个插入将节省大量时间。
  3. 如果您对批量插入不满意,请使用mysqli预处理语句,这将减少解析时间和传输时间,因此应提高整体性能
  4. 你可以信任加德纳的名单 - 考虑放弃你正在做的一些逃避。我不建议用户正常输入,但这是一个特例。

答案 5 :(得分:0)

谢谢大家的快速反馈。我设法通过使用array_chunks排序问题。示例如下:

$thumbListLocal = array_chunk($isbns, 4, preserve_keys);
$thumbListLocalCount = count($thumbListLocal);


while ($i <= $thumbListLocalCount):
    foreach($thumbListLocal[$i] as $index => $thumbName):
        $sqlConstruct[] = "INSERT IGNORE INTO onix_d2c_data (id) VALUES ('".$thumbName."')";

    endforeach;
    foreach($sqlConstruct as $processSql){
        mysql_query($processSql);
    }
    unset($thumbListLocal[$i]);
    $i++;
endwhile;

我希望这有助于某人。

儒略