2013-06-28 3 views
1

Этот вопрос довольно конкретный и длительный, и имеет дело с , расширяющим модели CodeIgniter. Это не важно (мое приложение работает в настоящее время), но я спрашиваю об этом, потому что мне интересно, есть ли «чистый» способ сделать это.Вопрос дизайна класса для расширения моделей CodeIgniter

Я растолковал blog post об уловке, который я использую для , чтобы сделать методы CRUD обобщенными для моих моделей. Поскольку я использую только библиотеку базы данных, когда модели задействованы, я расширил базовую модель (MY_Model), чтобы просто загружать базу данных из своего конструктора, а не автозагружать ее. Это не очень важно для автозагрузки, но дело в этом (и это важно для дальнейшего); Я мог бы использовать этот конструктор для выполнения других задач в будущем, поэтому нуждается в конструкторе.

Когда я, хотя о создании общих методов CRUD, я снова подумал об использовании MY_Model и смог успешно определить методы «create», «update», «delete» и «load_from_id». Однако эти методы неявно ссылаются на интерфейс или набор методов, которые необходимо определить в любой модели (в дополнение к переопределению параметров static/constant, например, некоторой проверки или функции, вызываемой при удалении в каскад конкретные последствия в БД). Два решения; используйте PHP интерфейсы или сделайте MY_Model аннотация и объявите абстрактные методы.

Решение 2 не может быть реализовано, так как мне нужен действительный конструктор в MY_Model, и в любом случае мне нужно иметь возможность вызвать конструктор CI_Model (даже если в нем пока ничего нет, я не могу предположить никогда не будет). В этом случае стек наследования будет (бетон [CI_Model], аннотация [MY_Model], бетон [Any_model]), и мне нужно будет «пропустить поколение» при вызове parent::__construct(); из моей конкретной модели. Плюс я не знаю, поддерживает ли CI расширение абстрактных основных классов.

Для решения 1, я не уверен, что он может быть реализован. Скажем, я определяю конкретный класс MY_Model и интерфейс CrudModelInterface. Я поместил все атрибуты в MY_Model (они не могут быть в интерфейсе), но тогда мои методы CRUD должны их использовать, поэтому CrudModelInterface должен расширять MY_Model вправо? Вот где это становится нечетким для меня ...

При условии, что вы поняли, что я хочу сделать, не могли бы вы посоветовать мне о моем дизайне, как вы это сделаете и т. Д. Что-нибудь конструктивное. В настоящее время я просто не налагал ограничений для определения этих «методов интерфейса», но я делаю это в каждой модели, поэтому он работает. Это просто не очень чисто.

ответ

1

Рекомендованный вариант - использовать надбавку DataMapper ORM for CodeIgniter или другую библиотеку ORM вместо того, чтобы писать свою собственную вещь.

Но в ответ на ваш прямой вопрос, я думаю, вам не нужен интерфейс или абстрактные функции. Вот краткий пример MY_Model и другая конкретная модель

class MY_Model extends CI_Model { 

    public $_table; 

    public function find_all() { 
     return $this->db->from($this->_table)->get()->result_object(); 
    } 

    public function find_by_id($id, $id_field_name = 'id') { 
     $this->db->where("$this->_table.$id_field_name", $id); 
     $result = $this->find_all(); 
     return count($result) == 1 ? $result[0] : null; 
    } 

    public function insert($data) { 
     $this->db->insert($this->_table, (array) $data); 
     $id = $this->db->insert_id(); 
     return $id; 
    } 

    public function update($id, $data) { 
     if ($id != null) { // update existing record 
      $updated = $this->db->update($this->_table, $data, "id = $id"); 
      return $updated; 
     } else {   // add a new record 
      $inserted = $this->insert($data); 
      return $inserted; 
     } 
    } 

    public function delete($id) { 
     $deleted = $this->db->delete($this->_table, array('id' => $id), 1); 
     return $deleted; 
    } 

    ......... 

} 

Теперь все, что вам нужно сделать для того, чтобы взять прибыль функций MY_Model является определить вашу модель и установить _table переменного $ с именем таблицы.

class Users_Model extends MY_Model { 

    public $_table = 'users'; 

} 

В MY_Model вы можете добавить много других методов для дальнейшего расширения.Этот подход имеет форму Bonfire, которая является HMVC, построенной поверх CodeIgniter. See their implementation of MY_Model.

+0

Прежде всего спасибо за ваш ответ. Есть несколько вещей, которые не соответствуют этому (часть из этих причин также оправдывает мой вопрос): во-первых, интерфейс, о котором я говорил, был не для методов CRUD, а для методов, на которые они полагаются (обычно при удалении, метод обрабатывать удаление записей в других таблицах, которые относятся к удаленной записи, в первую очередь, это один пример). Во-вторых, передача '$ id' в качестве входа' find_by_id' является плохим дизайном; это противоречит тому, что должна делать модель - абстрагируйте механизмы передачи данных на уровне приложений. – Sheljohn

+1

В-третьих, в идеале нет смысла, чтобы имена таблиц и имена полей id были бы переменными экземпляра для данной модели. Они должны быть статическими или постоянными, чтобы быть одинаковыми во всех случаях. – Sheljohn

+0

В целом, я не считаю, что вы ошибаетесь, чтобы использовать свой код, поскольку я уверен, что он работает так, как должен, и соответствует вашим потребностям. Мой код тоже работает для меня, но мой вопрос касался того, как он должен реализовываться с использованием функций PHP, чтобы уважать его собственную логику и выглядеть меньше как «взломать», как он (по крайней мере, для меня) прямо сейчас. +1 за усилие, хотя;) – Sheljohn