Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

web - tec / PHP 5 для начинающи

.pdf
Скачиваний:
69
Добавлен:
12.06.2015
Размер:
26.79 Mб
Скачать

Логические операторы, циклы и массивы 183

Все что нужно делать ++++++ снова и снова вычислять результат по данной формуле, пока долг не будет равен нулю, а затем посчитать, сколько месячных платежей для этого требуется. Чтобы это сделать, можно заставить PHP использовать цикл while.

Практика Использование цикла while

1. Откройте HTML+редактор и введите следующий код:

<html>

<head><title></title></head>

<body>

<b>Заявка на получение ссуды. Кредитный банк Namllu</b>

<?php

if (isset($_POST['posted'])) { $duration = 0;

switch ($_POST['loan']) { case "1000";

$interest = 5; break;

case "5000"; $interest = 6.5; break;

case "10000"; $interest = 8; break;

default:

echo "Вы не выбрали вариант ссуды<hr>"; exit;

}

while ($_POST['loan'] > 0)

{

$duration = $duration + 1;

$monthly = $_POST['month'] - ($_POST['loan']*$interest/100); if ($monthly <= 0)

{

echo "Чтобы погасить ссуду, требуются более крупные ежемесячные платежи<hr>";

exit;

}

$_POST['loan'] = $_POST['loan'] - $monthly;

}

echo "Для погашения ссуды при процентной ставке $interest процентов понадобится $duration месяцев.<hr>";

}

?>

<form method="POST" action="loan.php">

<input type="hidden" name="posted" value="true">

<br>

Выберите необходимую сумму ссуды<br><br>

<input name="loan" type="radio" value="1000">1000 долларов под 5,0% в месяц <br>

<input name="loan" type="radio" value="5000">5000 долларов под 6,5% в месяц <br>

<input name="loan" type="radio" value="10000">10000 долларов под 8,0% в месяц <br>

<br>

Введите сумму ежемесячного платежа

<input name="month" type="text" size="5"> <br>

184 Глава 4

<br>

<input type="submit" value="Рассчитать"> </form>

</body>

</html>

2.Сохраните данный файл как loan.php и закройте его.

3.Откройте страницу в браузере. Выберите вариант 1000 долларов, введите 100 как месячный платеж и нажмите кнопку Рассчитать. Результат показан на рис. 4.6.

Рис. 4.6.

Как это работает

Форма предлагает пользователю выбрать сумму ссуды, которая затем сохраняется в пе+ ременной $_POST['loan'], и сумму ежемесячного платежа, которая хранится в переменной $_POST['month']. После этого данные переменные используются в сце+ нарии loan.php. В представленном сценарии используется только две структуры. Первая структура ++++++ оператор switch, который описывался в предыдущем разделе. Сначала инициализируется переменная $duration, в которой будет храниться коли+ чество месячных платежей, необходимых для погашения ссуды. Затем для выбора процентной ставки используется оператор switch, поскольку процентная ставка за+ висит от ссуды, выбранной пользователем в HTML+форме:

$duration = 0;

switch ($_POST['loan']) { case "1000";

$interest = 5; break;

Логические операторы, циклы и массивы 185

case "5000"; $interest = 6.5; break;

case "10000"; $interest = 8; break;

default:

echo "Вы не выбрали вариант ссуды<hr>"; exit;

}

Существует только три возможных значения $_POST[loan]: 1000, 5000 и 10000. Значение переменной $loan используется для того, чтобы с помощью оператора switch присвоить переменной $interest соответствующую процентную ставку. Ес+ ли ни одно из значений не было выбрано, то пользователю выдается соответствую+ щее сообщение, и программа останавливает свою работу.

Прежде чем программа войдет в цикл while, необходимо проверить условие. Ус+ ловие заключается в том, что цикл может повторяться до тех пор, пока значение пе+ ременной $_POST[loan] не достигнет нуля; иными словами, пока имеется долг:

while ($_POST[loan] > 0){

Значение переменной $_POST[loan] ++++++ условие, с которого начинается цикл, так как значение $loan должно быть равно 1000, 5000 или 10000, но не 0. Затем счетчик месяцев $duration, первоначально равный нулю, увеличивается на единицу, чтобы показать, что это первая итерация цикла:

$duration = $duration + 1;

В следующей строке вычисляется сумма, которая будет выплачена по ссуде в дан+ ном месяце, включая проценты:

$monthly = $_POST['month'] - ($_POST['loan'] * $interest / 100);

Чтобы получить месячную сумму выплаты по процентам, процентная ставка де+ лится на 100%, а результат умножается на сумму ссуды. Затем, чтобы определить сумму ссуды, оставшуюся в данном месяце, необходимо вычесть платеж по процентам за этот месяц из фиксированного месячного платежа. Результат будет ответом на первую часть выражения, приведенного в начале данного примера:

Платеж = Месячный платеж – Проценты

Однако для чего в этой точке программы создается переменная $monthly? Поче+ му вместо этого нельзя использовать следующую строку:

$month = $month - ((($_POST['loan'] / 100) * $interest);

Причина заключается в том, что значение переменной $_POST['month'] должно оставаться постоянным во всех циклах, представляя, таким образом, фиксированный ежемесячный платеж 100 долларов. Если использовать данную строку кода, то значе+ ние $_POST['month'] будет изменяться в каждой итерации цикла, так как из него бу+ дет вычитаться месячный платеж. Поэтому, чтобы представить общую сумму платежа в данном месяце, используется другая переменная, $monthly. После каждой итера+ ции цикла в ней содержится другое значение.

Проигнорируем пока оператор if; он не изменяет значений переменных. Теперь, когда имеется значение, которое необходимо вычесть из остатка ссуды за данный ме+ сяц, можно получить общий остаток ссуды, $_POST['loan']:

$_POST['loan'] = $_POST['loan'] - $monthly;

186 Глава 4

Рассмотрим цикл. В начале первой итерации переменные имеют свои первона+ чальные значения:

$_POST['loan'] = 1000 $interest = 5 $duration= 0 $_POST['month']= 100

поэтому первая строка фактически означает

while (1000 > 0)

Так как 1000 больше 0, программа может безопасно войти в цикл, начиная с пер+ вой строки его кода, которая теперь означает

$duration = 0 + 1;

Теперь $duration равно единице. Далее следует строка

$monthly = 100 - (1000 * 5 / 100);

Вычислив результат в скобках, получаем

$monthly = 100 - (50);

Значение переменной $monthly равно 50. Программа достигла последней строки цикла:

$_POST['loan'] = 1000 - 50;

Поэтому $loan теперь равна 950. Затем следует закрывающая фигурная скобка, которая означает конец итерации. Программа возвращается обратно к проверке ус+ ловия цикла, и теперь условие таково:

while (950 > 0)

Условие снова соблюдается и программа снова входит в цикл. $duration увеличи+ вается на 1, и

$duration = 1 + 1;

Теперь переменная $duration содержит значение 2. Следующая строка несколь+ ко изменяется по сравнению с предыдущей итерацией, так как отличается значение переменной $loan:

$monthly = 100 - (950 * 5 / 100);

В результате этого переменная $monthly получает значение 52,5. Это влияет на вычисление остатка ссуды:

$_POST[loan] = 950 - 52.5;

После этого в переменной $_POST['loan'] хранится значение 897,5. Фактиче+ ский платеж по процентам уменьшается со временем, так как уменьшается остаток ссуды. Однако месячный платеж по ссуде фиксированный, поэтому фактическая вы+ плата по ссуде с каждым месяцем возрастает. В первом месяце пользователь выплачи+ вает 50 долларов, во втором ++++++ 52,50 и т.д.

Программа снова возвращается к проверке условия цикла: while (897.5>0)

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

Логические операторы, циклы и массивы 187

Бесконечные циклы

Известно, что очень медленная выплата ссуды ведет к тому, что проценты по ссуде превышают платежи, и ссуда постепенно возрастает, поэтому ее никогда нельзя будет выплатить. Эти устрашающие для человека перспективы также могут иметь фаталь+ ные последствия для программы. Если пользователь введет слишком маленькую сумму ежемесячного платежа, то цикл программы будет продолжаться бесконечно долго, потому что условие $loan>0 всегда будет верным. По умолчанию PHP+сценарии могут выполняться 30 секунд независимо от того, если ли в программе бесконечный цикл. Однако если сервер работает под управлением Windows 2000 и IIS 5, то браузер может в конце концов зависнуть, а если не предпринять определенные меры предосторож+ ности, то зависнет также и Web+сервер.

Это означает, что необходимо позаботиться о том, чтобы бесконечные циклы не возникали. В рассматриваемом здесь примере это можно сделать путем проверки мини+ мального значения платежа; однако данное значение полностью зависит от выбранного варианта ссуды. Следовательно, проверку необходимо реализовать внутри цикла. Те+ перь бесконечный цикл возникает только в том случае, если значение $loan каждый месяц увеличивается. Еще раз рассмотрим соответствующую строку в программе:

$_POST['loan'] = $_POST['loan'] - $monthly;

$monthly вычитается из $_POST['loan']. Сумма ссуды будет увеличиваться только тогда, когда значение переменной $monthly будет отрицательным (вычитание отри+ цательного числа эквивалентно прибавлению положительного). Поэтому необходимо проверять, не является ли значение $monthly меньшим или равным нулю. Пока это так, можно быть уверенным, что ссуда будет уменьшаться с каждой итерацией цикла, и число таких итераций конечно. На самом деле неважно, сколько будет итераций: PHP способен выполнять тысячи итераций в секунду.

Если создается условие для бесконечного цикла, то следует выйти из цикла с по+ мощью команды exit, предварительно отправив пользователю соответствующее со+ общение:

if ($monthly <= 0)

{

echo "Чтобы погасить ссуду, требуются более крупные ежемесячные платежи<hr>"; exit;

}

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

С другой стороны, если итерации заканчиваются корректно, то отображается окончательное значение переменной $duration:

echo "Для погашения ссуды при процентной ставке $interest процентов понадобится $duration месяцев.<hr>";

Таким образом, пользователь сможет узнать, как долго ему придется выплачивать ссуду. Несмотря на то, что цикл состоит всего из 5 строк кода, чтобы рассмотреть его подробно, понадобится некоторое время. Если работа цикла не совсем ясна, вы мо+ жете смоделировать его работу на бумаге, используя несколько отличающиеся цифры и записывая результаты для каждой итерации цикла, а затем сверить полученные дан+ ные с тем, что возвращает PHP. Данные в обоих случаях должны быть идентичными.

188 Глава 4

Циклы do while

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

do{

выполнить код в данных скобках;

}

while(условие верно); // вернуться и выполнить код в скобках снова

Вернемся к примеру с покупательским приложением, на этот раз используя в нем цикл do while. Очевидно, что данный цикл меняет всю работу кода:

do{

echo ("Вы превысили лимит своего кредита,

поэтому последний объект будет удален из Вашей корзины"); $last_purchase_but_one = $shopping_total - $last_purchase; $last_purchase = $last_purchase_but_one;

} while ($shopping_total > $credit_limit);

Предупреждение распечатывается еще до того, как программа проверит, не пре+ высил ли пользователь свой кредитный лимит. Это совсем не то, что нужно.

Рассмотрим другую ситуацию, когда цикл do while будет действительно полезным. Предположим, необходимо проехать по междугородной автомагистрали от выезда 14 до выезда 103. Это можно описать с помощью следующего псевдокода:

do{

ехать до следующего выезда; } while ($exit != 103);

Если водитель захочет свернуть с автомагистрали, то ему, как минимум, придется доехать до следующего выезда, поэтому, по крайней мере, одна итерация необходима. А если следующим будет не 103+й выезд, то цикл понадобится выполнить еще раз и т.д. до тех пор, пока водитель не доедет до нужного выезда. Еще один хороший пример использования цикла do while в PHP ++++++ вычисления, которые необходимо выпол+ нить хотя бы один раз, но, возможно, придется повторять вычисления до достижения определенного результата. Предположим, например, что необходимо создать про+ грамму для проверки простых чисел. Чтобы проверить, является ли число простым, его необходимо разделить на каждое число в диапазоне от двух и до самого числа, уменьшенного на единицу. Это можно сделать с помощью цикла do while:

do{

$remainder = $possible_prime_number % $number; $number=$number + 1;

} while ($remainder != 0 AND $number < $possible_prime_number);

Проверяемое число $possible_prime_number необходимо разделить нацело (оператор %) на каждое число от 2 до самого $possible_prime_number минус 1 и про+ верить, если ли остаток от деления. Деление и проверка остатка выполняются в каж+ дой итерации. Когда остаток равен нулю, программа должна выйти из цикла, потому что такое число может быть простым.

Чтобы определить, делится ли проверяемое число на другие числа, необходимо выполнить, как минимум, одно деление, и поэтому цикл do while в данной ситуации является наиболее подходящим. Если цикл доходит до самого проверяемого числа, то, очевидно, что это число делится только на само себя или на 1, поэтому данное число является простым.

Логические операторы, циклы и массивы 189

Цикл do while также оказывается полезным в ситуации, когда программа должна дождаться ввода данных от пользователя. В качестве примера можно модифициро+ вать PHP+программу, которая ‘‘загадывала’’ числа от 1 до 10. Чтобы дать возможность пользователю угадывать число до тех пор, пока он не введет верный ответ, можно поместить соответствующий код в цикл do while, который будет повторяться вплоть до ввода загаданного числа.

Чтобы разобраться в работе цикла do while, рассмотрим пример, конкретизи+ рующий фрагмент PHP+кода для проверки простых чисел.

Практика Использование циклов do while

1. Запустите редактор Web+страниц и введите следующий код:

<html>

<head><title></title></head>

<body>

<?php

if (isset($_POST['posted'])) { $count=2;

do

{

$remainder = $_POST['guess'] % $count; $count = $count + 1;

} while ($remainder != 0 and $count < $_POST['guess']);

if (($count < $_POST['guess']) || ($_POST['guess'] == 0)) { echo ("Введенное число не является простым<hr>");

} else {

echo ("Введенное число является простым<hr>");

}

}

?>

<form method="POST" action="check.php">

<input type="hidden" name="posted" value="true">

Введите число:

<input name="guess" type="text"> <br>

<br>

<input type="submit" value="Проверить число"> <br>

</form>

</body>

</html>

2.Сохраните данный файл как check.php и закройте его.

3.Откройте созданный файл в браузере, введите число и нажмите кнопку Прове-

рить число.

Результат показан на рис 4.7.

Как это работает

Задача HTML+формы состоит исключительно в получении числа от пользователя:

Введите число:

<input name="guess" type="text">

Введенное число передается в переменную $_POST['guess'], которая затем ус+ танавливает переменную $count:

$count=2;

190 Глава 4

Рис. 4.7.

Данной переменной присваивается значение 2, потому что нет смысла начинать проверку с деления на 1; в любом случае каждое целое число делится на 1. Затем на+ чинается цикл:

do{

Цикл начинается с проверки остатка от деления $_POST[‘guess’] на $count. За+ тем значение переменной $count увеличивается на единицу:

$remainder = $_POST['guess'] % $count; $count = $count + 1;

Эти две строки формируют все тело цикла. Следует учитывать, что если пользова+ тель ввел число 25634, то в данном цикле оно будет делиться на 2, 3, 4, 5, 6, 7, 8 и т.д. до 25633; т.е. потребуется довольно много итераций. В конце каждой итерации про+ веряется два момента: есть ли остаток от деления и не достигло ли значение $count проверяемого числа $_POST['guess']:

} while ($remainder != 0 AND $count < $_POST['guess']);

Цикл прерывается, главным образом, когда возникает одно из двух указанных усло+ вий. Если цикл прервался, но значение $count не равно значению $_POST[guess], то, скорее всего, проверяемое число было без остатка разделено на значение $count, поэтому $_POST[guess] не является простым числом. Необходимо также учиты+ вать, что пользователь может ввести число нуль, которое дает нулевой остаток от деления на любое число, но не является простым. В противном случае, если две данные переменные имеют одинаковые значения, значит, проверяемое число яв+ ляется простым:

if (($count < $_POST['guess']) || ($_POST['guess'] == 0)) { echo ("Введенное число не является простым<hr>");

} else {

echo ("Введенное число является простым<hr>");

}

Последний шаг ++++++ отобразить результаты пользователю.

Логические операторы, циклы и массивы 191

Циклы for

Циклы for применяются, когда необходимо повторять какой+либо блок кода за+ данное количество раз. Иными словами, такой цикл дает возможность указывать чис+ ло итераций. Условная часть в данном цикле более сложная, чем в цикле while, так как она состоит из трех частей:

for (установить счетчик цикла; проверить счетчик; увеличить или уменьшить счетчик){ выполнить код в фигурных скобках;

}

Цикл for вводит понятие счетчика цикла, т.е. переменной, которая используется для подсчета количества итераций и для остановки цикла, после того как достигнуто за+ данное число итераций. Первые две части условия цикла for ++++++ установка счетчика цикла, т.е. указание необходимого числа итераций, и проверка счетчика ++++++ не превыша+ ет ли количество выполненных итераций счетчик цикла. Третья часть условия цикла гарантирует, что в каждой итерации значение счетчика изменяется. Эти три части усло+ вия позволяют конструировать сложные условия и циклы. Ни одна из частей условия не является обязательной, но для начала рекомендуется использовать все три части.

Как можно использовать цикл for? Например, можно 10 раз распечатать строку текста. Для этого можно 10 раз использовать команду echo, но это было бы довольно утомительно. Можно также использовать цикл while и создать внутри него перемен+ ную для подсчета итераций:

$counter=0;

while ($counter<10){ echo "Привет!";

$counter=$counter+1;

}

Однако сколько в таком случае итераций выполнит цикл? Девять, потому что когда счетчик достигает 10, то цикл останавливается? Или 11, потому что цикл начинается со счетчиком равным 0? Цикл выполнится действительно 10 раз, но придется вер+ нуться назад и логически все проверить в уме. Гораздо проще контролировать коли+ чество итераций с помощью цикла for:

for ($counter = 1; $counter <= 10; $counter ++){ echo "Привет!";

}

В данном случае вообще нет необходимости следить за счетчиком цикла, все дела+ ется автоматически.

Практическое применение цикла for описано в следующем разделе ‘‘Практика’’.

Практика Использование циклов for

В следующем примере создается динамическая форма, которая принимает от пользователя некоторое число, использует это число для установки количества эле+ ментов управления, отображаемых на второй странице, а затем на третьей странице отображает содержимое этих элементов управления (следует отметить, что HTML+ код всех трех страниц расположен в соответствующих операторах if внутри одного файла, и отображается только при соблюдении определенных условий, а именно ко+ гда переменные $_POST[posted] и $_POST[posted01] существуют).

1. Введите следующий код в редакторе Web+страниц:

<html>

<head><title></title></head>

192 Глава 4

<body>

<?php

if (isset($_POST['posted'])) {

echo "<form method='POST' action='dynamic.php'>";

for ($counter = 0; $counter < $_POST['number']; $counter ++)

{

$offset = $counter + 1;

echo "<br>Введите имя $offset-го ребенка<br>"; echo "<input name='child[]' type='text'>";

}

echo"<br>Для продолжения нажмите кнопку<br>"; echo "<input type='submit' value='Далее'>";

echo "<input type='hidden' name='posted01' value='true'></form>";

} else {

if (isset($_POST['posted01'])) {

$count=0;

echo "Имена Ваших детей:"; do

{

$childs_name = $_POST['child'][$count]; echo"<br><b>$childs_name</b>"; $checkempty = $childs_name;

$count = $count + 1;

} while ($checkempty != "");

if ($count == 1) {

echo "Введите другое число";

}

}

?>

<hr>

<form method="POST" action="dynamic.php">

<input type="hidden" name="posted" value="true">

Сколько у Вас детей?

<input name="number" type="text"> <br>

<br>

<input type="submit" value="Отправить число"> <br>

</form>

<?

}

?>

</body>

</html>

2.Сохраните данный файл как dynamic.php и закройте его.

3.Откройте созданный файл в браузере (на рис. 4.8 показан созданный интер+ фейс) и введите число (для пробы введите число больше нуля).

4.Нажмите кнопку Отправить число и на следующей странице будет выведено не+ сколько текстовых полей, количество которых равно введенному числу. На рис. 4.9

показан примерный результат для пользователя, который ввел число 3 в поле

Сколько у Вас детей?

5.Введите в текстовые поля имена, нажмите кнопку Далее и на следующей стра+ нице отобразятся введенные имена (рис. 4.10).

Соседние файлы в папке web - tec