1

我希望你们能对我的问题有所了解。我需要的基本上是从数据库行(实例获取器)获取和分配属性的最佳实践。这是一个非常标准的问题,我知道它在 C# 中是如何工作的,但我不清楚如何在 php 中完成类似的结果,也没有在网上找到任何满足我需求的解决方案。

所以让我们假设我有这个简化的代码:

Class User{
  private $Pdo;
  private $UserID;
  private $UserName;

  function GetUserName(){
    return $this->UserName;
    }

  function GetUserInfo(){
    // return user object with given user id, in this example just use "1"
    $Pdo = $this->Pdo;
    $Query = $Pdo->query('select * from User where UserID = 1');
    $Query->setFetchMode(PDO::FETCH_CLASS, "User", array($Pdo) ); // this is returning object
    $UserInfo = $Query->fetch();
    return $UserInfo;
    }

  }

然后,当我想获取用户对象时,我会这样称呼它:

$User = new User($Pdo);
$UserInfo = $User->GetUserInfo();
echo $UserInfo->GetUserName();

这行得通,但是我不喜欢这样做。一种选择是使用静态方法,所以最后我会得到类似的结果:

$UserInfo = User::GetUserInfo()

我想这被称为“单身人士”(编辑:不是单身人士:)),通常被认为是不好的做法。

我的问题是它应该是什么样子?我想要的是这样的:

$UserInfo = new User($Pdo);
$UserInfo->GetUserInfo();
echo $UserInfo->GetUserName();

我知道在 GetUserInfo 方法中,我可以手动将值分配给当前对象($this),例如:

function GetUserInfo(){
    // get data from db
    $this->UserName = "John"; // this value I will get from db
   }

但是我想使用 FetchClass,这样我就可以在一行中根据它们的名称获取所有属性,而不是手动分配它们。我希望你明白我的问题是什么:) 我很想听听你对什么是最好的方法的意见。

非常感谢您的任何意见。

4

1 回答 1

4

朝着最佳实践和良好设计方向迈出的一步是将域模型和持久层分开。

因此,您可以独立于所使用的数据库,甚至可以使用 Web 服务替换数据库。查看数据映射器模式

因此,您的User模型将仅包含属性 + getter/setter 以及以某种方式使用这些属性的方法(业务逻辑)。

class User
{
    protected $UserID;
    protected $UserName;

    public function getUserId()
    {
        return $this->UserID;
    }

    public function setUserId($userId)
    {
        $this->UserID = userId;
        return $this;
    }

    ...

}

您的映射器持有数据库连接并负责保存/获取User对象。

class UserMapper
{
    protected $_pdo;

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

    public function getUserById($id)
    {
        // TODO: better use prepared statements!
        $query = $this->_pdo->query("select * from User where UserID = ".id);
        $query->setFetchMode(PDO::FETCH_CLASS, "User");
        return $query->fetch();
    }

    public function save(User $user)
    {
        // insert/update query
    }

    ...

}

你可以像这样使用它:

$userMapper = new UserMapper($pdo);
$user = $userMapper->getUserById(1);

echo $user->getUserName();

$user->setUserName('Steve');
$userMapper->save($user);

还有其他类似的模式,如表网关模式。但由于数据源的独立性,我更喜欢数据映射器。

查看 Martin Fowler 的整个目录:企业应用程序架构模式目录

另一个有用的线程:数据映射器、表数据网关(网关)、数据访问对象(DAO)和存储库模式有什么区别?

于 2013-10-09T20:06:51.233 回答