views:

266

answers:

4

I've seen a million of these threads here already, and read through every single one. That, plus some serious Googling.

UPDATE: I am rewriting this post to include complete code and explanation, so everyone understands what is going on and what I am trying to do.

I am developing using CodeIgniter, so some syntax may look weird if you are not familiar with it.

I have an link bar with letters A-Z. The idea is to find only "active" letters that have content in a particular column (mysql LIKE $letter%). With this information I would be able to "dim" certain "empty" letters if there are any, using CSS.

This function here queries mysql and gets each unique first letter of entries in a column. The result should be anywhere from 0 to 26 matches/array items.

  //From am_model.php              
  function getFirstLetter($domainId)
  {

   $q = $this->db->query("SELECT DISTINCT LEFT(alias_name, 1) 
                                     AS letter 
                                     FROM am_aliases 
                                     WHERE domain_id = '" . $domainId . "' 
                                     ORDER BY alias_name;");
   if($q->num_rows > 0):
    foreach($q->result() as $row) 
    {
     $result[] = $row;
    }
    //print_r($result); <-- prints out correct result.
    return $result;
   endif;

  }

After that, I call this function from a controller:

    $foundLetters = $this->am_model->getFirstLetter($domainId);

then define an $alphabet array.

    $alphabet = range('a','z');

    foreach($alphabet as $letter)
    {

         if(in_array($letter, $foundLetters, TRUE)):
                echo $letter . ' found<br />';
         else:
                echo $letter . ' not found<br />';
         endif;

    }

Nothing complicated. All I have to do is check if a single character in a loop matches my alphabet array.

As Col. Shrapnel suggested below, I did some debugging, and dump() of letters from $alphabet and $foundLetters arrays produce different results, so I guess it does point to possible encoding issues, which I am trying to figure out now...

Does anyone have any idea what the hell is going on here??

function dump(&$str) {
  $i=0;
  while (isset($str[$i])) echo strtoupper(dechex(ord($str[$i++])));

}

Here is the result from dump():

a: $alphabet->61 613C6272202F3E<-$foundLetters
b: $alphabet->62 613C6272202F3E<-$foundLetters
c: $alphabet->63 683C6272202F3E<-$foundLetters
d: $alphabet->64 613C6272202F3E<-$foundLetters

and these:

print_r($alphabet); // all 26 letters

Array ( 
        [0] => a
        [1] => b
        [2] => c
        ...            
        [23] => x
        [24] => y
        [25] => z
 )

 print_r($foundLetters); // dynamic array.

 Array ( 
        [0] => b
        [1] => s
 )
+2  A: 
Tom Dignan
Yeah, this works for me to.. Looks like the issue is with how arrays are generated. As Col. Shrapnel mentioned below, it may have something to do with encodings...
solefald
+3  A: 

got your letters from the file, eh? :)

use var_dump instead or print_r and trim in comparison :)

Edit
Use this code to see what is going on

foreach ($alphabet as $letter) {
  foreach ($empty_letters as $empty) {
    dump($letter);
    echo " ";
    dump($empty);
    echo "<br>";
    if ($letter == $empty) {
      echo "$letter was found in \$empty_letters<br>\n";
      break;
    }
  }
}

function dump(&$str) {
  $i=0;
  while (isset($str[$i])) echo strtoupper(dechex(ord($str[$i++])));
}
Col. Shrapnel
Nope. From MySQL. `SELECT DISTINCT LEFT(alias_name, 1) AS letter FROM am_aliases WHERE domain_id = 'XXX' ORDER BY alias_name;` Basically finds every unique 1st letter from a column
solefald
@solefald so, it can be encoding issue. You have to debug a little. See my post update.
Col. Shrapnel
Hmm.. this is interesting. I get different values with left and right columns, but what the hell is it? haha
solefald
I am going to crash right now, but i think we are onto something here.... i get `61 643C6272202F3E`.. gonna dig deeper in the morning... thank you!
solefald
+1 I think this is a great answer because it provides a general debugging strategy, which applies to many scenarios, and teaches the lesson that what you see is not necessarily what you have.
chris
Man, I wasted all this time, and all i had to do is to `trim()`; results right after the query. `$result[] = trim($row->letter);`
solefald
A: 

The only thing in your sample that is strange is the : that comes after the foreach - followed by curly braces will cause a syntax error. Is that the problem, or does your program just not output anything?

ABach
Typo. In this post, by accident. Its not in my code.
solefald
I agree with Tom - I tried this exact script and I got the expected results. Can you specify what exactly happens when you run yours? Does nothing show up? Some sort of warning/error?
ABach
@ABach. Nothing. Absolutely nothing. I ran it through the loop with `var_dump()` and got `bool(false)` for every letter. but there is one difference. You guys are manually setting the array, mine is dynamically generated. But i did `trim()` on every letter. and even printed out with `''` around each one.
solefald
Dynamic generation shouldn't matter unless the variable types are getting screwed up somehow. Can you post your exact code?
ABach
Just posted in my original post.
solefald
A: 

I got the expected results as well. But I think your example array is different from what you are actually passing through. Give this a try...

 foreach(array_values($alphabet) as $letter){
     echo $letter . '<br />'; // Correctly prints out every letter from $alphabet.
     if(in_array($letter, $emptyLetters)) {  // $strict is set
         // do something
         echo 'found';
     }
 }
CrashRoX