With the initial explode, I may be wrong but I don't think it's possible to
force every entry to be string-typed.  However, this little snippet could
$foo = explode(';', $db);
foreach($foo as &$bar) {
$bar = settype($bar, 'string);

which will set each element's type to string, but is hardly a fast or
elegant solution, but a solution it is nonetheless.  Alternatively, every
time you reference a field that ought to be an element but isn't, you can
use strval($element), but that's even uglier!

On an aside, coming from strict typing to loose typing is certainly an
enormous transition, you grow to learn these little things and work around
them.  The benefits and ease of the loose typing, at least to me, seem to
outweigh the overhead handling "fringe" type cases like these.  For a
performance nut like myself, though, it certainly drives me insane!

On Sun, May 24, 2009 at 10:46 PM, Clancy <clanc...@cybec.com.au> wrote:

> For some time I have been working on a text based database, in which each
> entry contains
> one or more lines of data, with the various fields delimited by semicolons,
> e.g.
> A;b;20GM;;;;;Restaurant;090508
> n;;;Arintji;;
> a;Federation Square;;;
> p;9663 9900;;;9663 9901;;i...@arintji.com.au<9901%3b%3bi...@arintji.com.au>
> ;
> All was going well but recently I decided to allocate every entry a unique
> identifier,
> and, in what with hindsight was clearly misguided enthusiasm, decided that
> each identifier
> should be a four digit base 36 number (the 20GM in the first line). This
> did not cause any
> problems until yesterday, when I tried to load a name beginning with 'R',
> and got the
> first name on the list. When I investigated I found that I was searching
> the array
> containing the data using:
>        if ($ident == $data[$i]['group']['ident'])  { ......
> I then found that I was searching for 20E2, but was getting a match on
> 2000. I tried
>        'if ((string) $ident == (string) $data[$i]['group']['ident'])',
> but this still matched. However
>        'if($ident === '
> worked, as did
>        'if (!strcmp($ident, $data[$i])) {...'.
> After puzzling about this for a long time, I realised that the comparison
> process must
> have been treating the second value as a floating point number, and
> converting it to
> integer, or vice versa.  (In floating point notation 20E2 = 20*10^^2 =
> 2000).  I had
> thought that the (string) override meant to treat the actual value as a
> string, but in
> this case it must be converting the (assumed) actual value to a string, and
> then comparing
> the results.
> This surprised me considerably as it is clear from the results I achieve in
> other
> circumstances that the data is actually stored as a raw string.
> $data is a variable format array, and when the original data is read each
> line is exploded
> into a term of the data array: $data[][] = explode(';',$line[$i]);.  If I
> print the value
> of the ident (or any other field) it is always shown as the original
> string, and when I
> save an updated version of the data, each term of the data array is
> imploded into a line
> of the data file in its original format. However if this value were
> actually converted to
> a floating point number when it was entered I would have to specify a
> format before I
> could write it out again, and as 20E2 is a rather  non-standard format it
> is most unlikely
> that it would come out as this unaided.
> Is there any way to specify that each field is always to be treated as a
> string when I
> originally explode the input file into the data array?  For someone brought
> up on rigidly
> defined data types dynamic typing can be very confusing!
> --
> PHP General Mailing List (http://www.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to