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

← К списку тем

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

Авторизуйтесь через Telegram, чтобы ответить.
Откройте бот @SiteAuthBot, нажмите кнопку Старт/Start. Следуйте инструкциям бота.


Ответы

  • Попробуйте вот этот код.

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

    <?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;
        }
    }
    ?>
    iMakeBots 14.05.2020 в 14:52
    • Всё работает.СПАСИБО
      Вадя 14.05.2020 в 18:31
    • А в место фамилии можно файл передать?
      Вадя 14.05.2020 в 18:58
      • Конечно. Используйте метод апи Telegram sendDocument
        iMakeBots 14.05.2020 в 19:01
        • а где в примере прописать?
          Вадя 14.05.2020 в 19:17
        • на sendDocument не реагирует.Хочу ссылку на видео передать вместо фамилии.
          ссылка: https://t.me/fullfilmsnavecher/222
          Вадя 14.05.2020 в 22:47
          • 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' => 'ССЫЛКА на ФАЙЛ']);
            iMakeBots 16.05.2020 в 08:24
            • тоже молчит бот
              Вадя 16.05.2020 в 08:55
            • не проснулся еще)))) Допустил неточность

              sendMessage замените на sendDocument
              iMakeBots 16.05.2020 в 08:58
            • так стоит $this->botApiQuery("sendDocument", ['chat_id' => $data->message->chat->id, 'file' => 'https://сайт/file/Logo.mp4']);
              Вадя 16.05.2020 в 09:01
            • Размер файла?
              iMakeBots 16.05.2020 в 09:02
            • 768 КБ
              Вадя 16.05.2020 в 09:03
            • так из базы пробовал $this->botApiQuery("sendDocument", ['chat_id' => $data->message->chat->id, 'file' => $item['surname']]);
              тихо
              Вадя 16.05.2020 в 09:05
            • Спасибо ещё раз. Надо было вместо 'file' => написать 'document' => и всё заработало
              Вадя 16.05.2020 в 11:50
            • Ещё возник вопрос. Как сделать комментарий к файлу?
              Вадя 16.05.2020 в 11:51
            • Укажите доп параметр caption
              iMakeBots 16.05.2020 в 11:52
            • Спасибо.
              Выводит так: https://ibb.co/c3HzBm5
              Вадя 16.05.2020 в 12:19
    • А как вывести несколько данных?
      К примеру есть несколько фильмов в базе с одинаковым названием.
      Вадя 16.05.2020 в 18:10
      • $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']);
            }
        }
        iMakeBots 18.05.2020 в 09:25
        • Один результат выдаёт.
          И так один: SELECT * FROM mytable WHERE name LIKE :name
          Вадя 18.05.2020 в 12:22
        • Приведите пример данных в бд
          iMakeBots 18.05.2020 в 12:48
          • https://ibb.co/jTBwKvR
            Вадя 18.05.2020 в 13:01
          • Покажите ваш код
            iMakeBots 18.05.2020 в 13:17
            • 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;
              }
              Вадя 18.05.2020 в 13:20
            • Обратите внимание на пример кода который я привел выше - вы не используете цикл while
              iMakeBots 18.05.2020 в 13:22
            • спасибо. всё отлично.
              Вадя 18.05.2020 в 13:44
            • Я уже наверно вам надоел :-)
              Если конечно у вас есть время,интересует ещё один вопрос.
              Как добавить ещё вывод похожих названий?
              К примеру есть название: Полёт на луну или просто Полёт.
              Или: Крепкий орешек 1,Крепкий орешек 2,Крепкий орешек 3
              Вадя 18.05.2020 в 14:05
            • Если не будете использовать полнотекстовый поиск, тогда просто используйте оператор LIKE

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

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

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

              iMakeBots 23.05.2020 в 19:02
            • именно в этот пример можно добавить ReplyKeyboardMarkup?
              уже всё перепробовал.
              Вадя 25.05.2020 в 15:12
            • <?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;
                  }
              }
              ?>
              iMakeBots 25.05.2020 в 15:19
          • увы не получается кнопки добавить.
            Вадя 24.05.2020 в 02:18
            • молчит бот.
              по моему из-за этой строки
              $this->sendMessageWithButtons($data->message->chat->id, "Пришлите имя пользователя еще выводим кнопки");
              Вадя 25.05.2020 в 15:44
            • Вы все методы добавили?
              iMakeBots 25.05.2020 в 15:46
            • 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;
                  }
              Вадя 25.05.2020 в 15:48
            • Посмотрите есть ли ошибки в логах на сервере и в webhookinfo
              iMakeBots 25.05.2020 в 15:50
            • да нету вроде ошибок
              Вадя 25.05.2020 в 15:58
            • удалил в private function sendMessageWithButtons($user_id, $text, $buttons)
              $buttons появились
              Вадя 25.05.2020 в 16:12
            • callback_data как обработать?
              Вадя 25.05.2020 в 17:50
            • Проверяете наличие этого свойства в объекте который вам пришел и обрабатываете заранее подготовленной логикой.

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

              Для теста поднимите бота из последней статьи про кнопки - "поиграйте" с методами и параметрами - поймете как все работает, потом смело и уверенно прикрутите к своему боту любой набор кнопок клавиатуры или инлайн.
              iMakeBots 25.05.2020 в 18:07
            • в этом боте не работает по чему-то
               /** Обработка 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'],
                      ]);
                  }
              
              Вадя 25.05.2020 в 18:35
            • Код который вы привели он не универсальный и работает в тех условиях которые описаны в боте в статье (там где вы его скопировали) - воспроизведите условия для этих методов и у вас все заработает
              iMakeBots 25.05.2020 в 21:00
            • Просто опыта маловата.
              Вадя 26.05.2020 в 15:29
            • Рассмотрите метод route() в примере в статье, посмотрите как он обрабатывает поступающие к нему запросы, обратите внимание на условия где ожидаются данные callback_data
              iMakeBots 26.05.2020 в 15:56
            • Так и не понял увы,как при клике на кнопку вывести текст к данному примеру бота.
              Вадя 29.06.2020 в 00:17
            • Здравствуйте,Ещё хотел спросить,как можно добавить поиск ещё и во второй колонке?
              $select = $this->pdo->prepare("SELECT * FROM mytable WHERE name = :name LIMIT 1");
              ищет в колонке name можно ещё колонку ID добавить?
              Как сделать на ID лимит 1 а на name лимит 30
              Вадя 03.09.2020 в 13:34
            • Лимит можно применить только к запросу, не к условию.

              Добавить еще одно условие к WHERE можно например через AND
              $select = $this->pdo->prepare("SELECT * FROM mytable WHERE name = :name AND id = :id LIMIT 1");
              iMakeBots 07.09.2020 в 10:44
    • Скажите пожалуйста как сделать приветствие пользователя по имени,в данном коде.
      Спасибо.
      Вадя 06.09.2020 в 18:03
      • вот и у меня ни как.
        Вадя 08.09.2020 в 14:36
      • В каком коде?
        iMakeBots 08.09.2020 в 14:38
        • приветствие по имени не получается добавить.
          Вадя 08.09.2020 в 14:40
        • Тот что выше.
          Вадя 09.09.2020 в 23:03
        • В самом вверху
          Вадя 09.09.2020 в 23:04
          • Замените в нем метод 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;
                }
            iMakeBots 10.09.2020 в 12:43
            • нету имени
              Вадя 10.09.2020 в 15:24
            • Не работает.
              Вадя 28.09.2020 в 16:55