Log in

View Full Version : implode and casting as array



traq
01-18-2011, 04:53 AM
hello, just a curiosity (I have a workaround for the problem; but I'd like to figure out what's going on):

Say I have this function:

function whereClause($words){
foreach($words as $k=>$v){ if(!empty($v)){ $words[$k] = "`field` LIKE '%$v%'"; } }
$where = "WHERE ".implode(' OR ',$words);
print $where;
}

$arr = array('these','are','some','words');
whereClause($arr); // works great. outputs:
// WHERE `field` LIKE '%these%' OR `field` LIKE '%are%' OR `field` LIKE '%some%' OR `field` LIKE '%words%'

BUT, as you may expect, if $words is a string (e.g., only one word), you have problems- foreach and implode both require arrays. I can solve this by casting $words as an array:

function whereClause($words){
foreach((array)$words as $k=>$v){ if(!empty($v)){ $words[$k] = "`field` LIKE '%$v%'"; } }
$where = "WHERE ".implode(' OR ',(array)$words);
print $where;
}

$str = 'these';
whereClause($str); // kinda works - no errors, but this is the output:
// WHERE `hese
wth did that come from?

even if (array)$words as $k=>$v is treating "t" as the key ($k), why is it losing the "`field` LIKE '% %'" part?

Thanks for any insights
(things that bug me just bug me)

djr33
01-18-2011, 05:18 AM
1. Whenever I have functions like that and might pass a string rather than an array, I use something like this:

myfunc($ar) {
if (!is_array($ar)) { $ar = array($ar); }
//...
}

2. I'm not exactly sure what is going on there, but I'm guess it's because you're asking PHP to pretend the string is an array and it's getting confused. It looks to me like it's treating the string as an array of characters, much like if you try to access $string[5], where that would be the 6th character (starting at 0). As for why exactly it turns out like it does, that's very strange, but you could probably figure it out by tracking the values throughout.

traq
01-18-2011, 05:33 AM
#1:

that's my workaround, exactly. I'm pretty sure casting does the same thing; it's always worked safely for me before.

#2:

I don't know...

$str = "string";

var_dump((array)$str);
// returns " array(1) { [0]=> string(5) "these" } "

foreach((array)$str as $s){ print $s.'<br>'; }
// returns " string " (not "s""t""r""i""n""g")

foreach((array)$str as $k=>$v){ print $k.'=>'.$v; }
// returns " 0=>string "

traq
01-18-2011, 05:41 AM
isolated it:


$str = "string";
foreach((array)$str as $s){ $str = "new ".$s; }
print $str; // returns " new string "

$str = "string";
foreach((array)$str as $k=>$v){ $str[$k] = $v; }
print $str; // returns " string "

$str = "string";
foreach((array)$str as $k=>$v){ $str[$k] = "new ".$v; }
print $str; // returns " ntring "
odd.

djr33
01-18-2011, 08:15 AM
Very interesting. My brain is too tired at the moment to fully comprehend that, but it would be good to figure out why.


Edit: as far as I can tell, that must be a bug in PHP... I can't see any reason that should happen like that.

traq
01-18-2011, 03:13 PM
yeah... time to browse the bug tickets, I guess. if I actually found one, maybe they'll name it after me :p