Хороший класс моделей для mvc, отслеживающий свойства


Вот мой класс 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 = '[email protected]';
$u->save();

Или как

$u = Model_User::get_by_id(2);
$u->email = '[email protected]';
$u->save();
// Different than the prior one since it would UPDATE, not INSERT

Я не спрашиваю, как реализовать весь метод save(), но мне нужно знать, как думать об этом таким образом, чтобы у меня был простой в использовании абстрактный класс модели. Один из барьеров, который мне нужно преодолеть, заключается в том, что существует два типа свойства, один тип, который является фактическим свойством модели (в данном случае "имя" или "электронная почта"), и другой тип, который имеет отношение к другим вещам, таким как "имя таблицы" или, возможно, даже к некоторым "имеет много" информации о связях.

Author: Matthew, 2011-11-16

1 answers

Один из ответов: метаданные.

Вам необходимо отслеживать некоторые данные о ваших данных.

Если вы хотите, чтобы ваши столбцы базы данных отображались в вашей модели как общедоступные свойства в виде простого ванили (и вы не хотите вдаваться в магию _get()/_set()), вам нужно где-то вести список, свойства которого должны быть прочитаны/записаны из/в бд.

У вас может быть что-то вроде;

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

Метод сохранения() затем проверит $this->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 ассоциативным массивом и иметь разные идентификаторы для своих свойств и имен столбцов, добавить правила проверки или экранирования и в конечном итоге все очень усложнить.

 3
Author: timdev, 2011-11-16 03:39:01