Как реализовать ajax запрос к БД?

92
02 сентября 2021, 05:10

Решил, тренировки ради, написать сервис для сокращения ссылок. На данный момент столкнулся с следующей трудностью:

Не совсем корректное поведение, при добавление ссылки, которой ещё нет в БД. Поясню – в input вставляю ссылку, которую необходимо сократить. Нажимаю submit и все :) происходит перезагрузка страницы, ссылка сокращается и добавляется в БД.

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

На данный момент меня интересуют 3 варианта и тогда этот компонент будет меня устраивать (его я планирую в дальнейшем вкорячить в другую реализацию).

1. Исходя из проблемы, я хочу реализовать подгрузку данных из БД ajax. Небольшая ремарка, я знаю, кто так пишет:

foreach ($sth as $existLink) {
      echo '<h1>...</h1>';
      echo '<ul>';
      echo '<li>...</li>';
      echo '</ul>';
}

Сжигают на кострах :), но эт это черновик и сейчас я разбираюсь с реализацией функционала, "красоту" наведу на финише. Поэтому прощу простить))

Файл отвечающий за обработку и сокращение ссылки:

<?php
include_once(__DIR__ . '/libraries/database.php');
$externalLink = $_POST['external_link'] ?? null;
function prepareExternalLink($link)
{
    $result = trim($link);
    $result = htmlspecialchars($result);
    return $result;
}
$preparedLink = prepareExternalLink($externalLink);
$sth = db_query("SELECT url, short_key FROM short WHERE url= '" . $preparedLink . "'");
if (empty($_POST['external_link'])) {
    echo 'Введите в поле ссылку, которую требуется сократь:';
} elseif (isset(db_query("SELECT url FROM short WHERE url= '" . $preparedLink . "'")->fetch()['url'])) {
// Должна подгружаться ajax    
foreach ($sth as $existLink) {
        echo '<h1>Такая ссылка уже есть в БД</h1>';
        echo '<ul>';
        echo '<li><strong>Внешняя ссылка</strong>: <a href="' . $existLink['url'] . '" target="_blank">' . $existLink['url'] . '</a></li>';
        echo '<li><strong>Сокращенная ссылка</strong>: <a href="//' . $_SERVER['HTTP_HOST'] . '/&' . $existLink['short_key'] . '" target="_blank">http://' . $_SERVER['HTTP_HOST'] . '/&' . $existLink['short_key'] . '</a></li>';
        echo '</ul>';
    }
} else {
    /*---- Генерация уникального id----*/
    $letters = 'qwertyuiopasdfghjklzxcvbnm1234567890';
    $count = strlen($letters);
    $intval = time();
    $result = '';
    for ($i = 0; $i < 4; $i++) {
        $last = $intval % $count;
        $intval = ($intval - $last) / $count;
        $result .= $letters[$last];
    }
    /*---- INSERT link in db---*/
    $sthInsert = db_query("INSERT INTO short (url,short_key) VALUE (:original_link, :short_key)", [
        'original_link' => $preparedLink,
        'short_key' => $result . $intval
    ]);
// Ajax – появляется информация о добавленной ссылке
}
?>
<form style="margin-top: 10px;" method="post">
    <input type="text" name="external_link">
    <input type="submit" name="submit">
</form>

Все что нагуглил, не смог адаптировать под свою задачу...может,кто знает где можно посмотреть схожие примеры, что бы посмотреть.

Я с БД не так часто сталкивался, а тут ещё через ajax нужно сделать. В принципе я делал запросы (не на нативном дж, а jquery – валидация формы), но тут БД и я немного потерялся.

  1. Касательно редиректа. Формируемая сокращенная ссылка выглядит примерно так: example.com/&8hde935. Как сделать, что бы сокращенная ссылка была без спец.символа (в моем случае амперсанд), то есть example.com/8hde935.

.htaccess

DirectoryIndex index.php
Options -Indexes
Options +FollowSymLinks
php_flag register_globals off
RewriteEngine on
RewriteRule ^&(.*) /redirect.php?key=$1 [L]

редирект

<?php
include_once(__DIR__ . '/libraries/database.php');
$key = htmlspecialchars($_GET['key']) ?? null;
if (isset(db_query("SELECT url, short_key FROM short WHERE short_key= '" . $key . "'")->fetch()['url'])) {
    $sthSelectSingle = db_query("SELECT url, short_key FROM short WHERE short_key= '" . $key . "'");
    header('HTTP/1.1 301 Moved Permanently');
    header('Location:' . $sthSelectSingle->fetch(PDO::FETCH_OBJ)->url);
} else {
    exit('Ошибка при переадресации');
}

Понимаю, что дела вот в этом RewriteRule ^&(.*) /redirect.php?key=$1 [L], но переписать правило не смог :(.

  1. Подсчет количества кликов по ссылке. Этот вопрос, пока теоретический, но раз уж обратился за помощью, могли бы сориентировать (пока что на пальцах, без конкретики). Как реализовать подсчет количества кликов по сокращенной ссылки? Есть предположение, что через куки, но не уверен, ранее не сталкивался.

На данный момент у меня 1 таблица 3 поля (id, url, short_key). Таблицу я дополню, в дальнейшем сделаю просто админку с информацией по сохраненным ссылкам.

Answer 1

Терминология. Нет такого понятия загрузка в БД аяксом. Есть: отправить аяксом запрос на сервер. А уж он положит в БД что захочет. Это поможет абстрагироваться вам от слоя БД. Вам нужно отправлять форму не прямым методом post из формы, а перехватить событие отправки в яваскрипт. Используйте jquery. Отправьте запрос на сервер с помощью его метода. ajax и в методе получения ответа вы сможете взять вашу укороченную строку и вставить в нужный dom объект на странице. Это если сервер не вернёт ошибку. И отдельно сделайте post обработчик на php. Можете в этом же файле, можете в другом. Главное правильно потом указать адрес до этого файла в аякс запросе. В обработчик вы получите массив POST, ВСТАВИТЕ ЕГО В БД и вернёте ответ. Тут надо подумать о формате ответа (текст, json). Ибо его тип нужно проставить в jquery в соотв. поле (гугл) Потому что если jquery ждёт json а вы из post обработчик делаете так: echo $shortString; То jquery вернёт ошибку формата.

READ ALSO
Не приходят push-уведомления на IOS

Не приходят push-уведомления на IOS

Написан функционал для отправки push-уведомлений для IOSС локального сервера уведомления приходят, а с сайта нет

112
Не получается сортировать по дате используя distinct

Не получается сортировать по дате используя distinct

У меня таблица из ссылокМногие повторяются

247
Преобразование class в массив byte []

Преобразование class в массив byte []

При работе через Bluetooth получаю ответ от оборудования по сокету в формате массива byte[] buffer

213
Проверка файла на наличие определенных строк во время сборки

Проверка файла на наличие определенных строк во время сборки

Требуется проверять файл xml на наличие определенных значений свойстваДумал сделать через antrun plugin и shell скрипт

233