重用AJAX发送的PHP文件中的数据库连接(PDO)

时间:2018-06-23 09:36:42

标签: php ajax variables code-reuse onkeyup

我想检查每个键入的内容,如果用户名可用或已经存储在数据库中。我对他的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;

2 个答案:

答案 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()));