← Вернуться к списку тем

Получение данных из БД

Подскажите пожалуйста как получить данные из бд и вывести их в бота?
Скриншот: https://ibb.co/1XSj03s
Есть таблица mytable а в ней Столбцы name и surname (имя и фамилия).
По запросу в боте Имени он бы выдавал Фамилию.
Пишем боту к примеру: Вадим а он в ответ: Петров. Пишем Иван в ответ Кротков.
Если можно пример.
Спасибо большое за помощь,вы супер.

Ответы


  • iMakeBots [14.05.2020 в 14:52 → Вадим]
    Попробуйте вот этот код.

    Не тестировал.

    <?php
    header("HTTP/1.1 200 OK");
    header('Content-type: text/html; charset=utf-8');
    
    new Bot();
    
    class Bot
    {
        private $token = "ВАШ_ТОКЕН";
    
        private $host = 'localhost';
        private $db = '';
        private $user = '';
        private $pass = '';
        private $charset = 'utf8mb4';
    
        private $pdo;
    
        public function __construct()
        {
            $this->setPdo();
            $this->router(json_decode(file_get_contents('php://input')));
            return true;
        }
    
        private function router($data)
        {
            if (isset($data->message->text)) {
                if ($data->message->text == "/start") {
                    $this->sendMessage($data->message->chat->id, "Пришлите имя пользователя");
                } else { 
                    $select = $this->pdo->prepare("SELECT * FROM mytable WHERE name = :name LIMIT 1");
                    $select->execute(['name' => $data->message->text]);
                    if ($select->rowCount() === 0) {
                        $this->sendMessage($data->message->chat->id, "По запросу =" . $data->message->text . "= данных нет");
                    } else {
                        $item = $select->fetch();
                        $this->sendMessage($data->message->chat->id, $data->message->text . " - " . $item['surname']);
                    }
                }
            } else { 
                $this->sendMessage($data->message->chat->id, "Wrong data");
            }
            return true;
        }
    
        private function sendMessage($user_id, $text)
        {
            $data_send = [
                'chat_id' => $user_id,
                'text' => $text,
                'parse_mode' => 'html'
            ];
            return $this->botApiQuery("sendMessage", $data_send);
        }
    
        private function setPdo()
        {
            $dsn = "mysql:host=$this->host;dbname=$this->db;charset=$this->charset";
            $opt = [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                PDO::ATTR_EMULATE_PREPARES => false,
                PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci"
            ];
            $this->pdo = new PDO($dsn, $this->user, $this->pass, $opt);
        }
    
        private function botApiQuery($method, $fields = array())
        {
            $ch = curl_init('https://api.telegram.org/bot' . $this->token . '/' . $method);
            curl_setopt_array($ch, array(
                CURLOPT_POST => count($fields),
                CURLOPT_POSTFIELDS => http_build_query($fields),
                CURLOPT_SSL_VERIFYPEER => 0,
                CURLOPT_RETURNTRANSFER => 1,
                CURLOPT_TIMEOUT => 10
            ));
            $r = json_decode(curl_exec($ch), true);
            curl_close($ch);
            return $r;
        }
    }
    ?>
  • Вадим [14.05.2020 в 18:31 → iMakeBots]
    Всё работает.СПАСИБО
  • Вадим [14.05.2020 в 18:58 → iMakeBots]
    А в место фамилии можно файл передать?
  • iMakeBots [14.05.2020 в 19:01 → Вадим]
    Конечно. Используйте метод апи Telegram sendDocument
  • Вадим [14.05.2020 в 19:17 → iMakeBots]
    а где в примере прописать?
  • Вадим [14.05.2020 в 22:47 → iMakeBots]
    на sendDocument не реагирует.Хочу ссылку на видео передать вместо фамилии.
    ссылка: https://t.me/fullfilmsnavecher/222
  • iMakeBots [16.05.2020 в 08:24 → Вадим]
    https://t.me/fullfilmsnavecher/222 -> это ссылка на пост в канале - она как ссылка на файл не будет валидной

    $this->sendMessage($data->message->chat->id, $data->message->text . " - " . $item['surname']);

    Замените на
    $this->botApiQuery("sendMessage", ['chat_id' => $data->message->chat->id, 'file' => 'ССЫЛКА на ФАЙЛ']);
  • Вадим [16.05.2020 в 08:55 → iMakeBots]
    тоже молчит бот
  • iMakeBots [16.05.2020 в 08:58 → iMakeBots]
    не проснулся еще)))) Допустил неточность

    sendMessage замените на sendDocument
  • Вадим [16.05.2020 в 09:01 → iMakeBots]
    так стоит $this->botApiQuery("sendDocument", ['chat_id' => $data->message->chat->id, 'file' => 'https://сайт/file/Logo.mp4']);
  • iMakeBots [16.05.2020 в 09:02 → iMakeBots]
    Размер файла?
  • Вадим [16.05.2020 в 09:03 → iMakeBots]
    768 КБ
  • Вадим [16.05.2020 в 09:05 → iMakeBots]
    так из базы пробовал $this->botApiQuery("sendDocument", ['chat_id' => $data->message->chat->id, 'file' => $item['surname']]);
    тихо
  • Вадим [16.05.2020 в 11:50 → iMakeBots]
    Спасибо ещё раз. Надо было вместо 'file' => написать 'document' => и всё заработало
  • Вадим [16.05.2020 в 11:51 → iMakeBots]
    Ещё возник вопрос. Как сделать комментарий к файлу?
  • iMakeBots [16.05.2020 в 11:52 → iMakeBots]
    Укажите доп параметр caption
  • Вадим [16.05.2020 в 12:19 → iMakeBots]
    Спасибо.
    Выводит так: https://ibb.co/c3HzBm5
  • Вадим [16.05.2020 в 18:10 → iMakeBots]
    А как вывести несколько данных?
    К примеру есть несколько фильмов в базе с одинаковым названием.
  • iMakeBots [18.05.2020 в 09:25 → Вадим]
    $select = $this->pdo->prepare("SELECT * FROM mytable WHERE name = :name");
    $select->execute(['name' => $data->message->text]);
    f ($select->rowCount() === 0) {
        $this->sendMessage($data->message->chat->id, "По запросу =" . $data->message->text . "= данных нет");
    } else {
        while ($row = $select->fetch()) {
            $this->sendMessage($data->message->chat->id, $data->message->text . " - " . $row['surname']);
        }
    }
  • Вадим [18.05.2020 в 12:22 → iMakeBots]
    Один результат выдаёт.
    И так один: SELECT * FROM mytable WHERE name LIKE :name
  • iMakeBots [18.05.2020 в 12:48 → iMakeBots]
    Приведите пример данных в бд
  • Вадим [18.05.2020 в 13:01 → iMakeBots]
    https://ibb.co/jTBwKvR
  • iMakeBots [18.05.2020 в 13:17 → iMakeBots]
    Покажите ваш код
  • Вадим [18.05.2020 в 13:20 → iMakeBots]
    if (isset($data->message->text)) {
    if ($data->message->text == "/start") {

    $this->sendMessage($data->message->chat->id, "Приветствую!nПришлите мне название фильма.(Без ошибок)");

    } else {

    $select = $this->pdo->prepare("SELECT * FROM mytable WHERE name = :name");

    $select->execute(['name' => $data->message->text]);
    if ($select->rowCount() === 0) {
    $this->sendMessage($data->message->chat->id, "По запросу =<b>" . $data->message->text . "</b>= данных нет,возможно написано с ошибкой.");
    } else {
    $item = $select->fetch();
    $this->botApiQuery("sendDocument", ['chat_id' => $data->message->chat->id, 'document' => $item['link'] ,'caption' => "<b>".$data->message->text." - (".$item['year'].")</b> rnИщите ваши любимые фильмы",'parse_mode' => 'html']);
    }
    }
    } else {
    $this->sendMessage($data->message->chat->id, "Wrong data");
    }
    return true;
    }
  • iMakeBots [18.05.2020 в 13:22 → iMakeBots]
    Обратите внимание на пример кода который я привел выше - вы не используете цикл while
  • Вадим [18.05.2020 в 13:44 → iMakeBots]
    спасибо. всё отлично.
  • Вадим [18.05.2020 в 14:05 → iMakeBots]
    Я уже наверно вам надоел :-)
    Если конечно у вас есть время,интересует ещё один вопрос.
    Как добавить ещё вывод похожих названий?
    К примеру есть название: Полёт на луну или просто Полёт.
    Или: Крепкий орешек 1,Крепкий орешек 2,Крепкий орешек 3
  • iMakeBots [18.05.2020 в 14:07 → iMakeBots]
    Если не будете использовать полнотекстовый поиск, тогда просто используйте оператор LIKE

    ... LIKE concat('%',:title,'%') ...
  • Вадим [23.05.2020 в 18:32 → iMakeBots]
    Спасибо всё отлично.
    Если можно ещё спрошу?
    Можно вывести данные в кнопки,с кнопкой далее и назад.(Это не критично).
    Пример:
    https://ibb.co/bN2QDgb
    https://ibb.co/jfnhhG7
    И вообще как в скрипте добавить кнопки ReplyKeyboardMarkup что-то пытался на ваших примерах,не выходит.
    Спасибо.
  • iMakeBots [23.05.2020 в 18:56 → Вадим]
    Кнопки Вперед<=>Назад - это по типу постраничной навигации, для этого можно использовать параметры LIMIT в запросах к MySQL - первым параметром передавайте начало вторым количество:

    LIMIT 0, 10 - значит вывести первые 10 шт записей попадающие под условия запроса - 0 - 9 записи,
    LIMIT 10, 10 - это типа 2 страница то есть следующие 10 записей начиная c 10-й записи, 10 - 19 записи

    Примеры кнопок, которые вы привели это InlineKeyboardMarkup.
  • Вадим [23.05.2020 в 19:00 → iMakeBots]
    Лимит добавил на 20 а вот как в кнопки вывести незнаю,ещё и кнопок хотелось добавить ReplyKeyboardMarkup
  • iMakeBots [23.05.2020 в 19:02 → iMakeBots]
    Примеры в статье очень наглядные - попробуйте.

  • Вадим [25.05.2020 в 15:12 → iMakeBots]
    именно в этот пример можно добавить ReplyKeyboardMarkup?
    уже всё перепробовал.
  • iMakeBots [25.05.2020 в 15:19 → iMakeBots]
    <?php
    header("HTTP/1.1 200 OK");
    header('Content-type: text/html; charset=utf-8');
    
    new Bot();
    
    class Bot
    {
        private $token = "ВАШ_ТОКЕН";
    
        private $host = 'localhost';
        private $db = '';
        private $user = '';
        private $pass = '';
        private $charset = 'utf8mb4';
    
        private $pdo;
    
        public function __construct()
        {
            $this->setPdo();
            $this->router(json_decode(file_get_contents('php://input')));
            return true;
        }
    
        private function router($data)
        {
            if (isset($data->message->text)) {
                if ($data->message->text == "/start") {
                    $this->sendMessageWithButtons($data->message->chat->id, "Пришлите имя пользователя + еще выводим кнопки");
                } else { 
                    $select = $this->pdo->prepare("SELECT * FROM mytable WHERE name = :name LIMIT 1");
                    $select->execute(['name' => $data->message->text]);
                    if ($select->rowCount() === 0) {
                        $this->sendMessage($data->message->chat->id, "По запросу =" . $data->message->text . "= данных нет");
                    } else {
                        $item = $select->fetch();
                        $this->sendMessage($data->message->chat->id, $data->message->text . " - " . $item['surname']);
                    }
                }
            } else { 
                $this->sendMessage($data->message->chat->id, "Wrong data");
            }
            return true;
        }
    
        private function sendMessage($user_id, $text)
        {
            $data_send = [
                'chat_id' => $user_id,
                'text' => $text,
                'parse_mode' => 'html'
            ];
            return $this->botApiQuery("sendMessage", $data_send);
        }
    
        private function sendMessageWithButtons($user_id, $text, $buttons)
        {
            $data_send = [
                'chat_id' => $user_id,
                'text' => $text,
                "reply_markup" => $this->getButtons(),
                'parse_mode' => 'html'
            ];
            return $this->botApiQuery("sendMessage", $data_send);
        }
    
        private function getButtons() {
            $buttons = json_encode([
               "keyboard" => [
                    [
                        [
                            // текст кнопки
                            "text" => "Button 1",
                            // необязательное поле: в значении true при нажатии на кнопку будет передан телефон
                            "request_contact" => false,
                            // необязательное поле: в значении true будет передано месторасположение
                            "request_location" => false,
                            // request_location и request_contact - взаимоисключающие значения
                        ],
                        [
                            "text" => "Button 2",
                        ]
                    ]
                ],
                // в значении true после нажатия на любую кнопку клавиатура будет скрыта,
                // вызвать обратно можно по нажатию спец иконки в интерфейсе приложения Телеграм
                'one_time_keyboard' => false,
                // в случае false клавиатура всегда имеет ту же высоту, что и стандартная клавиатура приложения.
                'resize_keyboard' => true,
                // показывать клавиатуру только пользователю который ее вызвал, удобно для групп
                'selective' => true,
            ], true);
    
            return $buttons;
        }
    
        private function setPdo()
        {
            $dsn = "mysql:host=$this->host;dbname=$this->db;charset=$this->charset";
            $opt = [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                PDO::ATTR_EMULATE_PREPARES => false,
                PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci"
            ];
            $this->pdo = new PDO($dsn, $this->user, $this->pass, $opt);
        }
    
        private function botApiQuery($method, $fields = array())
        {
            $ch = curl_init('https://api.telegram.org/bot' . $this->token . '/' . $method);
            curl_setopt_array($ch, array(
                CURLOPT_POST => count($fields),
                CURLOPT_POSTFIELDS => http_build_query($fields),
                CURLOPT_SSL_VERIFYPEER => 0,
                CURLOPT_RETURNTRANSFER => 1,
                CURLOPT_TIMEOUT => 10
            ));
            $r = json_decode(curl_exec($ch), true);
            curl_close($ch);
            return $r;
        }
    }
    ?>
  • Вадим [24.05.2020 в 02:18 → Вадим]
    увы не получается кнопки добавить.
  • Вадим [25.05.2020 в 15:44 → Вадим]
    молчит бот.
    по моему из-за этой строки
    $this->sendMessageWithButtons($data->message->chat->id, "Пришлите имя пользователя еще выводим кнопки");
  • iMakeBots [25.05.2020 в 15:46 → Вадим]
    Вы все методы добавили?
  • Вадим [25.05.2020 в 15:48 → Вадим]
    private function sendMessage($user_id, $text)
        {
            $data_send = [
                'chat_id' => $user_id,
                'text' => $text,
                'parse_mode' => 'html'
            ];
            return $this->botApiQuery("sendMessage", $data_send);
        }
    
        private function sendMessageWithButtons($user_id, $text, $buttons)
        {
            $data_send = [
                'chat_id' => $user_id,
                'text' => $text,
                "reply_markup" => $this->getButtons(),
                'parse_mode' => 'html'
            ];
            return $this->botApiQuery("sendMessage", $data_send);
        }
    
        private function getButtons() {
            $buttons = json_encode([
               "keyboard" => [
                    [
                        [
                            // текст кнопки
                            "text" => "Button 1",
                            // необязательное поле: в значении true при нажатии на кнопку будет передан телефон
                            "request_contact" => false,
                            // необязательное поле: в значении true будет передано месторасположение
                            "request_location" => false,
                            // request_location и request_contact - взаимоисключающие значения
                        ],
                        [
                            "text" => "Button 2",
                        ]
                    ]
                ],
                // в значении true после нажатия на любую кнопку клавиатура будет скрыта,
                // вызвать обратно можно по нажатию спец иконки в интерфейсе приложения Телеграм
                'one_time_keyboard' => false,
                // в случае false клавиатура всегда имеет ту же высоту, что и стандартная клавиатура приложения.
                'resize_keyboard' => true,
                // показывать клавиатуру только пользователю который ее вызвал, удобно для групп
                'selective' => true,
            ], true);
    
            return $buttons;
        }
  • iMakeBots [25.05.2020 в 15:50 → Вадим]
    Посмотрите есть ли ошибки в логах на сервере и в webhookinfo
  • Вадим [25.05.2020 в 15:58 → Вадим]
    да нету вроде ошибок
  • Вадим [25.05.2020 в 16:12 → Вадим]
    удалил в private function sendMessageWithButtons($user_id, $text, $buttons)
    $buttons появились
  • Вадим [25.05.2020 в 17:50 → Вадим]
    callback_data как обработать?
  • iMakeBots [25.05.2020 в 18:07 → Вадим]
    Проверяете наличие этого свойства в объекте который вам пришел и обрабатываете заранее подготовленной логикой.

    В обоих статьях про кнопки есть примеры обработки callback_data.

    Для теста поднимите бота из последней статьи про кнопки - "поиграйте" с методами и параметрами - поймете как все работает, потом смело и уверенно прикрутите к своему боту любой набор кнопок клавиатуры или инлайн.
  • Вадим [25.05.2020 в 18:35 → Вадим]
    в этом боте не работает по чему-то
     /** Обработка Inline кнопки
         * @param $callback_data
         */
        private function actionInlineButton($callback_data)
        {
            // получаем массив из переданного параметра callback_data кнопки inline
            // разделяем по знаку _
            // под индексом 0 идет значение actionInlineButton
            // под последующим индексом 1 идет значение, которое может при создании
            // кнопки генерироваться под ваши требования, например это может быть id какого-нибудь объекта
            // значений может быть больше, но общая строка не должна превышать 64 байта
            $params = explode("_", $callback_data["data"]);
    
            // отправляем Уведомление
            $this->botApiQuery("answerCallbackQuery", [
                "callback_query_id" => $callback_data["id"],
                "text" => "Событие inline получено",
                "alert" => false
            ]);
    
            // отправляем текстовое сообщение
            $this->botApiQuery("sendMessage", [
                "chat_id" => $this->userId,
                "text" => "Параметр " . $params["1"],
            ]);
        }
    
        /**
         * Обработка KeyBoard кнопки
         */
        private function actionKeyboardButton()
        {
            // отправляем текстовое сообщение
            $this->botApiQuery("sendMessage", [
                "chat_id" => $this->userId,
                "text" => "Обработана кнопка " . $this->data['message']['text'],
            ]);
        }
    
  • iMakeBots [25.05.2020 в 21:00 → Вадим]
    Код который вы привели он не универсальный и работает в тех условиях которые описаны в боте в статье (там где вы его скопировали) - воспроизведите условия для этих методов и у вас все заработает
  • Вадим [26.05.2020 в 15:29 → Вадим]
    Просто опыта маловата.
  • iMakeBots [26.05.2020 в 15:56 → Вадим]
    Рассмотрите метод route() в примере в статье, посмотрите как он обрабатывает поступающие к нему запросы, обратите внимание на условия где ожидаются данные callback_data
  • Вадим [29.06.2020 в 00:17 → Вадим]
    Так и не понял увы,как при клике на кнопку вывести текст к данному примеру бота.
  • Вадим [03.09.2020 в 13:34 → Вадим]
    Здравствуйте,Ещё хотел спросить,как можно добавить поиск ещё и во второй колонке?
    $select = $this->pdo->prepare("SELECT * FROM mytable WHERE name = :name LIMIT 1");
    ищет в колонке name можно ещё колонку ID добавить?
    Как сделать на ID лимит 1 а на name лимит 30
  • iMakeBots [07.09.2020 в 10:44 → Вадим]
    Лимит можно применить только к запросу, не к условию.

    Добавить еще одно условие к WHERE можно например через AND
    $select = $this->pdo->prepare("SELECT * FROM mytable WHERE name = :name AND id = :id LIMIT 1");
  • Вадим [06.09.2020 в 18:03 → iMakeBots]
    Скажите пожалуйста как сделать приветствие пользователя по имени,в данном коде.
    Спасибо.
  • Вадим [08.09.2020 в 14:36 → Вадим]
    вот и у меня ни как.
  • iMakeBots [08.09.2020 в 14:38 → Вадим]
    В каком коде?
  • Вадим [08.09.2020 в 14:40 → iMakeBots]
    приветствие по имени не получается добавить.
  • Вадим [09.09.2020 в 23:03 → iMakeBots]
    Тот что выше.
  • Вадим [09.09.2020 в 23:04 → iMakeBots]
    В самом вверху
  • iMakeBots [10.09.2020 в 12:43 → Вадим]
    Замените в нем метод router()
        private function router($data)
        {
            if(isset($data->message->new_chat_participant)) {
                $name = trim($data->message->new_chat_participant->first_name . ' ' . $data->message->new_chat_participant->last_name);
                $this->sendMessage($data->message->chat->id, "Привет " . $name);
            } elseif (isset($data->message->text)) {
                if ($data->message->text == "/start") {
                    $this->sendMessage($data->message->chat->id, "Пришлите имя пользователя");
                } else { 
                    $select = $this->pdo->prepare("SELECT * FROM mytable WHERE name = :name LIMIT 1");
                    $select->execute(['name' => $data->message->text]);
                    if ($select->rowCount() === 0) {
                        $this->sendMessage($data->message->chat->id, "По запросу =" . $data->message->text . "= данных нет");
                    } else {
                        $item = $select->fetch();
                        $this->sendMessage($data->message->chat->id, $data->message->text . " - " . $item['surname']);
                    }
                }
            } else { 
                $this->sendMessage($data->message->chat->id, "Wrong data");
            }
            return true;
        }
  • Вадим [10.09.2020 в 15:24 → iMakeBots]
    нету имени
  • Вадим [28.09.2020 в 16:55 → iMakeBots]
    Не работает.
  • Вадим [15.03.2021 в 17:53 → iMakeBots]
    Ребята помогите встретить пользователя по имени в коде в шапке,уже всё перепробовал.