Доброго времени суток всем. Проблема вот какая - есть вот такой массив PHP: Array ( [1] => Array ( [name] => Желаемая высота забора (м) [answers] => [multiple_ans] => 2 ) [2] => Array ( [name] => вопрос2 [answers] => ответ 2|ответ 2.2 [multiple_ans] => 0 ) ) начинаю его обрабатывать PHP: foreach ($calc as $item => $value) { // и тут выполняю разные действия ... $mas_answers = explode('|', $value['answers']); } И всюду где использую $value['name'] или 'answers' или 'multiple_ans' получаю Illegal string offset 'name' или 'answers' и тд Сам смысл ошибки я понимаю. Вместо массива оказалась строка, но , блин $value имеет вот такой вид PHP: Array ( [name] => Желаемая высота забора (м) [answers] => [multiple_ans] => 2 ) Array ( [name] => вопрос2 [answers] => ответ 2|ответ 2.2 [multiple_ans] => 0 ) Как же мне тогда к ним обращаться ? Подскажите в чем я неправ. Заранее благодарен.
Покажи массив свой $calc. Что то ты долго, не массив у тебя то что ты там написал, вот так можно: PHP: $calc = array( 1 => array( 'name' => 'Желаемая высота забора (м)', 'answers' => '', 'multiple_ans' => 2, ), 2 => array( 'name' => 'вопрос2', 'answers' => 'ответ 2|ответ 2.2', 'multiple_ans' => 0, ) ); foreach ($calc as $item => $value) { // и тут выполняю разные действия ... var_dump(explode('|', $value['answers'])); }
PHP: Array ( [1] => Array ( [name] => Желаемая высота забора (м) [answers] => [multiple_ans] => 2 ) [2] => Array ( [name] => вопрос2 [answers] => ответ 2|ответ 2.2 [multiple_ans] => 0 ) )
Тс, не смущает тот факт, что ты в конце концов, в каждой своей залитой данными переменные, результат получишь по ласт проходу массива? --- Добавлено --- PHP: $a = [1,2,3,4]; foreach ( $a AS $b ) { $c = $b; } print_r ( $c ); --- Добавлено --- Что получим ? 1 ? 2 3 ?
Сложно угадать, не видя всей картины. Ну, например, возможно вы обращаетесь к переменным не внутри цикла { ... } а где-то вообще в другом месте. Мы же не знаем После того, как вы написали Код (Text): $mas_answers = explode('|', $value['answers']); Массив ответов появился в переменной $mas_answers, а в $value['answers'] - там как была строка текста, так и осталась. И да, а что будет, если пользователь в комментарии поставит символ вертикальной черты | ? )) В PHP есть штатные функции для преобразования массива в строку (для сохранения в базе данных или в файле) и для обратного преобразования строки в массив. При этом, PHP позаботится о том, чтобы не зависимо от пользовательского ввода у вас элементы массива остались такими, какими должны быть. Например, посмотрите функции https://www.php.net/manual/ru/function.serialize.php https://www.php.net/manual/ru/function.unserialize.php
PHP: <form action="#" method="post"> <?php foreach($calc as $index => $value){ $mas_answers = explode('|', $value['answers']); echo '<div class="tabs_block" tabid="'.$index.'"'; if($index!=1){ echo ' style="display:none;"'; } echo '> <div class="input_form"> <p>Вопрос:</p> <div class="input_form"> <input class="form-control" name="question" type="text" id="response_options" placeholder="" value="'.addslashes($value['name']).'" autocomplete="off"><br> <span class=podkomment >Например: "Выберите тип материала"</span> </div> </div> <hr> <h2>Варианты ответов:</h2>'; if(count($mas_answers)==0){ echo '<div class="input_form answer_input" attr="1" quest="'.$index.'"> <p>1.</p><a href="javascript:void(0);" class="answer_remove"></a> <div class="input_form"> <input class="form-control" type="text" name="answer" autocomplete="off" placeholder="Вариант ответа #1" value=""> </div> </div>'; } else{ foreach($mas_answers as $nom=>$answers){ $nom_real=$nom+1; echo '<div class="input_form answer_input" attr="'.($nom_real).'" quest="'.($nom_real).'"> <p>'.($nom_real).'.</p><a href="javascript:void(0);" class="answer_remove"></a> <div class="input_form"> <input class="form-control" type="text" name="answer" autocomplete="off" placeholder="Вариант ответа #'.($nom_real).'" value="'.$answers.'"> </div> </div>'; } } echo '<a href="javascript:void(0);" class="right_add_content">Добавить ещё</a> <hr> <h2>Возможность выбора:</h2> <input type="radio" name="multiple_ans" id="one'.$index.'" autocomplete="off" value="0"'; if($value['multiple_ans']==0) echo ' checked="checked"'; echo '><label for="one'.$index.'">Можно выбрать только один ответ (radiobutton)</label><br> <input type="radio" name="multiple_ans" id="two'.$index.'" autocomplete="off" value="1"'; if($value['multiple_ans']==1) echo ' checked="checked"'; echo '><label for="two'.$index.'">Можно выбрать несколько вариантов (checkbox)</label><br> <input type="radio" name="multiple_ans" id="thr'.$index.'" autocomplete="off" value="2"'; if($value['multiple_ans']==2) echo ' checked="checked"'; echo '><label for="thr'.$index.'">Нужно вводить данные (input)</label> <hr> </form> </div>'; }
Чтобы совсем всё понятно было - после <?php и перед foreach добавьте ещё строку PHP: var_dump($calc); exit; и опубликуйте здесь, что оно выведет
PHP: array(2) { [1]=> array(3) { ["name"]=> string(47) "Желаемая высота забора (м)" ["answers"]=> string(0) "" ["multiple_ans"]=> string(1) "2" } [2]=> array(3) { ["name"]=> string(13) "вопрос2" ["answers"]=> string(27) "ответ 2|ответ 2.2" ["multiple_ans"]=> string(1) "0" } }
Хотите прикол ? начало все норм кроме после string перебираем в foreach PHP: foreach($mas_answers as $nom=>$answers){
@abutan Этот код с такими исходными данными (таким массивом $calc) - должен работать без ошибок. Для эксперимента, запустил его у себя, создав массив перед перебором в цикле. У меня этот код из этого массива успешно сгенерировал html. Посмотрите внимательно на текст сообщения об ошибке, которую выдаёт PHP - там указывается файл и номер строки, на которой произошла ошибка. Возможно, она происходит где-то в другом месте? У вас есть ошибка в вёрстке - в самом начале вы открываете <form> за пределами цикла, а закрываете </form> внутри цикла (то есть открывающий тег будет один, а закрывающих будет столько же, сколько элементов в массиве $calc). Но ошибка вёрстки никак не влияет на появление сообщения "Illegal string offset"
@sobachnik PHP: $a = [1,2,3,4]; foreach ( $a AS $b ) { $c = $b; } foreach ( $c AS $d ) { echo 1; } --- Добавлено --- пусть покажет полностью ошибку
Там все немного сложнее. Эта форма вложена во вторую форму. И этот весь код работает. Вполне корректно, я получаю в ответе то что мне надо. Проблема появляется когда я пытаюсь отправить результаты в контролер по ajax. Код (Javascript): form.submit(function(e) { e.preventDefault(); let post_data = {}; let user_id = $('input[name="user_id"]').val(); let url = form.attr('action'); $('.tabs_content_block .tabs_block').each(function(a,obj){ let name = $(obj).find('input[name="question"]').val(); let answers = $(obj).find('input[name="answer"]').map( function(){ if ( $(this).val()!='' ) return $(this).val().replace(/\|/g,' ');} ).get().join('|'); let multiple_ans = $(obj).find('input[name="multiple_ans"]:checked').val(); a++; post_data[a] = { 'name':name, 'answers':answers,'multiple_ans':multiple_ans }; }); post_data = {'calc':post_data, 'user_id': user_id}; $.post({ url: url, dataType: "json", data: post_data, done: function (response) { console.log(response) alert('YES'); } , error: function(result) { console.log(post_data); alert('Error: '+result['status']+': '+result['responseText']); } }); }); Вот в этот момент и вылетает HTML: Error: 500: <pre>PHP Warning 'yii\base\ErrorException' with message 'Illegal string offset 'answers'' in /var/www/html/frontend/views/widgetuser/calc.php:53 Stack trace: #0 /var/www/html/frontend/views/widgetuser/calc.php(53): yii\base\ErrorHandler->handleError(2, 'Illegal string ...', '/var/www/html/f...', 53, Array) #1 /var/www/html/vendor/yiisoft/yii2/base/View.php(348): require('/var/www/html/f...') #2 /var/www/html/vendor/yiisoft/yii2/base/View.php(257): yii\base\View->renderPhpFile('/var/www/html/f...', Array) #3 /var/www/html/vendor/yiisoft/yii2/base/View.php(156): yii\base\View->renderFile('/var/www/html/f...', Array, Object(frontend\controllers\WidgetuserController)) #4 /var/www/html/vendor/yiisoft/yii2/base/Controller.php(384): yii\base\View->render('calc', Array, Object(frontend\controllers\WidgetuserController)) #5 /var/www/html/frontend/controllers/WidgetuserController.php(150): yii\base\Controller->render('calc', Array) #6 [internal function]: frontend\controllers\WidgetuserController->actionCalc() #7 /var/www/html/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array(Array, Array) #8 /var/www/html/vendor/yiisoft/yii2/base/Controller.php(157): yii\base\InlineAction->runWithParams(Array) #9 /var/www/html/vendor/yiisoft/yii2/base/Module.php(528): yii\base\Controller->runAction('calc', Array) #10 /var/www/html/vendor/yiisoft/yii2/web/Application.php(103): yii\base\Module->runAction('widgetuser/calc', Array) #11 /var/www/html/vendor/yiisoft/yii2/base/Application.php(386): yii\web\Application->handleRequest(Object(yii\web\Request)) #12 /var/www/html/frontend/web/index1.php(36): yii\base\Application->run() #13 {main}</pre>
@Babka_Gadalka Я не понимаю, что вы хотите этим сказать или показать. Приведённый вами код приводит к ошибке Warning: Invalid argument supplied for foreach() поскольку в первом цикле, после его завершения, переменной $c присваивается значение 4 (число), а цикл foreach не может "перебрать" число. Если вы намекаете, что автор сперва в одном цикле создаёт переменную $mas_answers, а потом где-то в другом месте (после завершения первого цикла) пытается её использовать - то это не так. В приведённом автором коде видно, что массивы вложены друг в друга, а не расположены отдельно независимо друг от друга. То есть если комбинировать код автора и ваш - получится что-то типа PHP: $a = [1, 2, 3, 4]; foreach ($a as $b) { $c = explode('|', $b); foreach ($c as $d) { echo $d; } }
Интересный способ передачи user_id А что, если я элементарно открою в браузере "инструменты разработчика" и поменяю этому инпуту значение на id другого пользователя? А что касается сообщения об ошибке - нужно смотреть, что происходит в файле /var/www/html/frontend/views/widgetuser/calc.php Ошибка возникает в нём на строке 53.
Далее постепенно подниматься по коду вверх и смотреть, как и где создаются переменные, откуда берутся их значения. Если это тот самый код, который вы публиковали выше, значит в массив $calc попадают другие данные именно когда вы То есть вам нужно загрузить в браузере страницу с этой формой, после чего (пока страница открыта, но форма ещё не отправлена) вставить в код перед foreach строку PHP: var_dump($calc); exit; После этого отправляйте форму и смотрите, что выведет var_dump(). То есть суть в том, что нужно посмотреть содержимое массива именно в момент ошибки, а не тогда, когда генерация страницы проходит успешно.
Все переменные пришли из контролера, выбранные из бд. Так что ничего не меняется в var_dum. Возможно к сожалению.
Ошибка происходит в PHP коде, при обработке вашего ajax-запроса. Нужно, чтобы этот var_dump отработал именно тогда, когда происходит ошибка, а не тогда, когда страница нормально загружается. То есть нужно смотреть var_dump именно при обработке вашего ajax-запроса. И я выше написал, как это сделать, прочитайте, пожалуйста, внимательно. --- Добавлено --- Если при открытии страницы ошибки нет, а при ответе на ajax-запрос ошибка происходит - значит что-то меняется 100% Либо там выполняется другой код, либо в него приходят другие данные. А как иначе-то?