简体   繁体   中英

php/mqsql multiple calls to DB and multiple loops - different logic needed

Firstly let me apologise for my vague question title, this is my first post on this site; after spending 2 days searching for the answer to my question (and getting quite close in some cases) I've hit a wall. Normally I can find everything I need from stackoverflow but this time I've run out of ways to word my question in the search bar.

I have a mysql table containing data for clothes (tbl_clothing) and in this table (I've simplified this for my problem) I have columns: style, colour_url, size, carton_price

The 'style' is for a particulate type of garment $row['style'] in the first sql statement comes from the initial request to the database to find out if the users choice is actually a valid choice (don't worry I've sanitized it, no direct user input is ever used!)

I am grouping by colour_url to create an array of all the colour variations for the chosen style. Incidentally the colour_url is also the actual url to the image file for that colour (used later). Yes this does mean that in the database there is repeating data, the colour_url is repeated as many times as there are sizes for that colour - I've inherited it and can't change that yet.

I then iterate over this array 'foreach' of the different colours and perform another DB lookup to select all sizes and prices for the chosen style and the current colour.

Still in the above foreach loop I perform a while loop to create a second array to hold the sizes and prices (multiple rows are returned from the DB).

Still in the above foreach loop I perform another foreach loop on the second array to create the table structure for outputting.

This is now screaming at me that it is not the best way of achieving what I'm tying to do.

Am I just over thinking this or is there a much simpler way of doing things? I've tried doing a single sql lookup to retrieve a multidimensional array all in one hit but then cant separate out the data into correct groups I've been over and over transposing arrays re-looping through the array creating other "reference" arrays all without any success.

The basic logic works like this:
1 style = many colours
1 colour = many sizes
1 size = 1 price

And i'm trying to get a table output (for each colour) like this:
_ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __
| (IMG A) | Size(1) | Size(2) | Size(3) |
| colour_A | Price(1) | Price(2) | Price(3) |
| _ __ _ __ _ __ | __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ |

__ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ ___
| (IMG B) | Size(1) | Size(2) | Size(3) |
| colour_B | Price(1) | Price(2) | Price(3) |
| _ __ _ __ _ __ | __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ |

Here is my code, it does the job but this cant be the best way to do it:

$sql = "SELECT colour_url FROM tbl_clothing WHERE style = '".$row['style']."' GROUP BY colour_url";
$result = $mysqli->query($sql);
$numRows = $result->num_rows;

if ($numRows != 0){
    while ($rowS = $result->fetch_assoc()){
        $aResults[] = $rowS['colour_url'];
    }
    $result->free();

    foreach ($aResults as $k=>$v){
        echo "<table><tr><td rowspan='2'><img title='' alt='' src='".$v."' /></td>";

        $sql = "SELECT size, carton_price FROM tbl_clothing WHERE style = '".$row['style']."' AND colour_url = '".$v."'";
        $result = $mysqli->query($sql);
        $numRows = $result->num_rows;

        if ($numRows != 0){
            $aSizePrice = array();
            while ($rowS = $result->fetch_assoc()){
                $aSizePrice[$rowS['size']] = $rowS['carton_price'];
            }

            $sizes = "";
            $prices = "";
            foreach ($aSizePrice as $key=>$val){
                $sizes .= "<td>".$key."</td>";
                $prices .= "<td>".$val."</td>";
            }
        }
        $result->free();
        echo $sizes;
        echo "<tr>".$prices."</tr>";
        echo "</tr></table>";
    }
}
?>

Any help would be a hugely appreciated, even just a point in the right direction, a different opinion or even a sarcastic comment will do at this point...

One thing i might recommend right off the bat, seperate your concerns. You are trying to get data right from the database into your view layer. Instead, get your data, compile it into memory, THEN, display it. It will make your problem easier to solve right off the start.

For example:

//Prepare the data receptacle
$data = array();

//Query to data to work with
$result = $mysqli->query("SELECT * FROM tbl_clothing WHERE style = '".$row['style']."'");
$numRows = $result->num_rows;
while ($rowS = $result->fetch_assoc()){

    //Make sure our data can be stored correctly into our structure
    if(!isset($data[$row['style']])){ $data[$row['style']] = array(); }
    if(!isset($data[$row['style']][$rowS['colour_url'])){ $data[$row['style']][$rowS['colour_url'] = array(); }
    if(!isset($data[$row['style']][$rowS['colour_url']['sizes'])){ $data[$row['style']][$rowS['colour_url']['sizes'] = array(); }
    if(!isset($data[$row['style']][$rowS['colour_url']['prices'])){ $data[$row['style']][$rowS['colour_url']['prices'] = array(); }

    //Store the price and size
    $data[$row['style']][$rowS['colour_url']['sizes'][] = $rowS['size'];
    $data[$row['style']][$rowS['colour_url']['prices'][] = $rowS['carton_price'];

}

//At this point we have our data, let's just show it
?>
<table>
    <?php foreach($data as $style => $color_urls){ ?>
    <?php foreach($color_urls as $color_url => $content){ ?>
    <tr>
        <td rowspan="2">
            <img title="" alt="" src="<?php echo $colour_url; ?>" />
        </td>
    </tr>
    <tr>
        <?php foreach($content['sizes'] as $size){ ?>
        <td><?php echo $size; ?></td>
        <?php } ?>
    </tr>
    <tr>
        <?php foreach($content['prices'] as $price){ ?>
        <td><?php echo $prices; ?></td>
        <?php } ?>
    </tr>
    <?php } ?>
    <?php } ?>
</table>

This is just a quick draft, i might not have understood your question correctly, you'll have to fix the errors and the miscomprehensions yourself. At least you have a good start with this!

Well, let's start with your query. In your first query, you claim you're trying to get all of the colors for a given style. You can use the DISTINCT keyword for that

SELECT DISTINCT colour_url
  FROM tbl_clothing
  WHERE style = ?

But that's not what you're actually looking to get - you actually want all of the color/size combinations in your database for a given style, which you would likely want to select thusly:

SELECT colour_url, size, carton_price
  FROM tbl_clothing
  WHERE style = ?

Once you've done that, you want to parse it into a data structure. (you should be parameterizing your queries - I recommend the PDO library, so I'll show you how that would work).

<?php
  $db = new PDO('connection', 'user', 'pass');
  $query = $db->prepare('SELECT colour_url, size, carton_price
                           FROM tbl_clothing
                           WHERE style = :style');
  $query->bindValue(':style', $row['style'], PDO::PARAM_STR);
  $query->execute();

  $results = $query->fetchAll(PDO::FETCH_ASSOC);

  $clothes = array();

  foreach($results as $result){
      if(!isset($clothes[$result['colour_url']]))
          $clothes[$result['colour_url']] = array();
      $clothes[$result['colour_url']][$result['size']] = $result['carton_price'];
  }
?>

Your results are now in a series of nested maps - from $clothes[$color] , you get a map from size to price. $clothes[$color][$size] will net you the price of a specific color and size, and you can choose to print them that way:

<?php
  foreach($clothes as $color => $prices) {
    $sizeStr = '<td>' . implode('</td><td>', array_keys($prices)) . '</td>';
    $priceStr = '<td>' . implode('</td><td>', $prices) . '</td>';
    ?><table>
      <tr>
        <td rowspan="2">
          <img title="" alt="" src="<?=$color?>" />
        </td>
        <?= $sizeStr ?>
      </tr>
      <tr>
        <?= $priceStr ?>
      </tr>
    </table><?php
  }
?>

Your code now reads a lot closer to english, which will make it easier to debug, and easier to pas on to others.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM