note 28744 modified in ref.xml by danbrown
| From: | danbrown@php.net | Date: | Thu, 30 Jun 2011 13:34:27 +0000 |
| Subject: | note 28744 modified in ref.xml by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-181093@lists.php.net to get a copy of this message | ||
use:
<?php
while ($data = str_replace("\n","",fread($fp, 4096))){
// ...
}
?>
instead of:
<?php
while ($data = fread($fp, 4096)) {
// ...
}
?>
[UPDATE 17-FEB-2003: This post] resulted in some of the visitors e-mailg me on the carriage return
stripping issue with questions. I'll try to make the following mumble as brief and easy to
understand as possible.
1. Overview of the 4096 fragmentation issue
As you know the following freads the file 4096 bytes at a time (that is 4KB) this is perhaps ok for
testing expat and figuring out how things work, but it it rather dangerous in the production
environment. Data may not be fully understandable due to fread fragmentation and improperly
formatted due to numerous sources(formats) of data contained within (i.e. end of line delimited
CDATA).
<?php
while ($data = fread($fp, 4096)) {
if (!xml_parse($xml_parser, $data, feof($fp))) {
// ...
}
}
?>
Sometimes to save time one may want to load it all up into a one big variable and leave all the
worries to expat. I think anything under 500 KB is ok (as long as nobody knows about it). Some may
argue that larger variables are acceptable or even necessary because of the magic that take place
while parsing using xml_parse. Our XML parser(expat) works and can be successfully implemented only
when we know what type of XML data we are dealing with, it's average size and structure of
general layout and data contained within tags. For example if the tags are followed by a line
delimiter like a new line we can read it with fgets in and with minimal effort make sure that no
data will be sent to the function that does not end with a end tag. But this require a fair
knowledge of the file's preference for storing XML data and tags (and a bit of code between
reading data and xml_parse'ing it).
It will save you a headache.
2. Pre Parser Strings and New Line Delimited Data
One important thing to note at this point is that the xml_parse function requires a string variable.
You can manipulate the content of any string variable easily as we all know.
A better approach to removing newlines than:
<?php
while ($data = fread($fp, 4096)) {
$data = preg_replace("/\n|\r/","",$data); //flarp
if (!xml_parse($xml_parser, $data, feof($fp))) {...
?>
Above works across all 3 line-delimited text files (\n, \r, \r\n). But this could potentially (or
will most likely) damage or scramble data contained in for example CDATA areas. As far as I am
concerned end of line characters should not be used _within_ XML tags. What seems to be the ultimate
solution is to pre-parse the loaded data this would require checking the position within the XML
document and adding or subtracting (using a in-between fread temporary variable) data based on
conditions like: "Is within tag", "Is within CDATA" etc. before fedding it to
the parser. This of course opens up a new can of worms (as in parse data for the parser...). (above
procedure would take place between fread and xml_parser calls this method would be compatible with
the general usage examples on top of the page)
3. The Answer to parsing arbitrary XML and Preprocessor Revisited
You can't just feed any XML document to the parser you constructed and assuming that it will
work! You have to know what kind of methods for storing data are used, for example is there a end of
line delimited data in the file ?, Are there any carriage returns in the tags etc... XML files come
formatted in different ways some are just a one long string of characters with out any end of line
markers others have newlines, carriage returns or both (Microsloth Windows). May or may not contain
space and other whitespace between tags. For this reason it is important to what I call Normalize
the data before feeding it to the parser. You can perform this with regular expressions or plain old
str_replace and concatenation. In many cases this can be done to the file it self sometimes to
string data on the fly( as shown in the example above). But I feel it is important to normalize the
data before even calling the function to call xml_parse. If you have the ability to access all data
before that call you can convert it to what you fell the data should have been in the first place
and omit many surprises and expensive regular expression substitution (in a tight spot) while
fread'ing the data.
--was--
use:
<?php
while ($data = str_replace("\n","",fread($fp, 4096))){
// ...
}
?>
instead of:
<?php
while ($data = fread($fp, 4096)) {
// ...
}
?>
It will save you a headache.
http://php.net/manual/en/ref.xml.php