简体   繁体   English

检索页面内的连接:PDO和PHP类

[英]Retrieving a connection inside a page: PDO and PHP class

I'm new to classes and PDO as well. 我也是班级和PDO的新手。 I'm trying to write a class with separate functions for connecting to the db and closing the connection so that, in a page, I can: 我正在尝试编写一个具有单独功能的类,用于连接数据库和关闭连接,以便在页面中可以:

  1. Open the connection with the $db->connOpen $db->connOpen打开连接
  2. Perform all the queries I need inside the page 在页面内执行我需要的所有查询
  3. Close the connection at the end of the script with $db->connClose 使用$db->connClose在脚本末尾关闭连接

     class database { private $host = ''; private $db_name = ''; private $charset = ''; private $username = ''; private $password = ''; public function setHost($host) { $this->host = $host; } public function setDbName($db_name) { $this->db_name = $db_name; } public function setUser($username, $password) { $this->username = $username; $this->password = $password; } public function connOpen() { try { $dsn = "mysql:host=$this->host;dbname=$this->db_name;charset=$this->charset"; $db = new PDO($dsn, $this->username, $this->password, array(PDO::ATTR_PERSISTENT => true)); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (PDOException $e) { echo $e->getMessage(); } } public function connClose() { $db = null; } } 

I guess the problem is regarding more the classes syntax than the PDO, since to fire a query like the one below into the page I would need to instantiate again the class PDO , doubling the connection to the db. 我猜问题在于与PDO相比,更多的是类语法,因为要将类似下面的查询激发到页面中,我将需要再次实例化PDO类,从而使与数据库的连接增加一倍。

$stmt = $dbo->prepare('SELECT * FROM products WHERE id=:id');
$stmt->execute(array(':id' => $id));
$res  = $stmt->fetchAll(PDO::FETCH_ASSOC);

My questions are: 我的问题是:

  1. How can achieve what I want using a class like the one above? 如何使用上面的类来实现我想要的?
  2. Is it correct, in this case, using a persistent connection ? 在这种情况下,使用持久连接是否正确?

Thanks 谢谢

I am using this with one singlton class which give me db ojbect and then I am using that object to query in other classes; 我将它与一个给我db ojbect的singlton类一起使用,然后使用该对象在其他类中进行查询;

    <?php
    class db{
    /*** Declare instance ***/
    private static $instance = NULL;
    /**
     *
     * the constructor is set to private so
     * so nobody can create a new instance using new
     *
     */
    private function __construct() {
        /*** maybe set the db name here later ***/
    }
    /**
     *
     * Return DB instance or create intitial connection
     *
     * @return object (PDO)
     *
     * @access public
     *
     */
    public static function getInstance() {
        if (!self::$instance)
        {
            self::$instance = new \PDO("mysql:host=".databaseHost.";dbname=".databaseName."", databaseUserName,databasePassword);;
            self::$instance-> setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
            self::$instance-> setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
        }
        return self::$instance;
    }
    /**
     *
     * Like the constructor, we make __clone private
     * so nobody can clone the instance
     *
     */
    private function __clone(){
    }
} /*** end of class ***/
?>

class where i am querying using db object 我使用db对象查询的类

<?php
class posts {

    public function getPostOfUserId($userId,$offset=0,$limit=NULL){
        $helperString=" ";
        if(!empty($limit))
            $helperString=" LIMIT $offset, $limit ";
        $executor= db::getInstance()->prepare("SELECT posts.*,users.facebook_id, users.first_name as post_by FROM posts JOIN tagged_friends ON posts.id = tagged_friends.post_id JOIN users ON posts.user_id = users.id WHERE tagged_friends.user_id = :user_id ORDER BY posts.id DESC ".$helperString, array(\PDO::ATTR_CURSOR => \PDO::CURSOR_FWDONLY));
        $executor->execute(array(':user_id'=>$userId));
        $posts=$executor->fetchAll(\PDO::FETCH_ASSOC);
        if(!empty($posts))
            return $posts;
        else
            return ;
    }
}

For some reason, most people who wants to learn OOP starts with a database wrapper that implements singleton and interferes with error handling. 由于某些原因,大多数想学习OOP的人都从实现单例并干扰错误处理的数据库包装程序开始。

My tip is that you treat the database connection as any other variable: 我的技巧是将数据库连接视为任何其他变量:

class Post {
    function getByUserId(PDO $connection, $user_id) {
    }
}

$database = new PDO(...);
$post->getByUserId($database, 123);

This is called dependency injection. 这称为依赖注入。

And don't waste time and energy writing code to avoid useful features, such as: 并且不要浪费时间和精力编写代码来避免使用有用的功能,例如:

  • Centralised error handling 集中式错误处理
  • Being able to connect to more than one database 能够连接多个数据库

Only care about writing a database wrapper when you really have real features to add on top of PDO. 仅在真正具有要在PDO之上添加的实际功能时,才关心编写数据库包装程序。 I can think of: 我可以想到:

  • Convert dates to DateTime objects automatically 自动将日期转换为DateTime对象
  • Pass all queries to a logger 将所有查询传递给记录器
  • Throw custom exceptions on interesting events, such as duplicate index violation 在有趣的事件上引发自定义异常,例如重复索引冲突

... and even then be extremely careful to not make PDO worse ;-) ...即使如此,也要非常小心,不要使PDO变差;-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM