CodeIgniter: куда должна идти конкретная функциональность? - PullRequest
5 голосов
/ 16 апреля 2010

Вот краткий обзор функциональности контроллеров в большинстве приложений:

  • Контроллер загружает конкретную модель, получает от нее данные, форматирует данные и передает отформатированные данные в представление.

Теперь есть страница поиска, которая должна выполнять поиск по всей базе данных (все модели). Он должен отображать каждый тип данных в определенном формате на одной странице в виде списка.

Проблема:

Контроллер поиска может выполнять поиск, динамически загружать модель для каждого типа записи и получать данные из модели. Проблема возникает, когда данные должны быть отформатированы. Я пытаюсь загрузить конкретный контроллер из контроллера поиска, что вызывает проблемы.

Что делать?

PS: я попытался использовать библиотеку 'Wick', но она перестала работать, когда функция форматирования контроллера пытается использовать свою собственную модель и объект сеанса, выдавая ошибки при вызове члена не-объекта.

Ответы [ 4 ]

2 голосов
/ 20 апреля 2010

После значительного рефакторинга и проб / ошибок выясняется, что лучший способ достичь вышеуказанного - это:

  1. Сохраните функцию форматирования в базовом контроллере, из которого получены все остальные контроллеры. Параметры формата передаются функции вместе с объектом данных в качестве аргументов.

  2. Создать статическую функцию в каждом производном контроллере, которая возвращает параметры форматирования данных.

  3. Внутри контроллера поиска (который сам является производным от базового контроллера) для каждого объекта данных вызовите статическую функцию своего конкретного контроллера, которая возвращает параметры форматирования данных, а затем используйте ее для форматирования объекта для вид.

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

0 голосов
/ 17 апреля 2010

Как правило, вы не можете загрузить другой контроллер изнутри контроллера в CodeIgniter (хотя есть моды, которые позволяют вам делать что-то подобное).

Я бы попробовал создать класс для форматирования ваших данных и добавить его в папку application / library. Затем загрузите, используйте и повторно используйте этот класс для всех ваших контроллеров.

Вот страница из документации CodeIgniter Создание собственных библиотек , которая объясняет детали и соглашения.

Кроме того, если класс является избыточным, создание вспомогательных функций является еще более легким подходом.

Разница между библиотеками и помощниками в CodeIgniter заключается в том, что библиотеки - это классы, а помощники - просто группа функций php.

После того, как вы отформатировали свои данные, вы можете загрузить любое представление с любого контроллера, так что у вас все равно должно быть все необходимое для повторного использования, чтобы вы СУХОЙ (не повторяйтесь)

0 голосов
/ 18 апреля 2010

Есть несколько простых подходов, основанных на принципе того, что проще (по сравнению с тем, что совершенно СУХОЙ). Вот один альтернативный подход, который я использую с CodeIgniter:

  1. Вместо того, чтобы пытаться загрузить несколько контроллеров, повторно используйте фрагменты представления с вашего поискового контроллера (или маршрута поиска, в зависимости от того, что вы используете). Это требует использования тех же соглашений об именах для ваших элементов данных, чтобы представления были взаимозаменяемыми, но вы все равно должны это делать.
  2. Вместо использования нескольких моделей для поиска, добавьте одну модель поиска, которая знает о вещах, по которым можно искать. Если вы хотите предотвратить дублирование SQL, повторно используйте SQL между моделями (это можно сделать с помощью констант или загрузкой SQL с диска).

Контроллеры не являются хорошими кандидатами для повторного использования из вашего собственного кода PHP: они направляют действия и запросы ресурсов самим вещам. Они предназначены для вызова через HTTP, используя интерфейс URI, который вы придумали. Вызов их из кода - это связь, которую вы хотите избежать. Тем не менее, повторное использование контроллеров из JavaScript (или через cURL) является отличным, изолированным способом повторного использования вещей в любой веб-среде.

0 голосов
/ 16 апреля 2010

Звучит так, как будто вы хотите использовать Шаблон фабричного дизайна

Сделать библиотеку:

class MyModelFactory {
  static public function Factory($data) {
    $type = key($data);
    return new $type($data);
  }
}

Теперь, в вашем контроллере, вы можете сделать что-то вроде этого:

$model = MyModelFactory::Factory(array($_REQUEST['model'] => $_REQUEST));

и теперь у вас есть объект любой модели, указанной в $ _REQUEST ['model']. Обязательно примите все меры безопасности, которые могут понадобиться вашему приложению, чтобы убедиться, что у пользователя есть разрешения на использование модели, которую он запрашивает

Теперь, так как вы хотите использовать общие методы и прочее, ваши модели, вероятно, должны основываться на абстрактном классе / интерфейсе ... поэтому вместо

class MyModelOne extends Model {
  // stuff
}

Вы, вероятно, хотите что-то подобное, чтобы гарантировать, что требуемые методы всегда будут доступны:

abstract class MyAbstractModel extends Model {

  protected $search_params;

  public function __construct($data = array()) {
     $search_params = $data['search_params'];
  }

  protected function GetSearchParameters() {
    return $this->search_params;
  }
  abstract public function GetData();
  abstract public function GetColumns();
  abstract public function DefineViewOptions();
}

class MyModelOne extends MyAbstractModel {


  public function GetData() {
    $params = array();
    $params[] = $this->db->escape_str($this->GetSearchParameters());
    // return whatever data you want, given the search parameter(s)
  }
  public function GetColumns() {
    // return some columns
  }
  public function DefineViewOptions() {
    // return some configuration options
  }
}
...