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

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

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

452 Глава 11

Рис. 11.1.

Данная функция возвращает указатель на результирующее множество, в котором перечислены все поля таблицы user. Указатель сохраняется в переменной $result, а затем используется в функции mysql_num_fields() для выяснения количества по+ лей, содержащихся в данной таблице. Полученное значение используется как верх+ ний предел для цикла for...next:

for($i=0; $i < mysql_num_fields($result); $i++ ) {

Затем используется индекс цикла для указания поля и вызываются функции mysql_field_name(), mysql_field_len() и mysql_field_type(), которые воз+ вращают имя, длину и тип доступных полей:

echo mysql_field_name($result,$i );

echo "(" . mysql_field_len($result, $i) . ")";

echo " - " . mysql_field_type($result, $i) . "<BR>";

Некоторые из возвращаемых типов полей неоднозначны, например, CHAR и VARCHAR возвращаются как string, тогда как TEXT возвращается как BLOB. Чтобы по+ лучить точные типы полей (так, как они определены в MySQL+таблице), требуется до+ полнительная работа. Здесь оказывается полезной функция mysql_field_flags(). Код можно легко модифицировать так, чтобы сценарий выводил атрибуты полей. Ниже приведена новая версия данного сценария:

$link_id = db_connect();

$result = mysql_list_fields("sample_db", "user", $link_id);

for($i=0; $i < mysql_num_fields($result); $i++ ) { echo mysql_field_name($result,$i );

echo "(" . mysql_field_len($result, $i) . ")";

echo " - " . mysql_field_type($result, $i);

echo " " . mysql_field_flags($result, $i) . "<BR>";

}

Использование PHP для управления информацией в базах данных MySQL 453

Примерный результат работы сценария показан на рис. 11.2.

Рис. 11.2.

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

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

Свойство

Описание

 

 

blob

Равно True, если поле имеет тип BLOB

max_length

Максимальная длина поля

multiple_key

Равно True, если поле является ключом, но не уникально

name

Имя поля

not_null

Равно True, если значением поля не может быть NULL

numeric

Равно True, если поле является числовым

primary_key

Равно True, если поле является первичным ключом

table

Имя таблицы, которой принадлежит данное поле

type

Тип поля

unique_key

Равно True, если поле является уникальным ключом

unsigned

Равно True для беззнакового поля

def

Значение по умолчанию, если оно задано

zerofill

Равно True, если поле заполняется нулями. Этот атрибут используется

 

для того, чтобы сохранять число определенной длины, заполняя поле

 

ведущими нулями

454 Глава 11

Практика Использование функции mysql_fetch_field()

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

<?php

include "./common_db.inc"; $link_id = db_connect();

$result = mysql_list_fields("sample_db", "user", $link_id);

for($i=0; $i < mysql_num_fields($result); $i++ ) {

$field_info_object = mysql_fetch_field($result, $i);

echo $field_info_object->name . "(" . $field_info_object->max_length . ")";

echo " - " . $field_info_object->type;

if($field_info_object->def) {

echo "<br><b>Значение по умолчанию: $field_info_object->def</b> ";

}

if($field_info_object->not_null) { echo " not_null ";

} else {

echo " null ";

}

if($field_info_object->primary_key) { echo " primary_key ";

}else if ($field_info_object->multiple_key) { echo " key ";

}else if ($field_info_object->unique_key) { echo " unique ";

}

if($field_info_object->unsigned) { echo " unsigned ";

}

if($field_info_object->zerofill) { echo " zero-filled ";

}

echo "<BR>";

}

?>

Результат работы данного сценария показан на рис. 11.3.

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

Этот сценарий работает почти так же, как предыдущий, однако длина каждого по+ ля равна 0, что, естественно, неверно. К сожалению, несмотря на то, что функция mysql_fetch_field() ++++++ весьма универсальный инструмент, ее реализация имеет небольшой дефект, который приводит к тому, что свойство max_length всегда равно 0 независимо от фактической длины поля. На момент написания данной книги по+ следней версией PHP5 была версия RC1. Есть надежда, что в следующей версии эта ошибка будет устранена. А пока вернемся к функции mysql_field_len():

Использование PHP для управления информацией в базах данных MySQL 455

Рис. 11.3.

$field_info_object = mysql_fetch_field($result, $i);

echo $field_info_object->name . "(" . mysql_field_len($result, $i) . ")";

echo " - " . $field_info_object->type;

Теперь сценарий возвращает корректный размер каждого поля (рис. 11.4).

Рис. 11.4.

456 Глава 11

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

Параметры ENUM и стандартные значения полей

Тип поля ENUM уже упоминался в предыдущей главе, когда в таблицу пользователей бы+ ло включено поле sex. Это поле может принимать одно из двух значений: M или F. В каче+ стве еще одного хорошего примера рассмотрим модификацию поля userposition. Ограничим возможные значения данного поля предопределенным набором.

Первоначально для поля userposition был выбран тип VARCHAR(50) NOT NULL. Предположим, что все будущие игроки будут занимать одну из четырех позиций, ко+ торые уже введены в поле, и переопределим поле userposition с учетом этого предположения:

mysql> ALTER TABLE user MODIFY userposition

-> ENUM('Mid','Link', 'Winger','Utility Back') DEFAULT 'Utility Back'; Query OK, 6 rows affected (0.01 sec)

Records: 0 Duplicates: 0 Warnings: 0

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

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

if($field_info_object->def) echo "<br><b>Значение по умолчанию: $field_info_object->def</b> ";

Примерный результат работы сценария показан на рис. 11.5.

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

mysql> SHOW COLUMNS FROM user LIKE 'userposition';

результат которого представлен ниже:

+--------------

 

+--------------------------

+------

+-----

+-------------

+-------

+

| Field

| Type

| Null

| Key | Default

|

Extra|

+--------------

 

+--------------------------

+------

+—----+---------———-+----——-+

| userposition

| enum('Mid','Link',

|

|

|

|

|

|

 

| 'Winger','Utility Back') | YES

|

| Utility Back|

|

+--------------

 

+----------------————————--+—----—+--—--+--------————-+----——-+

1

row in set (0.02 sec)

 

 

 

 

 

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

Использование PHP для управления информацией в базах данных MySQL 457

Рис. 11.5.

Практика Получение ENUM-значений

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

<?php

include "./common_db.inc"; $link_id = db_connect(); mysql_select_db("sample_db");

$query = "SHOW COLUMNS FROM user LIKE 'userposition'"; $result = mysql_query($query);

$query_data = mysql_fetch_array($result);

if(eregi("('.*')", $query_data["Type"], $match)) { $enum_str = ereg_replace("'", "", $match[1]); $enum_options = explode(',', $enum_str);

}

echo "ENUM-варианты и значение по умолчанию:<BR>"; foreach($enum_options as $value) {

echo "-$value<BR>";

}

echo "<BR>Значение по умолчанию: <b>$query_data[Default]</b>"; echo "<P>";

?>

Результат работы данного сценария показан на рис. 11.6.

458 Глава 11

Рис. 11.6.

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

Сценарий начинается с ввода SQL+запроса, который находит запись, содержащую определение поля userposition. Данные извлекаются в форме ассоциативного мас+ сива $query_data:

$query = "SHOW COLUMNS FROM user LIKE 'userposition'"; $result = mysql_query($query);

$query_data = mysql_fetch_array($result);

Теперь к значениям Type и Default в определении поля можно получить доступ как к элементам массива $query_data[‘Type’] и $query_data[‘Default’] соот+ ветственно. В первом из них должна содержаться следующая строка:

enum('Mid','Link','Winger','Utility Back')

Чтобы извлечь значения, необходимо избавиться от предшествующей строки enum, скобок и кавычек. Сначала для поиска строки, заключенной в скобки, использу+ ется функция eregi() с регулярным выражением (‘.*’):

eregi("('.*')", $query_data["Type"], $match)

Третий аргумент данной функции представляет собой массив, который содержит все совпадения с заданным образцом, а второй элемент массива, $match[1], содер+ жит искомую строку:

'Mid','Link','Winger','Utility Back'

Теперь с помощью функции eregi_replace() следует избавиться от одинарных кавычек и записать модифицированную строку в переменную $enum_str:

$enum_str = eregi_replace("'", "", $match[1]);

которая в результате должна выглядеть так:

Mid, Link, Winger, Utility Back

Использование PHP для управления информацией в базах данных MySQL 459

После чего переменная $enum_str передается функции explode(), которая по+ мещает разделенные запятыми значения в массив $enum_options:

$enum_options = explode(',', $enum_str);

Врезультате этот массив содержит все доступные варианты выбора из ENUM+поля

ввиде отдельных элементов.

Остальная часть кода просматривает в цикле элементы массива $enum_options и выводит их. После того как выведены все enum+значения, жирным шрифтом выво+ дится значение данного поля по умолчанию:

echo "ENUM-варианты и значение по умолчанию:<BR>"; foreach($enum_options as $value) {

echo "-$value<BR>";

}

echo "<BR>Значение по умолчанию: <b>$query_data[Default]</b>"; echo "<P>";

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

function enum_options($field, $link_id)

{

$query = "SHOW COLUMNS FROM user LIKE '$field'"; $result = mysql_query($query, $link_id); $query_data = mysql_fetch_array($result); if(eregi("('.*')", $query_data["Type"], $match)) {

$enum_str = ereg_replace("'", "", $match[1]); $enum_options = explode(',', $enum_str); return $enum_options;

}else{ return 0;

}

}

Протестировать данную функцию можно с помощью следующего сценария (назовем его test_enum.php):

<?php

include_once "./common_db.inc"; $link_id = db_connect(); mysql_select_db("sample_db");

$array = enum_options('userposition', $link_id); foreach($array as $var){

echo $var,"<BR>";

}

?>

Создание сценария для регистрации пользователей

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

460Глава 11

1.Отображается страница с ‘‘Условиями использования’’: посетитель сайта дол+ жен принять данные условия, если хочет стать зарегистрированным пользова+ телем.

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

у пользователя необходимую информацию.

3.Создается учетная запись пользователя: в таблице user создается новая запись и в нее вставляется соответствующая информация.

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

5.По электронной почте отправляется запрос на подтверждение пользователь+ ского e+mail+адреса (пользователь вводит свой адрес во время регистрации).

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

Сценарий register.php

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

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

Ниже приводится исходный код сценария регистрации пользователей register.php с пояснениями. Сначала подключается файл common_db.inc:

<?php

//register.php

include_once "./common_db.inc";

Функция in_use()

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

function in_use($userid)

{

global $user_tablename;

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

if(!mysql_num_rows($result)){ return 0;

}else{ return 1;

}

}

Использование PHP для управления информацией в базах данных MySQL 461

Функция register_form()

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

function register_form()

{

global $userposition; global $PHP_SELF;

$link_id = db_connect(); mysql_select_db("sample_db");

$position_array = enum_options('userposition', $link_id); mysql_close($link_id);

?>

Теперь массив $position_array содержит все позиции, из которых пользова+ тель может выбирать. Затем создается HTML+таблица, которая послужит в качестве пользовательского интерфейса. Обратите внимание, что в представленном примере для передачи данных используется метод POST:

<center><H3>Создание учетной записи!</H3></center> <form method="post" action="<?php echo $PHP_SELF ?>"> <input type="hidden" name="action" value="register">

<div align="center"><center><table border="1" width="90%">

<tr>

<th width="30%" nowrap>Идентификатор</th>

<td width="70%"><input type="text" name="userid" size="8" maxlength="8"></td>

</tr>

<tr>

<th width="30%" nowrap>Пароль</th> <td WIDTH="70%"><input type="password"

name="userpassword" size="15"></td>

</tr>

<tr>

<th width="30%" nowrap>Повторите пароль</th> <td width="70%"><input type="password"

name="userpassword2" size="15"></td>

</tr>

<tr>

<th width="30%" nowrap>Полное имя</th>

<td width="70%"><input type="text" name="username" size="20"></td> </tr>

<tr>

<th width="30%" nowrap>Позиция</th>

<td width="70%"><select name="userposition" size="1">

<?php

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

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