我想检查每个键入的内容,如果用户名可用或已经存储在数据库中。我对他的html-tag onkeyup使用JS函数。在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 :(得分:0)
您可以借助php将结果缓存在应用程序的后端, 通过将其临时存储在用户的会话变量中。 您可以使用Javascript将否定结果缓存在应用程序的前端部分中,这样就不会对再次输入相同的用户名发出新请求。
此外,每当用户键入一些密钥时向服务器发出请求也是一种不好的做法。 在Javascript中,为服务器请求添加一些延迟,并至少计算4个字符,或者您的应用程序用户名的最小字符数是多少。 您还可以通过验证用户名来节省服务器的使用量,因此仅在用户名满足某些条件时才发出请求-最小字符数,允许的字符类型(如果之前对相同用户名提出了相同请求)。
这不能代替php数据验证,因此您也需要这样做。
在提及这一点时,您应该注意传递给数据库查询的内容,因为您将直接传递未经验证和未经消毒的数据。
答案 1 :(得分:0)
通过向单独的php脚本发送ajax调用,您在服务器上创建了一个新进程,该进程同时提供了前端文件和处理脚本。没有直接的方法可以交换数据库连接。
如果您想重复使用持久性连接,则应例如以所有请求都重定向到以下方式更改站点的路由: “ 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()));