PHP:在类中使用PDO数据库连接的正确方法

时间:2010-03-25 19:51:28

标签: php oop

尝试将我的所有代码组织到类中,并且无法使数据库查询在类中工作。我没有类包装器测试它,它工作正常。在课堂内=没有骰子。 我的课程怎么样搞乱了?

编辑:问题是它不会查询数据库并返回结果。任何结果。

class ac
  {
  public function dbConnect() 
    {
    global $dbcon;

    $dbInfo['server'] = "localhost";
    $dbInfo['database'] = "sn";
    $dbInfo['username'] = "sn";
    $dbInfo['password'] = "password"; 

    $con = "mysql:host=" . $dbInfo['server'] . "; dbname=" . $dbInfo['database'];
    $dbcon = new PDO($con, $dbInfo['username'], $dbInfo['password']);
    $dbcon->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $error = $dbcon->errorInfo();

    if($error[0] != "") 
      {
      print "<p>DATABASE CONNECTION ERROR:</p>";
      print_r($error);
      }
    }


  public function authentication()
    {
    global $dbcon;

    $plain_username = $_POST['username'];
    $md5_password = md5($_POST['password']);

    $ac = new ac();
    if (is_int($ac->check_credentials($plain_username, $md5_password)))
      {
      ?>
      <p>Welcome!</p> <!--go to account manager here-->
      <?php
      }
    else
      {
      ?>
      <p>Not a valid username and/or password. Please try again.</p>
      <?php
      unset($_POST['username']);
      unset($_POST['password']);
      $ui = new ui();
      $ui->start();
      }
    }



  private function check_credentials($plain_username, $md5_password)
    {
    global $dbcon;

    $userid = $dbcon->prepare('SELECT id FROM users WHERE username = :username AND password = :password LIMIT 1');
    $userid->bindParam(':username', $plain_username);
    $userid->bindParam(':password', $md5_password);
    $userid->execute();

    print_r($dbcon->errorInfo());

    $id = $userid->fetch();
    Return $id;
    }
  }

如果它有任何帮助,这就是正在调用它的类:

require_once("ac/acclass.php");
$ac = new ac();
$ac->dbconnect();
class ui
  {
  public function start()
    {
    if ((!isset($_POST['username'])) && (!isset($_POST['password'])))
      {
      $ui = new ui();
      $ui->loginform();
      }
    else
      {
      $ac = new ac();
      $ac->authentication();
      }
    }

  private function loginform()
    {
    ?>
    <form id="userlogin" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
     User:<input type="text" name="username"/><br/>
     Password:<input type="password" name="password"/><br/>
     <input type="submit" value="submit"/>
    </form>
    <?php
    }
  }

2 个答案:

答案 0 :(得分:3)

PDOStatement::fetch的默认值是将一行作为字段数组返回,按列名和编号索引(模式PDO::FETCH_BOTH)。这意味着ac::check_credentials返回一个数组,但ac::authentication检查一个整数。此外,字段值是字符串,因此除非您将结果字段显式转换为整数,否则is_int将失败。试试PDOStatement::fetchColumn()is_numeric

    public function authentication() {
        ...
        if (is_numeric($this->check_credentials($plain_username, $md5_password))) {
        ...
    }

    private function check_credentials($plain_username, $md5_password) {
        return $userid->fetchColumn();
    }

作为is_numeric的替代方案,请检查凭据检查的结果是否与False不同。

    public function authentication() {
        ...
        if (False !== $this->check_credentials($plain_username, $md5_password)) {
        ...
    }

一些Stylistic

正如Yaggo指出的那样,ui::startac::dbConnect应该是静态方法。 ac::authentication不需要创建新的ac;因为它不是静态方法,所以它可以通过$this特殊变量访问当前对象(如上所述)。 $dbcon应设为ac的静态属性,因此您不会pollute the global namespace。类名应使用UpperCamelCase,并且应该更具描述性。

类应该有一个明确定义的目的,而不是偏离它。 ac有许多用途:管理数据库连接,处理身份验证和显示身份验证结果。考虑为数据访问层设计一组类,将数据库与其他所有类隐藏起来。还要考虑将域逻辑(authentication&amp; c)与显示分开。这是称为Model View Controller架构的模式的一部分。这不需要一次全部发生;你可以慢慢地重构代码。

答案 1 :(得分:1)

无法解决您的问题,但如果您正在使用类作为名称空间来将类似的函数组合在一起,请考虑使用静态方法来避免创建实例的开销。

class Foo {

    static function bar() {

    }

}

Foo::bar()