Работа с БД в SMF для начинающих.

Автор Kira, 07 марта 2018, 12:00:33

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

Kira

В помощь новичкам и в качестве конспекта для себя.

Чтобы ничего не испортить, тренироваться будем на кошках. А чё, все любят котиков.

Сперва создадим в базе таблицу и заполним её котиками.
Правильно это делать при установке нашего мода, но для тренировки и наглядности пока не будем связываться с менеджером пакетов.

Создадим файл install_db.php с таким содержимым, положим на сервер и запустим его в браузере.
<?php
require_once("E:\\OSPanel\\domains\\w202\\SSI.php");
if (!
defined('SMF'))
 die(
'Hacking attempt...');

global 
$smcFunc;
  
// создаём таблицу для котиков
    
$smcFunc['db_query'](''"CREATE TABLE IF NOT EXISTS {db_prefix}cats (
      `id` int(2) NOT NULL auto_increment,
      `name` varchar(20) NOT NULL default '',
      `weight` int(2) NOT NULL default '0',
      PRIMARY KEY  (`id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=6"
);

    
// добавляем котиков в таблицу
    
$smcFunc['db_query'](''"INSERT IGNORE INTO {db_prefix}cats VALUES (1, 'Василий', 25)");
    
$smcFunc['db_query'](''"INSERT IGNORE INTO {db_prefix}cats VALUES (2, 'Мурка', 5)");
    
$smcFunc['db_query'](''"INSERT IGNORE INTO {db_prefix}cats VALUES (3, 'Варька', 7)");
?>

Если всё сделали правильно, у нас в базе форума появилась новая таблица с котиками. У неё три столбца (id, name и weight) и в ней содержатся три котика.

Теперь попробуем до них добраться. Выведем список котиков на экран. А чтобы было не так скучно, выведем не в строку, а в выпадающий список.
Создадим ещё один файл и назовём его cats.php
Напишем в нём следующее.
<?php
require_once("E:\\OSPanel\\domains\\w202\\SSI.php");
if (!
defined('SMF'))
 die(
'Hacking attempt...');

global 
$smcFunc;

// Получаем список котиков из базы
 
$request $smcFunc['db_query']('''
 SELECT id, name
 FROM {db_prefix}cats'
);
 
 
//Рисуем выпадающий список
 
echo '<form><select name="cats_list">';
 
//А теперь заполняем его
 
while ($row $smcFunc['db_fetch_assoc']($request)){
 echo 
'<option value = "'.$row["id"].'">'$row["name"].' </option>';
 }
 echo 
'</select>';
 
//Рисуем кнопку "Отправить"
 
echo'<p><input type="submit" value="Отправить"></p><form>';


Дадим пользователю возможность комментировать наших котиков. Для этого создадим таблицу с комментариями.
В первом файле поменяем содержимое на следующее и запустим его
// создаём таблицу для комментариев
    $smcFunc['db_query']('', "CREATE TABLE IF NOT EXISTS {db_prefix}cats_comments (
      `cat_id` int(2) NOT NULL,
      `cat_comment` varchar(100) NOT NULL
     ) ENGINE=MyISAM  DEFAULT CHARSET=utf8");

    // добавляем комментарии в таблицу
    $smcFunc['db_query']('', "INSERT IGNORE INTO {db_prefix}cats_comments VALUES (1, 'Фуу, жыырный!')");
    $smcFunc['db_query']('', "INSERT IGNORE INTO {db_prefix}cats_comments VALUES (2, 'Мимими')");
$smcFunc['db_query']('', "INSERT IGNORE INTO {db_prefix}cats_comments VALUES (1, 'Бугага!!!!!!!!!!!!111один')");
    $smcFunc['db_query']('', "INSERT IGNORE INTO {db_prefix}cats_comments VALUES (2, 'Какая прелесть!')");
$smcFunc['db_query']('', "INSERT IGNORE INTO {db_prefix}cats_comments VALUES (2, 'Урурур!')");

А во втором файле после echo '</select>'; добавим поле для комментаия и обработаем его.
//Добавляем поле для ввода комментария
 echo'<p><textarea name="comment"></textarea></p>';
 
 //Проверяем, существует ли то, что мы будем вносить в базу
 if(!empty($_GET['cats_list']) && !empty($_GET['comment'])){
 
 //Вносим в базу
 $smcFunc['db_insert']('insert',
 '{db_prefix}cats_comments',
 array(
 'cat_id' => 'int', 'cat_comment' => 'string',
 ),
 array(
 $_GET['cats_list'], $smcFunc['db_escape_string']($_GET['comment']),
 ),
 array()
 );
 
Добавить комментарий в базу можно и таким способом.
//Вносим в базу другим способом
 $smcFunc['db_query']('', '
 INSERT INTO {db_prefix}cats_comments
 SET cat_id = {int:cat_id},cat_comment = {string:cat_comment}',
 array(
 'cat_id' => $_GET['cats_list'],
 'cat_comment' => $smcFunc['db_escape_string']($_GET['comment']),
 )
 );

Ну и выведем на экран имена наших котиков с комментариями.
//Объединяем таблицы
 $request = $smcFunc['db_query']('', '
 SELECT *
 FROM {db_prefix}cats
 LEFT JOIN {db_prefix}cats_comments
 ON id = cat_id
 ');

 //Выводим
 while ($row = $smcFunc['db_fetch_assoc']($request)){
 echo $row["name"].' - '. $row["cat_comment"].' <br><br>';
 }

И под конец, освободим память от наших котиков.
//Освобождаем память от наших котиков
 $smcFunc['db_free_result']($request);

Вам недоступны вложения в этом разделе.

iaroslav

Спасибо. Оно реально полезная штука (по крайней мере для меня - лезть в дебри документации, что бы разобраться как через функции форума работать с базой мне было лениво). Единственное что - можете уточнить, о какой именно версии форума тут идёт речь? И можно ли как-то обойтись меньшей кровью, чем подгружать именно SSI.PHP с апи форума. Или оно особой экономии по ресурсам не даст и лучше именно тянуть ssi.php, а не углу[censored]ся в дебри форумного движка?

Кстати, а вы не пробовали через функции движка обращаться к другим базам данных? То есть не таблицам в той же базе данных, а именно к другой базе данных, у которой есть доступ для того же самого пользователя?

Kira

Я только начал осваивать, поэтому мало что могу подсказать.

Цитата: iaroslav от 07 марта 2018, 12:13:44и лучше именно тянуть ssi.php, а не углу[censored]ся в дебри форумного движка?
В первосточнике большими буквами написано "Call SSI.php before anything else
Before you do anything else you must call the SSI.php included with SMF." Сделал так, не стал проверять. :)

Цитата: iaroslav от 07 марта 2018, 12:13:44можете уточнить, о какой именно версии форума тут идёт речь?
Так понимаю, что справедливо для любой. Я игрался с 2.0.13.

iaroslav

Цитата: Kira от 07 марта 2018, 14:48:00Так понимаю, что справедливо для любой. Я игрался с 2.0.13.
Просто там же с 2.0.14 (или с 2.0.13 даже) убрали mysql (из-за прекращения использования его в php 7.0). Мог язык запросов слегка смениться...

А про использование другой базы всё-таки ничего не находили?

Kira

Так понимаю, в SMF свои функции для работы с БД как раз для таких случаев. Чтобы в случае каких изменений не переписывать весь движок с установленными модами, а только эти функции.

Цитата: iaroslav от 10 марта 2018, 11:42:14А про использование другой базы всё-таки ничего не находили?
Может глупость скажу, ноя бы попробовал перед вызовом функции переопределить global $db_server, $db_user, $db_passwd, $db_name;, а потом вернул бы назад.

iaroslav

Цитата: Kira от 11 марта 2018, 08:58:19Так понимаю, в SMF свои функции для работы с БД как раз для таких случаев. Чтобы в случае каких изменений не переписывать весь движок с установленными модами, а только эти функции.
Отчасти да.
Цитата: Kira от 11 марта 2018, 08:58:19Может глупость скажу, ноя бы попробовал перед вызовом функции переопределить global $db_server, $db_user, $db_passwd, $db_name;, а потом вернул бы назад.
Есть подозрение, что оно не сработает. Для использования другой базы, именно при таком алгоритме, требуется завершить текущие подключения, потом подключиться по новой уже с новыми параметрами. Вряд ли в смф для каждого запроса создаётся новое подключение...
Впрочем, спасибо за идею - надо будет проверить. А то теория теорией, но что там на практике...

Kira

Может, это поможет?


$smcFunc['db_select_db'] (database_name, connection)
Will return exact same results as mysql_select_db.
PostgreSQL functions will have this return true always in postg_select_db. PostgreSQL has database selected upon creating the connection.
SQlite will do nothing as there is only one database per file.
No Examples

iaroslav

Ага, спасибо. Похоже вот это оно самое и есть.