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

PHP5_nachinayushim

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

Ответы 693

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

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

Итак, рассмотрим страницы, из которых может состоять приложение.

1.Приветственная страница с формой для ввода предварительной информации и ссылка на страницу ‘‘Поиск работы/Отправка резюме’’.

2.Страница ‘‘Поиск работы/Отправка резюме’’ с формой для ввода информации резюме (разделенной на логические блоки), а также с текстовым полем и кноп+ кой для поиска.

Рассмотрим логику соответствующей PHP+программы.

Отобразить приветственную страницу.

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

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

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

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

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

Наконец, если пользователь успешно ввел резюме и претендует на определен+ ную работу, то приложение отображает страницу с благодарностью.

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

694 Приложение А

Глава 5

Упражнение

Создайте не менее трех регулярных выражений и вставьте их в соответствующие места последнего примера в данной главе. Примерные регулярные выражения:

семи+ и десятизначные номера телефонов в США;

номера социального обеспечения;

буква для обозначения пола пользователя (М ++++++ для мужчин и Ж ++++++ для женщин).

Решение

Существует множество способов проверки телефонных номеров, а библиотека регу+ лярных выражений содержит несколько примеров поиска телефонных номеров США. Простейший способ ++++++ поиск в строке только 7 или 10 цифр, исключая алфавитные символы. Регулярное выражение начинается с символа ^, за которым следует один символ в диапазоне от 2 до 9, два символа от 0 до 9, дефис, а затем один символ от 2 до 9, два сим+ вола от 0 до 9, дефис и, наконец, четыре символа от 0 до 9. Это выражение совпадает с те+ лефонным номером, состоящим из 10 цифр и дефисов между сегментами. Можно исполь+ зовать символ ‘‘или’’ (|) и повторить две вторые части первого образца так, чтобы выражение также совпадало с телефонными номерами, состоящими из 7 цифр. В конце регулярного выражения ставится знак доллара ($), который соответствует концу строки.

^([2-9][0-9]{2}-[2-9][0-9]{2}-[0-9]{4}|[2-9][0-9]{2}-[0-9]{4})$

Для проверки номеров социального страхования используется три символа в диа+ пазоне от 0 до 9, дефис, два символа от 0 до 9, дефис и четыре символа от 0 до 9. Про+ стейшее выражение имеет вид:

^[0-9]{3}-[0-9]{2}-[0-9]{4}$

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

Для определения буквы пола можно использовать классы символов:

^([М]|[Ж])$

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

Глава 6

Упражнение

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

Ответы 695

Решение

Это решение предполагает использование HTML+тегов в PHP. Начать можно с создания Web+формы: пользователь вводит предопределенное количество имен по+ лей и типов полей, а затем приложение определяет количество переменных, в кото+ рых будут содержаться HTML+теги для этих имен и типов полей. После того как поль+ зователь отправляет форму, на основании веденных им данных генерируется другая форма. Оператор switch..case можно поместить внутри функции, полностью ге+ нерирующей новую форму, и выбирать с его помощью HTML+код для генерации име+ ни поля и типа поля внутри предопределенной HTML+формы.

Также необходимо предусмотреть возможность запрашивать у пользователя допол+ нительную информацию, если выбран выпадающий список (тег <select>), поскольку для работы этих тегов внутри них должны присутствовать также теги <option>.

Ниже приведен пример, демонстрирующий создание функции для формирования HTML+тегов на странице:

//функция для формирования HTML-тегов function createTags($field_name,$field_type)

{

global $option_text01,$option_text02,$option_text03; global $option_value01,$option_value02,$option_value03; switch ($field_type) {

case "text";

$next_field = "<tr><td>$field_name:</td><td><input type='$field_type' name='$field_name'></td></tr>";

break; case "radio";

$next_field = "<tr><td>$field_name:</td><td><input type='$field_type' name='$field_name'></td></tr>";

break;

case "checkbox";

$next_field = "<tr><td>$field_name:</td><td><input type='$field_type' name='$field_name'></td></tr>";

break; case "hidden";

$next_field = "<tr><td>$field_name:</td><td><input type='$field_type' name='$field_name'></td></tr>";

break;

case "textarea";

$next_field = "<tr><td>$field_name:</td><td><textarea cols='40' name='$field_name'></textarea></td></tr>";

break; case "select";

$next_field = "<tr><td>$field_name:</td><td> <select name='$field_name'>"

."<option value='$option_value01'>$option_text01</option>"

."<option value='$option_value02'>$option_text02</option>"

."<option value='$option_value03'>$option_text03</option>"

."</select></td></tr>";

break;

default;

break;

}

return $next_field;

}

696 Приложение А

Глава 7

Упражнение

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

Решение

Вэтом приложении для поиска каталогов и обработки всех каталогов и подкаталогов

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

//получаем имя искомого каталога

$folder_to_find = "$_POST[folder]"; //устанавливаем каталог по умолчанию

$default_dir = "C:";

//определяем функцию для поиска существующего каталога function find_folder($default_dir,$folder_to_find) {

if (!($dp = opendir($default_dir))) { die("Невозможно открыть $default_dir.");

} else {

while ($file = readdir($dp)) { if ($file == $folder_to_find){

return ($file);

}

}

closedir($dp);

}

}

$folder = find_folder($default_dir,$folder_to_find);

if ($folder != "") {

echo "Найден каталог с именем " . $folder;

} else {

echo "Каталог не найден.";

}

Приведенный выше код ищет заданный каталог внутри каталога по умолчанию, но не ищет в его подкаталогах.

Глава 8

Упражнение

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

Решение

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

Ответы 697

//определяем изменяемый элемент $element_to_change = $_POST[element_to_change]; $change_value = $_POST[change_value];

if ($element_to_change == 0) { $first_xml_string->program[0]->price = $change_value;

} elseif ($element_to_change == 1) { $first_xml_string->program[1]->price = $change_value;

}

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

Глава 11

Упражнение 1

Создайте список подходящих дескрипторов для каждого столбца в таблице.

Совет: помните о том, что ресторанам ежедневно приходится иметь дело с множеством отдельных заказов (счетов):

Имя

Иденти-

Иденти-

Ресторан Пароль Фамилия Всего

E-mail

фикатор

фикатор

 

заказа

пользователя

 

 

 

($)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

David

2

1

Nandos

12345

Mercer

21.45

davidm@

 

 

 

 

 

 

 

contechst.com

David

4

1

Mimos

12345

Mercer

20.95

davidm@

 

 

 

 

 

 

 

contechst.com

Nic

3

2

St Elmos

23212

Malan

15.45

therot@

 

 

 

 

 

 

 

doggiestouch.co.za

Brian

5

4

Spur

32123

Reid

22.00

pads@

 

 

 

 

 

 

 

doggiestouch.co.za

Darren

1

3

Home

43212

Ebbs

11.85

Bacardi@

 

 

 

 

 

 

 

doggiestouch.co.za

 

 

 

 

 

 

 

 

Решение

Ниже приведен список подходящих дескрипторов полей:

VARCHAR(30)

MEDIUMINT(7)

MEDIUMINT(7)

VARCHAR(30)

VARCHAR(20)

VARCHAR(50)

FLOAT(7)

VARCHAR(60)

Упражнение 2

Администратор сайта решил создать страницу, на которой пользователи смогут просматривать свои предыдущие заказы и итоговые суммы. Используя принципы

698 Приложение А

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

Решение

Ниже показана структура таблицы Customer.

User_ID

Firstname

Lastname

Password

Email

 

 

 

 

 

1

David

Mercer

12345

davidm@contechst.com

2

Nic

Malan

23212

therot@doggiestouch.co.za

3

Darren

Ebbs

43212

Bacardi@doggiestouch.co.za

4

Brian

Reid

32123

pads@doggiestouch.co.za

 

 

Далее показана структура таблицы Orders.

 

Order_ID

User_ID

Restaurant

TotalPrice

 

 

 

 

1

3

Home

11.85

2

1

Nandos

21.45

3

2

St Elmos

15.45

4

1

Mimos

20.95

5

4

Spur

22.00

 

 

 

 

Упражнение 3

Создайте данные таблицы с помощью SQL+операторов.

Решение

Следующий SQL+оператор создает в базе данных таблицу Customer:

CREATE TABLE Customer (

User_ID MEDIUMINT(7) NOT NULL AUTO_INCREMENT, Firstname VARCHAR(30) BINARY NOT NULL, Lastname VARCHAR(50) BINARY NOT NULL, Password VARCHAR(20) BINARY NOT NULL,

Email VARCHAR(60), PRIMARY KEY (User_ID), UNIQUE (Email)

);

SQL+оператор для создания таблицы Orders в базе данных:

CREATE TABLE Orders (

Order_ID MEDIUMINT (7) NOT NULL AUTO_INCREMENT, User_ID MEDIUMINT (7) NOT NULL,

Resturaunt VARCHAR (30) NOT NULL,

Total_Price FLOAT (7) NOT NULL, PRIMARY KEY (Order_ID)

);

Ответы 699

Упражнение 4

После полугодового использования Web+сайта клиенты отметили, что сайт начи+ нает работать медленнее, когда они пытаются просмотреть свои предыдущие заказы. Администратор сайта изучил таблицу заказов и выяснил, что в ней теперь хранится несколько тысяч записей. Почему сайт работает медленно и как администратор мо+ жет повысить скорость работы сайта? Обновите таблицы соответствующим образом.

Решение

Сайт работает медленно, поскольку в таблице Orders содержится большое коли+ чество записей. Поиск производится по полю User_ID, так как с помощью значений можно определить, какие записи следует возвращать пользователю. Чтобы предот+ вратить полное сканирование таблицы при поиске записей, следует добавить индекс по полю User_ID. (Следует, однако, учитывать, что хотя это повышает скорость вы+ полнения операторов SELECT, скорость операторов INSERT и UPDATE уменьшается. В данном случае это, вероятно, имеет смысл, поскольку позволяет ускорить работу сайта со стороны клиентов.) Повысить скорость можно с помощью следующего запроса:

ALTER TABLE Orders ADD INDEX (User_ID);

Упражнение 5

Директор решил узнать, насколько популярен среди клиентов ресторан ‘‘Nandos’’. Какой запрос можно использовать, чтобы получить общие суммы по всем заказам: а) сделанным одним клиентом и б) в целом по ресторану ‘‘Nandos’’.

Совет: попытайтесь использовать запрос SELECT SUM(столбец).

Решение

(a):

SELECT SUM(Total_price) FROM Orders WHERE User_ID = 1;

(б):

SELECT SUM(Total_price) FROM Orders WHERE Restaurant = 'Nandos';

Упражнение 6

Создайте сценарий, с помощью которого пользователи во время регистрации на сайте смогут вводить в базу данных информацию о себе. База данных должна быть на+ строена так, чтобы идентификаторы пользователей назначались автоматически. Сра+ зу после регистрации пользователь должен иметь возможность разместить заказ в лю+ бом из пяти ресторанов. (Для начала только в одном. Беспокоиться о создании завершенного интерфейса не следует ++++++ важна возможность вводить цену.) После на+ жатия на кнопку Заказать в таблице заказов должна создаваться новая запись с уве+ личенным на 1 идентификатором заказа (Order_ID) и корректным идентификатором пользователя (User_ID). Совет: желательно использовать сеансы для хранения идентифи* каторов пользователей (User_ID) при регистрации.

Решение common_db.inc:

<?php

$dbhost = 'localhost'; $dbusername = 'phpuser';

700 Приложение А

$dbuserpassword = 'phppass'; $default_dbname = 'sample_db'; $max_menu_items = 10; $MYSQL_ERRNO = ''; $MYSQL_ERROR = '';

function db_connect($dbname=") {

global $dbhost, $dbusername, $dbuserpassword, $default_dbname; global $MYSQL_ERRNO, $MYSQL_ERROR;

$link_id = mysql_connect($dbhost, $dbusername, $dbuserpassword); if(!$link_id) {

$MYSQL_ERRNO = 0;

$MYSQL_ERROR = "Не удалось подключиться к узлу $dbhost."; return 0;

}

else if(empty($dbname) && !mysql_select_db($default_dbname)) { $MYSQL_ERRNO = mysql_errno();

$MYSQL_ERROR = mysql_error(); return 0;

}

else if(!empty($dbname) && !mysql_select_db($dbname)) { $MYSQL_ERRNO = mysql_errno();

$MYSQL_ERROR = mysql_error(); return 0;

}

else return $link_id;

}

function sql_error() {

global $MYSQL_ERRNO, $MYSQL_ERROR; if(empty($MYSQL_ERROR)) {

$MYSQL_ERRNO = mysql_errno(); $MYSQL_ERROR = mysql_error();

}

return "$MYSQL_ERRNO: $MYSQL_ERROR";

}

?>

Takeaway.php:

<?php

include_once "./common_db.inc";

function login_form() { global $PHP_SELF;

?>

<HTML>

<HEAD>

<TITLE>Вход в систему</TITLE> </HEAD>

<BODY>

<FORM METHOD="GET" ACTION="<?php echo $PHP_SELF ?>"> <INPUT TYPE="HIDDEN" NAME="action" VALUE="register">

<DIV ALIGN="CENTER"><CENTER>

<H2>Добро пожаловать в компанию "Быстрая доставка"!</H2> <H3>Пожалуйста, зарегистрируйтесь.</H3>

<TABLE BORDER="1" WIDTH="400" CELLPADDING="2"> <TR>

<TH WIDTH="25%" ALIGN="RIGHT" NOWRAP>Имя</TH> <TD WIDTH="82%" NOWRAP>

<INPUT TYPE="Input" NAME="userfirstname" SIZE="30"> </TD>

</TR>

Ответы 701

<TR>

<TH WIDTH="25%" ALIGN="RIGHT" NOWRAP>Фамилия</TH> <TD WIDTH="82%" NOWRAP>

<INPUT TYPE="Input" NAME="userlastname" SIZE="30"> </TD>

</TR>

<TR>

<TH WIDTH="25%" ALIGN="RIGHT" NOWRAP>Пароль</TH> <TD WIDTH="82%" NOWRAP>

<INPUT TYPE="PASSWORD" NAME="userpassword" SIZE="30"> </TD>

</TR>

<TR>

<TH WIDTH="25%" ALIGN="RIGHT" NOWRAP>Email</TH> <TD WIDTH="82%" NOWRAP>

<INPUT TYPE="Input" NAME="useremail" SIZE="30"> </TD>

</TR>

<TR>

<TD WIDTH="100%" COLSPAN="2" ALIGN="CENTER" NOWRAP> <INPUT TYPE="SUBMIT" NAME="Submit">

</TD>

</TR>

</TABLE>

</CENTER></DIV>

</FORM>

</BODY>

</HTML>

<?

}

function register_user() { global $default_dbname;

$PHP_SELF = $_SERVER['PHP_SELF'];

$link_id = db_connect($default_dbname); $query = "INSERT INTO Customer

VALUES(",'$_GET[userfirstname]','$_GET[userlastname]', $_GET[userpassword], '$_GET[useremail]')";

$result = mysql_query($query);

if(!$result) {

Echo "Пожалуйста, перейдите на главную страницу и зарегистрируйтесь.";

?>

<FORM method="GET" action="<?php echo $PHP_SELF ?>"> <INPUT type="submit" value="На главную">

</FORM>

<?php

exit;

}

return $result;

}

function get_userid(){ global $default_dbname;

$link_id = db_connect($default_dbname);

$query = "SELECT User_ID from Customer WHERE Password =

'$_GET[userpassword]'";

$result = mysql_query($query); $result_array = mysql_fetch_row($result); $userid = $result_array[0];

if(!$userid) $userid = ""; return $userid;

}

702 Приложение А

function order_menu(){

$PHP_SELF = $_SERVER['PHP_SELF'];

?>

<HTML> <HEAD><TITLE>Рестораны</TITLE></HEAD>

<BODY>

<DIV ALIGN="CENTER"><CENTER>

<H2>Добро пожаловать в "Nandos", <?php echo $_GET['userfirstname']; ?>!</H2> </CENTER></DIV>

<FORM method="GET" action="<?php echo $PHP_SELF ?>">

<INPUT

TYPE="HIDDEN" NAME="action" VALUE="order">

Крылышки:

$1.50

<INPUT name="Choice1" type="checkbox" value="1.50">

<BR>

 

Гамбургер:

$3.00

<INPUT name="Choice2" type="checkbox" value="3.00">

<BR>

Безалкогольный напиток: $0.75

<INPUT name="Choice3" type="checkbox" value="0.75"> <BR>

<BR>

<INPUT type="submit" value="Заказать"> </FORM>

</BODY>

</HTML>

<?php

}

function place_order(){

global $default_dbname, $max_menu_items; $PHP_SELF = $_SERVER['PHP_SELF']; $link_id = db_connect($default_dbname); $total = 0;

for ($counter = 1; $counter <= 10; $counter ++)

{

$a = "Choice" . "$counter"; if (isset($_GET[$a])){ $total += $_GET[$a];

}

}

$query = "INSERT INTO Orders VALUES (", '$_SESSION[userid]', 'Nandos', $total)";

$result = mysql_query($query);

if(!$result) die ("Заказ не принят. Попробуйте еще раз.");

else {

//В реальной системе здесь должен быть выполнен переход на

//страницу подтверждения, простое обновление страницы

//приводит к дублированию заказа.

echo "Ваш заказ принят и будет выполнен в течение часа. Общая стоимость заказа: \$$total";

?>

<FORM method="GET" action="<?php echo $PHP_SELF ?>"> <INPUT type="submit" value="На главную">

</FORM>

<?php

}

}

function customer_session(){ $_SESSION['useremail'] = $_GET['useremail'];

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