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

检索页面内的连接:PDO和PHP类,php,mysql,pdo,Php,Mysql,Pdo,我对课程和PDO也是新手。我正在尝试编写一个类,其中包含用于连接db和关闭连接的单独函数,以便在页面中,我可以: 使用$db->connOpen 在页面内执行我需要的所有查询 使用$db->connClose class database { private $host = ''; private $db_name = ''; private $charset = ''; private $username = ''; priv

我对课程和PDO也是新手。我正在尝试编写一个类,其中包含用于连接db和关闭连接的单独函数,以便在页面中,我可以:

  • 使用
    $db->connOpen
  • 在页面内执行我需要的所有查询
  • 使用
    $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;
        }
    }
    
  • 我想问题更多的是类的语法,而不是PDO,因为要在页面中触发下面这样的查询,我需要再次实例化类
    PDO
    ,将到db的连接加倍

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

  • 如何使用上面的类来实现我想要的
  • 在这种情况下,使用持久连接正确吗

  • 谢谢

    我在一个singlton类中使用它,它给了我db ojbect,然后我在其他类中使用该对象进行查询

        <?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 ***/
    ?>
    
    
    
    使用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 ;
        }
    }
    

    我在一个singlton类中使用它,它给我db ojbect,然后我在其他类中使用该对象进行查询

        <?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 ***/
    ?>
    
    
    
    使用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 ;
        }
    }
    

    出于某种原因,大多数想学习OOP的人都是从一个数据库包装器开始的,该包装器实现了单例并干扰了错误处理

    我的建议是将数据库连接视为任何其他变量:

    class Post {
        function getByUserId(PDO $connection, $user_id) {
        }
    }
    
    $database = new PDO(...);
    $post->getByUserId($database, 123);
    
    这称为依赖注入

    不要浪费时间和精力编写代码来避免有用的功能,例如:

    • 集中错误处理
    • 能够连接到多个数据库
    只有当您在PDO之上真正有了真正的特性可以添加时,才需要考虑编写数据库包装器。我能想到:

    • 自动将日期转换为
      DateTime
      对象
    • 将所有查询传递给记录器
    • 在感兴趣的事件上引发自定义异常,例如重复索引冲突

    。。。即使如此,也要格外小心,不要让PDO恶化;-)

    出于某种原因,大多数想要学习OOP的人都是从一个数据库包装器开始的,该包装器实现了单例并干扰了错误处理

    我的建议是将数据库连接视为任何其他变量:

    class Post {
        function getByUserId(PDO $connection, $user_id) {
        }
    }
    
    $database = new PDO(...);
    $post->getByUserId($database, 123);
    
    这称为依赖注入

    不要浪费时间和精力编写代码来避免有用的功能,例如:

    • 集中错误处理
    • 能够连接到多个数据库
    只有当您在PDO之上真正有了真正的特性可以添加时,才需要考虑编写数据库包装器。我能想到:

    • 自动将日期转换为
      DateTime
      对象
    • 将所有查询传递给记录器
    • 在感兴趣的事件上引发自定义异常,例如重复索引冲突

    。。。即使如此,也要格外小心,不要让PDO恶化;-)

    你的课似乎写得很好!但实际上我需要学习更多关于课程的知识才能完全理解:\你的课程似乎写得很好!但实际上,我需要学习更多关于类的知识才能完全理解它:\n我按照你的建议,将PDO连接视为一个变量,从
    conn()
    函数返回它,它成功了。谢谢你给阿尔瓦罗的其他建议!我遵循了您的建议,将PDO连接视为一个变量,从
    conn()
    函数返回它,它就成功了。谢谢你给阿尔瓦罗的其他建议!