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

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

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

432 Глава 10

Для создания сценария просмотра базы данных потребуется два отдельных файла. Глобальные переменные и часто используемые функции помещаются в подключае+ мый файл common_db.inc, а бизнес+логика реализована в файле userviewer.php. Предполагается, что существует база данных sample_db, которая содержит таблицы user и access_log, причем в обеих таблицах имеются соответствующие данные.

Содержимое файла common_db.inc

В последующих разделах рассматривается каждый блок кода в файле common_db.inc.

Для краткости код функций db_connect() и sql_error() здесь не описывается. Они ничем не отличаются от одноименных функций, описанных в предыдущей главе.

Глобальные переменные

В данном сценарии придется использовать несколько переменных. Их объявления можно поместить в файл common_db.inc и обращаться к ним из сценария userviewer как к глобальным переменным (некоторые переменные, возможно, следует изменить, чтобы отразить параметры конкретной системы):

<?php

$dbhost = 'localhost'; $dbusername = 'phpuser'; $dbuserpassword = 'phppass'; $default_dbname = 'sample_db';

Определим количество записей отображаемых на странице по умолчанию (5):

$records_per_page = 5;

Укажем имена таблиц (user и access_log):

$user_tablename = 'user'; $access_log_tablename = 'access_log';

Определим переменные для хранения номера и описания ошибки:

$MYSQL_ERRNO = "; $MYSQL_ERROR = ";

Зададим размер нового окна браузера:

$new_win_width = 600; $new_win_height = 400;

Функция html_header()

Код функции html_header() представляет собой начало HTML+страницы и оп+ ределение JavaScript+функции open_window(), которую можно вызывать для откры+ тия нового окна при отображении подробной информации о пользователе:

function html_header() {

global $new_win_width, $new_win_height; ?>

<HTML>

<HEAD>

<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript"> <!--

Получение данных от MySQL с помощью PHP 433

function open_window(url) { var NEW_WIN = null;

NEW_WIN = window.open ("", "RecordViewer", "toolbar=no,width="+

<?php echo $new_win_width ?>+ ",height="+<?php echo $new_win_height?>+ ",directories=no,status=no"+ ",scrollbars=yes,resize=no,menubar=no");

NEW_WIN.location.href = url;

}

//-->

</SCRIPT>

<TITLE>Сценарий просмотра базы данных</TITLE> </HEAD>

<BODY>

<?php

}

Функция html_footer()

Функция html_footer() завершает создание HTML+страницы (работа функций db_connect() и sql_error() уже рассматривалась):

function html_footer() { ?>

</BODY>

</HTML>

<?php

}

function db_connect($dbname=") {

...

}

function sql_error() {

...

}

Функция error_message()

Функция error_message() сообщает пользователю о возникновении ошибки, используя для этого JavaScript+метод alert():

function error_message($msg) { html_header();

echo "<SCRIPT>alert(\"Error: $msg\ ");history.go(-1)</SCRIPT>"; html_footer();

exit;

}

?>

Теперь рассмотрим рабочую часть приложения.

Содержимое файла userviewer.php

Сценарий userviewer.php использует подключаемый файл common_db.inc. В данном случае этот файл подключается из текущего каталога:

<?php

include "./common_db.inc";

434 Глава 10

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

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

Функция list_records()

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

function list_records()

{

global $default_dbname, $user_tablename; global $records_per_page;

$PHP_SELF = "userviewer.php";

$link_id = db_connect($default_dbname); if(!$link_id) error_message(sql_error());

$query = "SELECT count(*) FROM $user_tablename"; $result = mysql_query($query);

if(!$result) error_message(sql_error()); $query_data = mysql_fetch_row($result);

$total_num_user = $query_data[0];

if(!$total_num_user) error_message('Нет зарегистрированных пользователей!');

Глобальная переменная $cur_page, номер текущей страницы, содержит ключ для навигации по списку. Если данные списка занимают больше одной страницы, то они разделяются на несколько страниц. Размер страницы определяется глобальной пере+ менной $records_per_page. Общее количество страниц вычисляется как результат деления общего числа пользователей ($total_num_user) на длину страницы ($records_per_page) и округляется до ближайшего большего целого значения с помощью функции ceil().

Номер страницы перед его выводом в браузер необходимо увеличить на единицу, так как в глобальной переменной $cur_page первым номером будет 0, а нумерация страниц в браузере должна начинаться с 1. Переменная $record определена как верхняя граница для предложения LIMIT, которое используется в SQL+запросе. Пе+ ременная $cur_page инициализируется со значением, которое отправляется, как только пользователь щелкнет на навигационной ссылке. Если значения нет, то пере+ менной присваивается 0:

if(empty($_GET['next_page'])) { $_GET['next_page'] = 0;

}

$cur_page = $_GET['next_page']; $page_num = $cur_page + 1;

$record = $cur_page * $records_per_page + 5;

$total_num_page = $last_page_num = ceil($total_num_user/$records_per_page);

html_header();

Получение данных от MySQL с помощью PHP 435

echo "<CENTER><H3>В базе найдено $total_num_user пользователей. Страница $page_num из $last_page_num.</H3></CENTER>\n";

Теперь следует создать SQL+запрос, который будет извлекать данные из базы и ор+ ганизовывать их так, как это необходимо. Способ формирования запроса на самом деле зависит от ссылки, по которой щелкает пользователь. Возникает вопрос: как сформировать SQL+запрос динамически?

Для этого следует воспользоваться специальным PHP+массивом $_GET. Если инфор+ мация для данного запроса отправляется в URL, то ее можно получить и использовать. Необходимо помнить, что при первом посещении страницы никаких значений в масси+ ве $_GET не будет, поэтому первое, что необходимо сделать, ++++++ это присвоить всем пе+ ременным значения по умолчанию. Значение по умолчанию для сортировки (предложения ORDER BY в запросе) следует установить равным userid, по умолчанию порядок сортировки по возрастанию, а номер страницы по умолчанию равным 1 (напомним, что это влечет за собой присвоение переменной $cur_page значения 0).

Посетитель страницы может выбрать порядок сортировки, щелкнув на имени поля в заголовке таблицы с перечнем записей. Эта функция основана на изменении значения порядка сортировки (переменная $sort_order) до вывода этого значения в HTML+ ссылку. Обратимся еще раз к рис. 10.1. Ниже таблицы располагаются ссылки Следующая и В конец (а также В начало и Предыдущая). Эти ссылки не изменяют порядок сорти+ ровки списка, они просто позволяют перемещаться по таблице, поэтому для них следует создать отдельную переменную порядка сортировки ($org_sort_order):

if (empty($_GET['order_by'])){ $_GET['order_by'] = 'userid';

} $order_by = $_GET['order_by'];

if (empty($_GET['sort_order'])) { $_GET['sort_order'] = 'ASC'; $sort_order = 'ASC';

}

if ($_GET['sort_order'] == 'ASC') { $sort_order = 'DESC'; $org_sort_order = 'ASC';

}

else {

$sort_order = 'ASC'; $org_sort_order = 'DESC';

}

Затем необходимо создать и сохранить в переменной $limit_str предложение

LIMIT, используя переменные $cur_page, $records_per_page и $record.

$limit_str = "LIMIT ". $cur_page * $records_per_page . ", $record";

Окончательный запрос формируется путем передачи значений, полученных из $_GET+массива, в только что созданную переменную $limit_str:

$query = "SELECT usernumber, userid, username FROM $user_tablename ORDER BY $_GET[order_by] $_GET[sort_order] $limit_str ";

$result = mysql_query($query);

if(!$result){

error_message(sql_error());

 

}

 

?>

436 Глава 10

Теперь следует создать HTML+таблицу для вывода списка:

<DIV ALIGN="CENTER">

<TABLE BORDER="1" WIDTH="90%" CELLPADDING="2">

<TR>

<TH WIDTH="25%" NOWRAP>

<A HREF="<?php echo "$PHP_SELF?action=list_records& sort_order=$sort_order&

order_by=usernumber"; ?>">

Номер пользователя

</A>

</TH>

<TH WIDTH="25%" NOWRAP>

<A HREF="<?php echo "$PHP_SELF?action=list_records& sort_order=$sort_order&

order_by=userid"; ?>">

Идентификатор пользователя

</A>

</TH>

<TH WIDTH="25%" NOWRAP>

<A HREF="<?php echo "$PHP_SELF?action=list_records& sort_order=$sort_order&

order_by=username"; ?>">

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

</A>

</TH>

<TH WIDTH="25%" NOWRAP>Действие</TH> </TR>

<?php

Ссылки в заголовках таблицы являются неотъемлемой частью данной программы. Каждая ссылка указывает на страницу userviewer ($PHP_SELF) и передает значения, которые записываются в массив $_GET, который в свою очередь будет использоваться в сценарии при следующем запуске, т.е. когда пользователь щелкнет на ссылке. Обратите внимание, что значением параметра action в URL является строка list_records. Это важно, потому что в конце программы используется оператор switch, позволяющий определить, какая функция из файла userviewer будет использоваться.

Затем результирующее множество обрабатывается с помощью цикла while, в резуль+ тате чего формируются строки HTML+таблицы. Стоит отметить, что последняя строка со+ держит вызов JavaScript+функции open_window, определенной в файле common_db.inc. Кроме того, параметру action присваивается значение view_record. Это означает, что вместо функции list_records() будет вызвана функция view_record(), кото+ рая описывается в следующем разделе. Пример кода:

while($query_data = mysql_fetch_array($result)) { $usernumber = $query_data["usernumber"]; $userid = $query_data["userid"];

$username = $query_data["username"]; echo "<TR>\n";

echo "<TD WIDTH=\"25%\" ALIGN=\"CENTER\">$usernumber</TD>\n"; echo "<TD WIDTH=\"25%\" ALIGN=\"CENTER\">$userid</TD>\n"; echo "<TD WIDTH=\"25%\" ALIGN=\"CENTER\">$username</TD>\n"; echo "<TD WIDTH=\"25%\" ALIGN=\"CENTER\">

<A HREF=\"javascript:open_window('$PHP_SELF?action=view_record& userid=$userid');\">Просмотреть запись</A></TD>\n";

echo "</TR>\n";

Получение данных от MySQL с помощью PHP 437

}

?>

</TABLE>

</DIV>

<?php

echo "<BR>\n";

echo "<STRONG><CENTER>";

Наконец, нужно создать навигационные ссылки на основе номера текущей стра+ ницы и общего количества страниц. Поскольку значения переменной $cur_page на+ чинаются с нуля, для хранения номера текущей страницы используется другая пере+ менная ++++++ $page_num. Если номер текущей страницы больше 1, то необходимо вывести ссылки В начало и Предыдущая, которые позволят пользователю перехо+ дить к первой и предыдущей странице соответственно:

if($page_num > 1) {

$prev_page = $cur_page - 1;

echo "<A HREF=\"$PHP_SELF?action=list_records& ort_order=$org_sort_order&order_by=$order_by&next_page=0\">[В начало]

</A>";

echo "<A HREF=\"$PHP_SELF?action=list_records&sort_order=$org_sort_order &order_by=$order_by&next_page=$prev_page\">[Предыдущая]</A> ";

}

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

if($page_num < $total_num_page) { $next_page = $cur_page + 1; $last_page = $total_num_page - 1;

echo "<A HREF=\"$PHP_SELF?action=list_records&sort_order=$org_sort_order &order_by=$order_by&next_page=$next_page\">[Следующая]</A> ";

echo "<A HREF=\"$PHP_SELF?action=list_records&sort_order=$org_sort_order& order_by=$order_by&next_page=$last_page\">[В конец]</A>";

}

echo "</STRONG></CENTER>";

Определение функции list_records() завершается вызовом функции html_footer(), которая определена в файле common_db.inc:

html_footer();

}

Теперь сценарий можно запустить, не используя ссылок Просмотреть запись с правой стороны таблицы. Чтобы эти ссылки работали, необходимо создать функ+ цию view_record().

Функция view_record()

Функция view_record() отображает подробную информацию об определенном пользователе и данные из его журнала посещений.

Когда посетитель нажимает на ссылку Просмотреть запись, информация о вы+ бранном пользователе отображается в новом окне Web+браузера, которое открывает+ ся с помощью JavaScript+функции open_window(). Эта функция в свою очередь вызывает

438 Глава 10

сценарий со значением переменной $action, приводящим к выполнению функции view_record().

Сначала из таблицы user выбирается вся информация об указанном пользователе, а также все записи из журнала посещений (из таблицы access_log) этого пользователя. Если пользователь не посещал протоколируемых Web+страниц, то отображается соответ+ ствующее предупреждение и сценарий завершает работу. В данном случае нет необходи+ мости проверять массив $_GET, так как функция view_record() вызывается только со страницы userviewer; иными словами, просмотреть страницу записей, не щелкнув предварительно на ссылке, которая устанавливает $_GET+переменные, невозможно:

function view_record() {

global $default_dbname, $user_tablename, $access_log_tablename; $PHP_SELF = $_SERVER['PHP_SELF'];

$userid = $_GET['userid'];

if(empty($userid)){ error_message('Выберите пользователя!');

}

$link_id = db_connect($default_dbname);

if(!$link_id){ error_message(sql_error());

}

$query = "SELECT * FROM $user_tablename WHERE userid = '$userid'"; $result = mysql_query($query);

if(!$result){ error_message(sql_error());

}

$query_data = mysql_fetch_array($result); $usernumber = $query_data["usernumber"]; $userid = $query_data["userid"]; $username = $query_data["username"];

$userposition = $query_data["userposition"]; $useremail = $query_data["useremail"]; $userprofile = $query_data["userprofile"];

Затем отображается информация, относящаяся к выбранному пользователю:

html_header();

echo "<CENTER><H3>

Запись для пользователя №.$usernumber - $userid($username) </H3></CENTER>";

?>

<DIV ALIGN="CENTER">

<TABLE BORDER="1" WIDTH="90%" CELLPADDING="2"> <TR>

<TH WIDTH="40%">position</TH>

<TD WIDTH="60%"><?php echo $userposition ?></TD> </TR>

<TR>

<TH WIDTH="40%">Email</TH> <TD WIDTH="60%"><?php echo "<A

HREF=\"mailto:$useremail\">$useremail</A>" ; ?></TD>

</TR>

<TR>

Получение данных от MySQL с помощью PHP 439

<TH WIDTH="40%">Профиль</TH>

<TD WIDTH="60%"><?php echo $userprofile ?></TD> </TR>

</TABLE>

</DIV>

<?php

echo "<HR SIZE=\"2\" WIDTH=\"90%\">\n";

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

$query = "SELECT page, visitcount, accessdate FROM $access_log_tablename WHERE userid = '$userid'";

$result = mysql_query($query); if(!$result){

error_message(sql_error());

}

Функция mysql_num_rows() возвращает 0, если в таблице access_log нет запи+ сей, содержащих информации о страницах, посещенных этим пользователем:

if(!mysql_num_rows($result)){

echo "<CENTER>Для пользователя $userid ($username) нет записей в журнале посещений.</CENTER>";

} else {

echo "<CENTER>Записи журнала посещений для пользователя $userid ($username).</CENTER>";

?>

<DIV ALIGN="CENTER">

<TABLE BORDER="1" WIDTH="90%" CELLPADDING="2">

<TR>

<TH WIDTH="40%" NOWRAP>Web-страница</TH>

 

<TH WIDTH="20%" NOWRAP>Количество посещений</TH>

 

<TH WIDTH="40%" NOWRAP>Время последнего посещения</TH>

</TR>

<?php

while($query_data = mysql_fetch_array($result)) {

 

$page = $query_data["page"];

 

$visitcount = $query_data["visitcount"];

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

$accessdate = substr($query_data["accessdate"], 0, 4) . '-' . substr($query_data["accessdate"], 4, 2) . '-' . substr($query_data["accessdate"], 6, 2) . ' ' .

substr($query_data["accessdate"], 8, 2) . ':' . substr($query_data["accessdate"], 10, 2) . ':' . substr($query_data["accessdate"], 12, 2);

echo "<TR>\n";

echo "<TD WIDTH=\"40%\">$page</TD>\n";

echo "<TD WIDTH=\"20%\" ALIGN=\"CENTER\">$visitcount</TD>\n"; echo "<TD WIDTH=\"40%\" ALIGN=\"CENTER\">$accessdate</TD>\n"; echo "</TR>\n";

}

?>

</TR>

</TABLE>

440 Глава 10

</DIV>

<?php

}

html_footer();

}

Выбор действия

В конце файла userview.php расположен блок кода, который выполняется пер+ воначально при запуске сценария. В зависимости от значения переменной $action программа вызывает одну из главных функций, которые были определены выше. Та+ ким образом, в одном сценарии создается двойная функциональность. Конечно, не+ обходимо настроить поведение по умолчанию на случай первого посещения данной страницы. Для этого проверяется элемент action массива $_GET, и если он не уста+ новлен, то ему присваивается значение по умолчанию ++++++ list_records:

if (empty($_GET['action'])){ $_GET['action'] = 'list_records';

}

switch($_GET['action']) { case "view_record": view_record();

break;

default: list_records(); break;

}

Это все. Запустите Web+браузер и вызовите в нем страницу userviewer.php.

Использование сценария

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

Следует отметить URL в обоих окнах ++++++ в верхнем окне URL указывает на то, что данные отсортированы по имени пользователя, а в нижнем окне показаны подробные сведения о пользователе Brian Reid, идентификатор которого (значение поля userid) равен Pads.

Резюме

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

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

LIMIT ++++++ предложение для ограничения количества возвращаемых результатов;

WHERE ++++++ предложение, определяющее критерии отбора данных;

Получение данных от MySQL с помощью PHP 441

Рис. 10.2.

ORDER BY ++++++ предложение для упорядочения возвращаемых результатов;

GROUP BY ++++++ предложение для группировки возвращаемых результатов.

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

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

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

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