【问题标题】:How do I handle connecting to a mysql database in a separate class?如何处理连接到单独类中的 mysql 数据库?
【发布时间】:2014-05-01 23:52:03
【问题描述】:

所以我有一个完整的注册和登录序列,但我必须单独连接到每个内部的数据库。我正在尝试使用一个单独的类,我可以简单地包含它来连接到数据库。我希望这将简化未来需要数据库连接的页面,并将我的登录信息隐藏到数据库中。这是代码;我把旧代码留在里面,只是“注释”掉了:


DBconn

class DBconn {

protected $dbname;
protected $dbuser;
protected $dbpassword;
protected $dbhost;

protected $connection;

public function _construct($dbhost, $dbname, $dbuser, $dbpass) 
{
    $this->dbname = $dbname;
    $this->dbhost = $dbhost;
    $this->dbuser = $dbuser;
    $this->dbpass = $dbpass;

    $this->connect();
}

public function getConnection()
{
    return $this->connection;
}

protected function connect()
{
    $this->connection = new PDO("mysql:host={$this->dbhost};dbname={$this->dbname}", $this->dbuser, $this->dbpass);
}




}
?>


dblogin.php

<?php

$db = new DBconn('localhost','phpproject','carl','pdt1848?')

?>


registersecure.php

<?php
ini_set('display_errors', 1);
error_reporting(E_ALL); ini_set('display_errors', 1);

//db classes
require_once "/home/carlton/public_html/PHPproject/db/DBconn.class.php";
require_once "/home/carlton/public_html/PHPproject/db/dblogin.php";

//phpass 
require_once "/home/carlton/public_html/PHPproject/includes/PasswordHash.php";

if (empty($_POST)){

?>
 <form name="registration" action="registersecure.php" method="POST">
<label for "username">Username: </label>
<input type="text" name="username"/><br />
<label for "password">Password: </label>
<input type="password" name="password"/><br />
<label for "fname">First Name: </label>
<input type="text" name="fname"/><br />
<label for "lname">Last name: </label> 
<input type="text" name="lname"/><br />
<label for "email">Email: </label>
<input type="text" name="email"/><br />
<button type="submit">Submit</button>
</form>
<?php 
}
else{

$form = $_POST;
$username = $form['username'];
$password = $form['password'];
$fname = $form['fname'];
$lname = $form['lname'];
$email = $form['email'];
//$user = 'carl';
//$pass = 'pdt1848?';
$hash_obj = new PasswordHash(8, false);

//check for valid email 
if(filter_var($email, FILTER_VALIDATE_EMAIL)){
   echo "Thank you for using a valid email adress.";
}
else{
   die("Invalid Email, please go back and try again.");
}

// because hashing greatly increases the size of a password, 
// if password is longer than 72 chars it risk DoS attakcs
if (strlen($password)>72){die("Password must be less than 73 characters.");
}

// if the password was hashed correctly it must be longer than 20 char,
// therefore if the hash is less than 20 characters phpass isn't 
$hash = $hash_obj->HashPassword($password);
/*  if (strlen($hash)>=20){
    try{
        $db = new PDO('mysql:host=localhost;dbname=phpproject', $user, $pass);
        $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    }
    catch(PODException $e){
        echo 'Something has gone terribly wrong!';
    }*/
$sql = "INSERT INTO users (username, password, fname, lname, email)VALUES(:username, :password, :fname, :lname, :email)";
$query = $db->getConnection->prepare($sql);
$result = $query->execute(array(':username'=>$username, ':password'=>$hash, ':fname'=>$fname,
    ':lname'=>$lname, ':email'=>$email));
//};
if ($result){
    echo "Thanks for registering with us!";
} else {
    echo "Sorry, an error occurred while editing the database. Contact the guy who built this garbage.";
};

};

?>

【问题讨论】:

    标签: php mysql class pdo


    【解决方案1】:

    您的代码中有错误。 在 DBconn 类中,constrcut 开头应该有双下划线__construct

    下一个错误在 registersecure.php 中

    这个 $query = $db-&gt;getConnection-&gt;prepare($sql); 应该 $query = $db-&gt;getConnection()-&gt;prepare($sql);

    作为旁注,这不是获取连接实例的正确方法,您应该关闭连接并再次打开它,或者您应该为连接处理程序指定一个唯一的名称。我个人这样编写我的数据库连接处理程序类:

    class DBQuery {
      protected static $_connections = array();
      protected $_dbh;
    
      protected function __construct($dbh = null) {
        if (null !== $dbh) {
          $this->_dbh = $dbh;
        } else {
          $this->_dbh = new PDO(
            sprintf("mysql:host=%s;dbname=%s", DBHOST, DBNAME), 
            DBUSER, DBPASS
          );
        }
        $this->_dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
      }
    
      public static function getInstance($config = null) {
        if (null === $config) {
          $hash = "__default__";
          if (!isset(self::$_connections[$hash])) {
            self::$_connections[$hash] = new self();
          }
        } else {
          $hash = sha1(json_encode($config));
          if (!isset(self::$_connections[$hash])) {
            $dbh = new PDO(
              sprintf("mysql:host=%s;dbname=%s", $config->host, $config->name), 
              $config->username, $config->password
            );
            self::$_connections[$hash] = new self($dbh);
          }
        }
        return self::$_connections[$hash];
      }
    
      public function __call($methodName, $arguments) {
        return call_user_func_array(array($this->_dbh, $methodName), $arguments);
      }
    
      public function __destruct() {
        $this->_dbh = null; // closes the db connection
      }
    }
    

    然后要从任何其他地方获取新实例,您只需将其包含在该文件中

    require_once 'DBQuery.class.php';

    并获得一个新的 DBQuery 实例:

    $db = DBQuery::getInstance();

    您还可以将数据库名称、用户名、密码等配置参数作为数组传递,以即时连接到不同的数据库:)

    【讨论】:

      【解决方案2】:

      你还没有提出问题。但是,我可以看到您正在处理您的类实例$db,就好像它是连接一样,但事实并非如此。您仍然需要使用 getter 方法获取受保护的连接属性。

      $query = $db->getConnection()->prepare($sql); 
      

      【讨论】:

      • 啊,我明白了。但是我仍然收到错误:致命错误:在第 85 行的 /home/carlton/public_html/PHPproject/forms/registersecure.php 中的非对象上调用成员函数 prepare()
      • 你能打印$db对象的var_dump吗?您可能一开始就无法连接,但它可能会默默地失败。另外,尝试查看是否更改了包含的要求登录名,以确保在尝试实例化它时存在 DB 类。
      • 不幸的是,提交数据后仍然出现同样的错误。结果如下: object(DBconn)#1 (5) { ["dbname":protected]=> NULL ["dbuser":protected]=> NULL ["dbpassword":protected]=> NULL ["dbhost":protected ]=> NULL ["connection":protected]=> NULL } 致命错误:在第 86 行的 /home/carlton/public_html/PHPproject/forms/registersecure.php 中的非对象上调用成员函数 prepare()
      • 不确定这是否明显,但这是有问题的行:$query = $db->getConnection()->prepare($sql);
      • 见@Aram 的回答。构造的神奇方法需要两个下划线(你的类只有一个)。 getter 是一种方法,而不是属性。
      猜你喜欢
      • 2014-11-10
      • 2014-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-04
      相关资源
      最近更新 更多