Функция внутри цикла php

Функция внутри цикла php thumbnail

Заметка: активирована адаптивная версия сайта, которая автоматически подстраивается под небольшой размер Вашего браузера и скрывает некоторые детали сайта для удобства чтения. Приятного просмотра!

Здравствуйте уважаемые читатели блога Site on! В предыдущей статье мы узнали что есть функция в PHP, научились создавать собственные функции, передавать в них аргументы и вызывать их для выполнения. Продолжая тему функций в PHP необходимо подчеркнуть следующие вещи:

  • Внутри функции можно использовать любой PHP код (циклы, условия, любые операции), включая другие функции (как встроенные, так и собственные);
  • Имя функции должно начинаться с латинской буквы, либо знака подчёркивания, далее может идти любое количество латинских букв, цифр или знаков подчёркивания;
  • Все функции имеют глобальную область видимости, это значит, что любая функция может быть вызвана в любом месте, даже если эта функция определена внутри другой;
  • PHP не поддерживает перегрузку функций, также отсутствует возможность переопределить (изменить, дополнить) или удалить созданную функцию;
  • Функции не обязаны быть определены до их использования. То есть если вы сначала вызовите функцию, а только потом – ниже по коду её опишите, то это не повлияет на работоспособность и не вызовет ошибок.

Функции, зависящие от условий

Мы можем создавать (определять, описывать) функцию, в зависимости от условия. Например:

<?php $apply = true; sayHi(); //вызвали функцию sayHi, её можно вызывать в любом месте /*здесь нельзя вызвать функцию sayGoodbye, так как мы ещё не проверили условие и не зашли внутрь конструкции if*/ if($apply){ sayGoodbye(){ echo ‘Всем пока! <br>’; } } /*вот теперь можем вызвать sayGoodbye*/ sayGoodbye(); sayHi(){ echo ‘Всем привет! <br>’; }

Результат:

И взгляните на этот пример:

<?php $apply = true; sayHi(); /*вызвали функцию sayHi, её можно вызывать в любом месте*/ /*а вот что будет, если вызвать sayGoodbye здесь*/ sayGoodbye(); if($apply){ sayGoodbye(){ echo ‘Всем пока! <br>’; } } sayHi(){ echo ‘Всем привет! <br>’; }

Результат:

Функция внутри цикла php

Всё понятно из названия ошибки, разве что стоит пояснить следующую вещь: интерпретатор PHP при первом (быстром) обходе не видит что функция sayGoodbye вообще хоть где-то описана, он увидит это только когда код начнёт выполняться и только если условие будет true (читайте про типы переменных).

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

Вложенные функции

Вложенная функция – это функция, объявленная внутри другой функции. Пример:

<?php /*Здесь нельзя вызвать sayGoodbye, так как она появится только после вызова функции sayHi*/ sayHi(); /*вызвали функцию sayHi, её можно вызывать в любом месте*/ /*Теперь можем вызывать sayGoodbye*/ sayGoodbye(); sayHi(){ echo ‘Всем привет! <br>’; sayGoodbye(){ echo ‘Всем пока! <br>’; } }

Опять-таки, при первом обходе интерпретатор PHP помечает себе, что он нашёл описание функции sayHi, но не заходит внутрь её тела, он видит только название, а раз интерпретатор не заходит внутрь тела sayHi, то он понятия не имеет, что внутри мы определяем ещё одну функцию – sayGoodbye.

Далее код начинает исполняться, мы вызываем sayHi, интерпретатору PHP приходиться зайти в тело функции sayHi, чтобы выполнить её и там он случайно находит описание ещё одной функции – sayGoodbye, после чего и sayGoodbye можно вызывать в любом месте, сколько угодно раз.

Но стоит обратить внимание на очень тонкий момент в ситуации выше: функция sayHi становится одноразовой, потому что если мы ещё раз её вызовем, то PHP опять наткнётся на определение функции sayGoodbye, а в PHP так делать нельзя – нельзя переопределять функции. Об этом и о том, как с этим бороться я писал в предыдущей статье.

В PHP описанные выше приёмы применяются очень редко, чаще их можно увидеть, например, в JavaScript.

Область видимости переменных

В PHP ровно две области видимости: глобальная и локальная. В каждом языке программирования области видимости устроены по-разному. Например, в C++ даже в циклах своя (локальная) область видимости. В PHP, кстати, циклы – это глобальная область видимости. Но сегодня мы говорим о функциях.

У функций в PHP своя, внутренняя область видимости (локальная), то есть все переменные внутри функции видны только внутри этой самой функции.

Итак, ещё раз: все, что вне функций – это глобальная область видимости, все, что внутри функций – локальная область видимости. Пример:

<?php sayHi($name){ echo ‘Привет, ‘.$name.’! <br>’; $name = ‘Рудь Сергей’; } $name = ‘Андрей’; sayHi($name); echo $name; // ?

Уважаемые знатоки, внимание, вопрос! Что выведет последняя инструкция echo $name; ?

Ответ:

Как вы сами видели, у нас было 2 переменных $name, одна внутри функции (локальная область видимости), другая просто в коде (глобальная область видимости), последнее присвоение в переменную $name было $name = ‘Рудь Сергей’; Но так как это было внутри функции, то там оно и осталось. В глобальной же области видимости последним присвоением было $name = ‘Андрей’; что мы собственно и видим в результате.

То есть две одинаковые переменные, но в разных областях видимости никак не пересекаются и не влияют друг на друга.

Давайте я проиллюстрирую области видимости на рисунке:

Читайте также:  Как перебрать в цикле табличную часть документа

Функция внутри цикла php

При первом обходе интерпретатор бегло просматривает глобальную область видимости, запоминает какие есть переменные и функции, но не выполняет код.

Обращение к глобальным переменным из локальной области видимости

Но что если нам всё-таки нужно из функции обратиться к той самой переменной $name из глобальной области видимости, да не просто обратиться, а изменить её? Для этого есть 3 основных варианта. Первый из них использование ключевого слова global:

<?php sayHi($name){ echo ‘Привет, ‘.$name.’! <br>’; global $name; /*начиная с этого момента мы имеем ввиду глобальную переменную $name*/ $name = ‘Рудь Сергей’; } $name = ‘Андрей’; sayHi($name); echo $name; // ?

Результат:

Но у этого способа есть минус, с тех пор как мы обратились к глобальной переменной $name мы потеряли (переписали) локальную переменную $name.

Второй способ заключается в том, чтобы использовать суперглобальный массив PHP. В этот массив PHP сам, автоматически помещает каждую переменную, которую мы создали в глобальной области видимости. Пример:

$name = ‘Андрей’; //Тоже самое что и $GLOBALS[‘name’] = ‘Андрей’;

Следовательно:

<?php sayHi($name){ echo ‘Привет, ‘.$name.’! <br>’; $GLOBALS[‘name’] = ‘Рудь Сергей’; } $name = ‘Андрей’; sayHi($name); echo $name; // ?

Результат тот же, что и при использовании ключевого слова global:

Только в этот раз мы не переписали локальную переменную, то есть переменная $name внутри функции осталась прежней и равна “Андрей”, а не “Рудь Сергей”.

Передача аргументов по ссылке

Третий способ – это передача адреса (ссылки) переменной, а не её значения. Ссылки в PHP не очень удались, в отличие от других языков программирования. Тем не менее, я расскажу вам единственный правильный вариант передачи аргумента по ссылке в функцию, который нормально поддерживается в PHP 5.3 и выше. Есть и другие способы работы со ссылками, но они работали в PHP 5.2 и ниже, в итоге сами разработчики PHP решили от них отказаться, поэтому не будем о них.

Так вот, ПРАВИЛЬНАЯ передача аргумента по ссылке в PHP 5.3 и выше осуществляется следующим образом:

sayHi(&$name){

Мы в самом описании функции добавили значок амперсанд (&) – этот значок означает, что мы принимаем не значение переменной, а ссылку (адрес) на это значение в памяти. Ссылки в PHP позволяют создать две переменные, указывающие на одно и то же значение. Это означает, что при изменении одной из этих переменных, меняются обе, так как в памяти они обращаются к одному и тому же значению.

И в итоге имеем:

<?php sayHi(&$name){ //принимаем не значение, а ссылку на значение echo ‘Привет, ‘.$name.’! <br>’; $name = ‘Рудь Сергей’; } $name = ‘Андрей’; sayHi($name); echo $name; // ?

Результат:

Статические переменные

Представьте себе следующую ситуацию: нам нужно посчитать сколько раз мы всего поздоровались. Вот что мы пытаемся сделать:

<?php sayHi($name){ $c = 0; // счётчик echo ‘Привет, ‘.$name.’! <br>’; $c++; // увеличиваем счётчик на 1 echo ‘Всего поздоровались ‘ . $c . ‘ раз.<hr>’; } sayHi(‘Рудь Сергей’); sayHi(‘Андрей’); sayHi(‘Дмитрий’);

Результат:

Функция внутри цикла php

Переменная $c не запоминает своего значения, она каждый раз создаётся заново. Нам нужно сделать так, чтобы наша локальная переменная $c запоминала своё значение после выполнения функции, для этого используют ключевое слово ic:

<?php sayHi($name){ ic $c = 0; // счётчик, сделали статическим echo ‘Привет, ‘.$name.’! <br>’; $c++; // увеличиваем счётчик на 1 echo ‘Всего поздоровались ‘ . $c . ‘ раз.<hr>’; } sayHi(‘Рудь Сергей’); sayHi(‘Андрей’); sayHi(‘Дмитрий’);

Результат:

Функция внутри цикла php

Возврат значений

В функциях есть такая удобная вещь, как возврат значений. Это когда функция вместо того, чтобы вывести что-нибудь на экран, помещает всё в переменную и отдаёт эту переменную нам. А мы уже дальше решаем, что с ней делать. Для примера возьмём эту функцию, она возводит число в квадрат:

<?php getSquare($number){ $result = $number*$number; echo $result; } getSquare(5);

Результат:

Сделаем так, чтобы вместо вывода на экран она возвращала результат выполнения. Для этого используется ключевое слово return:

<?php getSquare($number){ $result = $number*$number; return $result; } getSquare(5);

Результат:

Теперь мы можем использовать это различными способами:

<?php getSquare($number){ $result = $number*$number; return $result; } echo getSquare(5); //выводит результат echo ‘<br>’; $num = getSquare(5); // присвоили результат в переменную echo $num; // вывели переменную на экран

Результат:

Обращаю ваше внимание, что ключевое слово return не просто возвращает значение, а полностью прерывает работу функции, то есть весь код, который находится ниже ключевого слова return никогда не исполниться. Другими словами, return для функций вдобавок работает как break для циклов:

<?php getSquare($number){ $result = $number*$number; return $result; echo ‘До меня PHP никогда не дойдёт :(‘; } echo getSquare(5); //выводит результат echo ‘<br>’; $num = getSquare(5); // присвоили результат в переменную echo $num; // вывели переменную на экран

Результат:

То есть return – это ещё и выход из функции. Его можно использовать и без возвращаемого значения, только ради выхода.

Рекурсивная функция

Рекурсивная функция – это функция, которая вызывает сама себя. Рекурсия используется не часто и считается ресурсоёмкой (медленной) операцией. Но бывает, что использование рекурсии самый очевидный и простой вариант. Пример:

Читайте также:  Маршруты и циклы в графах

<?php countPlease($number){ echo $number . ‘<br>’; if($number < 20){ // чтобы рекурсия не стала бесконечной countPlease(++$number); // функция countPlease вызвала сама себя } } countPlease(1);

Результат:

Функция внутри цикла php

Если вы знаете, как обойтись без рекурсии, то лучше так и сделать.

Строгая типизация в PHP (уточнение типа)

В PHP сделаны мелкие шаги к строгой типизации, благодаря этому мы можем заранее указать, какой тип должна принимать функция (это называется type-hint):

<?php countPlease(array $numbers){ // какой-то код } countPlease(1);

Результат:

Catchable fatal error: Argument 1 passed to countPlease() must be an array, integer given, called in /home/index.php on line 7 and defined in /home/index.php on line 3

Ошибка нам говорит, что функция ожидает принять массив, а вместо этого мы ей передаём число. К сожалению, пока что мы можем уточнять тип только для массивов (array), а с PHP 5.4 ещё добавился такой вариант как callable:

<?php countPlease(callable $v){ $v(); } countPlease(“getEcho”); getEcho(){ echo ‘Вызвали функцию getEcho; }

Callable проверяет, может ли переданное значение быть вызвано в качестве функции. Callable может быть как именем функции, заданным строковой переменной, так и объектом и именем вызываемого метода. Но про объекты и методы мы поговорим позже (это раздел объектно-ориентированного программирования), а с функциями вы уже знакомы. Результат работы я вам показать не могу, так как у меня сейчас стоит PHP 5.3, но он был бы:

Вызвали функцию getEcho

Использование аргументов переменной длины

И напоследок ещё один очень редко используемый нюанс. Представьте ситуацию, мы передаём в функцию аргументы, хотя в функции мы их не описали, например:

<?php getEcho(){ echo ‘Вызвали функцию getText’; } $age = 22; getEcho(‘Рудь Сергей’, $age);

Результат:

Функция внутри цикла php

Как видите, ошибок нет, но и наши переданные аргументы нигде не используются. Но это не значит, что они пропали – они всё равно передались в функцию и мы можем их использовать, для этого существуют встроенные функции PHP:

func_num_args() – Возвращает количество аргументов, переданных функции

func_get_arg(порядковый номер) – Возвращает элемент из списка аргументов

func_get_args() – Возвращает массив, содержащий аргументы функции

Пример:

<?php getEcho(){ echo ‘Вызвали функцию getText <br>’; echo func_get_arg(0); } $age = 22; getEcho(‘Рудь Сергей’, $age);

Результат:

Функция внутри цикла php

Заключение

Сегодняшняя статья является заключительной по теме функций в PHP. Теперь вы можете быть уверены в полноте своих знаний касательно этой темы и можете смело использовать функции для своих нужд.

Если у кого-то есть желание набить руку, но нет идей как это сделать – лучшим способом будет написание уже готовых (встроенных) функций PHP, например, можно написать собственную функцию count() или любую другую.

Благодарю всех за внимание и до новых встреч! Если что-то не понятно, смело задавайте ваши вопросы в комментариях!

Пожалуйста, оцените эту статью

Средняя оценка: 4.74 из 5 (проголосовало: 34)

Статья оказалась вам полезной? Подпишитесь, чтобы не пропустить новые!
Вы можете помочь развитию проекта, сделав всего 1 клик:

Спасибо!

Источник

Что-то вроде этого:

echo ‘<div class=”medium-auto small-12 cell” style=”padding:2px;”>’; echo ‘<select style=”margin: 0; height: auto; border: 0;” name=”program” id=”program-‘.$row[‘id’].'” >’; echo ‘<option value=”” disabled selected>’.$row[“program”].'</option>’; echo ‘<option value=”Hockey”>Hockey</option>’; echo ‘<option value=”Fundamentals”>Fundamentals</option>’; echo ‘</select>’; echo ‘</div>’; echo ‘<div class=”medium-auto small-12 cell” style=”padding:2px;”>’; echo ‘<select style=”margin: 0; height: auto; border: 0;” name=”plan” id=”plan-‘.$row[‘id’].'”>’; echo ‘<option value=”” disabled selected>’.$row[“plan”].'</option>’; echo ‘</select>’; echo ‘</div>’; ?> <script> var programsByplan = { Hockey: [“Off Season”, “Pre Season”, “In Season”], Fundamentals: [“Phase 1″], } $(‘select[name=”program”]’).change((){ var program = $(this).val(); var plan_id = $(this).prop(‘id’).replace(‘program’, ‘plan’); if(programsByplan[program]){ var options = []; $.each(programsByplan[program], (i,v){ options.push(‘<option value=”‘+v+'”>’+v+'</option>’); }); $(‘#’+plan_id).html(options.join(“n”)); }else{ //or, do somkind of error recovery here. $(‘#’+plan_id).html(‘<option value=””>No Plans</option>’); } }); </script>

Я бы избавился от onChangeЯ также активно использую jQuery, но вопрос помечен этим.

Таким образом, на изменение любого выбора с именем program (что мы не изменили, поэтому они все имеют одно и то же имя), мы запускаем обратный вызов события. Конечно, вы также можете выполнить эту часть с классом.

В обратном вызове мы получаем значение, выбранное в текущем выборе, затем мы проверяем, что оно существует в programsByplan (что всегда должно быть), но проверять не мешает.

Затем мы конвертируем идентификатор программы program-‘.$row[‘id’].’ в plan-‘.$row[‘id’].’, Теперь мы знаем, какой план выбрать для изменения. Я предпочитаю использовать массив для добавления параметров, но вы можете сделать += вещь. И тогда их просто заменить, теперь, когда мы знаем идентификатор элементов плана, .html(),

Я не проверял это, но это должно быть довольно близко. Самое главное – настроить себя на успех, легко идентифицируя идентификатор, или, другими словами, легко найти правильный plan элемент для измененных program элемент.

Я также предполагаю, что у вас есть $row[‘id’] это по крайней мере уникально для цикла, который генерирует их.

Обновить

Но как я могу получить параметры для отображения на странице загрузки, когда программа / план правильно из базы данных

Я бы еще изменил это так:

//outside of the loop define your data $programsByplan = [ ‘Hockey’ => [“Off Season”, “Pre Season”, “In Season”], ‘Fundamentals’ => [“Phase 1″], ]; //inside the loop echo ‘<div class=”medium-auto small-12 cell” style=”padding:2px;”>’; echo ‘<select style=”margin: 0; height: auto; border: 0;” name=”program” id=”program-‘.$row[‘id’].'” >’; foreach($programsByplan as $program => $plans){ //$selected = $row[“program”] == $program ? ‘disabled selected’ : ”; $selected = $row[“program”] == $program ? ‘selected=”selected”‘ : ”; echo ‘<option value=”‘.$program.'” ‘.$selected.’>’.$program.'</option>’; } echo ‘</select>’; echo ‘</div>’; echo ‘<div class=”medium-auto small-12 cell” style=”padding:2px;”>’; echo ‘<select style=”margin: 0; height: auto; border: 0;” name=”plan” id=”plan-‘.$row[‘id’].'”>’; foreach($programsByplan[$row[“program”]] as $plan){ //$selected = $row[“plan”] == $plan ? ‘disabled selected’ : ”; $selected = $row[“plan”] == $plan ? ‘selected=”selected”‘ : ”; echo ‘<option value=”‘.$plan.'” ‘.$selected.’>’.$plan.'</option>’; } echo ‘</select>’; echo ‘</div>’; ?> <script> var programsByplan = <?php echo json_encode($programsByplan); ?>; //… other code

Читайте также:  Технологический цикл обслуживания гостей схема

Здесь мы добавляем $programsByplan в PHP, затем с помощью json_encode мы можем добавить тот же массив в Javascript, что является удивительным. Надеюсь, это работает

var programsByplan = <?php echo json_encode($programsByplan); ?>;

Иногда это может потребовать некоторых усилий, но оно имеет огромные преимущества в поддержке кода. Потому что вы используете только один авторитетный источник данных для этого. В отличие от того, чтобы распространяться повсюду. Дополнительным преимуществом этого является то, что если вы идете и делаете программы и планы в виде двух таблиц с отношением «многие к одному», вы можете поместить их в БД и легко обновить код, создав этот массив. Посмотрите, распределяются ли данные только в жестком коде, тогда будет сложно внести подобные изменения позже.

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

echo ‘<option value=”” disabled selected>’.$row[“program”].'</option>’;

Вы на самом деле удаляете значение здесь, что, вероятно, не то, что вы хотите. Я также не уверен в disabled немного, так что я просто оставил это в. Может быть, это было просто там, чтобы исправить проблемы выбора при его инициализации? Во всяком случае, я поставил эту часть в комментарии. Я всегда выбирал так:

$selected = $row[“program”] == $program ? ‘selected=”selected”‘ : ”;

Это, вероятно, «старый школьный» способ сделать это, но он всегда работал для меня.

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

Это должно исправить большинство из этого, но все это сделано в моей голове, так что, надеюсь, все это работает так, как я думаю, что должно. Теория в любом случае обоснована.

Вы можете проверить это в этой песочнице:

https://sandbox.onlinephps.com/code/077c8a988697122549713ede9c305bf4f7620ed9

используя (как консервированные данные для строки.)

$row = [ ‘id’ => 1, ‘program’ => ‘Hockey’, ‘plan’ => ‘Off Season’ ];

Какие выводы:

<div class=”medium-auto small-12 cell” style=”padding:2px;”> <select style=”margin: 0; height: auto; border: 0;” name=”program” id=”program-1″ > <option value=”Hockey” selected=”selected”>Hockey</option> <option value=”Fundamentals” >Fundamentals</option> </select> </div> <div class=”medium-auto small-12 cell” style=”padding:2px;”> <select style=”margin: 0; height: auto; border: 0;” name=”plan” id=”plan-1″> <option value=”Off Season” selected=”selected”>Off Season</option> <option value=”Pre Season” >Pre Season</option> <option value=”In Season” >In Season</option> </select> </div>

Как вы можете видеть, у нас есть program-1 а также plan-1 наши идентификаторы, то оба выбора имеют соответствующий элемент с selected=”selected”

Up2

Для обработки случаев, когда данные ранее не были выбраны для программы.

Для первого цикла выше я бы добавил это

//echo <select … echo ‘<option value=”” > – Please select a program – </option>’; //foreach( …

Сделайте это до цикла и после открытия для <select, Затем для второго цикла я бы отключил второй выбор, пока они не сделают выбор в первом.

$disabled = empty($row[“program”]) ? ‘disabled=”disabled”‘: ”; echo ‘<select style=”margin: 0; height: auto; border: 0;” name=”plan” id=”plan-‘.$row[‘id’].'” ‘.$disabled.’>’;

А потом в Javascript

$(‘select[name=”program”]’).change((){ var program = $(this).val(); if(program == ” ) return; //exit on empty selection var plan_id = $(this).prop(‘id’).replace(‘program’, ‘plan’); //enable the select if disabled. $(‘#’+plan_id).attr(‘disabled’,false);

Тогда вы можете просто проверить перед сохранением, что они выбрали программу и т. Д. И т. Д.

Up3

Для любых проблем Javascript всегда используйте окно отладки в браузере (f12), затем нажмите на console, Тогда в вашем коде вы можете просто сделать как

console.log(var);

И это напечатает это значение в консоли. Это похоже на PHP var_export, _r или var_dump и т.д …

Поэтому я бы начал с этого

<script> var programsByplan = <?php echo json_encode($programsByplan); ?>; console.log(programsByplan); $(‘select[name=”program”]’).change((){ var program = $(this).val(); console.log(program); var plan_id = $(this).prop(‘id’).replace(‘program’, ‘plan’); console.log(programsByplan[program]); if(programsByplan[program]){ var options = []; $.each(programsByplan[program], (i,v){ options.push(‘<option value=”‘+v+'”>’+v+'</option>’); }); $(‘#’+plan_id).html(options.join(“n”)); }else{ //or, do somkind of error recovery here. $(‘#’+plan_id).html(‘<option value=””>No Plans</option>’); } }); </script>

И так далее, и посмотрите, что это за значения. Это, наверное, лучший способ.

Приветствия.

-1

Источник