【问题标题】:Could someone give a perfect example of a basic "user" object system, using PDO?有人可以举一个使用 PDO 的基本“用户”对象系统的完美示例吗?
【发布时间】:2013-10-22 09:17:15
【问题描述】:

我希望看到一个系统的理想框架,该系统具有一组对象(即用户),其中数据包含在数据库中。有人建议我有一个 User 类和一个 UserMapper 类,这是我对它的外观的理解:

user.class.php

/* The class for constructing any user's information
 */

    class User {

        protected $userId, $email, $userGroup;

        protected function getEmail() {
            return $this->email;
        }

        protected function getUserId() {
            return $this->userId;
        }


        public function __construct($userId, $email, $userGroup) {
            $this->userId = $userId;
            $this->email = $email;
            $this->userGroup = $userGroup;
        }

    }

    class UserMapper {
        // database connection
        private $db;

        public function __construct($db)
        {
            $this->db = $db;
        }

        public function findByUserId ($userId) {
            $userObject = new User();
            $q = $this->db->prepare("SELECT userId, email, userGroup FROM user WHERE userId = :userId");
            $q->bindValue(":userId", $id);
            $q->setFetchMode( PDO::FETCH_INTO, $userObject);
            $q->execute();
            $q->fetch(PDO::FETCH_INTO);
            return $userObject;

        }
    }   
?>

ma​​in.php

<?php  
    include user.class.php;
    $dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass, array(PDO::ATTR_PERSISTENT => true));
    $getUser = new UserMapper($dbh);
    $user = $getUser->findByUserId(41);
    echo $user->getEmail();
?>

但这在 main.php 方面似乎有点混乱。我可以不制作一个 PDO 对象并在我的所有脚本中定义它吗?以及 UserMapper 对象?或者每次我想从数据库中获取用户时,我是否需要创建一个新的 userMapper 对象,然后执行 findByUserId (如上)。或者有没有更简单的方法来做到这一点?

如果我想在 User 类中调用一个 UserGroup 对象,我该怎么做? (这也需要通过 PDO 连接到数据库)。执行以下操作似乎很混乱:

<?php
       $dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass, array(PDO::ATTR_PERSISTENT => true));
        $getUserGroup = new UserGroupMapper($dbh);
        $userGroup = $getUserGroupMapper->findByUserId($this->userGroup);
?>

【问题讨论】:

标签: php mysql class oop pdo


【解决方案1】:

我能想到的一件事是让这个类成为一个单例,并在该类的声明上方创建 $user,因此无论何时包含该类,您都会拥有该用户对象。

【讨论】:

    【解决方案2】:

    我可以不制作一个 PDO 对象并在我的所有文件中定义它吗? 脚本?以及一个 UserMapper 对象?

    您实际上是在寻找前端控制器。

    也就是说,为了避免相同类的相同实例化,你应该已经准备好它们。大多数人通常在bootstrap.php 中执行此操作,“调整”所有必需的依赖项。

    但前端控制器实现还包括调度程序和路由器。我不会对此进行深入探讨,而是专注于您要解决的问题。

    工厂模式

    它基本上抽象了实例化逻辑。好处是:1)您可以延迟对象实例化 2)您避免全局状态,这对单元测试不利。它的简化版本如下所示:

    class UserFactory
    {
       private $pdo;
    
       private $cache = array();
    
       public function __construct($pdo)
       {
          $this->pdo = $pdo;
       }
    
       public function build($mapper)
       {
          if (isset($this->cache[$mapper])) {
             return $this->cache[$mapper];
          } else {
             // Inject an instance into a mapper
             $instance = new $mapper($this->pdo);
             // Save the state into a cache
             $this->cache[get_class($instance)] = $instance;
             return $instance;
          }
       }
    }
    

    最后

    一个非常简化的引导程序版本看起来像,

    <?php
    
    /* File : bootstrap.php */
    
    $dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass, array(PDO::ATTR_PERSISTENT => true));
    
    // Include here UserFactory class
    $userFactory = new UserFactory($dbh);
    
    // Its kinda ready to be used
    

    您只需将需要访问用户的所有脚本包含在其中

    <?php
    
    /* File: main.php */
    include(__DIR__ . '/bootstrap.php');
    
    $getUser = $userFactory->build('UserMapper');
    $user    = $getUser->findByUserId(41);
    
    echo $user->getEmail();
    

    【讨论】:

      【解决方案3】:

      您需要改用 FETCH_CLASS 并且不需要 userMapper,只需扩展 PDO,然后在一个类中设置正确的获取模式。

      不要忘记使类定义可用或使用自动加载器

      $this->statement->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE,"className");
      

      FETCH_PROPS_LATE 是为了让构造函数在你的类中首先被触发但是你不需要构造函数,所以就丢掉它。如果你决定保留它,那么你应该先看看here

      希望这有助于好运

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-25
        • 2016-06-07
        相关资源
        最近更新 更多