用PHP解析巨大的XML文件

用PHP解析巨大的XML文件

我正在尝试将DMOZ内容/结构XML文件解析为MySQL,但是执行此操作的所有现有脚本都很老,并且运行不正常。如何在PHP中打开一个大的(+ 1GB)XML文件进行解析?



慕少森
浏览 755回答 3
3回答

慕森王

只有两个PHP API非常适合处理大型文件。第一个是旧的expat&nbsp;api,第二个是较新的XMLreader函数。这些apis读取连续流而不是将整个树加载到内存中(这就是simplexml和DOM所做的)。例如,您可能希望查看DMOZ目录的这个部分解析器:<?phpclass&nbsp;SimpleDMOZParser{ &nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;$_stack&nbsp;=&nbsp;array(); &nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;$_file&nbsp;=&nbsp;""; &nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;$_parser&nbsp;=&nbsp;null; &nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;$_currentId&nbsp;=&nbsp;""; &nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;$_current&nbsp;=&nbsp;""; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;__construct($file) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->_file&nbsp;=&nbsp;$file; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->_parser&nbsp;=&nbsp;xml_parser_create("UTF-8"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xml_set_object($this->_parser,&nbsp;$this); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xml_set_element_handler($this->_parser,&nbsp;"startTag",&nbsp;"endTag"); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;startTag($parser,&nbsp;$name,&nbsp;$attribs) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array_push($this->_stack,&nbsp;$this->_current); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;($name&nbsp;==&nbsp;"TOPIC"&nbsp;&&&nbsp;count($attribs))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->_currentId&nbsp;=&nbsp;$attribs["R:ID"]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;($name&nbsp;==&nbsp;"LINK"&nbsp;&&&nbsp;strpos($this->_currentId,&nbsp;"Top/Home/Consumer_Information/Electronics/")&nbsp;===&nbsp;0)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;$attribs["R:RESOURCE"]&nbsp;.&nbsp;"\n"; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->_current&nbsp;=&nbsp;$name; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;endTag($parser,&nbsp;$name) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->_current&nbsp;=&nbsp;array_pop($this->_stack); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;parse() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$fh&nbsp;=&nbsp;fopen($this->_file,&nbsp;"r"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!$fh)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;die("Epic&nbsp;fail!\n"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(!feof($fh))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$data&nbsp;=&nbsp;fread($fh,&nbsp;4096); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xml_parse($this->_parser,&nbsp;$data,&nbsp;feof($fh)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;}}$parser&nbsp;=&nbsp;new&nbsp;SimpleDMOZParser("content.rdf.u8");$parser->parse();

慕的地8271018

我最近不得不解析一些非常大的XML文档,并且需要一种方法来一次读取一个元素。如果您有以下文件complex-test.xml:<?xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"?><Complex> &nbsp;&nbsp;<Object> &nbsp;&nbsp;&nbsp;&nbsp;<Title>Title&nbsp;1</Title> &nbsp;&nbsp;&nbsp;&nbsp;<Name>It's&nbsp;name&nbsp;goes&nbsp;here</Name> &nbsp;&nbsp;&nbsp;&nbsp;<ObjectData> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<Info1></Info1> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<Info2></Info2> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<Info3></Info3> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<Info4></Info4> &nbsp;&nbsp;&nbsp;&nbsp;</ObjectData> &nbsp;&nbsp;&nbsp;&nbsp;<Date></Date> &nbsp;&nbsp;</Object> &nbsp;&nbsp;<Object></Object> &nbsp;&nbsp;<Object> &nbsp;&nbsp;&nbsp;&nbsp;<AnotherObject></AnotherObject> &nbsp;&nbsp;&nbsp;&nbsp;<Data></Data> &nbsp;&nbsp;</Object> &nbsp;&nbsp;<Object></Object> &nbsp;&nbsp;<Object></Object></Complex>并希望返回<Object/>sPHP:require_once('class.chunk.php');$file&nbsp;=&nbsp;new&nbsp;Chunk('complex-test.xml',&nbsp;array('element'&nbsp;=>&nbsp;'Object'));while&nbsp;($xml&nbsp;=&nbsp;$file->read())&nbsp;{ &nbsp;&nbsp;$obj&nbsp;=&nbsp;simplexml_load_string($xml); &nbsp;&nbsp;//&nbsp;do&nbsp;some&nbsp;parsing,&nbsp;insert&nbsp;to&nbsp;DB&nbsp;whatever}###########Class&nbsp;File###########<?php/** &nbsp;*&nbsp;Chunk &nbsp;*&nbsp; &nbsp;*&nbsp;Reads&nbsp;a&nbsp;large&nbsp;file&nbsp;in&nbsp;as&nbsp;chunks&nbsp;for&nbsp;easier&nbsp;parsing. &nbsp;*&nbsp; &nbsp;*&nbsp;The&nbsp;chunks&nbsp;returned&nbsp;are&nbsp;whole&nbsp;<$this->options['element']/>s&nbsp;found&nbsp;within&nbsp;file. &nbsp;*&nbsp; &nbsp;*&nbsp;Each&nbsp;call&nbsp;to&nbsp;read()&nbsp;returns&nbsp;the&nbsp;whole&nbsp;element&nbsp;including&nbsp;start&nbsp;and&nbsp;end&nbsp;tags. &nbsp;*&nbsp; &nbsp;*&nbsp;Tested&nbsp;with&nbsp;a&nbsp;1.8MB&nbsp;file,&nbsp;extracted&nbsp;500&nbsp;elements&nbsp;in&nbsp;0.11s &nbsp;*&nbsp;(with&nbsp;no&nbsp;work&nbsp;done,&nbsp;just&nbsp;extracting&nbsp;the&nbsp;elements) &nbsp;*&nbsp; &nbsp;*&nbsp;Usage: &nbsp;*&nbsp;<code> &nbsp;*&nbsp;&nbsp;&nbsp;//&nbsp;initialize&nbsp;the&nbsp;object &nbsp;*&nbsp;&nbsp;&nbsp;$file&nbsp;=&nbsp;new&nbsp;Chunk('chunk-test.xml',&nbsp;array('element'&nbsp;=>&nbsp;'Chunk')); &nbsp;*&nbsp;&nbsp;&nbsp; &nbsp;*&nbsp;&nbsp;&nbsp;//&nbsp;loop&nbsp;through&nbsp;the&nbsp;file&nbsp;until&nbsp;all&nbsp;lines&nbsp;are&nbsp;read &nbsp;*&nbsp;&nbsp;&nbsp;while&nbsp;($xml&nbsp;=&nbsp;$file->read())&nbsp;{ &nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;do&nbsp;whatever&nbsp;you&nbsp;want&nbsp;with&nbsp;the&nbsp;string &nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$o&nbsp;=&nbsp;simplexml_load_string($xml); &nbsp;*&nbsp;&nbsp;&nbsp;} &nbsp;*&nbsp;</code> &nbsp;*&nbsp; &nbsp;*&nbsp;@package&nbsp;default &nbsp;*&nbsp;@author&nbsp;Dom&nbsp;Hastings &nbsp;*/class&nbsp;Chunk&nbsp;{ &nbsp;&nbsp;/** &nbsp;&nbsp;&nbsp;*&nbsp;options &nbsp;&nbsp;&nbsp;* &nbsp;&nbsp;&nbsp;*&nbsp;@var&nbsp;array&nbsp;Contains&nbsp;all&nbsp;major&nbsp;options &nbsp;&nbsp;&nbsp;*&nbsp;@access&nbsp;public &nbsp;&nbsp;&nbsp;*/ &nbsp;&nbsp;public&nbsp;$options&nbsp;=&nbsp;array( &nbsp;&nbsp;&nbsp;&nbsp;'path'&nbsp;=>&nbsp;'./',&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;string&nbsp;The&nbsp;path&nbsp;to&nbsp;check&nbsp;for&nbsp;$file&nbsp;in &nbsp;&nbsp;&nbsp;&nbsp;'element'&nbsp;=>&nbsp;'',&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;string&nbsp;The&nbsp;XML&nbsp;element&nbsp;to&nbsp;return &nbsp;&nbsp;&nbsp;&nbsp;'chunkSize'&nbsp;=>&nbsp;512&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;integer&nbsp;The&nbsp;amount&nbsp;of&nbsp;bytes&nbsp;to&nbsp;retrieve&nbsp;in&nbsp;each&nbsp;chunk &nbsp;&nbsp;); &nbsp;&nbsp;/** &nbsp;&nbsp;&nbsp;*&nbsp;file &nbsp;&nbsp;&nbsp;* &nbsp;&nbsp;&nbsp;*&nbsp;@var&nbsp;string&nbsp;The&nbsp;filename&nbsp;being&nbsp;read &nbsp;&nbsp;&nbsp;*&nbsp;@access&nbsp;public &nbsp;&nbsp;&nbsp;*/ &nbsp;&nbsp;public&nbsp;$file&nbsp;=&nbsp;''; &nbsp;&nbsp;/** &nbsp;&nbsp;&nbsp;*&nbsp;pointer &nbsp;&nbsp;&nbsp;* &nbsp;&nbsp;&nbsp;*&nbsp;@var&nbsp;integer&nbsp;The&nbsp;current&nbsp;position&nbsp;the&nbsp;file&nbsp;is&nbsp;being&nbsp;read&nbsp;from &nbsp;&nbsp;&nbsp;*&nbsp;@access&nbsp;public &nbsp;&nbsp;&nbsp;*/ &nbsp;&nbsp;public&nbsp;$pointer&nbsp;=&nbsp;0; &nbsp;&nbsp;/** &nbsp;&nbsp;&nbsp;*&nbsp;handle &nbsp;&nbsp;&nbsp;* &nbsp;&nbsp;&nbsp;*&nbsp;@var&nbsp;resource&nbsp;The&nbsp;fopen()&nbsp;resource &nbsp;&nbsp;&nbsp;*&nbsp;@access&nbsp;private &nbsp;&nbsp;&nbsp;*/ &nbsp;&nbsp;private&nbsp;$handle&nbsp;=&nbsp;null; &nbsp;&nbsp;/** &nbsp;&nbsp;&nbsp;*&nbsp;reading &nbsp;&nbsp;&nbsp;* &nbsp;&nbsp;&nbsp;*&nbsp;@var&nbsp;boolean&nbsp;Whether&nbsp;the&nbsp;script&nbsp;is&nbsp;currently&nbsp;reading&nbsp;the&nbsp;file &nbsp;&nbsp;&nbsp;*&nbsp;@access&nbsp;private &nbsp;&nbsp;&nbsp;*/ &nbsp;&nbsp;private&nbsp;$reading&nbsp;=&nbsp;false; &nbsp;&nbsp;/** &nbsp;&nbsp;&nbsp;*&nbsp;readBuffer &nbsp;&nbsp;&nbsp;*&nbsp; &nbsp;&nbsp;&nbsp;*&nbsp;@var&nbsp;string&nbsp;Used&nbsp;to&nbsp;make&nbsp;sure&nbsp;start&nbsp;tags&nbsp;aren't&nbsp;missed &nbsp;&nbsp;&nbsp;*&nbsp;@access&nbsp;private &nbsp;&nbsp;&nbsp;*/ &nbsp;&nbsp;private&nbsp;$readBuffer&nbsp;=&nbsp;''; &nbsp;&nbsp;/** &nbsp;&nbsp;&nbsp;*&nbsp;__construct &nbsp;&nbsp;&nbsp;*&nbsp; &nbsp;&nbsp;&nbsp;*&nbsp;Builds&nbsp;the&nbsp;Chunk&nbsp;object &nbsp;&nbsp;&nbsp;* &nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;string&nbsp;$file&nbsp;The&nbsp;filename&nbsp;to&nbsp;work&nbsp;with &nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;array&nbsp;$options&nbsp;The&nbsp;options&nbsp;with&nbsp;which&nbsp;to&nbsp;parse&nbsp;the&nbsp;file &nbsp;&nbsp;&nbsp;*&nbsp;@author&nbsp;Dom&nbsp;Hastings &nbsp;&nbsp;&nbsp;*&nbsp;@access&nbsp;public &nbsp;&nbsp;&nbsp;*/ &nbsp;&nbsp;public&nbsp;function&nbsp;__construct($file,&nbsp;$options&nbsp;=&nbsp;array())&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;merge&nbsp;the&nbsp;options&nbsp;together &nbsp;&nbsp;&nbsp;&nbsp;$this->options&nbsp;=&nbsp;array_merge($this->options,&nbsp;(is_array($options)&nbsp;?&nbsp;$options&nbsp;:&nbsp;array())); &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;check&nbsp;that&nbsp;the&nbsp;path&nbsp;ends&nbsp;with&nbsp;a&nbsp;/ &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(substr($this->options['path'],&nbsp;-1)&nbsp;!=&nbsp;'/')&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->options['path']&nbsp;.=&nbsp;'/'; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;normalize&nbsp;the&nbsp;filename &nbsp;&nbsp;&nbsp;&nbsp;$file&nbsp;=&nbsp;basename($file); &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;make&nbsp;sure&nbsp;chunkSize&nbsp;is&nbsp;an&nbsp;int &nbsp;&nbsp;&nbsp;&nbsp;$this->options['chunkSize']&nbsp;=&nbsp;intval($this->options['chunkSize']); &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;check&nbsp;it's&nbsp;valid &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;($this->options['chunkSize']&nbsp;<&nbsp;64)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->options['chunkSize']&nbsp;=&nbsp;512; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;set&nbsp;the&nbsp;filename &nbsp;&nbsp;&nbsp;&nbsp;$this->file&nbsp;=&nbsp;realpath($this->options['path'].$file); &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;check&nbsp;the&nbsp;file&nbsp;exists &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!file_exists($this->file))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;Exception('Cannot&nbsp;load&nbsp;file:&nbsp;'.$this->file); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;open&nbsp;the&nbsp;file &nbsp;&nbsp;&nbsp;&nbsp;$this->handle&nbsp;=&nbsp;fopen($this->file,&nbsp;'r'); &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;check&nbsp;the&nbsp;file&nbsp;opened&nbsp;successfully &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!$this->handle)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;Exception('Error&nbsp;opening&nbsp;file&nbsp;for&nbsp;reading'); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;} &nbsp;&nbsp;/** &nbsp;&nbsp;&nbsp;*&nbsp;__destruct &nbsp;&nbsp;&nbsp;*&nbsp; &nbsp;&nbsp;&nbsp;*&nbsp;Cleans&nbsp;up &nbsp;&nbsp;&nbsp;* &nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;void &nbsp;&nbsp;&nbsp;*&nbsp;@author&nbsp;Dom&nbsp;Hastings &nbsp;&nbsp;&nbsp;*&nbsp;@access&nbsp;public &nbsp;&nbsp;&nbsp;*/ &nbsp;&nbsp;public&nbsp;function&nbsp;__destruct()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;close&nbsp;the&nbsp;file&nbsp;resource &nbsp;&nbsp;&nbsp;&nbsp;fclose($this->handle); &nbsp;&nbsp;} &nbsp;&nbsp;/** &nbsp;&nbsp;&nbsp;*&nbsp;read &nbsp;&nbsp;&nbsp;*&nbsp; &nbsp;&nbsp;&nbsp;*&nbsp;Reads&nbsp;the&nbsp;first&nbsp;available&nbsp;occurence&nbsp;of&nbsp;the&nbsp;XML&nbsp;element&nbsp;$this->options['element'] &nbsp;&nbsp;&nbsp;* &nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;string&nbsp;The&nbsp;XML&nbsp;string&nbsp;from&nbsp;$this->file &nbsp;&nbsp;&nbsp;*&nbsp;@author&nbsp;Dom&nbsp;Hastings &nbsp;&nbsp;&nbsp;*&nbsp;@access&nbsp;public &nbsp;&nbsp;&nbsp;*/ &nbsp;&nbsp;public&nbsp;function&nbsp;read()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;check&nbsp;we&nbsp;have&nbsp;an&nbsp;element&nbsp;specified &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!empty($this->options['element']))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;trim&nbsp;it &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$element&nbsp;=&nbsp;trim($this->options['element']); &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$element&nbsp;=&nbsp;''; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;initialize&nbsp;the&nbsp;buffer &nbsp;&nbsp;&nbsp;&nbsp;$buffer&nbsp;=&nbsp;false; &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;if&nbsp;the&nbsp;element&nbsp;is&nbsp;empty &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(empty($element))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;let&nbsp;the&nbsp;script&nbsp;know&nbsp;we're&nbsp;reading &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->reading&nbsp;=&nbsp;true; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;read&nbsp;in&nbsp;the&nbsp;whole&nbsp;doc,&nbsp;cos&nbsp;we&nbsp;don't&nbsp;know&nbsp;what's&nbsp;wanted &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;($this->reading)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$buffer&nbsp;.=&nbsp;fread($this->handle,&nbsp;$this->options['chunkSize']); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->reading&nbsp;=&nbsp;(!feof($this->handle)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;return&nbsp;it&nbsp;all &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;$buffer; &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;we&nbsp;must&nbsp;be&nbsp;looking&nbsp;for&nbsp;a&nbsp;specific&nbsp;element &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;set&nbsp;up&nbsp;the&nbsp;strings&nbsp;to&nbsp;find &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$open&nbsp;=&nbsp;'<'.$element.'>'; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$close&nbsp;=&nbsp;'</'.$element.'>'; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;let&nbsp;the&nbsp;script&nbsp;know&nbsp;we're&nbsp;reading &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->reading&nbsp;=&nbsp;true; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;reset&nbsp;the&nbsp;global&nbsp;buffer &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->readBuffer&nbsp;=&nbsp;''; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;this&nbsp;is&nbsp;used&nbsp;to&nbsp;ensure&nbsp;all&nbsp;data&nbsp;is&nbsp;read,&nbsp;and&nbsp;to&nbsp;make&nbsp;sure&nbsp;we&nbsp;don't&nbsp;send&nbsp;the&nbsp;start&nbsp;data&nbsp;again&nbsp;by&nbsp;mistake &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$store&nbsp;=&nbsp;false; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;seek&nbsp;to&nbsp;the&nbsp;position&nbsp;we&nbsp;need&nbsp;in&nbsp;the&nbsp;file &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fseek($this->handle,&nbsp;$this->pointer); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;start&nbsp;reading &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;($this->reading&nbsp;&&&nbsp;!feof($this->handle))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;store&nbsp;the&nbsp;chunk&nbsp;in&nbsp;a&nbsp;temporary&nbsp;variable &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$tmp&nbsp;=&nbsp;fread($this->handle,&nbsp;$this->options['chunkSize']); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;update&nbsp;the&nbsp;global&nbsp;buffer &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->readBuffer&nbsp;.=&nbsp;$tmp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;check&nbsp;for&nbsp;the&nbsp;open&nbsp;string &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$checkOpen&nbsp;=&nbsp;strpos($tmp,&nbsp;$open); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;if&nbsp;it&nbsp;wasn't&nbsp;in&nbsp;the&nbsp;new&nbsp;buffer &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!$checkOpen&nbsp;&&&nbsp;!($store))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;check&nbsp;the&nbsp;full&nbsp;buffer&nbsp;(in&nbsp;case&nbsp;it&nbsp;was&nbsp;only&nbsp;half&nbsp;in&nbsp;this&nbsp;buffer) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$checkOpen&nbsp;=&nbsp;strpos($this->readBuffer,&nbsp;$open); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;if&nbsp;it&nbsp;was&nbsp;in&nbsp;there &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;($checkOpen)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;set&nbsp;it&nbsp;to&nbsp;the&nbsp;remainder &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$checkOpen&nbsp;=&nbsp;$checkOpen&nbsp;%&nbsp;$this->options['chunkSize']; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;check&nbsp;for&nbsp;the&nbsp;close&nbsp;string &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$checkClose&nbsp;=&nbsp;strpos($tmp,&nbsp;$close); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;if&nbsp;it&nbsp;wasn't&nbsp;in&nbsp;the&nbsp;new&nbsp;buffer &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!$checkClose&nbsp;&&&nbsp;($store))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;check&nbsp;the&nbsp;full&nbsp;buffer&nbsp;(in&nbsp;case&nbsp;it&nbsp;was&nbsp;only&nbsp;half&nbsp;in&nbsp;this&nbsp;buffer) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$checkClose&nbsp;=&nbsp;strpos($this->readBuffer,&nbsp;$close); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;if&nbsp;it&nbsp;was&nbsp;in&nbsp;there &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;($checkClose)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;set&nbsp;it&nbsp;to&nbsp;the&nbsp;remainder&nbsp;plus&nbsp;the&nbsp;length&nbsp;of&nbsp;the&nbsp;close&nbsp;string&nbsp;itself &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$checkClose&nbsp;=&nbsp;($checkClose&nbsp;+&nbsp;strlen($close))&nbsp;%&nbsp;$this->options['chunkSize']; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;if&nbsp;it&nbsp;was &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;elseif&nbsp;($checkClose)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;add&nbsp;the&nbsp;length&nbsp;of&nbsp;the&nbsp;close&nbsp;string&nbsp;itself &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$checkClose&nbsp;+=&nbsp;strlen($close); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;if&nbsp;we've&nbsp;found&nbsp;the&nbsp;opening&nbsp;string&nbsp;and&nbsp;we're&nbsp;not&nbsp;already&nbsp;reading&nbsp;another&nbsp;element &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;($checkOpen&nbsp;!==&nbsp;false&nbsp;&&&nbsp;!($store))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;if&nbsp;we're&nbsp;found&nbsp;the&nbsp;end&nbsp;element&nbsp;too &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;($checkClose&nbsp;!==&nbsp;false)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;append&nbsp;the&nbsp;string&nbsp;only&nbsp;between&nbsp;the&nbsp;start&nbsp;and&nbsp;end&nbsp;element &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$buffer&nbsp;.=&nbsp;substr($tmp,&nbsp;$checkOpen,&nbsp;($checkClose&nbsp;-&nbsp;$checkOpen)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;update&nbsp;the&nbsp;pointer &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->pointer&nbsp;+=&nbsp;$checkClose; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;let&nbsp;the&nbsp;script&nbsp;know&nbsp;we're&nbsp;done &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->reading&nbsp;=&nbsp;false; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;append&nbsp;the&nbsp;data&nbsp;we&nbsp;know&nbsp;to&nbsp;be&nbsp;part&nbsp;of&nbsp;this&nbsp;element &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$buffer&nbsp;.=&nbsp;substr($tmp,&nbsp;$checkOpen); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;update&nbsp;the&nbsp;pointer &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->pointer&nbsp;+=&nbsp;$this->options['chunkSize']; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;let&nbsp;the&nbsp;script&nbsp;know&nbsp;we're&nbsp;gonna&nbsp;be&nbsp;storing&nbsp;all&nbsp;the&nbsp;data&nbsp;until&nbsp;we&nbsp;find&nbsp;the&nbsp;close&nbsp;element &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$store&nbsp;=&nbsp;true; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;if&nbsp;we've&nbsp;found&nbsp;the&nbsp;closing&nbsp;element &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;elseif&nbsp;($checkClose&nbsp;!==&nbsp;false)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;update&nbsp;the&nbsp;buffer&nbsp;with&nbsp;the&nbsp;data&nbsp;upto&nbsp;and&nbsp;including&nbsp;the&nbsp;close&nbsp;tag &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$buffer&nbsp;.=&nbsp;substr($tmp,&nbsp;0,&nbsp;$checkClose); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;update&nbsp;the&nbsp;pointer &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->pointer&nbsp;+=&nbsp;$checkClose; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;let&nbsp;the&nbsp;script&nbsp;know&nbsp;we're&nbsp;done &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->reading&nbsp;=&nbsp;false; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;if&nbsp;we've&nbsp;found&nbsp;the&nbsp;closing&nbsp;element,&nbsp;but&nbsp;half&nbsp;in&nbsp;the&nbsp;previous&nbsp;chunk &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;elseif&nbsp;($store)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;update&nbsp;the&nbsp;buffer &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$buffer&nbsp;.=&nbsp;$tmp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;and&nbsp;the&nbsp;pointer &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->pointer&nbsp;+=&nbsp;$this->options['chunkSize']; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;return&nbsp;the&nbsp;element&nbsp;(or&nbsp;the&nbsp;whole&nbsp;file&nbsp;if&nbsp;we're&nbsp;not&nbsp;looking&nbsp;for&nbsp;elements) &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;$buffer; &nbsp;&nbsp;}}
打开App,查看更多内容
随时随地看视频慕课网APP