Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 执行大文件时发生服务器错误_Php_Xml_Magento_Xmlreader - Fatal编程技术网

Php 执行大文件时发生服务器错误

Php 执行大文件时发生服务器错误,php,xml,magento,xmlreader,Php,Xml,Magento,Xmlreader,我创建了一个脚本,用于读取XML文件并将其添加到数据库中。我正在为此使用XML阅读器。 问题是我的XML包含500000个产品。这会导致我的页面超时。我有办法做到这一点吗 我的代码如下: $z = new XMLReader; $z->open('files/NAGardnersEBook.xml'); $doc = new DOMDocument; # move to the first node while ($z->read() && $z->name

我创建了一个脚本,用于读取XML文件并将其添加到数据库中。我正在为此使用XML阅读器。 问题是我的XML包含500000个产品。这会导致我的页面超时。我有办法做到这一点吗

我的代码如下:

$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);
}
谢谢,

朱利安

你有没有尝试过添加set\u time\u limit0;在你的PHP文件之上

编辑:


在此处指定您的限制。

您可以使用该函数延长允许的脚本执行时间或在php.ini中设置最大执行时间。

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

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

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

例如,每分钟10.000件产品

您对每个ISBN执行两个查询,只是为了检查ISBN是否已经存在。相反,将ISBN列设置为unique(唯一),如果它还没有设置,则应该设置为unique(唯一),然后继续插入而不进行检查。如果MySQL检测到可以处理的重复项,它将返回一个错误。这将减少查询数量并提高性能。 您将通过对数据库的单独调用插入每个标题。相反,使用扩展的插入语法在一个查询中批处理多个插入-有关ful语法,请参阅MySQL手册。批处理,比如说,250次插入将节省大量时间。 如果您对批处理插入不满意,请使用mysqli准备的语句,这将减少解析时间和传输时间,从而提高总体性能 你可能信任加德纳列表-考虑放弃一些你正在做的逃避。通常情况下,我不建议用户输入,但这是一种特殊情况。
谢谢大家这么快的反馈。我设法通过使用array_块对问题进行排序。示例如下:

$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;
我希望这对某人有帮助


朱利安

是的,它不起作用。我想这是因为内存不足。我的猜测是将数组分割成多个块?不知道该怎么办it@Julian,则需要增加内存限制。检查我的编辑。No-OP是在顺序执行查询之前将查询组装成一个数组。如果他在构造查询时执行每个查询,那么内存就不应该是问题。
$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;