2
\$\begingroup\$

The goal of this code was to create a table from an associative array.

  • I need to create horizontal rows where the keys need to be used as "headers" while the values are posted below each header.
  • I need to be able to reuse the code with associative arrays of unknown lengths and varying number of columns allowed in the tables.

I realize this is not set up as a function. I'm just playing with the code for now.

The code that I have actually does work. I'm not sure if it's "proper" form especially here - $startIndex = $index in the for loop.

I create two rows at a time - one for the header, one for the values. After the end of these two rows, I'm re-setting the index on the for loop so it runs through the next group in the array. I'm trying to get better at coding and would like some input on what I've done.

    <h2>Print out a horizontal table with a capability to vary the number of  cells across</h2>
<table class="<?php echo $tableClass; ?>">
<caption>Horizontal</caption>

<?php 
$array = array(
    "A" => 1,
    "B" => 2,
    "C" => 3,
    "D" => 4,
    "E" => 5,   
    "F" => 6,    
    "G" => 7,    
    "H" => 8,
    "I" => 9,    
    "J" => 10,   
    "K" => 11,   
    "L" => 12,
    "M" => 13        
);

$maxColumns = 8;//set the number of columns allowed in the table
$arrayOfKeys = array_keys($array);//grab the keys from the initial array
$count = count($arrayOfKeys);//gets a count of the number of items in  the array
$maxRows = ceil($count/$maxColumns) * 2;//takes the count and determines the number of rows based on the number of items and the maxColumns * 2 for total rows  (need a "header" and value for each set of keys/values in the array
$endIndex = $maxColumns-1;//initialize the endIndex on the loop that runs the 
$startIndex = 0;//initialize the start index for the second loop which will loop through the array assigning keys to first row - value to second

for ($row=1; $row<=$maxRows; $row++){//loops based on the number of rows required to generate the table for the number of cells required

    echo '<tr>';//start the row
    $rowEvenOdd = ($row % 2); //figures whether an even or odd row

    for ($index=$startIndex; $index<=$endIndex; $index++){//creates the rows
            if($rowEvenOdd == 1) {//if the row is odd, grab and display the key
                if(array_key_exists($index, $arrayOfKeys))
                    {$thiskey = $arrayOfKeys[$index];}
                    else {$thiskey ="&nbsp;";}
                echo "<td>$thiskey</td>";
                }//end of odd rows
            if($rowEvenOdd == 0) {//if the row is even, grab and display the value
                if(array_key_exists($index, $arrayOfKeys))
                    {$thisvalue = $array[$arrayOfKeys[$index]];}
                    else {$thisvalue ="&nbsp;";}            
                echo "<td>". $thisvalue ."</td>";
                }//end of odd rows          
    }//end of loop to generate content for the cells
    echo '</tr>';//end the row
    if($rowEvenOdd == 0) {$startIndex = $index; $endIndex = $index + $maxColumns-1;/* reset the index begin and end  to loop through next group of rows */                           }
    }//end loops that creates the rows

?>
</table>
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

Use array_chunk() to split $rows into rows. Each row will be double high $doubleRows, so store the values in a small multi-dimension array $tablerows before echoing the rows.

// One single row.
$rows = array(
    "A" => 1,
    "B" => 2,
    "C" => 3,
    "D" => 4,
    "E" => 5,
    "F" => 6,
    "G" => 7,
    "H" => 8,
    "I" => 9,
    "J" => 10,
    "K" => 11,
    "L" => 12,
    "M" => 13
);

// Split into 1 or more rows of 8 columns each.
$doubleRows = array_chunk( $rows, 8, true );

// Rows are now double high.
// Keys on the first row and values on the second.
foreach ( $doubleRows as $columns ) {

    // Reset rows.
    $tableRows = array();
    foreach ( $columns as $key => $value ) {
        $tableRows['keys'][] = "<td>$key</td>";
        $tableRows['values'][]  = "<td>$value</td>";
    }

    echo "<tr>", join( '', $tableRows['keys'] ), "</tr>";
    echo "<tr>", join( '', $tableRows['values'] ), "</tr>";
}

Style

You used a lot of end comments. I try to avoid them and I try to avoid obvious comments like, // Start the row. To me, the <tr> tag is pretty self explanatory, but if it is not to you, then I understand why you did it.

Wrap long comments and use proper punctuation and capitalization. Comments are for humans. PHP strips them out. If you are the only person who ever sees your code, write your comments for the (different) person you will be in six months. The future you may appreciate comments that look like sentences and paragraphs.

Be consistent with your indentation and white space. Always indent the same number of characters. This foreach is indented 4 spaces (or 1 tab). The conditional statement is indented 12 spaces (or 3 tabs).

    for ($index=$startIndex; $index<=$endIndex; $index++){//creates the rows
            if($rowEvenOdd == 1) {//if the row is odd, grab and display the key

I would write it like this:

    // Create table rows.
    for ( $index = $startIndex; $index <= $endIndex; $index++ ) {
        if ( $rowEvenOdd == 1 ) {
            // Row is odd. Grab and display the key.

I added some white space so it wouldn't look all scrunch up. I find it easier to read like that. The comment after the conditional tells you what the condition is instead of what the conditional does.

If this is your style for writing one line conditionals, I guess it is fine, but it looks scrunch up and harder to read.

if(array_key_exists($index, $arrayOfKeys))
    {$thisvalue = $array[$arrayOfKeys[$index]];}
    else {$thisvalue ="&nbsp;";}

I prefer this:

if ( array_key_exists( $index, $arrayOfKeys ) ) {
    $thisvalue = $array[$arrayOfKeys[$index]];
} else {
    $thisvalue ="&nbsp;";
}

Or this:

if ( array_key_exists( $index, $arrayOfKeys ) )
    $thisvalue = $array[$arrayOfKeys[$index]];
else
    $thisvalue ="&nbsp;";

I tend to not add white space near brackets [] and to add it in parenthesis ().

Except for $thisvalue and $thiskey all your variable name use camel case. $thisValue and $thisKey would be more consistent.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.