PHP 2016. Уровень 3.2: ООП + SQLite
SQLite — компактная встраиваемая СУБД. конспект-памятка видеокурса 'Программирование на PHP 2016'. Лектор Борисов Игорь Олегович. Учебный Центр «Специалист» при МГТУ им. Н.Э.Баумана.
конспектировал Капустин Яков
оглавление
SQLite (/ˌɛskjuːɛlˈlaɪt/ или /ˈsiːkwəl.laɪt/) — компактная встраиваемая СУБД. Исходный код библиотеки передан в общественное достояние. В 2005 году проект получил награду Google-O’Reilly Open Source Awards.
PHP поддерживает и процедурный и объектно-ориентированный подход при работе с SQLite. Кроме того, в SQLite существует много встроенных решений, выполненных в объектно-ориентированном стиле, и, что еще важнее, в последнее время наблюдается тенденция к отказу от процедурной парадигмы в пользу объектно-ориентированной.
01Создание, открытие и закрытие баз данных
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
// создаём или открываем базу данных
if($db = new SQLite3("/full/path/to/_php32/test.db")){
echo __LINE__." YES<br>\n";
}else{echo __LINE__." NO<br>\n";}
// закрываем базу данных без удаления объекта
if($db->close()){
echo __LINE__." YES<br>\n";
}else{echo __LINE__." NO<br>\n";}
// открываем другую базу данных
if($db->open("/full/path/to/_php32/another.db")){
echo __LINE__." YES<br>\n";
}else{echo __LINE__." NO<br>\n";}
// удаляем объект
unset($db);
9 YES
15 NO
02Создание приложения 'Лента новостей'
Создаём в директории _php32/_classes файлы с описанием интерфейса и класса, а также save_news.inc.php, get_news.inc.php и delete_news.inc.php.
Все строковые данные прогоняем через функцию escapeString().
Структура приложения 'Лента новостей':
- laboratory_3.2.1.php - основной файл новостной ленты;
- INewsDB.class.php - интерфейс INewsDB с декларациями методов для новостной ленты;
- NewsDB.class.php - класс NewsDB реализующий интерфейс INewsDB;
- save_news.php - php-код обработки данных для добавления записи в таблицу БД;
- delete_news.php - php-код обработки данных для удаления записи из таблицы БД;
- get_news.php - вывод списка записей из таблицы БД.
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/*
* Interface INewsDB
* содержит основные методы работы с новостной лентой
*/
Interface INewsDB{
/*
* Добавление новой записи в новостную ленту
*
* @param string $title - заголовок новости
* @param string $category - категория новости
* @param string $description - текст новости
* @param string $source - источник новости
*
* @return boolean - результат успех/ошибка
*/
function saveNews($title,$category,$description,$source);
/*
* Выборка всех записей в новостную ленту
*
* @return array - результат в виде массива
*/
function getNews();
/*
* Удаление записи из новостной ленты
*
* @param integer $id - id новости
*
* @return boolean - результат успех/ошибка
*/
function deleteNews($id);
}
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
class NewsDB implements INewsDB{
const DB_NAME = "/full/path/to/_php32/news.db";
private $_db;
public $title;
public $category;
public $description;
public $source;
function __get($n){ // геттер для получения значения приватного свойства _db
if($n=="_db"){
return $this->_db;
throw new Exception("unknown property!");
}
}
function __construct(){
$this->_db = new SQLite3(self::DB_NAME);
if(filesize(self::DB_NAME)==0){
try{
$sql="CREATE TABLE msgs(
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT,
category INTEGER,
description TEXT,
source TEXT,
datetime INTEGER
)";
if(!$this->_db->exec($sql)){throw new Exception($this->_db->lastErrorMsg());}
$sql="CREATE TABLE category(
id INTEGER,
name TEXT
)";
if(!$this->_db->exec($sql)){throw new Exception($this->_db->lastErrorMsg());}
$sql="INSERT INTO category(id,name)
SELECT 1 as id, 'Наука' as name
UNION SELECT 2 as id, 'Образование' as name
UNION SELECT 3 as id, 'Культура' as name
";
if(!$this->_db->exec($sql)){throw new Exception($this->_db->lastErrorMsg());}
}catch(Exception $e){
// здесь можно выполнить запись в лог, отправку email и прочее
echo "exception: ".$e->getMessage()."in file: ".$e->getFile()."in line: ".$e->getLine()."<br>\n";
}
}else{
}
}
function __destruct(){
unset($this->_db);
}
function saveNews($title,$category,$description,$source){
$datetime=time();
$sql="INSERT INTO msgs(
title,
category,
description,
source,
datetime)
VALUES(
'$title',
$category,
'$description',
'$source',
$datetime)";
return $this->_db->exec($sql);
}
function getNews(){
$sql="SELECT msgs.id as id,
title,
category.name as category,
description,
source,
datetime
FROM msgs, category
WHERE category.id = msgs.category
ORDER BY msgs.id DESC";
$res = $this->_db->query($sql);
if($res){
return $this->db2arr($res);
}else{
return false;
}
}
function db2arr($data){
$arr=[];
while($row=$data->fetchArray(SQLITE3_ASSOC)){$arr[]=$row;}
return $arr;
}
function deleteNews($id){
try{
$sql="DELETE FROM msgs WHERE id=$id";
$res=$this->_db->exec($sql);
if(!$res){
throw new Exception($this->_db->lastErrorMsg());
}else{
return TRUE;
}
}catch(Exception $e){
// $e->getMessage(); - при необходимости посылаем себе письмо или чего еще
return FALSE;// и возвращаем FALSE
}
}
function clearStr($str){
$str=strip_tags($str);
return $this->_db->escapeString($str);
}
function clearInt($int){
return abs((int)$int);
}
public function printProp(){
echo "Prop: <br>\n";
foreach($this as $name=>$val){// перебор свойств объекта
echo " $name: $val;<br>";
}unset($name,$val);
}
}
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
$t=$news->clearStr($_POST["title"]);
$c=$news->clearStr($_POST["category"]);
$d=$news->clearStr($_POST["description"]);
$s=$news->clearStr($_POST["source"]);
if(empty($t) or empty($d)){
$errMsg.="Заполните все поля!<br>\n";
}else{
if(!$news->saveNews($t,$c,$d,$s)){
$errMsg.="Произошла ошибка при добавлении новости.<br>\n";
}else{
header("Location: https://yakoffka.ru/conspects/laboratory_3.2.1");// избавляемся от $_POST
exit;
}
}
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$result=$news->getNews();
if(!is_array($result)){
$errMsg='Ошибка вывода ленты новостей.<br>\n';
$result->columnType(0);
$result->columnType(1);
$result->columnType(2);
$result->columnType(3);
}else{
echo '<p>новостей: '.count($result).'шт.</p>';
foreach($result as $key=>$arr_news){
echo "
<div class='news'>
<h2>".$arr_news['title']."</h2>
<!--div class='id'>id=".$arr_news['id']."</div-->
<div class='datetime'>".date('Y.m.d',$arr_news['datetime'])." ".$arr_news['category']."</div>
<div class='description'>".$arr_news['description']."</div>
<div class='source'>источник: ".$arr_news['source']."</div>
<form action='https://yakoffka.ru/conspects/laboratory_3.2.1' method='post'>
<input type='hidden' name='del_news' value='".$arr_news['id']."'>
<input type='submit' value='удалить эту новость'></p>
</form>
</div>";
}
}
02
03
04
05
06
07
08
09
10
11
12
$id=$news->clearInt($_POST['del_news']);
if($id>0){
if(!$news->deleteNews($id)){
$errMsg="Ошибка удаления записи.<br>\n";
}else{
header("Location: https://yakoffka.ru/conspects/laboratory_3.2.1");// избавляемся от $_POST
//exit;
$errMsg="Ошибка удаления записи.<br>\n";
}
}
Создаём основной файл новостной ленты. Также добавим правило RewriteRule в .htaccess для вновь создаваемого файла.
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// реализуем метод автозагрузки
spl_autoload_register(function($class){
include(DIR_SRC_CONSP_PHP32."/_classes/$class.class.php");
});
$errMsg="";
$news=new NewsDB();
if($_SERVER['REQUEST_METHOD']=='POST'){
if($_POST['title']){
require DIR_SRC_CONSP_PHP32."/_classes/save_news.inc.php";
}elseif($_POST['del_news']){
require DIR_SRC_CONSP_PHP32."/_classes/delete_news.inc.php";
}
}
$mc.="
<p class='err_mess'><?php echo \$errMsg;?></p>
<?php
echo \"
<h2>Добавление новости</h2>
<form action='https://yakoffka.ru/conspects/laboratory_3.2.1' method='post'>
<p>Заголовок новости: <input type='text' name='title' style='width:200px;'>
Выберите категорию:
<select name='category'>
<option value='1'>Наука</option>
<option value='2'>Образование</option>
<option value='3'>Культура</option>
</select>
Текст новости:</p>
<textarea name='description' cols='90' rows='10' style='width:100%'></textarea><br>
<p>Источник: <input type='text' name='source'> <input type='submit' value='Добавить'></p>
</form>
\";
require('/full/path/to/_php32/_classes/get_news.inc.php');
?>
";
Капустин Яков (2018.12.28 22:24)