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

PHP5_nachinayushim

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

154 Глава 3

Сервер находит данные соответствующего сеанса и предоставляет к ним доступ лю+ бому исполняемому впоследствии сценарию.

Если поддержка cookie в браузере включена, то диспетчер сеансов автоматически отправляет клиенту cookie для данного SID+значения. Если клиент не может (или не хочет) использовать cookie, простейшим решением является добавление SID в каж+ дую строку запроса, которая ссылается на данный Web+сайт.

С помощью PHP+сеансов все это происходит очень точно. Сеансы весьма способст+ вуют быстрому созданию интерактивных сайтов, так как позволяют разработчику не бес+ покоиться о важных деталях реализации постоянства данных и полностью сосредото+ читься на разработке сайта. Программисты, внимательно изучающие механизм обеспечения постоянства в PHP (так как этот механизм является частью самого PHP), гарантируют, что поддерживающий этот механизм код работает настолько хорошо, на+ сколько это возможно. Кроме того, сеансы очень хорошо документированы в основной документации по PHP, доступной на официальном Web+сайте PHP (www.php.net/). Итак, сеансы просты в освоении, надежны и почти всегда доступны для использова+ ния. Теперь следует разобраться, как их использовать.

В большинстве случаев использование PHP+сеансов сводится к примерно следующей инструкции, переданной PHP: ‘‘Сделать переменные X, Y и Z постоянными для данного приложения’’. Вся работа выполняется самим PHP. Программист должен позаботиться лишь о том, как дать PHP команду зарегистрировать переменную сеанса ++++++ т.е. сделать данную переменную постоянной ++++++ а затем как получить доступ к этой переменной.

Для регистрации постоянных переменных с помощью PHP+сеансов предназначена функция session_register(). При условии передачи этой функции имени пере+ менной (без знака доллара) функция делает указанную переменную и ее содержимое постоянным в течение всего текущего сеанса. Если текущий сеанс еще не определен, то автоматически создается новый сеанс. Длительность сеанса (период времени, в те+ чение которого сеанс сохраняется в PHP, даже если клиент не использует данный сайт) определяется настройками в файле php.ini. По умолчанию такой период ра+ вен 1440 секундам (24 минутам).

Например, если требуется сделать постоянными переменные myvar1 и myvar2, то сценарий следует начать так:

<?php session-register("myvar1"); session-register("myvar2"); ?>

Приведенный выше код необходимо поместить в начало сценария. Cookie исполь+ зуются незаметно. Еще раз следует подчеркнуть, что все переменные сеанса необхо+ димо зарегистрировать до того, как будет отправлен какой+либо HTML+код. Хорошей практикой является использование подобного самодостаточного фрагмента PHP+кода в самом начале сценария.

Как только переменная зарегистрирована, получить доступ к ее содержимому очень просто ++++++ следует только обратиться к переменной сеанса так же, как к любой другой глобальной переменной. Если для регистрации переменных $myvar1 и $myvar2 ис+ пользовался приведенный выше код, то эти переменные можно использовать как лю+ бые другие переменные. Единственное отличие состоит в том, что эти переменные будут оставаться постоянными, пока продолжается данный сеанс, поэтому в следую+ щий раз, когда внутри данного сеанса страница будет вызвана тем же пользователем, переменные будут содержать те же значения, которые они имели, когда страница бы+ ла вызвана в предыдущий раз.

PHP, HTML и состояние сеанса 155

Чтобы использовать сеансы на Windows+сервере, вероятно, придется изменить параметр session.save_path в файле php.ini, так чтобы он указывал на коррект+ ный каталог в Windows (например, D:\WinNT\Temp, где D ++++++ имя логического диска).

Практика Счетчик посещений

Рассмотрим практический пример. Требуется подсчитать количество визитов поль+ зователя на страницы Web+сайта с момента начала текущего сеанса. Эту задачу легко ре+ шить с помощью PHP+сеансов, сделав с помощью функции session_register() по+ стоянными различные счетчики (по одному для каждой страницы сайта):

<?php session_register('view1count'); session_register('view2count'); session_register('view3count'); session_register('view4count'); ?>

<?php

//Остальная часть сценария иллюстрирует, как с помощью гиперссылок //передавать PHP информацию, необходимую для доступа к данным сеанса, //буквально – SID-идентификатор.

echo "<html><head><title>Счетчик посещений Web-страниц</title></head><body>";

if (isset($_GET['whichpage'])) {

echo "<b>В данный момент Вы просматриваете страницу $_GET[whichpage].</b><br><br>\n";

$_SESSION["view".$_GET['whichpage']."count"]++;

}

for ($i = 1; $i <= 4; $i++) {

if (isset($_GET['whichpage']) == $i) {

echo "<b><a href=\"sessions.php?".session_id()."&whichpage=$i\"> Страница $i</a></b>";

} else {

echo "<a href=\"sessions.php?".session_id()."&whichpage=$i\">Страница $i</a>";

}

if (!isset($_SESSION["view".$i."count"])) $_SESSION["view".$i."count"] = 0; echo ", которую Вы смотрели ".$_SESSION["view".$i."count"]." раз.<BR>\n";

}

echo "\n\n<br><br>\n\n"; echo "</body></html>"; ?>

Сохраните данный файл как sessions.php. Откройте файл в браузере и смените страницу несколько раз. На рис. 3.21 показан примерный результат.

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

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

Эта простая программа начинается с регистрации четырех переменных сеанса

спомощью функции session_register(). Вызовы функции помещены в отдельный блок PHP+кода (обрамленный тегами <?php и ?>), для того чтобы было понятно, что они должны располагаться до всего остального кода и не должны перемешиваться

сHTML+заголовками:

156 Глава 3

Рис. 3.21.

<?php session_register('view1count'); session_register('view2count'); session_register('view3count'); session_register('view4count'); ?>

Затем выводится HTML+заголовок и проверяется, определена ли переменная $_GET['whichpage'] (обозначающая текущую страницу). Если эта переменная опре+ делена, то ее значение используется для отображения соответствующего сообщения и определения страницы, счетчик посещений которой необходимо инкрементировать:

if (isset($_GET['whichpage'])) {

echo "<b>В данный момент Вы просматриваете страницу $_GET[whichpage].</b><br><br>\n";

$_SESSION["view".$_GET['whichpage']."count"]++;

}

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

PHP, HTML и состояние сеанса 157

вателю о том, сколько раз данная страница посещалась во время текущего сеанса. Ссылка на текущую страницу выделяется жирным шрифтом:

for ($i = 1; $i <= 4; $i++) {

if (isset($_GET['whichpage']) == $i) {

echo "<b><a href=\"sessions.php?".session_id()."&whichpage=$i\">Страница $i</a></b>";

} else {

echo "<a href=\"sessions.php?".session_id()."&whichpage=$i\">Страница $i</a>";

}

if (!isset($_SESSION["view".$i."count"])) $_SESSION["view".$i."count"] = 0; echo ", которую Вы смотрели ".$_SESSION["view".$i."count"]." раз.<BR>\n";

}

echo "\n\n<br><br>\n\n"; echo "</body></html>"; ?>

В каждой ссылке указывается три элемента: текущий сценарий (sessions.php), текущий сеанс (идентифицируется с помощью функции session_id()) и страни+ ца, с которой связана ссылка (это то, для чего предназначена переменная $_GET ['whichpage']). Это все. Весь необходимый код обработки сеансов содержится в первых четырех строках. Едва ли он мог бы быть еще проще.

Резюме

Вданной главе были описаны многие предопределенные переменные, доступные PHP+программам в то время, когда между клиентом и Web+сервером происходит об+ мен данными (запросы и ответы). Также рассматривалось отображение и использо+ вание отдельных предопределенных переменных, таких как $_SERVER, $_REQUEST.

Вглаве были описаны основные элементы для построения интерактивных PHP+ программ: строки запроса в гиперссылках (использование дескриптора <a>) и HTML+ формы (дескрипторы <input>, <textarea> и <select>). Кроме того, обсуждалось различие между методами GET и POST, а также обстоятельства, в которых предпочти+ тельно применять тот или иной метод.

Наконец, в главе было рассмотрено понятие состояния, а вернее отсутствие фик+ сации состояния в протоколе HTTP и способы преодоления связанных с этим огра+ ничений: использование скрытых полей форм, строк запросов, cookie+файлов, сеан+ сов и даже баз данных для хранения и передачи информации о состоянии между обращениями к страницам.

Упражнение

В PHP имеется очень полезная функция isset(), которая сообщает PHP+програм+ ме, установлена ли определенная переменная. Например, предположим, что сущест+ вует страница с формой, содержащей submit+кнопки login и logout. С помощью функции isset() можно узнать, какая кнопка была нажата:

if (isset($login)) { //делаем что-то

} elseif (isset($logout)) { //делаем что-то другое

}

158Глава 3

Вэтом упражнении требуется создать Web+страницу с формой, которая отправляет данные самой себе, и заставить PHP+программу сообщать об отправке формы, ис+ пользуя функцию isset(). Если форма не была отправлена, то программа должна отобразить форму (без сообщения), запрашивающую имя и фамилию пользователя. Иначе программа должна вместо формы отобразить сообщение (короткое предложе+ ние, например: ‘‘Ваше имя XX, а фамилия YY’’).

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

4

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

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

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

структурами управляющей логики (control*flow structures) или структурами ветвления

(branching structures). Они выполняют наборы базовых инструкций по условию в зави+ симости от значений или выражений, которые могут быть постоянными или изме+ няться в каждом шаге цикла. По форме все они представляют собой простые структу+ ры, как, например, оператор if, но их можно комбинировать и реализовывать сложную логику принятия решений.

Вданной главе рассматривается практическая постановка задач на простом языке

изапись псевдокода, отражающего формулировку задачи. Кроме того, в главе описана Булева логика, несколько PHP+структур, оператор break и работа с массивами, в том числе и с многомерными массивами.

Проектирование логики PHP-программы

Существует много способов начать разработку приложения, но поэтапный подход помогает сэкономить время и уменьшает риск неудачи. Один из хороших методов за+ ключается в том, чтобы начинать разработку с постановки задачи (формулировки проблемы). Затем следует написание псевдокода (инструкций компьютеру, подобных

160 Глава 4

реальному языку программирования, но написанных на обычном языке, например, на английском или на русском) на основе поставленной задачи и, наконец, написание реального PHP+кода на основе псевдокода. Псевдокод часто может послужить в каче+ стве основы для комментариев (эта тема подробнее рассматривается в главе 5).

Постановка задачи

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

Если не использовать готовую программу или Web+службу для генерации суммы взноса и даты оплаты, то приложение должно будет генерировать эти данные само+ стоятельно. Методологию обработки в данном случае можно выразить в логических понятиях, абсолютно не связанных с каким+либо языком программирования, напри+ мер: ‘‘Принять в качестве входных данных баланс по ссуде, процентную ставку и срок предоставления ссуды. Предположить равные помесячные выплаты начиная с перво+ го месяца и в течение всего срока ссуды. Вычислить каждую сумму и дату выплаты, а затем сгенерировать HTML+код для отображения этих данных пользователю. По+ вторять вычисления до тех пор, пока не будут рассчитаны все выплаты, а затем вер+ нуть HTML+код пользователю в форме Web+страницы’’.

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

Написание псевдокода

Что такое псевдокод? На самом деле нет строгого и точного определения. Здесь пред+ лагается общее определение, которое облегчает понимание терминов: псевдокод представляет собой последовательность операторов на обычном языке, которые логиче+ ски структурированы почти так же, как будет структурирован код в реальной программе.

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

Для приведенной выше формулировки проблемы можно написать следующий псевдокод (с учетом того, что его впоследствии придется преобразовать в код PHP5):

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

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

//Создать строковую переменную, содержащую HTML-код для отображения //сумм и дат платежей, и вставлять даты и суммы платежей на каждом //шаге описанного выше цикла. Добавлять следующий HTML-код, дату

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

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

//переменным данные значения на каждом шаге цикла и инкрементировать их //Присвоить переменной строковое значение, содержащее HTML-код для //отображения итоговых сумм

//Отправить пользователю HTML-код и сгенерированные значения.

В дополнение к демонстрации некоторых базовых методик написания псевдокода следует отметить методику повторяющихся вычислений (или другого вида обработки данных) в цикле. Многие используемые структуры языка программирования являют+ ся структурами управляющей логики, в которых решения принимаются в зависимости от значений, вычисленных или сгенерированных динамически (во время работы приложения). Нередко структуры принятия решений объединяются с циклами, что+ бы можно было повторять вычисления снова и снова до тех пор, пока не будет найден окончательный ответ. Независимо от языка программирования почти все виды обра+ ботки данных основаны на одних и тех же структурах управляющей логики и циклах.

Булева логика

Весьма важной для управляющих структур является булева логика, так как булевы значения часто используются для выражения ‘‘условий’’, определяющих то, какой на+ бор инструкций будет обрабатываться дальше (по существу, принимаемое решение). Булева логика названа в честь Джорджа Буля (George Boole), создавшего булеву алгебру.

Булевы термы

Читатели, скорее всего, уже сталкивались с булевой логикой при работе с поиско+ выми машинами. Например, если слово “and” (‘‘и’’) между словами в поисковом за+ просе означает ‘‘получить документы, содержащие слово A и слово B’’. ‘‘И’’ ++++++ булев терм, как и “или” (“or”) и “не” (“not”). Эти термы постоянно используются в по+ вседневной жизни, и каждый из нас интуитивно понимает, что они означают. Суще+ ствует также специальный терм ++++++ xor ++++++ он означает ‘‘если любое подвыражение (но не оба) истинно’’. Существуют также специальные операторы, имитирующие термы "или" и "и" (|| и &&), но они имеют более высокий приоритет (в главе 2 тема при+ оритетов рассматривается подробнее).

Если рассматривать эти операторы в терминах результатов поиска, то можно отме+ тить, что включение or в поисковый запрос дает большее количество возможных ре+ зультатов, а xor, not и and последовательно все более сужают результаты поиска. Это можно проверить на любой поисковой машине (если она поддерживает булеву логику).

Конструируя блок логики обработки данных, можно использовать булевы термы для создания условий, при которых будет выполняться обработка данных. Например, в управ+ ляющей структуре if..thenelse..end if за оператором if следует выражение, ко+ торое либо истинно, либо ложно (истина (true) и ложь (false) называются булевыми значениями). Если оно истинно, то выполняется код, следующий сразу за оператором if. Если выражение ложно, то данные операторы пропускаются и управление переда+ ется блоку else, а если данного блока нет, то пропускается вся управляющая структура.

Булевы значения

Булевыми значениями являются ‘‘истина’’ и ‘‘ложь’’, представленные в PHP клю+ чевыми словами TRUE и FALSE. И хотя булевы значения можно преобразовать, в боль+ шинстве случаев для выполнения соответствующих действий внутри логической

162 Глава 4

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

нуль как целое число (0);

нуль как число с плавающей точкой (0.0);

пустая строка ("");

строковый нуль ("0");

массив с нулевым количеством элементов;

объект с нулевым количеством внутренних переменных;

специальный тип NULL (включая любые незаданные переменные).

Все остальные значения интерпретируются как TRUE. Следует помнить о том, что истинность или ложность выражения зависит от результата вычислений, а не от сравниваемых значений. Например, если значением A является 20, а B ++++++ 30, и есть выражение A < B (A меньше B), то результатом будет TRUE. Для структур принятия решений возможно только два результата: истина или ложь. В таких структурах не до+ пускается результат может быть.

Ранее рассматривались переменные, которые могли содержать числа или строки. Булевы значения содержатся в переменной третьего типа, которая может содержать одно из двух абсолютных значений: true или false. Любой из переменных можно присвоить одно из этих значений:

$Variable = true;

Однако если впоследствии отобразить значение данной переменной на экране, то будет выведено числовое значение:

1

Очевидно, что булевы значения могут иметь как числовую, так и литеральную форму. Само по себе это не вызывает особого интереса, но как только потребуется принять решение в зависимости от результата и определить, является ли заданное выражение истинным или ложным (либо, что то же самое, выражение равно 1 или 0), то выяснится, что булевы значения используются очень часто.

Использование булевых термов и значений

Чтобы определить истинность или ложность заданного выражения, можно опре+ делить его значение и сравнить это значение с некоторым другим значением. В ре+ зультате вычисления выражения может получаться несколько значений (в форме: это и то, это или то, это не то), каждое из которых проверяется. Эти утверждения соединяют+ ся булевыми операторами and, or и xor. В PHP терм ‘‘не’’ представлен оператором !.

Когда в качестве условия используется два значения, первое из которых истинно, а второе ложно, и они соединены оператором and, то все условие будет ложным, и первый набор инструкций будет пропущен. Напротив, если оба выражения истин+ ны и они соединены оператором and, то все условие будет истинным и будут выпол+ няться операторы в первом блоке кода. Остальные группы операторов также приво+ дят к тому, что решение принимается в зависимости от булева значения, которое возвращается после обработки всех операторов.

Проиллюстрировать работу данных условий может таблица результатов для про+ стого блока управляющей логики if..then..else/elseif..end if. (Следует от+ метить, что then и end if в PHP представлены фигурными скобками; оператор if

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

подробнее рассматривается далее в настоящей главе.) Рассмотрим код (термы AND и OR записаны прописными буквами, чтобы они выделялись среди остального кода, хотя вообще они не чувствительны к регистру символов):

$my_var = 27; $my_var02 = 30;

if ($my_var == $my_var02) { //выполнить эти строки кода

}elseif ($my_var + 3 == $my_var02) { //выполнить эти строки кода

}elseif ($my_var + 3 == $my_var02 AND $my_var == $my_var02) { //выполнить эти строки кода

}elseif ($my_var == $my_var02 OR $my_var == $my_var02-3) { //выполнить эти строки кода

}elseif ($my_var == $my_var02 AND !$my_var == $my_var02-3) {

//выполнить эти строки кода

}

В приведенной ниже таблице перечислены возможные результаты.

Условие

Результат

 

 

$my_var == $my_var02

Данное выражение будет истинным, только если обе

 

переменные содержат в точности равные значения. Во всех

 

остальных случаях результат будет ложным

$my_var + 3 == $my_var02

Сначала вычисляется выражение $my_var + 3, затем

 

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

 

переменной $my_var02

$my_var + 3 == $my_var02 AND $my_var == $my_var02

$my_var == $my_var02 OR $my_var == $my_var02 - 3

$my_var == $my_var02 – 3 AND !($my_var == $my_var02)

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

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

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

Очевидно, что можно выбрать условия, которые удовлетворяют почти любым об+ стоятельствам. Например, можно написать управляющую структуру, которая ищет только конкретное значение, введенное пользователем. Если написать условие так, что только одно значение активизирует код в структуре, то появится множество воз+ можностей потерять это единственное значение и код никогда не будет выполнен (иногда это как раз то, что нужно). В других ситуациях необходимо убедиться, что код выполняется почти всегда, кроме очень специфических случаев. Можно написать ус+ ловие, которое запускает код, если пользователь не ввел определенное значение:

if ($submitted_value !== $my_internal_value) { //выполнить код

}

Использование структур управляющей логики (как самих по себе, так и вместе с циклами) открывает разработчику множество возможностей заставить программу

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]