Форум программистов, компьютерный форум, киберфорум
PHP для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.92/13: Рейтинг темы: голосов - 13, средняя оценка - 4.92
225 / 216 / 89
Регистрация: 12.09.2015
Сообщений: 986

Функция не выполняется в цикле

02.12.2015, 08:17. Показов 2530. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет. Вот код функции:
PHP
1
2
3
4
5
6
7
8
9
10
function print_attribute_radio( $checked_value, $value, $label, $name ) {
    // This handles < 2.4.0 bw compatibility where text attributes were not sanitized.
    $checked = sanitize_title( $checked_value ) === $checked_value ? checked( $checked_value, sanitize_title( $value ), false ) : checked( $checked_value, $value, false );
 
    $input_name = 'attribute_' . esc_attr( $name ) ;
    $esc_value = esc_attr( $value );
    $id = esc_attr( $name . '_v_' . $value );
    $filtered_label = apply_filters( 'woocommerce_variation_option_name', $label );
    printf( '<div><input type="radio" name="%1$s" value="%2$s" id="%3$s" %4$s><label for="%3$s">%5$s</label></div>', $input_name, $esc_value, $id, $checked, $filtered_label );
}
Она выводит вариации товара в виде радиокнопок. Плагин - вукомерц. Дальше на странице в цикле (foreach) выводятся вариации этой функцией. Пока на странице один товар всё работает нормально, но когда появляется ещё один, то появляется ошибка Fatal error: Cannot redeclare print_attribute_radio() (previously declared in [..]variable.php:17) in [..]variable.php on line 26. 17 строка это начало функции, 26 соответственно конец.
Сижу и вообще не могу понять как исправить.

Добавлено через 5 минут
UPD. Вынес функцию в отельный файл и подключил через include_once, визуально всё исправилось и ошибки не возникает. Но радиокнопки работают только у первого товара.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
02.12.2015, 08:17
Ответы с готовыми решениями:

Не выполняется операция в цикле
Почему-то при повторении цикла игнорируется первый оператор. Привожу нехитрый код. #include &lt;avr/io.h&gt; int...

Не выполняется условие в while цикле
Привет, пытаюсь протестировать код из книги, но у меня внезапно перестал правильно работать цикл. Вот такой код: #include...

Не выполняется условие в цикле for
Доброго времени суток. Почему не выполняется код в цикле for? #include &lt;iostream&gt; using namespace std; int main(){ for (int...

9
162 / 161 / 66
Регистрация: 28.06.2015
Сообщений: 576
02.12.2015, 09:24
Вобще это ошибка означает что у вас эта функция объявляется несколько раз. Заметьте не вызывается а объявляется. Ищите где то в коде, можно включить поиск по файлам и написать допустим эту строку:
PHP
1
function print_attribute_radio(
Добавлено через 2 минуты
В nodepad++ и в sublime точно можно искать по файлам, на счет других редакторов не знаю, и еще можно через констоль *nix систем, например так:
Bash
1
grepfunction print_attribute_radio(” directory
directory - соответственно папка в которой лежит сайт

Добавлено через 3 минуты
Хотя тут подумал, похоже у вас функция объявлялась в цикле. А вам нужно вызывать ее в цикле. Приведите код, где вы выводите товары в цикле
0
 Аватар для GoDr
90 / 79 / 33
Регистрация: 17.08.2015
Сообщений: 512
Записей в блоге: 1
02.12.2015, 12:43
PHP
1
2
3
4
5
if (!function_exists('print_attribute_radio')) {
    function print_attribute_radio( $checked_value, $value, $label, $name ) {
        // ..................
    }
}
0
162 / 161 / 66
Регистрация: 28.06.2015
Сообщений: 576
02.12.2015, 14:14
Цитата Сообщение от GoDr Посмотреть сообщение
PHP
1
2
3
4
if (!function_exists('print_attribute_radio')) {
* * function print_attribute_radio( $checked_value, $value, $label, $name ) {
* * * * // ..................
* * }
}
У меня такое предчувствие что у ТС было что то типа:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
 
    foreach ($products as $product) {
        function print_attribute_radio( $checked_value, $value, $label, $name ) {
            // This handles < 2.4.0 bw compatibility where text attributes were not sanitized.
            $checked = sanitize_title( $checked_value ) === $checked_value ? checked( $checked_value, sanitize_title( $value ), false ) : checked( $checked_value, $value, false );
         
            $input_name = 'attribute_' . esc_attr( $name ) ;
            $esc_value = esc_attr( $value );
            $id = esc_attr( $name . '_v_' . $value );
            $filtered_label = apply_filters( 'woocommerce_variation_option_name', $label );
            printf( '<div><input type="radio" name="%1$s" value="%2$s" id="%3$s" %4$s><label for="%3$s">%5$s</label></div>', $input_name, $esc_value, $id, $checked, $filtered_label );
        }
 
        print_attribute_radio($checked_value, $value, $label, $name );
        //Далее какой то код
    }
Потому что он пишет:
Цитата Сообщение от Анар Посмотреть сообщение
Дальше на странице в цикле (foreach) выводятся вариации этой функцией. Пока на странице один товар всё работает нормально, но когда появляется ещё один, то появляется ошибка Fatal error: Cannot redeclare print_attribute_radio() (previously declared in [..]variable.php:17) in [..]variable.php on line 26. 17 строка это начало функции, 26 соответственно конец.
Поэтому ему, скорее всего, нужно просто вынести объявление функции за пределы цикла, и не тратить дополнительные ресурсы на проверку существует ли функция или нет. Иначе он не поймет в чем причина, и в дальнейшем всегда будет писать так как вы ему посоветовали
1
 Аватар для GoDr
90 / 79 / 33
Регистрация: 17.08.2015
Сообщений: 512
Записей в блоге: 1
02.12.2015, 14:25
Цитата Сообщение от Xenox Посмотреть сообщение
У меня такое предчувствие что у ТС было что то типа:
у мня такое чувство что это полный идиотизм
PHP
1
2
3
foreach ($products as $product) {
        function print_attribute_radio .....
}
И я боюсь что вопрос не в трате ресурсов, а с таким подходом вопросов будет ещё много

Цитата Сообщение от Xenox Посмотреть сообщение
Иначе он не поймет в чем причина, и в дальнейшем всегда будет писать так как вы ему посоветовали
Зато узнает что есть и такая функция
0
225 / 216 / 89
Регистрация: 12.09.2015
Сообщений: 986
02.12.2015, 18:32  [ТС]
Всем спасибо за ответы.
Если сделать через function_exists, то получается полный аналог include_once, т.е. визуально всё нормально, но вариации работают только у первого товара, далее всё статично, хотя так быть не должно.

Эта функция больше нигде не объявляется, потому это это надгрузка (плагин) над вукомерц, который меняет селекторы вариаций на радиокнопки. Там всего 3 файла.

Выводится далее эта функция дважды в циклах вот так:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<td class="value">
<?php
if ( ! empty( $options ) ) {
    if ( taxonomy_exists( $name ) ) {
    // Get terms if this is a taxonomy - ordered. We need the names too.
        $terms = wc_get_product_terms( $product->id, $name, array( 'fields' => 'all' ) );
            foreach ( $terms as $term ) {
                if ( ! in_array( $term->slug, $options ) ) { continue; } 
                    print_attribute_radio( $checked_value, $term->slug, $term->name, $sanitized_name );
                                    }
} else {
    foreach ( $options as $option ) {
        print_attribute_radio( $checked_value, $option, $option, $sanitized_name );
                                    }
                                }
                            }
//echo end( $attribute_keys ) === $name ? '<a class="reset_variations" href="#">' . __( 'Clear selection', 'woocommerce' ) . '</a>' : ''; ?>
</td>
UPD. Пока писал кое что понял... Что я идиот) При function_exists и include_once всё работает.
Причина была в том, что сами input я скрыл для того, чтобы через css визуально сделать из радиокнопок - обычные кнопки. Как мне казалось клик по label аналогичен клику по input, но тут проблема в том, что этого происходит только у первого товара, а далее переключить вариацию можно только по нажатию на input...

UPD2. Маразм крепчает. Опять, пока пиал осенило, лейбл-то не может не переключать... И, лейбл переключает вариацию, но не своего товара, а *дробь* первого! Потому что у лейблов одинаковый for и он переключает первый input с таким id на странице! При этом сами input'ы всё меняют правильно...

В общем решение пришло-то за 2 минуты, надо просто к for и id прицепить id товара. На странице id товара выводится через <?php echo absint( $product->id ); ?>. Вот как мне теперь значение из $product->id вставить в $id, потому что
PHP
1
$id = esc_attr( $name . '_v_' . $value .'-'.$product->id );
Естественно не работает.

Вот код всей страницы:
Кликните здесь для просмотра всего текста
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<?php
/**
 * Variable product add to cart
 *
 * @author  WooThemes
 * @package WooCommerce/Templates
 * @version 2.4.0
 *
 * Modified to use radio buttons instead of dropdowns
 * @author 8manos
 */
 
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}
if (!function_exists('print_attribute_radio')) {
function print_attribute_radio( $checked_value, $value, $label, $name ) {
    // This handles < 2.4.0 bw compatibility where text attributes were not sanitized.
    $checked = sanitize_title( $checked_value ) === $checked_value ? checked( $checked_value, sanitize_title( $value ), false ) : checked( $checked_value, $value, false );
 
    $input_name = 'attribute_' . esc_attr( $name ) ;
    $esc_value = esc_attr( $value );
    $id = esc_attr( $name . '_v_' . $value );
    $filtered_label = apply_filters( 'woocommerce_variation_option_name', $label );
    printf( '<div><input type="radio" name="%1$s" value="%2$s" id="%3$s" %4$s><label for="%3$s">%5$s</label></div>', $input_name, $esc_value, $id, $checked, $filtered_label );
}
}
 
global $product;
 
$attribute_keys = array_keys( $attributes );
 
do_action( 'woocommerce_before_add_to_cart_form' ); ?>
 
<form class="variations_form cart" method="post" enctype='multipart/form-data' data-product_id="<?php echo absint( $product->id ); ?>" data-product_variations="<?php echo esc_attr( json_encode( $available_variations ) ) ?>">
    <?php do_action( 'woocommerce_before_variations_form' ); ?>
 
    <?php if ( empty( $available_variations ) && false !== $available_variations ) : ?>
        <p class="stock out-of-stock"><?php _e( 'This product is currently out of stock and unavailable.', 'woocommerce' ); ?></p>
    <?php else : ?>
        <table class="variations" cellspacing="0">
            <tbody>
                <?php foreach ( $attributes as $name => $options ) : ?>
                    <tr>
<!--                        <td class="label"><label for="<?php echo sanitize_title( $name ); ?>"><?php echo wc_attribute_label( $name ); ?></label></td> -->
                        <?php
                        $sanitized_name = sanitize_title( $name );
                        if ( isset( $_REQUEST[ 'attribute_' . $sanitized_name ] ) ) {
                            $checked_value = $_REQUEST[ 'attribute_' . $sanitized_name ];
                        } elseif ( isset( $selected_attributes[ $sanitized_name ] ) ) {
                            $checked_value = $selected_attributes[ $sanitized_name ];
                        } else {
                            $checked_value = '';
                        }
                        ?>
                        <td class="value">
                            <?php
                            if ( ! empty( $options ) ) {
                                if ( taxonomy_exists( $name ) ) {
                                    // Get terms if this is a taxonomy - ordered. We need the names too.
                                    $terms = wc_get_product_terms( $product->id, $name, array( 'fields' => 'all' ) );
 
                                    foreach ( $terms as $term ) {
                                        if ( ! in_array( $term->slug, $options ) ) {
                                            continue;
                                        } 
                                        print_attribute_radio( $checked_value, $term->slug, $term->name, $sanitized_name );
 
                                    }
                                } else {
                                    foreach ( $options as $option ) {
                                        print_attribute_radio( $checked_value, $option, $option, $sanitized_name );
                                    }
                                }
                            }
 
                            //echo end( $attribute_keys ) === $name ? '<a class="reset_variations" href="#">' . __( 'Clear selection', 'woocommerce' ) . '</a>' : '';
                            ?>
                        </td>
                    </tr>
                <?php endforeach; ?>
            </tbody>
        </table>
 
        <?php do_action( 'woocommerce_before_add_to_cart_button' ); ?>
 
        <div class="single_variation_wrap" style="display:none;">
            <?php do_action( 'woocommerce_before_single_variation' ); ?>
 
            <div class="single_variation"></div>
 
            <div class="variations_button">
 
                <?php woocommerce_quantity_input( array(
                    'input_value' => ( isset( $_POST['quantity'] ) ? wc_stock_amount( $_POST['quantity'] ) : 1 )
                ) ); ?>
                <button type="submit" class="single_add_to_cart_button button alt"><?php echo $product->single_add_to_cart_text(); ?></button>
            </div>
 
            <input type="hidden" name="add-to-cart" value="<?php echo absint( $product->id ); ?>" />
            <input type="hidden" name="product_id" value="<?php echo absint( $product->id ); ?>" />
            <input type="hidden" name="variation_id" class="variation_id" value="" />
 
            <?php do_action( 'woocommerce_after_single_variation' ); ?>
        </div>
 
        <?php do_action( 'woocommerce_after_add_to_cart_button' ); ?>
 
    <?php endif; ?>
 
    <?php do_action( 'woocommerce_after_variations_form' ); ?>
</form>
 
<?php do_action( 'woocommerce_after_add_to_cart_form' ); ?>
0
 Аватар для GoDr
90 / 79 / 33
Регистрация: 17.08.2015
Сообщений: 512
Записей в блоге: 1
02.12.2015, 18:49
Цитата Сообщение от Анар Посмотреть сообщение
Если сделать через function_exists, то получается полный аналог include_once,
Нет! Одна проверяет наличие функции, другая только один раз подключает файл. Конечно, в твоём варианте это может быть одно и тоже. Но Если кто-то другой сделает просто include(), то это будет беда. Или, к примеру, назовёт свою функцию таким же именем..

В принципе многие вещи можно делать по разному главное игра мысли и лучше своей! Нетрадиционные подходы к решению задач всегда рождают гениев.... Пусть это будет даже "велосипед", но он твой и ты к этому сам пришёл
0
225 / 216 / 89
Регистрация: 12.09.2015
Сообщений: 986
02.12.2015, 19:18  [ТС]
GoDr, я понимаю, что это не одно и тоже) Поэтому написал, что получается аналог, т.е. результат аналогичен)

В принципе, отдохнул полчаса и голова заработала. Исправил, если кому интересно сделал вот так:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
if (!function_exists('print_attribute_radio')) {
function print_attribute_radio( $checked_value, $value, $label, $name ) {
    // This handles < 2.4.0 bw compatibility where text attributes were not sanitized.
    $checked = sanitize_title( $checked_value ) === $checked_value ? checked( $checked_value, sanitize_title( $value ), false ) : checked( $checked_value, $value, false );
    $input_name = 'attribute_' . esc_attr( $name ) ;
    $esc_value = esc_attr( $value );
$pid = get_the_ID();
    $id = esc_attr( $name . '_v_' . $value . '-' . $pid );
    $filtered_label = apply_filters( 'woocommerce_variation_option_name', $label );
    printf( '<div><input type="radio" name="%1$s" value="%2$s" id="%3$s" %4$s><label for="%3$s">%5$s</label></div>', $input_name, $esc_value, $id, $checked, $filtered_label );
}
}
Вместо продукт id сделал через id поста, что одно и тоже. И всё заработало.
0
 Аватар для GoDr
90 / 79 / 33
Регистрация: 17.08.2015
Сообщений: 512
Записей в блоге: 1
02.12.2015, 19:29
Цитата Сообщение от Анар Посмотреть сообщение
Поэтому написал, что получается аналог, т.е. результат аналогичен)
Цитата Сообщение от Анар Посмотреть сообщение
то получается полный аналог include_once


Но как ранее сказал Xenox, это не самый хороший способ.. Нужно поменять логику проекта, чтобы по сути такой проблемы не возникало
0
225 / 216 / 89
Регистрация: 12.09.2015
Сообщений: 986
02.12.2015, 20:02  [ТС]
Цитата Сообщение от GoDr Посмотреть сообщение
Но как ранее сказал Xenox, это не самый хороший способ.. Нужно поменять логику проекта, чтобы по сути такой проблемы не возникало
Я понимаю, что это заплатка) Но проблема в том, что это не мною написанный код, это плагин над другим плагином, а мои познания php просто не позволяют мне сделать это самостоятельно. По этому приходится использовать плагин, который ещё и пришлось править.
На карандаш конечно возьму и возможно передам эту задачу какому-нибудь специалисту на исправление.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
02.12.2015, 20:02
Помогаю со студенческими работами здесь

Не выполняется условие в цикле
Доброго времени суток На форме &quot;Карточка занятий&quot; расположена кнопка, по нажатию которой выполняется некий код, нужно выбрать 1. Я попал...

Выполняется ли условие в цикле
Учебная программа взята из книги Шилдта. Программа определяет простые числа до 9 включительно, а также находит наименьший общий множитель...

Не выполняется оператор в цикле
Не выполняется оператор realdn в цикле while при первом прохождение цикла не могу понять из за чего это происходит program Probel; ...

Неправильно выполняется формула в цикле
#include &quot;stdafx.h&quot; long temp, timer; double T1, T2; double dT1, dT2; float dtime=0.01, a1, a2; int timer0; int...

Что выполняется в данном цикле
void removeColumns(Matrix *a, int *xs, int n) { for (int i = 0; i &lt; n-1; i++) { int swapped = 0; for (int j = 0; j &lt; n-i-1; j++)...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru