Arhn - архитектура программирования

Перерыв PHP, продолжение в 2 цикла

Я немного запутался в выходе из циклов и продолжении и т. Д. У меня есть 2 SQL-запроса, которые сопоставляют привилегии пользователя с фактическими привилегиями пользователя с новыми. Однако, если некоторые из новых привилегий совпадают с теми, которые есть у пользователя, я хочу пропустить вставку SQL и перейти к следующему:

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')";
                  }             
             }
         }
     }
}

Я почти никогда не сталкиваюсь с ситуацией, когда нужно сопоставить более двух вещей в цикле. Мне нужно убедиться, что у меня не будет двойных привилегий для этого пользователя. Я знаю, что где-то во внутреннем цикле должен быть оператор «продолжить», но не уверен, где именно.


  • Что вы делаете с $x = false; ? 15.12.2012
  • Не обращайте на это внимания, это была предыдущая функция. Это бесполезно. РЖУ НЕ МОГУ 15.12.2012
  • continue 2 должен помочь, он пропускает верхнюю часть вашего foreach. 15.12.2012
  • @ Джек, это должен быть ответ, а не комментарий. Он заслуживает +2: первый +1 за правильный ответ и еще один +1 за использование continue 2 15.12.2012
  • Это пользовательский Class, почему бы не использовать отдельные функции? checkPriveleges, а затем insertPriveleges? 15.12.2012
  • @alfasin Даст ли это другой результат, используя continue 2 vs break в этом конкретном случае? 15.12.2012
  • @alfasin На самом деле в этом даже нет необходимости, потому что подход можно просто улучшить, не читая базу данных снова и снова. 15.12.2012
  • @cheesemacfly В данном случае нет. Но если между концом цикла while и концом цикла foreach что-то было, то да :) 15.12.2012
  • @ Джек, хорошо, я всегда использовал перерыв ... спасибо! 15.12.2012
  • Пытаясь избежать другого метода класса, чтобы сделать это, в то время как я могу просто иметь возможность сделать это в одном 15.12.2012
  • @ Джек, теперь вопрос в том, где бы вы поставили «продолжить» во всем этом процессе? Внутренний цикл после оператора SQL или перед оператором SQL? 15.12.2012
  • @DimitriTopaloglou Я добавил это в свой ответ :) 15.12.2012

Ответы:


1

После утверждения INSERT вы можете добавить continue 2, чтобы вернуться к началу foreach ($ex as .... Вы также можете использовать break; в этом случае, потому что после вашего внутреннего while ничего нет.

Однако на самом деле вам это не нужно, если вы делаете это по-другому. Вместо того, чтобы читать таблицу для каждой привилегии, просто прочитайте их все один раз и сравните.

Этот код получит все привилегии из базы данных, а затем вставит только недостающие, исходя из $ex; он использует array_diff() для вычисления разницы между ними.

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);
         }
     }
}

Кстати, вы могли бы рассмотреть возможность использования INSERT IGNORE INTO из-за условий гонки, но поскольку вы не проверяете возвращаемое значение оператора, здесь это не имеет значения :)

15.12.2012
  • +1 Это решение сократит все вызовы SELECT в БД до одного вызова, а также все вызовы INSERT до одного вызова. Дополнительная ценность этого решения ВЕЛИКОЛЕПНА! 15.12.2012
  • @alfasin Ну, на самом деле может быть несколько операторов INSERT :) 15.12.2012
  • хммм, в таком случае я считаю, что его можно сократить до одного запроса (с использованием добавления строки), например: electrictoolbox.com/mysql-insert-multiple-records 15.12.2012
  • @alfasin Конечно, вопрос в том, строго ли это необходимо. Подготовленные заявления были бы моими любимыми на самом деле. 15.12.2012
  • Правильно! Я думаю, это зависит от того, сколько вызовов в БД вы сохраните;) 15.12.2012
  • @ Джек, это работает отлично. Сокращение вызовов БД также. Спасибо! :) 15.12.2012

  • 2

    Просто добавьте разрыв после 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;
                      }             
                 }
             }
         }
    }
    

    Чтобы быть полным, я бы рекомендовал прочитать следующую ссылку: http://php.net/manual/en/faq.databases.php#faq.databases.mysql.deprecated

    15.12.2012
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..