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

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

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

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

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

Задание описано ++++++ можно приступать к проектированию.

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

Решение

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

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

2.Опыт работы.

3.Образование.

4.Специальная информация о квалификации (ученая степень, сертификаты и т.д.).

5.Дополнительная информация.

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

Есть несколько условий, которые касаются поиска работы и отправки резюме. Пер+ вое условие: люди без высшего образования могут претендовать лишь на работу началь+ ного уровня в отделе продаж или доставки. Надо ли давать им возможность начинать поиск работы, прежде чем они ответят на некоторые отборочные вопросы (зачем по+ казывать этим людям список работ, к которым они не могут быть допущены?).

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

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

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

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

Ответы 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;

}

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