不确定我是否理解OOP和PDO。试着学习如何使用它

时间:2014-10-22 20:35:49

标签: php mysql oop pdo

我不是100%肯定,如果我这样做,有人可以看看我的代码,只是让我知道我做错了什么。

当我测试代码时,数据库中没有任何内容发生,并且页面上没有列出错误。

这是config.php文件

<?php
// defines database connection data
define('DB_HOST', 'localhost');
define('DB_USER', '*******');
define('DB_PASSWORD', '********');
define('DB_DATABASE', 'BetterGamerzUnited');
?>

register.class.php

class Register {

    private $conn;

    public function __construct() {
        try { 
            $this->conn = new PDO("mysql:host=".DB_HOST.";dbname=".DB_DATABASE, DB_USER, DB_PASSWORD);
        } catch(Exception $e) { 
            var_dump($e);
        }
    }

    public function __destruct() {
        $this->conn->close();
    }

    public function addUser($first_name, $last_name, $username, $password, $email, $country, $gender, $ip) {
        try {
            $query = "INSERT INTO users (username, email, firstname, lastname, password, gender, country, ip, signup, lastlogin, notescheck) VALUES (?, ?, ?, ?, ?, ?, ?, ?, now(), now(), now())";
            $stmt = $this->conn->prepare($query);
            $stmt->bindValue(1, $username);
            $stmt->bindValue(2, $email);
            $stmt->bindValue(3, $first_name);
            $stmt->bindValue(4, $last_name);
            $stmt->bindValue(5, $password);
            $stmt->bindValue(6, $gender);
            $stmt->bindValue(7, $country);
            $stmt->bindValue(8, $ip);
            $stmt->execute();
            $this->conn->close();
        }catch(PDOException $e) {
            echo 'There was an error';
        }
    }
}

然后这是register.php

<?php 

require_once 'class/register.class.php';

$register = new Register();

$register->addUser('Andrew', 'McComs', 'test', 'test', 'testtest@test.com', 'usa', 'm', '192.168.0.1');
echo $register->addUser();


?>

屏幕上没有任何东西回响,也没有进入数据库。

2 个答案:

答案 0 :(得分:3)

问题#1

您正在混淆局部变量和类属性。在构造函数中,设置$conn = $this->mMysqli = new PDO()

$conn = $this->mMysqli = new PDO("mysqli:host=".$DB_HOST.";dbname=".$DB_DATABASE, $DB_USER, $DB_PASSWORD);

然后在您的::addUser()方法中,您尝试访问此$conn变量。此变量仅在构造函数方法中本地可用,您应该继续使用您的类mMysqli属性:

public function addUser($first_name, $last_name, $username, $password, $email, $country, $gender, $ip) {
    try {
        $this->mMysqli->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $this->mMysqli->prepare("INSERT INTO users (username, email, firstname, lastname, password, gender, country, ip, signup, lastlogin, notescheck) VALUES (?, ?, ?, ?, ?, ?, ?, now(), now(), now())");
        $this->mMysqli->bindValue(1, $username);
        $this->mMysqli->bindValue(2, $email);
        $this->mMysqli->bindValue(3, $first_name);
        $this->mMysqli->bindValue(4, $last_name);
        $this->mMysqli->bindValue(5, $password);
        $this->mMysqli->bindValue(6, $gender);
        $this->mMysqli->bindValue(7, $country);
        $this->mMysqli->bindValue(8, $ip);
        $this->mMysqli->execute();
        $this->mMysqli->close();
    }catch(PDOException $e) {
        return 'There was an error';
    }
}

问题#2

您正在访问定义的常量(DB_HOST等)错误。它们不需要$像普通变量一样:

$this->mMysqli = new PDO("mysqli:host=".DB_HOST.";dbname=".DB_DATABASE, DB_USER, DB_PASSWORD);

问题#3

您的PDO构造函数应使用mysql:host而不是mysqli:hostmysqli是访问MySQL的PHP​​扩展,数据库仍然是MySQL(用于通过PDO访问)。

归功于@ Fred-ii -


附加功能

  • function __construct() {}应为public function __construct() {}
  • $this->mMysqli->setAttribute()修改了您的整个PDO连接,因此可能应该在构造函数方法中调用它。
  • return 'There was an error';除非您执行echo $register->addUser();之类的操作,否则不会在页面上打印任何内容。了解return的工作原理。

答案 1 :(得分:2)

这并不能解决所有[小]问题;但是,代码是一个错误的设计;

  1. 现在,连接已嵌入到Register类中 - 它代表了Data Access Layer (DAL)中完美的存储库/访问类。这样的类应使用连接,但拥有/管理连接。

  2. 连接生存期是每个Register对象的生命周期,因为它认为它也管理连接:使用这种方法,每个DAL类型实例打开/关闭每个实例的连接。随着使用数据库的类型数量的增加,这比例。

  3. 一种可行的方法是将连接接受为Dependency(即构造函数参数),可以在所有DAL类型的所有实例之间共享,并在特定请求或“隔离数据库任务”中进行所有数据库访问。 ,例如:

    public function __construct($conn) {
      // The supplied connection should be open, in a valid state, and configured.
      // Connection-specific attributes should not be changed within the DAL.
      // (And do not close the connection from the destructor.)
      $this->conn = $conn;
    }
    
    // Where $conn was already created appropriately and meets the above rules
    $register = new Register($conn);
    

    可能存在特定DAL类型要创建 - 或者更确切地说,给出 - 新/不同连接的情况,但这种情况相对不常见;另外,对自己的依赖可能是一个工厂,但这是一个兔子洞......

    DAL方法应该使用适当的事务,否则连接,打开或关闭数据库。 程序上下文和/或IoC容器负责管理连接和生命周期。


    另外,我鼓励在DAL中捕获错误(除非它们可以从中恢复,忽略,包装或以其他方式正确处理),但也将其留给使用地点。捕获/返回的使用是可疑的,因为否则它是一种“无效”方法。考虑重写它:

    try {
      $register->addUser(..);
    } catch (Exception $e) {
      echo "Failed to add user";  // Can be changed without mucking DAL, although
                                  // I recommend a more MVC approach to `echo`.
    }
    

    如果DAL想要在这样的例外情况下包含有用的信息,它可以包装内部异常并提供更多细节。也就是说,细节可能是“用户名已存在”。