2

I'm a little confused about breaking out and continuing out of loops etc. I have 2 SQL queries that match user priveleges against the user's actual priveleges with the new ones put it. However, if some of the new priveleges match the one the user has, I want to skip the SQL insert and move on to the next one:

public static function insertPriveleges($user_id,$priveleges)
{
    $ex = explode(",",$priveleges); // separated by commas
    if(count($ex)>0)
    {
         $x = false;
         foreach($ex as $i => $priv)
         {
             $check_user = mysql_query("SELECT * FROM users_access_codes WHERE user_id='$user_id'") or die(mysql_error()); // get user's current priveleges
             while($check_data = mysql_fetch_array($check_user))
             {
                  if($check_data['access_code']!=$priv)
                  {
                      //if it doesn't match, insert 
                      $sql = "INSERT INTO users_access_codes (uaID,user_id,access_code) VALUES (NULL,'".$user_id."','$priv')";
                  }             
             }
         }
     }
}

I almost never have a situation that needs to match more than two things in loops. I need to make sure I don't end up with double priveleges for that user. I know there must be a 'continue' statement somewhere in the inner loop, but not sure where.

12
  • What do you do with $x = false; ? Commented Dec 15, 2012 at 5:26
  • Disregard that, that was the previous function. No use for this one. LOL Commented Dec 15, 2012 at 5:27
  • 2
    continue 2 should do the trick, it skips back the top of your foreach. Commented Dec 15, 2012 at 5:29
  • @Jack this should be an answer - not a comment. It deserves +2: first +1 for a correct answer and another +1 for the use of continue 2 Commented Dec 15, 2012 at 5:32
  • 1
    @cheesemacfly In this case, no. But if there was anything between the end of the while loop and the end of the foreach loop, then yes :) Commented Dec 15, 2012 at 5:38

2 Answers 2

4

After your INSERT statement, you can add continue 2 to bring you back to the top of your foreach ($ex as .... You can also use break; in this case because there's nothing after your inner while.

However, you don't actually need it if you do it differently. Instead of reading the table for each privilege, just read all of them once and them compare.

This code will get all privileges from the database and then only inserts those that are missing, based on $ex; it uses array_diff() to calculate the difference between the two.

public static function insertPriveleges($user_id, $priveleges)
{
    $ex = explode(",", $priveleges); // separated by commas
    if (count($ex) > 0) {
         // get user's current priveleges
         $check_user = mysql_query("SELECT * FROM users_access_codes 
             WHERE user_id='$user_id'") or die(mysql_error()); 
         $actual = array();
         while ($row = mysql_fetch_array($check_user)) {
             $actual[] = $row['access_code'];
         }

         foreach (array_diff($ex, $actual) as $priv) {
             //if it doesn't match, insert 
             $sql = "INSERT INTO users_access_codes (uaID,user_id,access_code) VALUES (NULL,'".$user_id."','$priv')";
             mysql_query($sql);
         }
     }
}

Btw, you could consider using INSERT IGNORE INTO because of race conditions, but because you're not checking the statement return value, it won't matter here :)

Sign up to request clarification or add additional context in comments.

6 Comments

+1 This solution will reduce all the SELECT calls to the DB to just one call and also all the INSERT calls to just one call. The added-value of this solution is BRILLIANT!
@alfasin Well, there can be multiple INSERT statements actually :)
hmmm, in that case I believe that it can be reduced into one query (using string append) like this: electrictoolbox.com/mysql-insert-multiple-records
@alfasin For sure, question is whether that's strictly necessary. Prepared statements would be my favourite actually.
right! I guess it depends on how many calls to the DB you save ;)
|
1

Simply add a break after the INSERT:

public static function insertPriveleges($user_id,$priveleges)
{
    $ex = explode(",",$priveleges); // separated by commas
    if(count($ex)>0)
    {
         $x = false;
         foreach($ex as $i => $priv)
         {
             $check_user = mysql_query("SELECT * FROM users_access_codes WHERE user_id='$user_id'") or die(mysql_error()); // get user's current priveleges
             while($check_data = mysql_fetch_array($check_user))
             {
                  if($check_data['access_code']!=$priv)
                  {
                      //if it doesn't match, insert 
                      $sql = "INSERT INTO users_access_codes (uaID,user_id,access_code) VALUES (NULL,'".$user_id."','$priv')";
                      break;
                  }             
             }
         }
     }
}

To be complete I would recommand the reading of the following link: http://php.net/manual/en/faq.databases.php#faq.databases.mysql.deprecated

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.