首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP父类和子类DB操作

问PHP父类和子类DB操作
EN

Stack Overflow用户
提问于 2012-09-24 11:39:39
回答 4查看 1.7K关注 0票数 1

新的PHP和OOP,所以请容忍我..。我是乐观的早期设计和编写我的第一个PHP & OOP网站后,一生写烂M$ VBA垃圾。

我有一个类"User“,它有一个保存方法,有相关的数据库调用等等.(实际上,我有处理连接和CRUD的DB和DBUtils类--我的业务类只是调用DB Utils上的select、update、delete方法和传递关联的数据数组)

不管谁..。我的“用户”类是由一个"Admin“类扩展的,它在"User”yada .

处理“管理”上的保存方法的最佳方法是什么?我知道,如果我向Admin类添加一个保存方法,它将取代用户上的方法,但我不希望这样做。我希望在Admin上编写保存方法,只处理特定于Admin对象的属性等,并在用户保存方法中处理从" User“继承的属性。

这有意义吗?这是我要找的一个特定的OOP模式吗?任何帮助或指导,我应该如何设计和构造这段代码,将不胜感激。

编辑:哇!感谢以下所有的回答。还不确定哪一个是我喜欢的。我得玩一玩.

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-09-24 12:13:06

您正在尝试实现活动记录模式。

对象持久性的一种方法是提供一个共同的祖先类,例如BasicEntity每个子类扩展,它基于给定的数据模式构建查询:

代码语言:javascript
复制
class BasicEntity
{

    protected $tablename;

    protected $schema;

    public function update()
    {

        $fields = "";
        $placeholders = "";

        foreach($this -> schema as $field => $type)
        {

            // you join the fields here to get something like ('username', 'email', 'enabled', 'createdAt', 'password')
            // then you write your PDO statement providing placeholders like (:?, :?, :?, :?, :?)
            // you'll have to bind parameters based on their $type [int, string, date]

        }

        $query = sprintf(
            "UPDATE %s SET VALUES(%s) = %s",
            $this -> tablename,
            $fields,
            $placeholders
        );

        // execute statement here, handle exceptions, and so...

    }

}

因此,您的User类将类似于:

代码语言:javascript
复制
class User extends BasicEntity
{

    protected $id;
    protected $username;
    protected $email;
    protected $password;
    protected $enabled;
    protected $createdAt;

    public function __construct()
    {

        $this -> tablename = '_user';
        $this -> schema = array(
            'id'        => 'int',
            'username'  => 'string',
            'email'     => 'string',
            'password'  => 'string',
            'enabled'   => 'int',
            'createdAt' => 'datetime'
        );

    }

}

你的Admin课程:

代码语言:javascript
复制
class Admin extends User
{

    protected $additionalProperty;

    public function __construct()
    {

        parent::__construct();

        $this -> schema['additionalProperty'] = 'string';

    }

}

调用update()将基于类架构构建正确的查询。这种方法适用于低复杂度级别,因为您会注意到:

  • 如果在同一表上扩展实体,则需要为没有此类类字段的行提供空表字段--在本例中为additionalProperty;
  • 如果模式发生变化,例如更改变量名,则必须将其硬编码为类构造函数,从而使其更难维护;
  • 如果您想处理实体之间的关系,那么在每个SELECT语句中编写适当的联接将是一件很痛苦的事情,除非您只编写了许多单独的查询,从而降低了性能。

要解决第一个问题,需要对象的组合,这样就不会使主表增长太多--例如,它只获得对外部AdditionalPropertyList实体的引用。

要解决第二个问题,必须将模式保存在外部文件中或使用内联注解。

要解决第三个问题,您必须编写自己的ORM [对象关系映射],或者更好地切换到现有的。

无论如何,出于学习的好处,如果您计划构建一个可伸缩和可维护的应用程序,我会站在巨人的肩膀上,选择一个框架。

票数 3
EN

Stack Overflow用户

发布于 2012-09-24 11:46:27

当您在Admin类中编写您的保存方法时,可以在将标准保存推迟到父对象之后执行额外的工作.

代码语言:javascript
复制
class Admin extends User
{
    // Other methods

    public function save()
    {
        parent::save();
        // now save your additional fields wherever they need to go
    }
}

另外,虽然使用对象来表示域(如用户和管理),但这是可以的--有时在其他地方使用持久性逻辑是有好处的,例如使用库房模式。这将防止您的对象被绑定到持久性机制。

票数 3
EN

Stack Overflow用户

发布于 2012-09-24 11:46:47

解决这个问题有很多种方法。其中之一是具有可在扩展类中重写以提供来自该扩展类的数据的受保护方法;

一个例子是:

代码语言:javascript
复制
class User
{
  public function Save()
  {
    $savestuff = $this->GetProperties();
    // do save acctions
  }

  protected function GetProperties()
  {
    return 'user prop';
  }
}

class Admin Extends User
{
  protected function GetProperties()
  {
    return  'admin prop';
  }
} 
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12564328

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档