- •Технология организации баз данных и знаний
- •Методические указания к выполнению лабораторных работ
- •Методические указания к выполнению лабораторных работ
- •Предисловие
- •Библиографический список
- •Лабораторная работа № 1 Тема №1. ИнсталляцияMySqLи создание локального сервера
- •1. Цель работы
- •2. Основные технические возможности
- •3. Описание установки
- •4. Порядок выполнения работы
- •5. Содержание отчета
- •Лабораторная работа № 1
- •6. Содержание отчета
- •Лабораторная работа № 2 Тема №1. Создание баз и таблиц данных
- •1. Цель работы
- •2. Основные сведения
- •3. Программа работы
- •4. Указания к выполнению работы
- •3. Программа работы
- •00 Проверка моего домена с именем Moy.Loc
- •4. Указания к выполнению работы
- •5. Содержание отчета
- •3. Указания к выполнению работы
- •Задание 2: Разработать html-форму с методом Post
- •Тема №2. Передача значений переменным в сценариях php. Использование возможностей метода get без html-формы для передачи значений переменных в сценариях php
- •Тема №3. Создание формы и рнр-сценария в одном файле
- •Задание 1: Получение данных из текстового поля
- •I курсив
- •Тема №4. Использование чисел. Управляющие структуры
- •Тема №5. Использование управляющей структурыswitch
- •Тема № 6. Использование регулярных выражений в сценариях рнр
- •Проверка ошибок
- •Задание 1. Вывод информации о ошибочно заполненных полях формы
- •Задание 2. Использование функций пользователя для контроля полей формы
- •Задание 3. Проверка ограничений в текстовом поле.Lab6_0_2.Php
- •Задание 4. Специфика имени пользователя. Lab6_0_3.Php
- •Задание 5. Специфика имени пользователя с помощью JavaScript. Lab6_0_4.Php
- •Тема №7. Работа с массивами
- •Задание 1. Означивание массива и вывод на экран. Lab7_0.Php.
- •Задание 4. Сортировка массива.Lab7_3.Php.
- •Тема №8. Функции в сценариях рнр
- •Задание 1. Вложенные функции.Lab8_0_0.Php
- •Задание 2. Объявление функций внутри других функций.Lab8_0.Php
- •Задание 3. Возврат значений функцией.Lab8_1.Php
- •Задание 4. Возврат нескольких значений функцией.Lab8_2.Php
- •Задание 5. Возвращение функцией нескольких величин.Lab8_3.Php
- •Задание 6. Рекурсивные функции .Lab8_4.Php
- •Задание 7. Функции-переменные.Lab8_5.Php
- •Задание 8. Построение библиотек функций.Lab8_6_0.Php.
- •Задание 9. Построение шаблона сайта.Lab8_7_0.Php.
- •Тема №9. Использование файлов для хранения данных в сценариях рнр
- •Создание сценария загрузки.
- •Задание 3. Сохранение пользовательских данных в текстовом файлеLab9_5.Php
- •Задание 4. Сохранение пользовательских данных в текстовом файлеLab9_6_0.Php
- •Тема № 10. Работа с каталогами в сценариях рнр
- •Тема №11. Создание панели управления файлами
- •Задание 1. Разработать форму и сопутствующее ей приложение для панели управления файлами.
- •Тема № 12.Работа с базой через монтторMySql и PhpMyAdmin
- •Задание 1. Создать базу данных через командную строку
- •Задание 3. Вставка данных в базу данных
- •Задание 4. Создание командных файлов и файлов сценариев для вставки данных в базу данных.
- •Тема № 13. Извлечение данных из базы данных
- •Задание 1. Оператор выборки данныхSelect
- •Задание 2. Извлечение данных по определенному критерию
- •Задание 3. Извлечение данных из нескольких таблиц
- •Задание 4. Поиск несоответствующих строк
- •Задание 5. Использование псевдонимов имен таблиц (as)
- •Задание 6. Извлечение данных в определенном порядке
- •Задание 7. Группировка и агрегирование данных
- •Задание 8. Обновление записей в базе данных (update)
- •Задание 10. Удаление записей, таблиц и базы данных (delete)
- •Тема № 14.Php и MySql. Доступ к базе данных MySql из Web с помощью рнр
- •Задание 1. Изучение работы архитектуры Web-баз данных
- •Задание 2. Проверка и фильтрация данных, исходящих от пользователя. Использование объектно-ориентированного синтаксисаPhp
- •Задание 3. Внесение новой информации в базу данных. Проверка и фильтрация данных, исходящих от администратора
- •Задание 4. Создание и удаление баз данных
- •Содержание
Задание 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>
<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
8 if(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="";
16 if (!$isbn || !$author || !$title || !$price):
17 echo 'Вы ввели не все необходимые сведения.<br />'
18 .'Пожалуйста, вернитесь на предыдущую страницу и повторите ввод.<br>';
19 //Внимание! Если $price=0 - то считаем, что цена не означена.
20 exit; //выход из программы
21 endif;
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. Сначала нам необходимо убедиться, что нужные нам функции установлены и доступны. Для этого используются операторы:*/
26 if (function_exists('filter_list')):
27 //echo 'список фильтров установлен!';
28 else:
29 die('Ошибка: фильтры не найдены. '); // выход из программы
30 endif;
31 //FILTER_VALIDATE_FLOAT — проверка на число с плавающей точкой
32 $valid_float = filter_var($price, FILTER_VALIDATE_FLOAT);
33 if ($valid_float !== false):
34 // проверка прошла успешно, $price - число
35 //echo "проверка Float прошла успешно <br>";
36 if (strpos($price, ".")===false): // символ точки в $price не найден
37 echo "<br> Точки нет. Введено ".$price." strlen ".strlen($price)."<br>";
38 if ($lenprice>2):
39 echo "Указаная цена ".$price." превышает формат хранения в базе. В базе
40 указан формат хранения Float(4.2). <br>Исправьте ввод данных.";
41 exit;
42 endif;
43 else://точку указали
44 echo "<br> Точка есть. Позиция ".strpos($price, ".")." Введено ".$price."
strlen ".strlen($price)."<br>";
45 if ($lenprice>5):
46 echo "Указаная цена ".$price." превышает формат хранения в базе. В базе
указан формат хранения Float(4.2). <br>Исправьте ввод данных.";
47 exit;
48 endif;
49 if (strpos($price, ".") >2):
50 //Точка есть. Например, позиция 3 в введенной Цене 333.5 Длина strlen =5
51 //Внимание! Если пропустить в базу пропишется число 99.99
52 exit ("Указаная цена ".$price." превышает формат хранения в базе. В базе указан формат хранения Float(4.2). <br>Исправьте ввод данных, иначе в базу запишется 99.99 .");
53 endif;
54 endif;
55 else: // проверка на число не прошла
56 echo "В поле Цена указано ".$price." В поле есть недопустимый символ !
<br>Исправьте ввод данных.";
57 exit;//выход из программы
58 endif;
59
60 if (preg_match("/^[0-9].+$/",$price)):
61 //echo "Ввели число <br>";
62 else:
63 //echo "Во вводе есть символ <br>";
64 endif;
65
66 if (substr($price, 0, 1)=="-"):
67 echo "В поле Цена не должно быть отрицательного числа! <br>
Исправьте ввод данных.";
68 exit;//выход из программы
69 endif;
70
71 if (!get_magic_quotes_gpc())://директива в Php.ini = off выключена
72 $isbn = addslashes($isbn);
73 $author = addslashes($author);
74 $title = addslashes($title);
75 $price = doubleval($price);//фильтрации всех
// неподходящих символов для числового поля.
76 else: //В нашем PHP.ini установлена по умолчанию включенной
//get_magic_quotes_gpc включена = on.
77 endif;
78
79 @ $db = new mysqli($Host, $User, $Password, $DBName);
80 if (mysqli_connect_errno()):
81 echo 'Ошибка: Не удалось установить соединение с базой данных.<br />
82 Пожалуйста, повторите попытку позже.';
83 exit;
84 endif;
85
86 $sql = "insert into books values('".$isbn."', '".$author."', '".$title."', '".$price."')";
87 $result = $db->query($sql);
88 if ($result):
89 echo "<br>".$db->affected_rows." Книга добавлена в базу данных.";
90 else://есть ошибки при добавлении записи (книги)
91 echo "<br> <font color=red>Книга Не добавлена в базу данных.<br>";
92 echo "<br>Ошибка MySql= ".mysqli_error($db).",result= ".$result.", affected_rows= ".$db->affected_rows ;
93 //exit() // для тестирования
94 if ($db->errno==1062)://нарушение первичного ключа
95//Номер ошибки=1062, описание Duplicate entry '1' for key 1,sqlstate 23000
96 // echo("<br>Номер ошибки=".$db->errno.", описание ".$db->error.",sqlstate ".$db->sqlstate);
97 echo("<br> Ошибка! Подобный isbn= ".$isbn." уже Вами был использован! <br>db->error ".$db->error);
98 //запрос к базе
99 //Используется Объектно-ориентированный стиль и библиотека MYSQLI
100 $sql ="SELECT * FROM books WHERE isbn='".$isbn."'";
101 $q = $db->query($sql);
102 if (!$q):
103 exit ('Ошибка: запроса.<br>');
104 endif;
105 // Выводим заголовок таблицы для записи книги с существующим ISBN:
106 echo"<table border=\"1\" width=\"50%\" bgcolor=\"#FFFFE1\">";
107 echo "<tr><td>ISBN</td><td>Автор</td><td>Название</td>";
108 echo "<td>Цена</td>";
109 // Выводим в таблице характеристики книги
110 for ($c=0; $c<mysqli_num_rows($q); $c++)
111 {echo "<tr>";
112 $f = mysqli_fetch_array($q);
113 echo "<td>$f[isbn]</td><td>$f[author]</td><td>$f[title]</td>";
114 echo "<td>$f[price]</td>";
115 echo "</tr>";}//конец цикла вывода таблицы
116 echo "</table>";
117
118 echo "<h3> Сведения о полях</h3>";
119 $field_cnt = $q->field_count;//
120 //printf("В результате %d поля (ей).\n", $field_cnt);
121 //На экране: В результате 4 поля (ей).
122 echo("В результате field_cnt=".$field_cnt." поля (ей) mysqli_num_fields=".mysqli_num_fields($q));
123 //На экране:/В результате field_cnt=4 поля (ей) mysqli_num_fields=4
124 echo"<table border=\"1\" width=\"50%\" bgcolor=#33FFFF\">";
125 echo "<tr><td>Номер</td><td>Имя</td><td>Тип</td>";
126 echo "<td>Ширина столбца</td><td>Факт.дл.</td><td>Флаги поля</td>";
127 for ($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); -эти три функции в
137 //$f l=mysqli_field_flags($q,$i); объектно-ориентированном
138 //$t = mysqli_field_type($q,$i); подходе не работают
139 echo "<td>$j</td><td>$c<td>$t</td><td>$dl</td><td>$dm</td><td>$fl</td>";
140 echo "</tr>";}
141 echo "</table>";
142 //Процедурный подход
143 @ $dbb = mysql_pconnect($Host, $User, $Password);
144 mysql_select_db( "books");//открытие базы
145 $result=mysql_db_query("books","select * from books");// запрос к базе
146 echo "<BR>";
147 for($i=0;$i<mysql_num_fields($result);$i++)
148 {
149 echo "Свойства поля ".($i+1).":<BR>";
150 $param=mysql_fetch_field($result);
151 if(!$param) echo "Нет информации о свойствах!";
152 echo "<PRE>
153 name: $param->name
154 table: $param->table
155 max_length: $param->max_length
156 not_null: $param->not_null
157 primary_key: $param->primary_key
158 unique_key: $param->unique_key
159 multiple_key: $param->multiple_key
160 numeric: $param->numeric
161 blob: $param->blob
162 type: $param->type
163 unsigned: $param->unsigned
164 zerofill: $param->zerofill
165 </PRE>";
166 }
167
168 if (!$db=mysql_connect($Host, $User, $Password))
169 {echo "<h2>MySQL Error!</h2>"; exit; }//неудача
170 // Выбираем базу данных:-mysql_select_db($db);
171 if (!@mysql_select_db("books",$db) )
172 {echo "<p>К сожалению, не доступна база данных</p>"; exit();}
173 endif;
174 $q=mysql_db_query("books","select * from books");
175 echo "<h2> Сведения о полях</h2>";
176 echo"<table border=\"1\" width=\"50%\" bgcolor=#33FFFF\">";
177 echo "<tr><td>Номер</td><td>Имя</td><td>Тип</td>";
178 echo "<td>Длина</td><td>Флаги поля</td>"; //td
179 for ($i = 0; $i < mysql_num_fields($q); $i++)
180 {echo "<tr>";
181 $c =mysql_field_name($q, $i);
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 ; //порядковый номер поля
186 echo "<td>$j</td><td>$c<td>$t</td><td>$dl</td><td>$fl</td>";
187 echo "</tr>";}
188 echo "</table>";
189 endif; //конец 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(), которая отфильтрует все неподходящие символы в числовом поле. Эта же функция позаботится и обо всех символах валюты, которые пользователь может печатать при заполнении формы.
Обратите внимание на особую обработку информации чисел с плавающей запятой.
Пусть, например, пользователь в поле цены ввел следующую информацию (рис. 3.282).
Рис. 3.282. Информация о новой книге.
Если в коде сценария (рис. 3.280) закомментарить строку 52 (фрагмент закомментаренного кода показан на рис. 3.283):
Рис. 3.283. Модифицированное тело программы Lab15_05.php.
то нажатие кнопки приведет к результату (рис. 3.284)
Рис. 3.284. Состав таблицы books после добавления новой книги.
Естественно наличие подобной ошибки может привести к нежелательным последствиям.
Также из семантических соображений, понятно почему надо использовать оператор указанный в 66-ой строке кода, представленного на рис. 3.280.
Рис. 3.285. Фрагмент кода непозволяющий вводить отрицательную цену.
Мы соединяемся с базой данных, создавая экземпляр , и настраиваем запрос. В данном случае этоINSERT .
Рис. 3.286. Фрагмент кода обеспечивающий соединение с базой и вставку данных.
Запрос выполняется в базе данных как обычно:
При процедурном подходе следует использовать оператор $result = mysqli_query($sql);
Одно существенное различие между INSERT и SELECT заключается в использовании mysqli_affected_rows(). В процедурной версии это функция, а в объектно-ориентированной версии это переменная-член класса , которая хранит количество строк модифицированых в запросе.
В предыдущем сценарии функция mysql_num_rows() применялась для определения количества строк, которые будет возвращать SELECT. При написании запросов, которые изменяют базу данных, например, INSERT, DELETE, UPDATE, следует использовать mysql_affected_rows().
Чтобы раскрыть назначение строк кода с 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).
Рис. 3.289. Сообщение раскрывающее суть ошибки.
Для целей обучения, далее приводятся сообщения из кода программы, описывающие сведения о полях (строки 99-141) при использовании объектно-ориентированного синтаксиса PHP (рис. 3.290) и процедурного синтаксиса PHP (строки 142-189 рис. 3.280) результат которого приведен на рис. 3.291.
Рис. 3.290. Сообщение о составе и свойствах полей, использованных в запросе.
Рис. 3.291. Сообщение о составе и свойствах полей при использовании процедурного подхода.
Возвращаемый объект имеет следующие свойства:
name - имя поля
table - имя таблицы, которой принадлежит поле
max_length - максимальная длина поля
not_null - 1, если полю разрешено пустое значение
primary_key - 1, если поле является ключевым
unique_key - 1, если в поле допускаются только уникальные значения
multiple_key - 1, если в поле допустимо иметь повторяющиеся значения
numeric - 1, если поле числовое
blob - 1, если поле имеет тип BLOB
type - тип поля
unsigned - 1, если поле числовое беззнаковое
zerofill - 1, есле поле заполняется нулями
Мы рассмотрели основы использования баз данных MySQL из РНР. В следующем задании рассматриваются еще некоторые полезные функции, не упомянутые ранее.