我必须为我的商店(产品,价格,类别)解析3个远程XML文件,其中最大的约为500MB +。我必须解析它们并插入到mysql数据库中。
我可以选择2种格式
所以,基本上我有2个选项(我认为)
我两个都有麻烦。
在流式传输时“随时随地”解析XML
$url = "http://example.xml";
$reader = new XMLReader();
$reader->open($url);
$item = array();
while ($reader->read()) {
switch ($reader->nodeType) {
case (XMLReader::ELEMENT):
if ($reader->localName == 'item') {
$item = array();
$item['id'] = $reader->getAttribute('id');
while ($reader->read()){
if ($reader->nodeType == XMLReader::ELEMENT) {
$name = strtolower($reader->localName);
$reader->read();
$item[$name] = $reader->value;
}
if ($reader->nodeType == XMLReader::END_ELEMENT && $reader->localName == 'item')
break;
}
// Yii framework's mysql query
Yii::app()->db->createCommand('INSERT INTO `products` (id, name, parent_id, parent_name, brand, image) VALUES
('.$item['id'].', "'.$item['name'].'", '.$item['parent_id'].', "'.$item['parent_name'].'", "'.$item['brand'].'", "'.$item['img'].'")
')->execute();
}
} }
这段代码可以正常使用没有mysql查询,但是如果我把它们放在一起会抛出各种错误
解析器错误:文档末尾的额外内容
说我想在myxml.tar.gz中解析products.xml,它甚至可能吗?
$url = "compress.zlib:///myxml.tar.gz";
$reader = new XMLReader();
$reader->open($url);
$reader->read();
它说文件是空的
答案 0 :(得分:0)
我喜欢你。
我已经从web-service zip archive下载了压缩的3 xml大文件。 我这样做: 在init i上设置:
ini_set('max_execution_time',1000); // 600秒
ini_set('mysql.connect_timeout',1000); //运行大型sql
ini_set('default_socket_timeout',1000);
我将zip文件下载到临时文件夹:
/**
* Metoda care scrie arhiva pe hardisc
* @param $string textul de scris in fisierul zip
* @return string Calea catre fisiser
*/
private function write_to_file($string)
{
$base = $this->tmpPath;
$date_folder = $base.date('Y_m').DIRECTORY_SEPARATOR.date('d');
if(!file_exists($date_folder))
{
mkdir($date_folder, 0777, TRUE);
}
$file = $date_folder.DIRECTORY_SEPARATOR.'products_'.date("Y_m_d_H_i").'.zip';
// This uses less memory than file_put_contents
$f = fopen($file, 'w');
fwrite($f, $string);
fclose($f);
return $file;
}
在此之后,我将zip文件从zip文件夹中提取出来:
public function dezarhiveaza($file)
{
$zip = new ZipArchive;
$res = $zip->open($file);
if ($res === TRUE) {
$zip->extractTo($this->tmpPath);
$zip->close();
$this->write_log('extract success');
} else {
$this->write_log('error ');
}
}
接下来,我从XML中提取产品列表,然后使用1000行插入MySQL查询:
private function deserializeazaForme()
{
$formePath=$this->tmpPath.
"data".DIRECTORY_SEPARATOR.'forme.xml';
$xml = simplexml_load_file($formePath);
$forme = $xml->xpath('//Table');
if($forme)
{
$strFormeInsertFirst="INSERT INTO `forme` (`id`, `denumire`) VALUES ";
$strFormeInsert=$strFormeInsertFirst;
foreach ($forme as $key=>$forma) {
$strFormeInsert .= "(".$forma->id.",'".$forma->denumire."),";
if($key%1000==0 && $key >0){
$strFormeInsert = rtrim($strFormeInsert, ",") ;
$strFormeInsert .=";";
$this->runQuery($strFormeInsert);
$strFormeInsert=$strFormeInsertFirst;
}
}
$strFormeInsert = rtrim($strFormeInsert, ",") ;
$strFormeInsert .=";";
$this->runQuery($strFormeInsert);
}
}