knot22
knot22

Reputation: 2768

foreach to build an HTML table from data in an array

The following code tests to see how certain values come out against PHP functions:

//array to hold test values
$values = array
(
    'empty string' => '',
    'space' => ' ',
    'false' => false,
    'true' => true,
    'empty array' => array(),
    'null' => null,
    '0 as string' => '0',
    '0 as integer' => 0,
    '0 as float' => 0.0,
    '$var declared but without a value' => $var
);

foreach($values as $key => $value):
    $result['isset'][$key] = isset($value);
    $result['empty'][$key] = empty($value);
    $result['is_null'][$key] = is_null($value);
    $result['is_numeric'][$key] = is_numeric($value);   //added this line on 10/7/13
    $result['strlen'][$key] = strlen($value);   //added this line on 12/23/13
endforeach;

//view results by function
echo "<h3>view results by function</h3><pre>" . print_r($result,1) . "</pre>";

The array outputted from this code is as follows:

Array
(
    [isset] => Array
        (
            [empty string] => 1
            [space] => 1
            [false] => 1
            [true] => 1
            [empty array] => 1
            [null] => 
            [0 as string] => 1
            [0 as integer] => 1
            [0 as float] => 1
            [$var declared but without a value] => 
        )

    [empty] => Array
        (
            [empty string] => 1
            [space] => 
            [false] => 1
            [true] => 
            [empty array] => 1
            [null] => 1
            [0 as string] => 1
            [0 as integer] => 1
            [0 as float] => 1
            [$var declared but without a value] => 1
        )

    [is_null] => Array
        (
            [empty string] => 
            [space] => 
            [false] => 
            [true] => 
            [empty array] => 
            [null] => 1
            [0 as string] => 
            [0 as integer] => 
            [0 as float] => 
            [$var declared but without a value] => 1
        )

    [is_numeric] => Array
        (
            [empty string] => 
            [space] => 
            [false] => 
            [true] => 
            [empty array] => 
            [null] => 
            [0 as string] => 1
            [0 as integer] => 1
            [0 as float] => 1
            [$var declared but without a value] => 
        )

    [strlen] => Array
        (
            [empty string] => 0
            [space] => 1
            [false] => 0
            [true] => 1
            [empty array] => 
            [null] => 0
            [0 as string] => 1
            [0 as integer] => 1
            [0 as float] => 1
            [$var declared but without a value] => 0
        )

)

The results would be much more friendly to view in an HTML table. So far I have only had success building the row that contains th tags:

$html = "\n<table>\n<tr>\n\t<th>test</th>\n";
//table header row
foreach ($result as $key => $value):
    $html .= "\t<th>$key</th>\n";
endforeach;
$html .= "</tr>\n";
//add detail rows here
$html .= "</table>\n";

I am having much difficulty figuring out how to build the detail rows properly. The goal is to display one test name per row (). The tests are the keys in the $values array. The s would be the test name, answer to isset, answer to empty, answer to is_null, answer to is_numeric, answer to strlen. How can this be achieved using foreach loops?

Upvotes: 0

Views: 2905

Answers (4)

Bryan
Bryan

Reputation: 3494

I think this is much easier to pull off if you rearrange the array. Here's what I did.

$values = array
(
    'empty string' => '',
    'space' => ' ',
    'false' => false,
    'true' => true,
    'empty array' => array(),
    'null' => NULL,
    '0 as string' => '0',
    '0 as integer' => 0,
    '0 as float' => 0.0,
    '$var declared but without a value' => @$var
);
$tests = array('isset','empty','is_null','is_numeric','strlen');
?>
<table>
    <tr>
        <th>test</th>
        <th><?=implode("</th>\n<th>",$tests)?></th>
    </tr>
<?php foreach($values as $key=>$value): ?>
    <tr>
        <td><?=$key?></td>  
        <?php foreach($tests as $test): ?>
        <td>
            <?php if($test == 'isset'): ?>
                <?=(int)isset($value)?>
            <?php elseif($test == 'empty'): ?>
                <?=(int)empty($value)?>
            <?php else : ?>
                <?=@(int)$test($value)?>
            <?php endif; ?>
            </td>
        <?php endforeach; ?>
    </tr>
<?php endforeach; ?>
</table>

Now you can add more tests if you want to the tests array easily and you don't need to use \n and \t to format the markup except in the implode. the @ symbols are to suppress warning the code generates in 2 place - one when using an undefined variable and 2 - when trying to use strlen on an array.

The reason for the conditionals in the inner foreach is because isset and empty are language constructs and not functions, so they cannot be called dynamically.

I know that's not really what you asked for, but I learned something playing around with this so figured I would share.

Upvotes: 1

Paresh Gami
Paresh Gami

Reputation: 4782

Here is the complete code. I think it should work for you.

<?php
$var="";
$values = array
(
    'empty string' => '',
    'space' => ' ',
    'false' => false,
    'true' => true,
    'empty array' => array(),
    'null' => null,
    '0 as string' => '0',
    '0 as integer' => 0,
    '0 as float' => 0.0,
    '$var declared but without a value' => $var
);

foreach($values as $key => $value)
{
    $result['isset'][$key] = isset($value);
    $result['empty'][$key] = empty($value);
    $result['is_null'][$key] = is_null($value);
    $result['is_numeric'][$key] = is_numeric($value);   //added this line on 10/7/13
    if(!(is_array($value)))
    $result['strlen'][$key] = strlen($value);   //added this line on 12/23/13 

}
//echo "<h3>view results by function</h3><pre>" . print_r($result,1) . "</pre>";
?>
<table border="1">
    <tr>
        <th>Key</th>
        <th>Value</th>   
    </tr>
<?php
foreach ($result as $key => $value):

    foreach ($value as $k => $val) 
    {
?>
        <tr><td><?php echo $k ?></td><td><?php echo $val ?></td></tr>
<?php 
    }
endforeach;
?>

Upvotes: 0

Ivarpoiss
Ivarpoiss

Reputation: 1035

I would suggest you to "rotate" your array structure around first. From "result -> columns -> rows" to "result -> rows -> columns"

foreach($values as $key => $value):
    $result[$key]['isset'] = (int)isset($value);
    $result[$key]['empty'] = (int)empty($value);
    $result[$key]['is_null'] = (int)is_null($value);
    $result[$key]['is_numeric'] = (int)is_numeric($value);
    $result[$key]['strlen'] = (int)strlen($value);
endforeach;


$html = "<table>\n";

$html .= "<tr>";
$first_row = reset($result);
foreach ($first_row as $key => $value):
    $html .= "<th>$key</th>";
endforeach;
$html .= "</tr>\n"

foreach ($result as $row):
    $html .= "<tr>";
    foreach($row as $key => $value):
        $html .= "<td>$value</td>";
    endforeach;
    $html .= "</tr>\n";
endforeach;

$html .= "</table>\n"

Upvotes: 0

Sharanya Dutta
Sharanya Dutta

Reputation: 4021

Add the following lines at the end of your code:

print("<table border=1>
<tr>
    <th></th>
    <th>isset</th>
    <th>empty</th>
    <th>is_null</th>
    <th>is_numeric</th>
    <th>strlen</th>
</tr>".PHP_EOL);
foreach($values as $key => $value):
print("<tr>
    <td>$key</td>
    <td>{$result["isset"][$key]}</td>
    <td>{$result["empty"][$key]}</td>
    <td>{$result["is_null"][$key]}</td>
    <td>{$result["is_numeric"][$key]}</td>
    <td>{$result["strlen"][$key]}</td>
</tr>".PHP_EOL);
endforeach;
print("</table>");

Upvotes: 1

Related Questions