yaleksandr89
@yaleksandr89
PHP developer

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

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

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

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

P.S. ссылку убрал, как оказалось этот ресурс посещают психически не стабильные люди :\ (если требуется, напишите – скину)


На данный момент меня интересуют 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 – валидация формы), но тут БД и я немного потерялся.



2. Касательно редиректа. Формируемая сокращенная ссылка выглядит примерно так: 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], но переписать правило не смог :(.



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

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

P.S. не зря же тэг PDO включил. Хотелось бы услышать мнения у более опытных коллег, насколько правильно...хотя неправильно выразился :) не сильно ли наговнокоденно в скрипте отвечающем за работу с БД:
database

<?php

// Connecting database
function db_connect()
{
    // Connections settings
    $db_host = 'localhost';
    $db_name = 'test';
    $db_charset = 'utf8';
    $db_user = 'root';
    $db_password = '';
    static $pdh;
    if ($pdh === null) {
        $dns = sprintf("mysql:host=%s;dbname=%s;charset=%s", $db_host, $db_name, $db_charset);
        $options = [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES => false,
        ];
        try {
            $pdh = new PDO($dns, $db_user, $db_password, $options);
        } catch (PDOException $exception) {
            echo "Technical troubles in the site. Soon all fix.";
            file_put_contents('Errors_Log.txt', date(DATE_RFC822) . ': ' . $exception->getMessage() . PHP_EOL, FILE_APPEND);
        }
    }
    return $pdh;
}

// Request processing
function db_query(string $sql_query, array $params_execute = [])
{
    $pdh = db_connect();
    $sth = $pdh->prepare($sql_query);
    $verifiedParams = [];
    foreach ($params_execute as $placeholder => $item) {
        if (is_int($item)) {
            $sth->bindParam(count($params_execute), $placeholder, PDO::PARAM_INT);
            $verifiedParams[] = $item;
        } elseif (is_string($item)) {
            $sth->bindParam(count($params_execute), $placeholder, PDO::PARAM_STR);
            $verifiedParams[] = $item;
        }
    }

    $sth->execute($verifiedParams);
    return $sth;
}



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

Всем буду очень благодарен за помощь!
  • Вопрос задан
  • 1161 просмотр
Пригласить эксперта
Ответы на вопрос 1
humiliation
@humiliation
Чем больше знаю - тем больше дурак
1. При GET/POST/PUT/DELETE запросе получаете нужные данные. При GET - INSERT INTO `table` VALUES и пошло. Возвращать ничего не надо - достаточно 200/400 и это уже валидировать на жквери.

Аякс тут для БД лишь поставляет данные. Все остальное делает ПХП.

3. Добавьте в таблицу к ссылке поле clicks и инкрементируйте при клике. Как раз в тот момент пока пхп редиректит.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы