Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

Switch inside for loop - php / mysql problem

Options
  • 14-07-2009 9:10pm
    #1
    Closed Accounts Posts: 38


    I've spent a couple of days trying to get my head around this to no avail.
    I have two arrays as follows:
    $A holds id of record in a mysql table - [0]=>100 [1]=>506
    $B holds name of programme - [0]=>ProgX [1]=>ProgY

    0th element in A corresponds to 0th element in B.
    $size = count[$A];
    

    I need to loop through both arrays extracting the ids from $A and their corresponding names from $B plugging the name into switch structure and the id into a SQL query for the number of iterations in $size (2 in this case):
    for ($i=0; $i<$size; $i++) {
        switch($B[$i]) {
            case 'ProgX':
                $query="SELECT * FROM table
                    WHERE id='$A[$i]';
                // display results in tabular format
            
            break;
            case 'ProgY':
                $query="SELECT * FROM table
                    WHERE id='$A[$i]';
                // display results in tabular format
            
        
            break;
            case 'ProgZ':
                $query="SELECT * FROM table
                    WHERE id='$A[$i]';
                // display results in tabular format
        
            break;
            case 'ProgW':
                $query="SELECT * FROM table
                    WHERE id='$A[$i]';
                // display results in tabular format
        
            break;
        } // end switch
    } // end for loop
    
    All I ever get is the first iteration, i.e. it only gives the me results the query for case 'ProgX'.
    I've tried substituting continue for break to no avail.
    What am I doing wrong? Any help would be great!
    Thanks:confused:
    Tagged:


Comments

  • Registered Users Posts: 68,317 ✭✭✭✭seamus


    I suspect your break is causing it to break out of the for loop. Quick fix is to replace "break" with "continue". This may not work, but my gut says it does.

    Something tells me there's a much better way of doing this, but I'd need to see the actual code. For a start, try using an associative array instead of relying on having two arrays which *should* be the same length. That is instead of
    $A = array(100, 101, 102);
    $B = array("Prog1", "Prog2", "Prog3");
    
    You have one array, such as:
    $progs = array(100 => "Prog1",
    				101 => "Prog2",
    				102 => "Prog3");
    
    This means that you can use a foreach loop instead of a for.

    Meaning that the start of your code looks like this:
    foreach ($progs as $progid => $progname ) {
        switch($progname) {
            case 'ProgX':
    ...
    
    Does it perform better? I dunno. It's a million times more readable, and you're guaranteed that you will always have a pair (i.e. one array isn't bigger than the other).


  • Closed Accounts Posts: 38 PixelPixie


    seamus wrote: »
    I suspect your break is causing it to break out of the for loop. Quick fix is to replace "break" with "continue". This may not work, but my gut says it does.
    That's what I thought as well. But taking out the break and replacing with continue has no effect whatsoever.
    seamus wrote: »
    Something tells me there's a much better way of doing this, but I'd need to see the actual code. For a start, try using an associative array instead of relying on having two arrays which *should* be the same length. That is instead of
    $A = array(100, 101, 102);
    $B = array("Prog1", "Prog2", "Prog3");
    
    You have one array, such as:
    $progs = array(100 => "Prog1",
    				101 => "Prog2",
    				102 => "Prog3");
    
    This means that you can use a foreach loop instead of a for.

    Meaning that the start of your code looks like this:
    foreach ($progs as $progid => $progname ) {
        switch($progname) {
            case 'ProgX':
    ...
    
    Yea, I thought so too. And proceeded to merge the two arrays - they are always the same length:
    $AB = array_merge($A1, $B1);
    
    But that just adds one array onto the other which is no good.
    I want to get a new array whose keys are the values of $A and whose values are the values of $B.
    I thought if I stripped the keys out of each first thus:
    $A1 = array_values($A);
    $B1 = array_values($B);
    
    and then looped through them to create a new array thus:
    for ($i=0; $i<$size; $i++) {
                    // assign ids as keys to new array & PROGs as values of same
    		echo "Element ".$i." : ".$A1[$i]." is ".$B1[$i]."<br />";
                   $AB[] = array($A1[$i] => $B1[$i]);		
    }
    
    But this does not give me what I want. The echo prints off correctly but the creation of the new array $AB[] only adds one element and gives a multi-dimensional array as follows:
    print_r($AB);
    
    Array ( [0] => Array ( [100] => Prog1 ) )

    Arrays have never been my strong point I'm afraid. I know I probably doing something really silly here - but I can't see what.
    seamus wrote: »
    Does it perform better? I dunno. It's a million times more readable, and you're guaranteed that you will always have a pair (i.e. one array isn't bigger than the other).
    Performance doesn't matter as it's on an intranet on which no more than 10 people will be running the code simultaneously at any one time. That's the reason I can't post the actual code.


  • Registered Users Posts: 981 ✭✭✭fasty


    In PHP, is there a difference between a "string" and a 'string'? I'm not a PHP programmer but I checked the docs, and most examples use "string". PHP seems really loosely typed, so are it's possible that's the problem... I mean, you breaking after each case is just how it should be done.


  • Users Awaiting Email Confirmation Posts: 351 ✭✭ron_darrell


    I think the problem might be more basic than what has been suggested so far. The break that people seem to be worried about will apply only to the switch statement not to the the entire code segment (as the break breaks only the current code block i.e. the switch statement).

    Looking at the queries you're generating there is no difference between the query generated by the detection of a ProgX and any of the other Progs. It's always SELECT * FROM table WHERE id = $A[$id];

    Could you state again for me why you're storing data in 2 arrays and the effect you are trying to achieve? Where is the data for the 2 arrays coming from initially?

    If, as I surmise, you have a table storing data about the progs and a table with a list of progs and you only seem interested in Progs W-Z a better solution for what you are trying to achieve might be as follows:
    
    $strQ1 = "SELECT id FROM progListTable WHERE name IN ('ProgX', 'ProgY', 'ProgZ', 'ProgW');";
    $result = mysql_query($strQ);
    while($row = mysql_fetch_array($result)) {
    $strQ2 = "SELECT * FROM table WHERE id = ".$row[0]";";
    $result2 = mysql_query($strQ2);
    while($row2 = mysql_fetch_array($result)) {
    //display data in table format
    }
    }
    
    

    But this is just a wild suggestion as I'm not 100% sure what it is you're trying to achieve.

    -RD


  • Closed Accounts Posts: 7,794 ✭✭✭JC 2K3


    $query="SELECT * FROM table
                    WHERE id='$A[$i]';
    

    Missing a " ?

    Also, you don't need a switch if the only entries in your $B array are ProgX, ProgY, ProgZ and ProgW, if there are more you want to ignore, why not do this:
    switch($B[$i]) {
            case 'ProgX':
            case 'ProgY:
            case 'ProgZ':
            case 'ProgW':
                $query="SELECT * FROM table
                    WHERE id='$A[$i]'[color=red]"[/color];
                // display results in tabular format
            break;
    }
    

    (I've put the quote you're missing in red)


  • Advertisement
  • Closed Accounts Posts: 38 PixelPixie


    I think the problem might be more basic than what has been suggested so far. The break that people seem to be worried about will apply only to the switch statement not to the the entire code segment (as the break breaks only the current code block i.e. the switch statement).

    Looking at the queries you're generating there is no difference between the query generated by the detection of a ProgX and any of the other Progs. It's always SELECT * FROM table WHERE id = $A[$id];
    Well, I've simplified the query actually. Depending on the Programme case selected in the switch different tables are queried and most involve a join with another table - I left out the detail as this is not the issue.
    Could you state again for me why you're storing data in 2 arrays and the effect you are trying to achieve? Where is the data for the 2 arrays coming from initially?
    The data from the 2 arrays comes from the results of a previous query on a progs table holding information 1, 2, or 3 programmes taken by a student in a particular sojourn. Usually there is only one progs table record per student per year which has a unique id (a foreign key from another table which holds the registration data) - see below. But occasionally there may be more than one when a student leaves and comes back again to do a different set of programmes in the same year. I've got it working perfectly for the students who have only 1 record per year, but for those with more than one record it's not working.
    So the progs table has the following fields for each record:
    id (primary key), studentid, centreid, year, prog (which is one of 7 values)
    Obviously I need to store the query results in a multidimensional array (in case a student has more than 1 record in a year) for querying specific modules/subject details stored in other tables (the id acting as a foreign key in same) for display depending on which specific programme is specified in the programmes table (this is where the switch comes in).
    The code that gives the $B array (the one that holds the prog name) is here:
    $progs_array = array();
    
    		// initialise arrays to hold programmes for switch below
    
    		$programme_array=array();
    
                    for ($i=0; $i<$num_results; $i++) {
    
    				$row[$i] = mysql_fetch_array($result);
    
                                    $programme[$i] = $row[$i]["programme"];
    
    				$B[] = $programme[$i];
    
    
    The code that gets the unique record id(s) for $A is from a preceding query on another table that holds data on when the student registered and left (if applicable) - the primary key for each record is the what gives the unique key that tracks each student sojourn in all the other tables. This is why I have 2 separate arrays.

    It seems to me now from what you and others have been saying that the best option is to use a foreach loop but for that I need to create a new array whose keys are the values of $A (the record id(s)) and whose values are the values of $B (the programme name(s)).
    I can't seem to make any headway here.
    If, as I surmise, you have a table storing data about the progs and a table with a list of progs and you only seem interested in Progs W-Z a better solution for what you are trying to achieve might be as follows:
    
    $strQ1 = "SELECT id FROM progListTable WHERE name IN ('ProgX', 'ProgY', 'ProgZ', 'ProgW');";
    $result = mysql_query($strQ);
    while($row = mysql_fetch_array($result)) {
    $strQ2 = "SELECT * FROM table WHERE id = ".$row[0]";";
    $result2 = mysql_query($strQ2);
    while($row2 = mysql_fetch_array($result)) {
    //display data in table format
    }
    }
    
    

    But this is just a wild suggestion as I'm not 100% sure what it is you're trying to achieve.

    -RD


  • Closed Accounts Posts: 38 PixelPixie


    I've narrowed down the problem to the sql query and subsequent data display inside the switch case.
    The code that gets the IDs and PROGs from the multidimensional array is as follows:
    for ($row = 0; $row < $size; $row++) {
        echo "<p><strong>Record $row :</strong> ";
        foreach($multiarray[$row] as $ID => $PROG) {        
            echo " ".$ID." => ".$PROG." </p>";
            
            switch ($PROG) {
                case 'ProgX':
                    echo "<p>ID is $ID and Programme is $PROG</p>";
                    echo "<p>Do other stuff here!</p>";
                break;
                case 'ProgY':
                    echo "<p>ID is $ID and Programme is $PROG</p>";
                    echo "<p>Do other stuff here!</p>";
                break;
            } // end switch 
        } // end foreach
    }  // end for
    
    This works when I comment out the sql code inside the cases so I'm now debugging that to see what is causing the foreach loop to stop after displaying the 1st row. :(


  • Closed Accounts Posts: 38 PixelPixie


    I've finally located the problem - it's the for loop that cycles through the results of the sql query inside the switch case that has been causing the problem.
    Basically, the
    $row = mysql_fetch_array($result);
    
    that retrieves the result array from the query (inside the switch case) was overwriting the $row array in the for loop
    for ($row = 0; $row < $size; $row++) {
        foreach($multiarray[$row] as $ID => $PROG) {        
            switch ($PROG) {
          // etc. etc.
    
    and therefore stopping it from going further than the first iteration.
    Doh! :o
    Thanks to everyone who pitched in their ideas. It's much appreciated.


Advertisement