0

I understand that pdo/mysqli is the required standard, for the time being I have no choice other than to use msql

Currently I have this setup to loop through results and display them accordingly

foreach($Items as $Item)
{
    if($Item["Col1"] == "valueFoo"){
        echo "<li>display relevant results</li>";                   
    }
} 

Is there way I can do this without looping through the whole array if Items and instead combining the foreach loop with a condition. Alternatively filtering the array prior to the foreachloop? What is the most efficient?

Currently I have 60 items and display them in lists like as below

$SQL = "SELECT * FROM tableName WHERE Col1 IS NOT NULL";
$Data = mysql_query($SQL, $db);

$Items = array();
    while ($NewRow = mysql_fetch_assoc($Data)) {
    // Append all rows to an array
    $Items[] = $NewRow;
}

echo "<ul>";
foreach($Items as $Item)
    {
        if($Item["Col1"] == "valueFoo"){
            echo "<li>display relevant results</li>";                   
        }
    } 
echo "</ul>";
echo "<ul>";
foreach($Items as $Item)
    {
        if($Item["Col1"] == "valueDoo"){
            echo "<li>display relevant results</li>";                   
        }
    } 
echo "</ul>";
echo "<ul>";
foreach($Items as $Item)
    {
        if($Item["Col1"] == "valueHoo"){
            echo "<li>display relevant results</li>";                   
        }
    } 
echo "</ul>";

Is there a more efficient way? I'm still a newbie when it comes to php

4
  • I think you can directly use mysql_fetch_assoc($Data) in your foreach loop (you might have to change that to a while loop though). That way you can get rid of $Items = array(); and $Items[] = $NewRow; Commented Oct 9, 2013 at 15:02
  • Additionally, in place of iterating through the whole $Items array thrice, maybe you can write 3 separate queries for the values of Col1 and filter the values at the query level itself. Commented Oct 9, 2013 at 15:04
  • What about $Items[$NewRow['Col1']][] = $NewRow; Then foreach($Items['valueFoo'] as $Item) . That way you still make one sql query. Commented Oct 9, 2013 at 15:05
  • There's not really anything wrong with this. I'd prefer to filter the results in php vs doing additional database queries. Commented Oct 9, 2013 at 15:09

4 Answers 4

2

What I'd do is combine each check into one foreach, assigning the text to variables until the end, then echoing them as needed. Inside the foreach use a switch statement to avoid the multiple ifs.

foreach($Items as $Item)
    {
      switch($Item["Col1"])
      {
         case 'valuefoo':
         $result_foo="<li>display relevant results</li>";  
         break;
         case 'valuedoo':
         $result_doo="<li>display relevant results</li>";  
         break;
         case 'valuehoo':
         $result_hoo="<li>display relevant results</li>";  
         break;
         default:
         // handle error if there is one
      }                
        }
    } 
echo "<ul>";
echo $result_foo;
echo "</ul>";

echo "<ul>";
echo $result_doo;
echo "</ul>";

echo "<ul>";
echo $result_hoo;
echo "</ul>";
Sign up to request clarification or add additional context in comments.

3 Comments

I wanted to combine the foreach loops but because it is nested and displayed within a list it would multiply the <ul> of each list
I didn't really want to just code it for you, but I did it anyway. Please see my edit.
I don't want to actually change the code now that it's been accepted, but where I have lines like $result_foo="<li>display relevant results</li>"; It should probably be $result_foo.="<li>display relevant results</li>"; notice the concatenation operator.
0

You can avoid your multiple foreaches by using this :

in_array(array("Col1" => "valueFoo"), $Items);
// ...
in_array(array("Col1" => "valueDoo"), $Items);
// ...
in_array(array("Col1" => "valueHoo"), $Items);

edit

If you want a better way, replace your whole code by this (see @Maximus2012 comment) :

while ($NewRow = mysql_fetch_assoc($Data)) {
    // Append all rows to an array
    if($NewRow["Col1"] == "valueFoo"){
        $foo = true;                 
    } else if($NewRow["Col1"] == "valueDoo"){
        $doo = true;
    } else if($NewRow["Col1"] == "valueHoo"){
        $hoo = true;
    }
} 

if($foo) {
    echo "<ul>display relevant results</ul>";
}

if($doo) {
    echo "<ul>display relevant results</ul>";
}

if($hoo) {
    echo "<ul>display relevant results</ul>";
}

Comments

0

I would change how you've ordered the records fetched from the table. So that they are sequenced by Col1 (first, and then other values second) and then you can check for changes in Col1 to start a new <ul> group.

$SQL = "SELECT * FROM tableName WHERE Col1 IS NOT NULL ORDER BY Col1";

If your values for Col1 are fixed values and can be mapped to functions. You could just dispatch calls to local functions of the same name. Otherwise you'll have to use a switch statement.

// create some functions to render each value type
function valueFoo()
{
    echo "<li>display relevant results</li>";
}

function valueHoo()
{
    echo "<li>display relevant results</li>";
}

function valueDoo()
{
    echo "<li>display relevant results</li>";
}

$last_col = false;
foreach($items as $item)
{
    $foo = $item["Col1"];
    if($last_col != $foo)
    {
        if($last_col !== false) echo "</ul>";
        echo "<ul>";
    }
    $foo();
    $last_col = $foo;
}
if($last_col !== false)
{
    echo "</ul>";
}

Comments

0

You can use something like this:

$ValuesAll = array();

foreach ($Items as $Item) {
    $ValuesAll[$Item['Col1']][] = '<li>' . $Item['Col2'] . '</li>';
}

foreach ($ValuesAll as $Value) {
    echo '<ul>' . implode('', $Value) . '</ul>';
}

This example will create UL for every unique $Item['Col1']. So, if you have Col1 valueFoo, valueDoo, and valueHoo, you will get 3 lists with Col2s for each of Col1.

Comments

Your Answer

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