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

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

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

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

В сценарии нет ничего сложного. Когда страница cookies.php вызывается поль+

зователем впервые, как cookie+переменные, так и переменные формы пусты. Если вы+ брать какие+либо параметры в списках и нажать кнопку Получить cookie, то перемен+

ным формы будут присвоены значения, которые тут же будут выведены на экран.

Это говорит о том, что переменные формы type_sel и size_sel получают зна+ чения, соответствующие пользовательскому выбору при первом посещении страни+ цы. Следует отметить, что обе cookie+переменные все равно пусты. Они присутству+ ют, но для того чтобы вывести их, необходимо обновить страницу.

Собственные сеансы в PHP

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

Вчастности, когда возникает необходимость обрабатывать секретные или объем+ ные данные, имеет смысл переслать их однажды и сохранить на сервере, а не хранить на клиентской машине и пересылать каждый раз между клиентом и сервером. Гораздо практичнее хранить данные на сервере, а клиенту выдать ‘‘ключ’’, позволяющий ему уникально идентифицировать себя на этом сервере и, следовательно, использовать любые связанные с этим ключом серверные данные. Такой ключ называется иденти* фикатором сеанса (session identifier); он однозначно связывает клиента с сеансом и, сле+ довательно, с его данными. В PHP идентификатор сеанса называется SID (Session ID)

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

Вэтой главе уже было показано, как установить сеанс, используя cookie для сохранения данных на клиентской машине. Такой метод управления сеансами небезопасен, однако PHP имеет встроенную поддержку управления сеансами, поэтому разбираться в точных деталях реализации нет необходимости. PHP создает SID каждый раз, когда в сценарии вызывается функция session_start(), а также по умолчанию, когда используются не+ которые другие связанные с сеансами функции, такие как session_register(). Зна+ чение SID хранится в глобальной переменной с именем PHPSESSID.

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

Вмомент инициализации PHP+сеанса сервер назначает данному сеансу идентифи+ катор или SID. Любые переменные, зарегистрированные как переменные сеанса (как это делается, будет показано далее), хранятся на сервере в очень похожем на cookie файле. Именем данного файла, как правило, является значение SID. Все, что требует+ ся сделать клиенту, чтобы получить доступ к своей информации на сервере, ++++++ вклю+ чить SID в свой запрос к данному серверу. Для этого можно использовать скрытое по+ ле формы, строку запроса или cookie+файл, если это определено SID в HTTP+запросе.

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

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