Вывод счетчика товаров

Есть анонимная функция по выводу товаров и их наименованию: наименование, старая цена и т.д.

$upsells = ['Наименование товара №1_~-250$_~-99$', 'Наименование товара №2_~-699$_~-399$', 'Наименование товара №3_~-299$_~-149$',];
       
$enumerationGoods = function($upsells) {
            
    $productInformation = explode('_~-', $upsells);
    $numberProduct .= '<b>Товар №</b> '.($number += 1).':<br />';
    $orderDetails = ['Наименование', 'Старая цена', 'Новая цена'];
                            
    for ($i = 0; $i < count($productInformation); $i++) {
        $nomination .= '<b>'.$orderDetails[$i].':</b> '.$productInformation[$i].'<br />';
    }                   
    return $numberProduct . $nomination;
};
$orderTable = array_map($enumerationGoods, $upsells);
echo implode('', $orderTable);

Результат

Товар № 1:
Наименование: Наименование товара №1
Старая цена: 250$
Новая цена: 99$
Товар № 1:
Наименование: Наименование товара №2
Старая цена: 699$
Новая цена: 399$
Товар № 1:
Наименование: Наименование товара №3
Старая цена: 299$
Новая цена: 149$

Как исправить работу счетчика товаров?


Ответы (2 шт):

Автор решения: u_mulder

Это происходит потому, что анонимная функция (как и обычная функция) не имеет понятия о том, какие переменные находятся вне её области видимости.

Поэтому $number каждый раз определяется заново нулем и прибавляя единицу получается 1.

Для прокидывания в анонимную функцию нужных значений используется конструкция use, а с учетом того, что переменная будет увеличиваться - передавать ее надо по ссылке:

$number = 0;
$enumerationGoods = function() use (&$number) {
    $number += 1;
    echo $number;
};
$enumerationGoods();  // 1
$enumerationGoods();  // 2
$enumerationGoods();  // 3

Стоит также открыть и почитать мануал (пример 3).

→ Ссылка
Автор решения: Максим Степанов

Если честно, не понимаю, зачем в этом примере вы используете анонимную функцию, если в итоге вам нужно заполнить переменную html с таблицей...

В этом случае, как уже ответили, либо использовать use для передачи переменной в функцию, либо пойти другим путем и просто перебрать ваш массив в обычном цикле:

$upsells = ['Наименование товара №1_~-250$_~-99$', 'Наименование товара №2_~-699$_~-399$', 'Наименование товара №3_~-299$_~-149$',];

$orderTable = '';
$orderDetails = ['Наименование', 'Старая цена', 'Новая цена'];

for ($i = 0; $i < count($upsells); $i++) {
    $orderTable .= '<b>Товар №</b> '.($i + 1).':<br />';
    $productInformation = explode('_~-', $upsells[$i]);
    for ($k = 0; $k < count($productInformation); $k++) {
        $orderTable .= '<b>'.$orderDetails[$k].':</b> '.$productInformation[$k].'<br />';
    }
}

echo $orderTable;
→ Ссылка