WEB PHP 07 - Работа с базами данных.ppt
- Количество слайдов: 28
Взаимодействие с базами данных web-программирование (php)
Содержание • • • Универсальный коннектор (ODBC) Использование специфичных коннекторов Persistent и non-persistent соединения в PHP Защита от SQL-инъекций Взаимодействие с My. SQL Паттерн "Адаптер" для работы с базами данных web-программирование (php)
Универсальный коннектор (ODBC) ODBC – Open Database Connectivity – программный интерфейс (API) для доступа к широкому спектру баз данных. В PHP используется штатный модуль для работы с ODBC. $dbc = odbc_connect("Driver={Microsoft Access Driver (*. mdb)}; Dbq=$file", $user, $pass); $res = odbc_exec($dbc, "SELECT * FROM tmp. Table"); while ($row = odbc_fetch_array($res)) { echo $row['name']; }// while more rows. . . odbc_free_result($res); odbc_close($dbc); web-программирование (php)
Универсальный коннектор (ODBC) DSN – Database Source Name – строка, описывающая структуру подключения к источнику данных. Обычно, включает в себя: описание драйвера и путь к данным. "Driver={SQL Server; Server=(local); Trusted_Connection=Yes; Database=Adventure. Works; " "Driver={Microsoft ODBC for Oracle; Server=ORACLE 8 i 7; Persist Security Info=False; Trusted_Connection=Yes" "Driver={Microsoft Access Driver (*. mdb); DBQ=c: binNorthwind. mdb" "Driver={Microsoft Excel Driver (*. xls); DBQ=c: binbook 1. xls" "Driver={Microsoft Text Driver (*. txt; *. csv); DBQ=c: bin" "DSN=dsnname" web-программирование (php)
Универсальный коннектор (ODBC) Подключение: $file = realpath ('C: /base. mdb'); $dsn = "Driver={Microsoft Access Driver (*. mdb)}; Dbq=$file"; $user = ''; $pass = ''; $dbc = odbc_connect ($dsn, $user, $pass); Выполнение команды: $res = @odbc_exec ($dbc, 'CREATE TABLE employee ('. 'id AUTOINCREMENT(1, 1) PRIMARY KEY, '. 'name TEXT(250) not null, '. 'phone TEXT(100) not null)'); if ($res === FALSE) echo "ERROR: ". odbc_errormsg($dbc); Отключение: odbc_close ($dbc); web-программирование (php)
Универсальный коннектор (ODBC) Выполнение команды: $dbc = odbc_connect($dsn, $user, $pass); $res = odbc_prepare ($dbc, "INSERT INTO employee (name, phone) VALUES (? , ? )"); if ($res === FALSE) echo "ERROR: ". odbc_errormsg($dbc); foreach ($employees as $name => $phone) { $err = odbc_execute ($res, array($name, $phone)); if ($err === FALSE) echo "ERROR: ". odbc_errormsg($dbc); }// foreach employees. . . odbc_close($dbc); • строки должны быть переданы строго в ' ' (одинарных кавычках) • параметризованные запросы не поддерживаются в Access • если в в строке есть ' ' по краям, то значение считается именем файла, который нужно загрузить web-программирование (php)
Универсальный коннектор (ODBC) Выполнение команды: $dbc = odbc_connect($dsn, $user, $pass); $req = "INSERT INTO employee (name, phone) VALUES ('abc', '+73511234567')"; $res = odbc_prepare ($dbc, $req); if ($res === FALSE) echo "ERROR: ". odbc_errormsg($dbc); $err = odbc_execute ($res); if ($err === FALSE) echo "ERROR: ". odbc_errormsg($dbc); odbc_close($dbc); Упрощенный вариант: $req = "INSERT INTO employee (name, phone) VALUES ('name', 'phone')"; $res = odbc_exec ($dbc, $req); if ($res === FALSE) echo "ERROR: ". odbc_errormsg($dbc); web-программирование (php)
Универсальный коннектор (ODBC) Выполнение запроса: $dbc = odbc_connect($dsn, $user, $pass); $res = odbc_exec ($dbc, "SELECT * FROM employee"); if ($res === FALSE) echo "ERROR: ". odbc_errormsg($dbc); while (odbc_fetch_row($res)) { echo odbc_result($res, 'name'); echo odbc_result($res, 3); }// while any row. . . // phone, индексы идут с 1 odbc_free_result ($res); odbc_close($dbc); web-программирование (php)
Универсальный коннектор (ODBC) Выполнение запроса: $dbc = odbc_connect($dsn, $user, $pass); $res = odbc_exec ($dbc, "SELECT * FROM employee"); if ($res === FALSE) echo "ERROR: ". odbc_errormsg($dbc); while ($row = odbc_fetch_array($res)) { echo $row['name']; //echo $row[3]; //! не знает полей по индексу }// while any row. . . odbc_free_result ($res); odbc_close($dbc); web-программирование (php)
Универсальный коннектор (ODBC) Выполнение запроса: $dbc = odbc_connect($dsn, $user, $pass); $res = odbc_exec ($dbc, "SELECT * FROM employee"); if ($res === FALSE) echo "ERROR: ". odbc_errormsg($dbc); while ($obj = odbc_fetch_object($res)) { echo $obj->name; // COLUMN NAME }// while any row. . . odbc_free_result ($res); odbc_close($dbc); web-программирование (php)
Универсальный коннектор (ODBC) Пример получения описания базы: $dbc = odbc_connect ($dsn, $user, $pass); $res = odbc_tables ($dbc); while (odbc_fetch_row($res)) { echo '['. odbc_result ($res, 'TABLE_TYPE'). '] '; echo odbc_result ($res, "TABLE_NAME"); // TABLE_QUALIFIER // TABLE_OWNER // REMARKS }// while … // [SYSTEM TABLE] MSys. Queries // [TABLE] employee // [VIEW] students Запрос odbc_close($dbc); web-программирование (php)
Использование специфичных коннекторов Производители СУБД или сторонние разработчики предоставляют модули для работы с базой из PHP. Примеры поддерживаемых СУБД: • • My. SQL – mysql_* Firebird/Inter. Base – ibase_* SQLite 3 – SQLite 3: : * Postgre. SQL – pg_* Набор обязательных операций: • • подключение к базе получение статистики сервера выполнение запроса выборка строки данных из ответа http: //www. php. net/manual/en/refs. database. vendors. php web-программирование (php)
Persistent соединения Обычное подключение к базе создается при каждом запуске скрипта (точнее, при каждом connect). Persistent (постоянное) соединение устанавливается один раз для каждого рабочего потока web-браузера, затем используется повторно. Плюсы постоянных соединений: • быстрое подключение к удаленной СУБД Минусы постоянных соединений: • • сложности с транзакциями сложности с временными таблицами синхронность обращений к базе заблокированный процесс может потребовать перезагрузки web-сервера web-программирование (php)
Защита от SQL-инъекций SQL-инъекция – один из способов взлома информационных систем с целью получить данные из базы. Осуществляется при помощи внедрения SQL запросов. Добавленный при помощи инъекции к исходному запросу код может помочь злоумышленнику не только узнать больше информации из базы, но и удалить/изменить существующие данные. Способы защиты от инъекций: • наложение escape_string на полученные от пользователя строчные параметры • принудительное конвертирование чисел в числа • использование параметризованных (prepared) запросов web-программирование (php)
Взаимодействие с My. SQL Правильная последовательность: // соединение $host = 'localhost'; $user = 'mtuser'; $pass = '123 qwe'; $database = 'mt'; $base = new mysqli ($host, $user, $pass, $database, 3307); // проверка соединения на сбой подключения if ($base->connect_error) die ('Connect Error: '. $base->connect_error); // установка настроек кодировки if (!$base->set_charset("utf 8")) echo "Error loading character set utf 8: {$base->error}"; // проверка текущей кодировки соединения echo 'Current character set: '. $base->character_set_name(); //. . . полезная работа. . . // отключение $base->close(); web-программирование (php)
Взаимодействие с My. SQL Выполнение команд без возвращаемого результата: if ($base->query ('CREATE TABLE IF NOT EXISTS employee ('. 'id int unsigned NOT NULL auto_increment, '. 'name varchar(250) NOT NULL, '. 'phone varchar(100) NOT NULL, '. 'PRIMARY KEY (id)'. ')' ) === FALSE) { echo $base->error; goto close_and_exit; }// if error. . . // … полезная работа. . . close_and_exit: $base->close(); exit(); web-программирование (php)
Взаимодействие с My. SQL Выполнение команд без возвращаемого результата: $req = 'INSERT INTO employee (id, name, phone) VALUES (NULL, "pupkin", "+51267890")'; if ($base->query($req) === FALSE) { echo $base->error; goto close_and_exit; }// if error. . . // новое вставленное значение для auto_increment поля echo 'New employee id = '. $base->insert_id; $req = ' UPDATE employee SET name="Свердликов Андрей Павлович" '; if ($base->query($req) === FALSE) { echo $base->error; goto close_and_exit; }// if error. . . // количество измененных строк echo 'Affected rows on update: '. $base->affected_rows; web-программирование (php)
Взаимодействие с My. SQL Экранирование символов в строках: $name = "Muhamed l'Pari"; $ename = $base->real_escape_string ($name); $req = "INSERT INTO employee (name, phone) VALUES ('$ename', '+73445678900')"; if ($base->query() === FALSE) { echo $base->error; goto close_and_exit; }// if error. . . web-программирование (php)
Взаимодействие с My. SQL Параметризованные запросы: $query = "INSERT INTO employee (name, phone) VALUES (? , ? )"; if (( $stmt = $base->prepare($query) ) === FALSE) goto show_error; // прикрепляем переменные к полям запроса if ($stmt->bind_param("ss", $name, $phone) === FALSE) goto show_error; $name = 'Мистер Фёрст'; $phone = '001'; if ($stmt->execute() === FALSE) goto show_error; echo 'Новый идентикатор: '. $stmt->insert_id; $name = 'Мистер Секонд'; $phone = '002'; if ($stmt->execute() === FALSE) goto show_error; echo 'Задело строк: '. $stmt->affected_rows; web-программирование (php)
Взаимодействие с My. SQL Запросы с результатом: $res = $base->query ('SELECT * FROM employee'); if ($res === FALSE) goto show_error; $all = $res->fetch_all (MYSQLI_BOTH); // MYSQLI_ASSOC, MYSQLI_NUM // Array // [0] => 1 // [id] => 1 // [1] => Свердликов Андрей Павлович // [name] => Свердликов Андрей Павлович // [2] => +51234567890 // [phone] => +51234567890 // [1] => Array // [0] => 28 // [id] => 28 // [1] => Muhamed l'Pari // [name] => Muhamed l'Pari // [2] => +73445678900 // [phone] => +73445678900 web-программирование (php)
Взаимодействие с My. SQL Запросы с результатом: $res = $base->query ('SELECT * FROM employee AS EMP'); if ($res === FALSE) goto show_error; // информация о полях $finfo = $res->fetch_fields(); foreach ($finfo as $val) echo "{$val->orgtable} AS {$val->table} -> {$val->name} n"; // employee AS EMP -> id // employee AS EMP -> name // employee AS EMP -> phone while ($row = $res->fetch_array (MYSQLI_BOTH)) {// MYSQLI_ASSOC, MYSQLI_NUM echo "name: {$row[1]}, phone: {$row['phone']}n"; }// while rows. . . web-программирование (php)
Взаимодействие с My. SQL Запросы с результатом: if ($base->real_query ('SELECT * FROM employee') === FALSE) goto show_error; $res = $base->use_result(); // store_result() if ($res === FALSE) goto show_error; while ($row = $res->fetch_array()) { echo "name: {$row[1]}, phone: {$row[2]}n"; }// while rows. . . $res->free_result(); web-программирование (php)
Взаимодействие с My. SQL Запросы с результатом: $res = $base->query ('SELECT * FROM employee', MYSQLI_USE_RESULT); if ($res === FALSE) goto show_error; while ($row = $res->fetch_array()) { echo "name: {$row[1]}, phone: {$row[2]}n"; }// while rows. . . $res->free_result(); web-программирование (php)
Взаимодействие с My. SQL Запросы с результатом: $res = $base->query ('SELECT id as Ident, name as Name FROM employee'); if ($res === FALSE) goto show_error; while ($obj = $res->fetch_object()) { // std. Class echo 'Сотрудник '. $obj->Name. ' под №'. $obj->Ident; }// while rows. . . // object(std. Class) (2) { // ["Ident"] => string(1) "1" // ["Name"]=> string(50) "Свердликов Андрей Павлович" //} web-программирование (php)
Взаимодействие с My. SQL Запросы с результатом: class Emp { private $prefix; public function __construct ($prefix) { $this->prefix = $prefix; } public function Pref. Name() { return $this->prefix. ' '. $this->Name; } }// class Emp $res = $base->query ('SELECT id as Ident, name as Name FROM employee'); if ($res === FALSE) goto show_error; while ($obj = $res->fetch_object( 'Emp', array('special prefix') )) { echo $obj->Pref. Name(); }// while rows. . . //object(Emp) (3) { // ["prefix": "Emp": private] => string(14) "special prefix" // ["Ident"] => string(1) "1" // ["Name"] => string(50) "Свердликов Андрей Павлович" //} web-программирование (php)
Взаимодействие с My. SQL Параметризованные запросы с результатом: // готовим запрос $query = "SELECT name, phone FROM employee WHERE id=? "; if (($stmt = $base->prepare($query)) === FALSE) goto show_error; // прикрепляем переменные к полям запроса if ($stmt->bind_param("i", $id) === FALSE) goto show_error; // выполняем $id = 1; if ($stmt->execute() === FALSE) goto show_error; // закрепляем переменные за полями ответа $stmt->bind_result ($name, $phone); // получаем значения while ($stmt->fetch()) { echo "name: $name, phone: $phonen"; }// while rows. . . web-программирование (php)
Взаимодействие с My. SQL Множественный запрос: // http: //www. php. net/manual/en/mysqli. use-result. php $query = "SELECT NOW(); "; $query. = "SELECT name FROM employee ORDER BY phone LIMIT 10"; /* execute multi query */ if (!$base->multi_query ($query)) goto show_error; do { /* store first result set */ if ($result = $base->use_result()) { while ($row = $result->fetch_row()) printf ("%sn", $row[0]); $result->free(); }// if. . . /* print divider */ if ($base->more_results()) printf ("---------n"); } while ($base->next_result()); web-программирование (php)
Паттерн "Адаптер" для работы с базами данных web-программирование (php)
WEB PHP 07 - Работа с базами данных.ppt