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

metoda / Ml_ITIn_2013

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

261

Задание 3. Внесение новой информации в базу данных. Проверка и фильтрация данных, исходящих от администратора

Внесение новой информации очень похоже на получение существующей. Нужно пройти те же шаги — установить соединение, отправить запрос и проверить результаты. Только в данном случае вместо SELECT будет использоваться INSERT.

На рис. 3.278 показана HTML форма для помещения новых книг в базу BOOKS. HTML-код этой страницы приведен на рис. 3.279 и продублирован в файле http://localhost/php/lab15_04.php.

Рис. 3.278. Интерфейс для добавления новых книг.

Результаты заполнения этой формы передаются в Lab15_05.php, а сценарий, занимающийся деталями, выполняет определенную аутентификацию и пытается записать данные в базу данных.

Листинг Lab15_04.php – HTML код страницы ввода информации о новых книгах.

<html><head>

<meta http-equiv="Content-Type" content="text/html; charset=windows-1251"/> <title>Lab15_04 Форма ввода новой книги</title>

</head><body>

<h1>Форма ввода новой книги</h1><!--Заголовок HTML-->

<!--Обработка вводимой информации производится в файле Lab15_05.php --> <form action="Lab15_05.php" method="post">

<table border="0"> <tr>

<td>ISBN</td>

<td><input type="text" name="isbn" maxlength="13" size="13"></td> </tr>

262

<tr>

<td>Автор</td>

<td> <input type="text" name="author" maxlength="30" size="30"></td> </tr>

<tr> <td>Название</td>

<td> <input type="text" name="title" maxlength="60" size="30"></td> </tr>

<tr>

<td>Цена, $</td>

<td><input type="text" name="price" maxlength="7" size="7"></td> </tr>

<tr>

<td colspan="2"><input type="submit" value="Зарегистрировать"></td>

</tr>

</table>

</form>

</body></html>

Рис. 3.279. HTML-код страницы добавления новых книг.

Листинг Lab15_05.php — сценарий записи новой книги в базу данных. (для удобства строни кода пронумерованы)

1<html><head>

2<meta http-equiv="Content-Type" content="text/html; charset=windows-1251"

/>

3<title>Lab15_05 Обработчик формы ввода для Lab15_04.php </title>

4<h1>Магазин "Книг"</h1><h2> Результаты ввода</h2>

5<body>

6<?php

7// Проверяем не пустой ли суперглобальный массив $_POST

8if(empty($_POST)) exit("Означьте элементы формы");

9// создание коротких имен переменных

10

$isbn=trim($_POST['isbn']); //Trim - убираем пробелы в

11$author=trim($_POST['author']);//начале и в конце строки.

12$title = trim($_POST['title']);

13$price=trim($_POST['price']);//формат хранения Float(4.2)

14//Означиваем необходимые компоненты для связи с базой

15$Host="localhost"; $User="root"; $DBName="books"; $Password="";

16if (!$isbn || !$author || !$title || !$price):

17echo 'Вы ввели не все необходимые сведения.<br />'

18.'Пожалуйста, вернитесь на предыдущую страницу и повторите ввод.<br>';

19//Внимание! Если $price=0 - то считаем, что цена не означена.

20exit; //выход из программы

21endif;

263

22$lenprice=strlen($price); //длина введенной строки символов в поле цены

22$formatted = sprintf ("%01.2f", $price);

23$tochka=substr($price, $lenprice-1, 1);

24//echo "<br>Введено ".$price." formatted=".$formatted." strlen=

25".strlen($price).",tochka=".$tochka."<br>"; // отладочный оператор

/*Начиная с версии 5.2.0 в PHP присутствуют специальные функции для фильтрации данных. Одна из таких функций - filter_var. Сначала нам необходимо убедиться, что нужные нам функции установлены и доступны. Для этого используются операторы: */

26if (function_exists('filter_list')):

27//echo 'список фильтров установлен!';

28else:

29die('Ошибка: фильтры не найдены. '); // выход из программы

30endif;

31//FILTER_VALIDATE_FLOAT — проверка на число с плавающей точкой

32$valid_float = filter_var($price, FILTER_VALIDATE_FLOAT);

33if ($valid_float !== false):

34// проверка прошла успешно, $price - число

35//echo "проверка Float прошла успешно <br>";

36if (strpos($price, ".")===false): // символ точки в $price не найден

37echo "<br> Точки нет. Введено ".$price." strlen ".strlen($price)."<br>";

38if ($lenprice>2):

39echo "Указаная цена ".$price." превышает формат хранения в базе. В базе

40указан формат хранения Float(4.2). <br>Исправьте ввод данных.";

41exit;

42endif;

43else://точку указали

44echo "<br> Точка есть. Позиция ".strpos($price, ".")." Введено ".$price."

strlen ".strlen($price)."<br>";

45if ($lenprice>5):

46echo "Указаная цена ".$price." превышает формат хранения в базе. В базе

указан формат хранения Float(4.2). <br>Исправьте ввод данных.";

47exit;

48endif;

49if (strpos($price, ".") >2):

50//Точка есть. Например, позиция 3 в введенной Цене 333.5 Длина strlen =5

51//Внимание! Если пропустить в базу пропишется число 99.99

52exit ("Указаная цена ".$price." превышает формат хранения в базе. В базе указан формат хранения Float(4.2). <br>Исправьте ввод данных, иначе в базу запишется 99.99 .");

53endif;

54endif;

55else: // проверка на число не прошла

56echo "В поле Цена указано ".$price." В поле есть недопустимый символ ! <br>Исправьте ввод данных.";

264

57exit;//выход из программы

58endif;

59

60if (preg_match("/^[0-9].+$/",$price)):

61//echo "Ввели число <br>";

62else:

63//echo "Во вводе есть символ <br>";

64endif;

65

66if (substr($price, 0, 1)=="-"):

67echo "В поле Цена не должно быть отрицательного числа! <br> Исправьте ввод данных.";

68exit;//выход из программы

69endif;

70

71if (!get_magic_quotes_gpc())://директива в Php.ini = off выключена

72$isbn = addslashes($isbn);

73$author = addslashes($author);

74$title = addslashes($title);

75$price = doubleval($price);//фильтрации всех

//неподходящих символов для числового поля.

76else: //В нашем PHP.ini установлена по умолчанию включенной

//get_magic_quotes_gpc включена = on.

77endif;

78

79@ $db = new mysqli($Host, $User, $Password, $DBName);

80if (mysqli_connect_errno()):

81echo 'Ошибка: Не удалось установить соединение с базой данных.<br />

82Пожалуйста, повторите попытку позже.';

83exit;

84endif;

85

86 $sql = "insert into books values('".$isbn."', '".$author."', '".$title."', '".$price."')";

87$result = $db->query($sql);

88if ($result):

89echo "<br>".$db->affected_rows." Книга добавлена в базу данных.";

90else://есть ошибки при добавлении записи (книги)

91echo "<br> <font color=red>Книга Не добавлена в базу данных.<br>";

92echo "<br>Ошибка MySql= ".mysqli_error($db).",result= ".$result.", affected_rows= ".$db->affected_rows ;

93//exit() // для тестирования

94if ($db->errno==1062)://нарушение первичного ключа

95//Номер ошибки=1062, описание Duplicate entry '1' for key 1,sqlstate 23000 96 // echo("<br>Номер ошибки=".$db->errno.", описание ".$db- >error.",sqlstate ".$db->sqlstate);

265

97echo("<br> Ошибка! Подобный isbn= ".$isbn." уже Вами был использован! <br>db->error ".$db->error);

98//запрос к базе

99//Используется Объектно-ориентированный стиль и библиотека

MYSQLI

100$sql ="SELECT * FROM books WHERE isbn='".$isbn."'";

101$q = $db->query($sql);

102if (!$q):

103

exit ('Ошибка: запроса.<br>');

104endif;

105// Выводим заголовок таблицы для записи книги с существующим

ISBN:

106echo"<table border=\"1\" width=\"50%\" bgcolor=\"#FFFFE1\">";

107echo "<tr><td>ISBN</td><td>Автор</td><td>Название</td>";

108echo "<td>Цена</td>";

109// Выводим в таблице характеристики книги

110for ($c=0; $c<mysqli_num_rows($q); $c++)

111{echo "<tr>";

112$f = mysqli_fetch_array($q);

113echo "<td>$f[isbn]</td><td>$f[author]</td><td>$f[title]</td>";

114echo "<td>$f[price]</td>";

115echo "</tr>";}//конец цикла вывода таблицы

116echo "</table>";

117

118echo "<h3> Сведения о полях</h3>";

119$field_cnt = $q->field_count;//

120//printf("В результате %d поля (ей).\n", $field_cnt);

121//На экране: В результате 4 поля (ей).

122echo("В результате field_cnt=".$field_cnt." поля (ей) mysqli_num_fields=".mysqli_num_fields($q));

123//На экране:/В результате field_cnt=4 поля (ей) mysqli_num_fields=4

124echo"<table border=\"1\" width=\"50%\" bgcolor=#33FFFF\">";

125echo "<tr><td>Номер</td><td>Имя</td><td>Тип</td>";

126echo "<td>Ширина столбца</td><td>Факт.дл.</td><td>Флаги поля</td>";

127for ($i = 0; $i < mysqli_num_fields($q); $i++)

128{echo "<tr>";

129$finfo = $q -> fetch_field ();//Object oriented style (method)

130$j = $q -> current_field ; //порядковый номер поля

131

$c =$finfo -> name;

//имя поля

132

$t= $finfo -> type;

//тип поля

133

$fl=$finfo -> flags;

//строка флагов поля

134$dm=$finfo -> max_length;//фактически использовано в базе

135$dl=$finfo -> length;//отведено в базе

136//$c =mysqli_field_name($q, $i); -эти три функции в

266

137//$f l=mysqli_field_flags($q,$i); объектно-ориентированном

138//$t = mysqli_field_type($q,$i); подходе не работают

139echo "<td>$j</td><td>$c<td>$t</td><td>$dl</td><td>$dm</td><td>$fl</td>";

140echo "</tr>";}

141echo "</table>";

142

//Процедурный подход

143@ $dbb = mysql_pconnect($Host, $User, $Password);

144mysql_select_db( "books");//открытие базы

145$result=mysql_db_query("books","select * from books");// запрос к базе

146echo "<BR>";

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

148{

149echo "Свойства поля ".($i+1).":<BR>";

150$param=mysql_fetch_field($result);

151if(!$param) echo "Нет информации о свойствах!";

152echo "<PRE>

153name: $param->name

154table: $param->table

155max_length: $param->max_length

156not_null: $param->not_null

157primary_key: $param->primary_key

158unique_key: $param->unique_key

159multiple_key: $param->multiple_key

160numeric: $param->numeric

161

blob:

$param->blob

162

type:

$param->type

163unsigned: $param->unsigned

164zerofill: $param->zerofill

165</PRE>";

166}

167

168if (!$db=mysql_connect($Host, $User, $Password))

169{echo "<h2>MySQL Error!</h2>"; exit; }//неудача

170// Выбираем базу данных:-mysql_select_db($db);

171if (!@mysql_select_db("books",$db) )

172{echo "<p>К сожалению, не доступна база данных</p>"; exit();}

173endif;

174$q=mysql_db_query("books","select * from books");

175echo "<h2> Сведения о полях</h2>";

176echo"<table border=\"1\" width=\"50%\" bgcolor=#33FFFF\">";

177echo "<tr><td>Номер</td><td>Имя</td><td>Тип</td>";

178echo "<td>Длина</td><td>Флаги поля</td>"; //td

179for ($i = 0; $i < mysql_num_fields($q); $i++)

180{echo "<tr>";

181$c =mysql_field_name($q, $i);

267

182$fl=mysql_field_flags($q,$i);

183$t =mysql_field_type($q,$i);

184$dl = mysql_field_len($q, $i);

185$j = $i+1 ; //порядковый номер поля

186echo "<td>$j</td><td>$c<td>$t</td><td>$dl</td><td>$fl</td>";

187echo "</tr>";}

188echo "</table>";

189endif; //конец if ($result):

190?>

191</body></html>

Рис. 3.280. Сценарий Lab15_05.php добавления новых книг.

Результаты успешного добавления книги в базу данных показаны на рис. 3.281.

Рис. 3.281. Сообщение о добавлении новой книги.

После изучения кода C:\WebServers\home\localhost\www\php\lab15_05.php

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

и отформатированы с помощью addslashes () перед внесением данных в базу (обратите внимание на требованию к конфигурации PHP.ini, использованного на Вашей машине):

$isbn = addslashes ($isbn) ; $author = addslashes ($author) ; $title = addslashes ($title) ; $price = doubleval ($price) ;

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

Обратите внимание на особую обработку информации чисел с плавающей запятой.

268

Пусть, например, пользователь в поле цены ввел следующую информацию (рис. 3.282).

Рис. 3.282. Информация о новой книге.

Если в коде сценария (рис. 3.280) закомментарить строку 52 (фрагмент закомментаренного кода показан на рис. 3.283):

Рис. 3.283. Модифицированное тело программы Lab15_05.php.

то нажатие кнопки приведет к результату (рис. 3.284)

Рис. 3.284. Состав таблицы books после добавления новой книги. Естественно наличие подобной ошибки может привести к

нежелательным последствиям.

Также из семантических соображений, понятно почему надо использовать оператор указанный в 66-ой строке кода, представленного на рис. 3.280.

269

Рис. 3.285. Фрагмент кода непозволяющий вводить отрицательную цену.

Мы

соединяемся

с базой

данных,

создавая

экземпляр

 

,

и настраиваем

запрос.

В данном

случае это

INSERT

 

 

 

.

 

Рис. 3.286. Фрагмент кода обеспечивающий соединение с базой и вставку данных.

Запрос выполняется в базе данных как обычно:

При процедурном подходе следует использовать оператор $result = mysqli_query($sql);

Одно существенное различие между INSERT и SELECT заключается в использовании mysqli_affected_rows(). В процедурной версии это функция, а

вобъектно-ориентированной версии это переменная-член класса

, которая хранит количество строк модифицированых в запросе.

В предыдущем сценарии функция mysql_num_rows() применялась для определения количества строк, которые будет возвращать SELECT. При написании запросов, которые изменяют базу данных, например, INSERT, DELETE, UPDATE, следует использовать mysql_affected_rows().

270

Чтобы раскрыть назначение строк кода с 90 по 189 на рис. 3.280 рассмотрим ситуацию, когда пользователь пытается ввести информацию в

базу с уже существующим реляционным ключом (рис. . 3.287). В нашем случае, в таблице с именем books, реляционным ключом является атрибут ISBN.

Для проведения эксперимента раскомментарим строку 93 в коде программы Lab15_05.pp.

и введем информацию показанную на рис. 3.287 14.22.

Рис. 3.287. Форма с исходной информацией.

Если соединение с базой данных пройдет коррекстно, то при вставке информации о новой книге MySql выполняя запрос присвоит значение

переменной равное False и будет выведено сообщение показанное на рис. 3.288.

Рис. 3.288. Сообщение о дублировании ключа.

Для пользователя подобное сообщение является недостаточно информативным, поэтому если закоментарить оператор EXIT (строка 93) получим более информативное сообщение (рис. 3.289).

Соседние файлы в папке metoda