array_chunk Question

I have a question about array_chunk.

I have a list of about a thousand people’s names in a table named “people,” and the numerical key (field N) is arranged alphabetically by last name, like this…

N | URL
1 | Edward_Abbey
2 | John_Adams
[Intermediate Values]
1000 | Howard_Zinn

If I order my query by the numerical key (P.N), it then displays an alphabetized list of people in a single column. However, I’d like to display it in multiple columns of approximately the same height.

So I tried the array_chunk feature, and it basically works, but there are two problems. First, the alphabetical order is kind of weird. The first column begins with Edward_Abbey and ends with Henry_Wallace. The second column more or less starts over, beginning with Jack_Abramoff and ending with William_Wallace.

Instead, the second column should start where the first column ends; if the last value in the first column is Chuck_Henderson the first value in the second column should be Linda_Henry.

The second problem is that I can’t seem to dictate the number of columns with $how_many_chunks. At first, it displayed three columns, even if the value was $how_many_chunks = 2. Now it’s displaying four columns, regardless of the value I type in.

Can anyone tell me what’s wrong with my code? I’m new to PDO, so I could have made a mistake there. However, the select statement works fine when I paste it into phpMyAdmin > SQL.

Thanks.


$stm = $pdo->prepare("SELECT P.URL, P.Title, P.Site, P.Live,
 PB.Common, ART.URL, ART.Site, ART.Brief, ART.Article
 FROM people P
 LEFT JOIN people_1_bio PB ON PB.URL = P.URL
 LEFT JOIN people_articles ART ON ART.URL = P.URL
 WHERE P.Site = 'PX' AND ART.Site = 'PX' AND ART.Brief !='' AND P.Live = 1
 ORDER BY P.N");

$stm->execute(array(
));

while ($row = $stm->fetch())
{
 $Common = $row['Common'];
 $Roster[] = '<a href="/People/'.$URL.'">'.$Common.'</a><br>';
}

// Set how many chunks you want to break the array into.
$how_many_chunks = 2;

// Break the '$Roster' array into '$roster_chunks'
$roster_chunks = array_chunk($Roster, $how_many_chunks, true);

// Roll through the '$roster_chunks'
foreach ($roster_chunks as $roster_chunk_key => $roster_chunk_value) {
  echo '<div style="width: 175px; font-size: 75%; text-align: left; float: left; margin-right: 15px;">';
  echo join($roster_chunk_value, '' );
  echo '</div>';
}

So taking your query out of the equation, here is what I tested with:

<?php
$Roster[] = "<a href=\\"/People/Edward_Abbey\\">Edward_Abbey</a>";
$Roster[] = "<a href=\\"/People/John_Adams\\">John_Adams</a>";
$Roster[] = "<a href=\\"/People/Jordan_Arheit\\">Jordan_Arheit</a>";
$Roster[] = "<a href=\\"/People/Jennifer_Lawerence\\">Jennifer_Lawerence</a>";
$Roster[] = "<a href=\\"/People/Howard_Zinn\\">Howard_Zinn</a>";

var_dump(array_chunk($Roster, 2, true));

It produced the following output, which seems correct to me…

array (size=3)
  0 => 
    array (size=2)
      0 => string '<a href="/People/Edward_Abbey">Edward_Abbey</a>' (length=47)
      1 => string '<a href="/People/John_Adams">John_Adams</a>' (length=43)
  1 => 
    array (size=2)
      2 => string '<a href="/People/Jordan_Arheit">Jordan_Arheit</a>' (length=49)
      3 => string '<a href="/People/Jennifer_Lawerence">Jennifer_Lawerence</a>' (length=59)
  2 => 
    array (size=1)
      4 => string '<a href="/People/Howard_Zinn">Howard_Zinn</a>' (length=45)

So it sounds like I have the right idea and script, but I have some kind of problem in my code or database I need to track down, right? I’ll play with it some more. Thanks.

Yes, I’d start with checking that the data you are getting back is in the order you think it is. Export/dump that data before working with it.

I’m going to guess the answer may be closer to home.


  echo join($roster_chunk_value, '' );

You’re not putting anything between the values. So your DIV is expanding to try and fit multiple names on a single line; this causes it to LOOK like the second column has started over; what it’s actually done is do exactly what you said it to do.

Try putting a <br> in your code (and putting the parameters in the right order!)

  echo join("<br />",$roster_chunk_value);

That may show you a bit clearer what’s going on. If the values STILL dont look right, it’s most likely something to do with your database pull, as said in the previous post.

I must be writing sloppy code, though I don’t understand this…

I pasted my query into phpMyAdmin > SQL, and everything displays in the perfect order.

I then changed my code a bit, then posted your code - echo join(“<br />”,$roster_chunk_value); - replacing $roster_chunk_value with $List. And I echoed it ABOVE the foreach function. It displays all the names in perfect alphabetical order - but in a single column.

But when I use the code below, it works as before - but better. I still can’t control the number of columns; it just wants to display four columns. And they data doesn’t display alphabetically from top to bottom in the column on the left, continuing with the next column.

However, it DOES display alphabetically from left to right, with each column starting with a name ending in A. Before the display looked really ragged; now it looks nice.

So my best guess is I messed up on one of the two lines of code I marked below.


$stm = $pdo->prepare("SELECT P.N, P.URL, P.Title, P.Site, P.Live,
 PB.Common, ART.URL, ART.Site, ART.Brief, ART.Article
 FROM people P
 LEFT JOIN people_bios PB ON PB.URL = P.URL
 LEFT JOIN people_articles ART ON ART.URL = P.URL
 WHERE P.Site = 'PX' AND ART.Site = 'PX' AND ART.Brief !='' AND P.Live = 1
 ORDER BY P.N");
$stm->execute(array(
));

while ($row = $stm->fetch())
{
 $URL = $row['URL'];
 $Common = $row['Common'];

 $List[] = '<a href="/People/'.$URL.'">'.$Common.'</a><br>';
}

$how_many_chunks = 3;

// Did I do something wrong in this line of code?
$roster_chunks = array_chunk($List, $how_many_chunks, true);

// Otherwise there must be something wrong with my foreach statement...
foreach ($roster_chunks as $roster_chunk_key => $roster_chunk_value) {
  echo '<div style="width: 175px; font-size: 75%; text-align: left; float: left; margin-right: 15px;">';
  echo join($roster_chunk_value);
  echo '</div>';
}

answer to the first part: Your original call to join() had the parameters in the wrong order (The parameters on join(), which is an alias of implode() are ‘glue,pieces’). I suggested you use <br /> instead of ‘’ (the empty string) as your glue so that it would break the list up. So instead of Henry_AaronGeorge_Adams, you get Henry_Aaron<br />George_Adams, which will render in a browser better. You chose not to do so, based on your new code. (You chose to omit the glue… which, if i recall correctly, defaults to a glue of the comma character?)

answer to the second part: Yes, you did something wrong. Sorta. Actually it’s more that you misunderstood a parameter.
the second parameter of array_chunk is not $how_many_chunks, it’s $how_big_is_each_chunk. So by putting ‘3’ there, you’re telling array chunk to make the chunks 3 elements big. You can work around that by counting the array and dividing by 3, then ceiling-ing the result (the third column may come up short, but that’s okay.)

Actually, I used the break, which did help, but I simply omitted it when I wrote the new code.

In the meantime, I was wrong in that I initially thought array_chunk would sort/display data vertically, not horizontally. But it’s still a cool function, and I’ll play around with it a little more. Thanks for all the tips.