PHP Array: дважды, если оператор в for

Мне сложно закончить оператор if дважды. Остальное работает нормально, но когда я пытаюсь проверить другой подмассив, оно не работает.

РЕДАКТИРОВАТЬ: - Первое условие if - проверка типов продуктов. - Второе условие if - проверка атрибутов размера. - Продукты: sweatshirt_crianca и sweatshirtc_crianca_capuz - Размеры: 4_anos, 6_anos, 8_anos, 11_anos, 12_anos и 14_anos Необходимо отключить ( $this->enabled = false;) Эти размеры, кроме 14_anos.

Это то, что я получаю от $order->products[$i]

Array
(
    [qty] => 1
    [name] => .Mr Mickey T-shirt
    [model] => 
    [image] => blusa-mr-mrs-blusao-sweat-camisolas-portugal.png
    [tax] => 20
    [tax_description] => IVA 23%
    [price] => 10.8333
    [final_price] => 16.6666
    [weight] => 0.00
    [id] => 1342{18}135{17}132{19}148
    [attributes] => Array
        (
            [0] => Array
                (
                    [option] => s_cor_produto
                    [value] => branco
                    [option_id] => 18
                    [value_id] => 135
                    [prefix] => +
                    [price] => 0.0000
                )

            [1] => Array
                (
                    [option] => s_produto
                    [value] => sweatshirt_crianca
                    [option_id] => 17
                    [value_id] => 132
                    [prefix] => +
                    [price] => 5.8333
                )

            [2] => Array
                (
                    [option] => s_tamanho_produto
                    [value] => 8_anos
                    [option_id] => 19
                    [value_id] => 148
                    [prefix] => +
                    [price] => 0.0000
                )

        )

)
Array
(
    [qty] => 1
    [name] => Adivinha quem vai ser mama shirt
    [model] => 
    [image] => adivinha-quem-vai-ser-mama-tshirt-gravida.png
    [tax] => 20
    [tax_description] => IVA 23%
    [price] => 10.8333
    [final_price] => 10.8333
    [weight] => 0.00
    [id] => 1860{20}157{18}139{17}128{19}152
    [attributes] => Array
        (
            [0] => Array
                (
                    [option] => s_cor_impressao
                    [value] => branco
                    [option_id] => 20
                    [value_id] => 157
                    [prefix] => +
                    [price] => 0.0000
                )

            [1] => Array
                (
                    [option] => s_cor_produto
                    [value] => azul_royal
                    [option_id] => 18
                    [value_id] => 139
                    [prefix] => +
                    [price] => 0.0000
                )

            [2] => Array
                (
                    [option] => s_produto
                    [value] => tshirt_mulher
                    [option_id] => 17
                    [value_id] => 128
                    [prefix] => +
                    [price] => 0.0000
                )

            [3] => Array
                (
                    [option] => s_tamanho_produto
                    [value] => M
                    [option_id] => 19
                    [value_id] => 152
                    [prefix] => +
                    [price] => 0.0000
                )

        )

)

Иногда он может содержать 1 или 4 подмассива. Это тресковая оплата от osCommerce, я пытаюсь исключить определенные продукты из этого метода на основе его атрибутов. Это прекрасно работает в первом операторе if, чтобы проверить [значение], но закомментированные строки синтаксиса верны, но не работают. Вот код, который я получил:

  for ($i=0, $n=sizeof($order->products); $i<$n; $i++) {
    if ($order->products[$i]['weight'] > '0.00') {
      $this->enabled = false;
    }
    if ( (isset($order->products[$i]['attributes'])) && (sizeof($order->products[$i]['attributes']) > 0) ) {
      for ($j=0, $n2=sizeof($order->products[$i]['attributes']); $j<$n2; $j++) {
        if ( ($order->products[$i]['attributes'][$j]['option'] == 's_produto') && ($order->products[$i]['attributes'][$j]['value'] == 'sweatshirt_crianca') ) {
          //if ( ($order->products[$i]['attributes'][$j]['option'] == 's_tamanho_produto') && ($order->products[$i]['attributes'][$j]['value'] == '14_anos') ) {
            $this->enabled = false;
          //}
        }
        else if ( ($order->products[$i]['attributes'][$j]['option'] == 's_produto') && ($order->products[$i]['attributes'][$j]['value'] == 'sweatshirtc_crianca_capuz') ) {
          //if ( ($order->products[$i]['attributes'][$j]['option'] == 's_tamanho_produto') && ($order->products[$i]['attributes'][$j]['value'] != '14_anos') ) {
            $this->enabled = false;
          //}
        }
      }
    }
  }

Какие-либо решения? Благодарю.

3 ответа

Основная проблема с вашим кодом заключается в том, что вы хотите тестировать различные элементы массива, но вы делаете это, повторяя один за другим. Код внутри for Цикл будет видеть только текущий элемент на итерации. Поэтому, когда вы вкладываете if утверждений, вы в основном проверяете, равен ли текущий элемент чему-либо, а затем проверяете, равен ли этот самый элемент чему-то еще. Эта логика не удастся.

Поскольку, по-видимому, только option а также value ключи важны, я предлагаю сначала создать еще один массив. Затем вы можете получить доступ ко всем этим свойствам одновременно, а не только к текущему атрибуту внутри итератора. Например, вот упрощенный массив атрибутов для вашего последнего примера в вопросе:

$attributes = [
    s_cor_impressao   => 'branco'
    s_cor_produto     => 'azul_royal'
    s_produto         => 'tshirt_mulher'
    s_tamanho_produto => 'M'
];

Чтобы создать это легко, а также упростить ваш код, я предлагаю использовать foreach ... as петля. Также вам не нужно проверять, есть ли в массиве элементы. Если нет никаких предметов, просто foreach не будет выполнен вообще. Стоит проверить, установлен ли он, как вы, если вы не знаете заранее. Но другой способ - просто перейти непосредственно к следующей итерации, если она не установлена ​​с помощью continue структура управления.

foreach ($order->products as $product) {
    if ($product['weight'] > 0)
        $this->enabled = false;

    if (!isset($product['attributes']) || !is_array($product['attributes']))
        continue;

    $attributes = [];
    foreach ($products['attributes'] as $attr)
        $attributes[ $attr['option'] ] = $attr['value'];

    # [tests]
}

Теперь, в тесте выше, вы можете сделать ваши тесты, как:

if ($attr['s_produto'] == 'sweatshirt_crianca' &&
    $attr['s_tamanho_produto'] == '14_anos') {
    # do something
    # $this->enabled = false;
} else if (...) {
    # do something else
}

Сидил побил меня этим, но я думал по тому же принципу:

  // loop through each product
  foreach ( $order->products as $prod )
  {

        if($prod['weight'] > '0.00')
        {
                $this->enabled = false;
        }

        if( isset($prod['attributes']) && is_array($prod['attributes']) )
        {
                $matching_product_type_found = false;
                $matching_valid_size_found = false;

                foreach ( $prod['attributes'] as $attr )
                 {
                       if ( $attr['option'] == 's_produto' &&
                            ( $attr['value'] == 'sweatshirt_crianca' ||
                              $attr['value'] == 'sweatshirtc_crianca_capuz'
                            ) )
                          {
                            $matching_product_type_found = true;
                          }

                       if ( $attr['option'] == 's_tamanho_produto' && $attr['value'] == '14_anos' )
                          {
                            $matching_valid_size_found = true;
                          }
                 }


                if( $matching_product_type_found == true )
                {

                     $this->enabled = $matching_valid_size_found;

                }

        }

  }

Я бы переписал твой цикл используя foreach чтобы сделать его более читабельным и менее подверженным ошибкам. Также следите за своими сравнениями (== против ===). Попробуйте это следующим образом:

foreach ($order->products as $product) {
    if ($product['weight'] > 0.00) {
        $this->enabled = false;
    }
    if (!empty($product['attributes'])) {
        foreach ($product['attributes'] as $attribute) {

            if ($attribute['option'] === 's_produto') {

                switch ($attribute['value']) {
                    case "sweatshirt_crianca" :
                        // .. do some code
                        break;
                    case "s_tamanho_produto" :
                        // .. do some code
                        break;
                    case "14_anos" :
                        // .. do some code
                        break;
                    case "something else" :
                        // .. do some code
                        break;
                    default:
                        break;
                }

            }
        }
    }
}
Другие вопросы по тегам