mvc的良好模型类,跟踪属性

时间:2011-11-16 02:46:55

标签: php database model-view-controller class model

这是我的model_users类(它扩展的“模型”还没有任何东西 - 仍然试图准备好这个,然后抽象出用于其他模型的常用函数),Database::query只返回结果mysql_fetch_assoc()

class Model_User extends Model {    
    private static $_table = 'users';

    public function __construct($properties = array())
    {
        parent::__construct();
        foreach ($properties as $key => $value) {
            $this->{$key} = $value;
        }
    }

    public function exists()
    {
        return ($this->id) ? TRUE : FALSE;
    }

    public static function get_by_id($id = NULL)
    {
        if ($id)
        {
            $result = Database::query(
                sprintf('SELECT * FROM ' . self::$_table . ' WHERE id = %d', $id)
            );

            return new Model_User($result);
        }
        else
        {
            return new Model_User(array());
        }
    }

    public function save()
    {
        return TRUE;
    }
}

这允许我做类似的事情:

$u = Model_User::get_by_id(5);
        if ($u->exists())
        {
            echo $u->name;
            echo $u->id;
        }
        else
        {
            echo 'No user';
        }

我正在尝试学习如何使用没有orm或类似东西的模型(我以前使用过那些,但我想学习如何做一个简单的版本)。

我想知道如何以抽象的方式跟踪模型的属性,我已经看到了php的反射对象,这可能就是我需要的东西。我只想做一些事情:

$u = new Model_User();
$u->name = 'John';
$u->email = 'john@example.com';
$u->save();

或喜欢

$u = Model_User::get_by_id(2);
$u->email = 'someone@example.com';
$u->save();
// Different than the prior one since it would UPDATE, not INSERT

我不是在问如何实现整个save()方法,但我需要知道如何以一种允许我拥有易于使用的抽象模型类的方式来思考这个问题。我需要克服的障碍之一是有两种类型的属性,一种是模型的实际属性(在本例中为“name”或“email”),另一种类型与其他类型有关作为'表名'或甚至某些'有很多'关系信息。

1 个答案:

答案 0 :(得分:3)

一个答案是:元数据。

您需要跟踪有关数据的一些数据。

如果你想让你的db-columns在你的模型上公开为普通公共属性(并且你不想进入魔法_ get()/ _set()东西) ,您需要维护一个列表,其中某些属性需要从/向db读取/写入。

你可以拥有类似的东西;

<?php
class User extends Model {
    public $dbcols = array(
        'id',
        'name',
        'email'
    );
}

然后,save()方法将检查$ this-&gt; dbcols以确定需要担心的数据。在上面的示例中,update()方法可以执行以下操作:

function update(){
    $updates = array();
    foreach($this->dbcols as $name){
        $updates[$name] = "'{$this->escape($this->$name))}'";
    }
    $sql = "UPDATE {$this->tableName} SET " . implode(',',$updates) . " WHERE id={$this->id}";
    ...
}

当然,你可以使$ dbcols成为一个关联数组,并为你的属性和列名提供不同的标识符,添加验证或转义规则,最终使事情变得非常复杂。