【问题标题】:Should I create an object or work with an array?我应该创建一个对象还是使用一个数组?
【发布时间】:2013-06-01 11:17:46
【问题描述】:

我对@9​​87654321@ 还很陌生,在构建我的第一个项目时,我遇到了一些困难的困境。

我正在尝试建立一个论坛。是的,我知道那里有很多免费的,我只想拥有一个可以根据自己的需要构建的 :)。另外,编码很有趣。

我已经为论坛、帖子和帖子构建了一个基本模型、控制器和模板。 基本模型具有标准的数据库功能,如查找全部、按 id 查找等。各个模型扩展了模型类,并且只具有该类的特定功能。 我是这样设置的:

class Post_Model extends Model {

    static protected $_table_name = 'post';
    static protected $_db_fields = array('id', 'thread_id', 'parent_id', 'username', 'user_id',
        'title', 'date_line', 'pagetext', 'show_signature', 'ip_address', 'icon_id', 'visible');

    /**
     * @var db fields
     */
    public $id;
    public $thread_id;
    public $parent_id;
    public $username;
    public $user_id;
    public $title;
    public $date_line;
    public $pagetext;
    public $show_signature;
    public $ip_address;
    public $icon_id;
    public $visible;
}
/*
 * joined fields with user object. needed to display posts in all details
 */

static public function get_posts($id, $limit, $offset){
    $result_set = static::find_by_sql("
        SELECT * 
        FROM post 
        LEFT JOIN user ON (post.user_id = user.id) where post.thread_id=".(int)$id." 
        ORDER BY date_line DESC 
        LIMIT {$offset} , {$limit}");

    return !empty($result_set) ? $result_set : false;  
}

除了那些艰难的决定之外,我已经不得不做出关于某些函数和变量是否为静态的决定。我有这个困境:

基本的 CRUD 从基本模型开始工作。这很好,我可以通过从(基础)模型调用静态方法来创建、更新、删除和读取我的数据库,该模型为这些论坛、线程和帖子模型实例化对象。到目前为止一切顺利。

部分Model Class

    <?php
        /**
     * Find rows from database based on sql statement
     * @param string $sql
     * @retun array $result_set
     */
    static public function find_by_sql($sql = '') {
        $db = Database::getInstance();
        $mysqli = $db->getConnection();
        $result = $mysqli->query($sql);
        $object_array = array();
        while ($record = $result->fetch_array()) {
            $object_array[] = static::instantiate($record);
        }
        return $object_array;
    }

    private static function instantiate($record) {
        $object = new static;
        foreach ($record as $attribute => $value) {
            if ($object->has_attritube($attribute)) {
                $object->$attribute = $value;
            }
        }
        return $object;
    }
}
?>

我转移这些对象以在我的模板中显示。从一张表读取时,效果很好。

    <?php
$postcount = $pagination->offset + 1;
if (!empty($posts)) {
    foreach ($posts as $post) {
        ?>

        <div class="post">
            <div class="posttime"><?php echo strftime("%A %e %B %G  %H:%M", $post->date_line); ?></div>
            <div class="postnumber">#<?php echo $postcount; ?></div>
            <div class="postuser">
                <div class="username"><?php echo $post->username; ?></div>
                <div class="avatar">avatar</div>
            </div>
            <div class="postcontents">
                <div class="posttext"><?php echo $post->pagetext; ?></div>  
            </div>
        </div>

        <?php
        $postcount++;
    }
    ?>    
<div class="pagination"><?php echo $page_split; ?></div> 

但是,为了显示线程中的所有帖子,我需要来自用户表的信息,例如他们的帖子数量,排名,头像等。

好的,事情就是这样:

SELECT * FROM post
LEFT JOIN user ON (post.user_id = user.id)
where thread_id={$id}
ORDER BY date_line DESC
LIMIT {$offset} , {limit}

我现在拥有比我在 Post 模型中设置的变量更多的字段。所以它们不会被转移来显示。

我应该使用数组而不是对象来显示这些额外的字段吗?我宁愿仍然使用对象方法进行显示,因为我现在已经为此做好了准备。

或者我应该将这些用户字段作为变量添加到我的 Post 模型中吗?我认为这不是最整洁的方法,但它会起作用。

或者我应该通过foreach 循环来获取(尚未创建)用户类的单独实例吗?我认为它会比 Left Join 消耗更多的内存,而 Left Join 只是让我得到我需要的数据。

我想要一些关于如何解决这个问题的提示。

【问题讨论】:

  • 静态变量不是面向对象范式的一部分。模型是一个层,而不是数据库表的抽象。这也让“后模型”变得毫无意义。
  • 感谢您的评论。我正在尝试自己学习这一点,所以我依赖于我在我参加的一些在线课程中学到的东西。我正在尝试将我在这些事情中学到的东西结合起来。我可能没有得到最好的信息,可能。那你会怎么设置呢?

标签: php oop iteration


【解决方案1】:

可能打破困境的一件事;在 PHP 中,对象也可以act as an array(或even a function!),但普通的普通数组不能有属性或任何其他 OOP 特性。

【讨论】:

  • 也许我根本不应该实例化 Post_Model 类的对象,而是用我需要的所有字段硬编码这个标准对象的创建。
  • 我不得不说.. 自己学习这个太难了...我正在努力学习如何以最好的方式做到这一点,每个人都有不同的意见。我所能做的基本上就是在谷歌上征求意见......但是建立这个系统的实际正确方法是什么......这对我来说是一个脑残。
【解决方案2】:

您将无法使用架构解决此问题,因为您在 Post 实体中混合了来自不同实体的属性 [即用户名]。

这个想法是,您只需让您的代码了解实体之间的关系,例如:

class Post extends Entity
{

  protected $id;
  protected $body;
  protected $date;

  // this will be an instance of a Thread entity, let's say
  protected $thread;

  // this will be an instance of the User entity
  protected $user;

  ...

}

这样你就可以做到:

$somePost -> getUser() -> getAvatar();

但是如何为每个帖子注入正确的用户和线程?这就是Object Relational Mappers 的用途:在您的情况下,所有 SQL 内容都将由 ORM 处理,您只需处理对象图,无需担心自己构建查询;你只需要定义这样的关系。

一个流行的 PHP ORM 是 Doctrine: here is an example about how it handles relationships declarations

当然,这种方法也有缺点,但这取决于您调查并找出灵活性和依赖性之间的最佳权衡。

【讨论】:

  • 谢谢!就在我觉得我快要接近了的时候......我发现我在这里有很多东西要学......我肯定会调查它。这至少让我进入了另一种思维模式,谢谢。
  • 那么我理解这里的主要“想法”了吗?控制器从模型中获取信息并将其传递给视图。模型告诉这个 Mapper 我需要数据库中的这些信息……去帮我拿吧?
猜你喜欢
  • 2011-12-26
  • 1970-01-01
  • 2019-09-23
  • 1970-01-01
  • 1970-01-01
  • 2012-07-07
  • 2017-08-01
  • 1970-01-01
  • 2016-04-10
相关资源
最近更新 更多