有人可以使用PDO给出基本“用户”对象系统的完美示例吗?

时间:2013-10-14 18:13:38

标签: php mysql class oop pdo

我想要的是看到一个系统的理想框架,该系统具有一组对象(即用户),其中数据包含在数据库中。我被建议有一个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;

        }
    }   
?>

main.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);
?>

3 个答案:

答案 0 :(得分:1)

我能想到的一件事是让这个类成为一个单例,并在类的声明之上创建$ user,所以每当你包含这个类时,你都会拥有该用户对象。

答案 1 :(得分:1)

  

我是否可以制作一个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;
      }
   }
}

最后

一个非常简化的bootstrap-er版本看起来像,

<?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();

答案 2 :(得分:1)

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

不要忘记提供课程定义或使用自动加载器

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

FETCH_PROPS_LATE是在你的类中首先获取构造函数但是你不需要构造函数,所以只是丢失它。如果你决定保留它,你应该首先看看here

希望这有助于好运