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

Использование 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():


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 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, вводимое в поле значение заменяется звездочками, поэтому даже сам пользователь не видит то, что он вводит. Два обязательных для заполнения поля такого типа позволят исключить любые опечатки (далее в коде выполняется проверка на совпадение двух значений).