Повторное использование базы данных (PDO) в PHP-файле, отправленном AJAX

Я хочу проверять каждый ключ, есть ли имя пользователя доступно или уже сохранено в базе данных. Я использую JS-функцию с html-тегом onkeyup. В JS-функции я использую AJAX асинхронно, чтобы открыть соединение с базой данных, выбрать имена пользователей и вернуться, если конкретное имя пользователя было найдено.

Я не мог понять и не нашел аналогичного запроса о том, как повторно использовать переменную базы данных (PDO, SQLLite3). На данный момент я должен инициировать и вызывать соединение с базой данных при каждом ключе вверх. Думая о больших числах пользователей, это может быть большой нагрузкой для базы данных, верно? Есть ли лучший способ использовать AJAX асинхронно и сделать вызов в базу данных?

HTML-код:

<input id="register_username" type="text" onkeyup="checkUsernameOfRegisterForm();" required>

JS-функция:

function checkUsernameOfRegisterForm() {
var currentText = $('#register_username').val();
usernameLengthOk = checkUsernameLength(currentText);

showIfUsernameIsTaken(currentText);
}

function showIfUsernameIsTaken(str) {
usernameAvailable = false;
updateButton(); // blocks the form-Button, if on *Available is false
$.post('ajax/getUsernameAvailable.php', {q:str}, function (data, status) { // TODO kann status weg?
usernameAvailable = data === '';
updateButton();
});
}

GetUsernameAvailable.php выглядит так:

<?php
$q = $_REQUEST["q"];
$result = "";
try {
$dsn = "sqlite:../sqlite-pdo.db";
$db = new PDO($dsn); // how can I reuse the $db of other php-files? global doesnt work.
$allUsernames = $db->query("SELECT ownUsername FROM usertable");
foreach($allUsernames as $name) {
$ownUsername = strtolower($name['ownUsername']);
$lowerQ = strtolower($q);
if (strcmp($ownUsername, $lowerQ) === 0) {
$result = $q;
break;
}
}
} catch (PDOException $exception) {}

echo $result;

0

Решение

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

Кроме того, плохой практикой является выполнение запроса к серверу каждый раз, когда пользователь вводит какой-либо ключ.
В Javascript добавьте некоторую задержку для запроса к серверу и укажите не менее 4 символов или минимальное количество символов для имени пользователя вашего приложения.
Вы также можете сохранить некоторое использование сервера, проверив имя пользователя, поэтому отправляйте запрос только тогда, когда имя пользователя удовлетворяет некоторым критериям — минимальное количество символов, допустимый тип символов, если один и тот же запрос был сделан ранее для того же имени пользователя.

Это не замена проверки данных php, поэтому вам нужно это сделать.

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

0

Другие решения

Отправляя вызов ajax вашему отдельному php-скрипту, вы создаете новый процесс на сервере, который доставляет как ваш файл веб-интерфейса, так и скрипт обработки. Прямого обмена базой данных с подключением нет.

Если вы хотите повторно использовать постоянное соединение, вы должны, например, изменить маршрутизацию своих сайтов таким образом, чтобы все запросы перенаправлялись, например, на. «Main.php». В этом файле вы можете создать постоянное pdo-соединение, которое можно повторно использовать в представлении и файлах обработки запросов на стороне сервера.

Пример для такого класса:

class CC_DBV {

private static $mysqlhost;
private static $mysqluser;
private static $mysqlpwd;
public static $mysqldb;
private static $db;
private static $mysqlport;


function __construct() {


// ini File einlesen
$globSettings = parse_ini_file(_ROOTV_.'cfg/main.ini',true);

// Datenbankverbindung
self::$mysqlhost = $globSettings ['db_settings']['host'];                   // MySQL-Host aus Config Datei
self::$mysqluser = $globSettings ['db_settings']['db_user'];        // MySQL-User aus Config Datei
self::$mysqlpwd = $globSettings ['db_settings']['db_pswd'];         // Passwort aus Config Datei
self::$mysqldb = $globSettings ['db_settings']['db'];                       // Datenbank aus Config Datei
self::$mysqlport = $globSettings ['db_settings']['port'];                   // Datenbank aus Config Datei

}

public function getInstance( ) {
if(!self::$db) {

try{

self::$db = new \PDO(
'mysql:host='.self::$mysqlhost.';dbname='.self::$mysqldb.';port='.self::$mysqlport,
self::$mysqluser,
self::$mysqlpwd,
array(
\PDO::ATTR_PERSISTENT => true,
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION ,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
\PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'")
);
//self::$db->exec("SET NAMES utf8");

return self::$db;

}catch (\PDOException $e){
echo 'Connection failed: ' . $e->getMessage();
}

}else{
return self::$db;
}

}

}

Чтобы использовать это, вы делаете что-то вроде этого:

$conn = new CC_DBV(); // you can use this connection multiple times, it's persistant.
$inst = $conn->getInstance(); // create or get the instance of the opened connection
$stmnt = $inst->prepare("SELECT * FROM tablename WHERE xyz = :VAR1"); // prepare statement with placeholder(s)
$v = array(':VAR1' => 'aValue'); // set up an array with corresponding values
$r1 = $stmnt->execute($v); // execute statement with values
if(!$r1){ echo "PANICMODE";}else{ var_dump($stmnt->fetchAll()));
0