【问题标题】:Retrieving a connection inside a page: PDO and PHP class检索页面内的连接:PDO 和 PHP 类
【发布时间】:2017-02-28 09:28:24
【问题描述】:

我也是课程和 PDO 的新手。我正在尝试编写一个具有单独函数的类,用于连接到数据库并关闭连接,以便在页面中:

  1. 打开与$db->connOpen的连接
  2. 在页面内执行我需要的所有查询
  3. 在脚本末尾用$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,将与数据库的连接加倍。

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

我的问题是:

  1. 如何使用上述类实现我想要的?
  2. 在这种情况下,使用持久连接是否正确?

谢谢

【问题讨论】:

    标签: php mysql pdo


    【解决方案1】:

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

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

    class Post {
        function getByUserId(PDO $connection, $user_id) {
        }
    }
    
    $database = new PDO(...);
    $post->getByUserId($database, 123);
    

    这称为依赖注入。

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

    • 集中式错误处理
    • 能够连接到多个数据库

    只有当您确实有真正的功能要添加到 PDO 之上时,才关心编写数据库包装器。我能想到:

    • 自动将日期转换为DateTime 对象
    • 将所有查询传递给记录器
    • 对有趣的事件抛出自定义异常,例如重复索引违规

    ...即使这样也要非常小心,不要让 PDO 变得更糟 ;-)

    【讨论】:

    • 我按照您的建议将 PDO 连接视为变量,从 conn() 函数返回它,并且它起作用了。感谢所有其他提示 Álvaro!
    【解决方案2】:

    我将它与一个给我 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 ;
        }
    }
    

    【讨论】:

    • 你的课似乎写得很好!但我实际上需要学习更多关于类的知识才能完全理解它:\
    猜你喜欢
    • 1970-01-01
    • 2015-03-10
    • 2017-02-04
    • 2015-08-04
    • 1970-01-01
    • 2011-12-24
    • 2013-05-13
    • 1970-01-01
    相关资源
    最近更新 更多